Updated CPU Module

This commit is contained in:
0xmac 2024-11-28 23:17:10 +01:00
parent 7a668f2462
commit b1ec2bd4e4

156
src/cpu.c
View File

@ -12,14 +12,6 @@ extern uint8_t read6502(uint16_t address);
extern void write6502(uint16_t address, uint8_t value); extern void write6502(uint16_t address, uint8_t value);
//6502 defines //6502 defines
#define UNDOCUMENTED //when this is defined, undocumented opcodes are handled.
//otherwise, they're simply treated as NOPs.
//#define NES_CPU //when this is defined, the binary-coded decimal (BCD)
//status flag is not honored by ADC and SBC. the 2A03
//CPU in the Nintendo Entertainment System does not
//support BCD operation.
#define FLAG_CARRY 0x01 #define FLAG_CARRY 0x01
#define FLAG_ZERO 0x02 #define FLAG_ZERO 0x02
#define FLAG_INTERRUPT 0x04 #define FLAG_INTERRUPT 0x04
@ -77,10 +69,17 @@ uint8_t sp, a, x, y, status = FLAG_CONSTANT;
//helper variables //helper variables
uint64_t instructions = 0; //keep track of total instructions executed uint32_t clockticks6502 = 0;
uint32_t clockticks6502 = 0, clockgoal6502 = 0; uint32_t clockgoal6502 = 0;
uint16_t oldpc, ea, reladdr, value, result;
uint8_t opcode, oldstatus; uint16_t oldpc;
uint16_t ea;
uint16_t reladdr;
uint16_t value;
uint16_t result;
uint8_t opcode;
uint8_t oldstatus;
//a few general functions used by various other functions //a few general functions used by various other functions
void push16(uint16_t pushval) { void push16(uint16_t pushval) {
@ -157,7 +156,7 @@ static void absx() { //absolute,X
startpage = ea & 0xFF00; startpage = ea & 0xFF00;
ea += (uint16_t)x; ea += (uint16_t)x;
if (startpage != (ea & 0xFF00)) { //one cycle penlty for page-crossing on some opcodes if (startpage != (ea & 0xFF00)) { //one cycle penalty for page-crossing on some opcodes
penaltyaddr = 1; penaltyaddr = 1;
} }
@ -226,22 +225,6 @@ static void adc() {
overflowcalc(result, a, value); overflowcalc(result, a, value);
signcalc(result); signcalc(result);
#ifndef NES_CPU
if (status & FLAG_DECIMAL) {
clearcarry();
if ((a & 0x0F) > 0x09) {
a += 0x06;
}
if ((a & 0xF0) > 0x90) {
a += 0x60;
setcarry();
}
clockticks6502++;
}
#endif
saveaccum(result); saveaccum(result);
} }
@ -572,6 +555,7 @@ static void ror() {
if (value & 1) setcarry(); if (value & 1) setcarry();
else clearcarry(); else clearcarry();
zerocalc(result); zerocalc(result);
signcalc(result); signcalc(result);
@ -599,23 +583,6 @@ static void sbc() {
overflowcalc(result, a, value); overflowcalc(result, a, value);
signcalc(result); signcalc(result);
#ifndef NES_CPU
if (status & FLAG_DECIMAL) {
clearcarry();
a -= 0x66;
if ((a & 0x0F) > 0x09) {
a += 0x06;
}
if ((a & 0xF0) > 0x90) {
a += 0x60;
setcarry();
}
clockticks6502++;
}
#endif
saveaccum(result); saveaccum(result);
} }
@ -682,67 +649,6 @@ static void tya() {
signcalc(a); signcalc(a);
} }
//undocumented instructions
#ifdef UNDOCUMENTED
static void lax() {
lda();
ldx();
}
static void sax() {
sta();
stx();
putvalue(a & x);
if (penaltyop && penaltyaddr) clockticks6502--;
}
static void dcp() {
dec();
cmp();
if (penaltyop && penaltyaddr) clockticks6502--;
}
static void isb() {
inc();
sbc();
if (penaltyop && penaltyaddr) clockticks6502--;
}
static void slo() {
asl();
ora();
if (penaltyop && penaltyaddr) clockticks6502--;
}
static void rla() {
rol();
and();
if (penaltyop && penaltyaddr) clockticks6502--;
}
static void sre() {
lsr();
eor();
if (penaltyop && penaltyaddr) clockticks6502--;
}
static void rra() {
ror();
adc();
if (penaltyop && penaltyaddr) clockticks6502--;
}
#else
#define lax nop
#define sax nop
#define dcp nop
#define isb nop
#define slo nop
#define rla nop
#define sre nop
#define rra nop
#endif
static void (*addrtable[256])() = { static void (*addrtable[256])() = {
/* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | */ /* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | */
/* 0 */ imp, indx, imp, indx, zp, zp, zp, zp, imp, imm, acc, imm, abso, abso, abso, abso, /* 0 */ /* 0 */ imp, indx, imp, indx, zp, zp, zp, zp, imp, imm, acc, imm, abso, abso, abso, abso, /* 0 */
@ -765,22 +671,22 @@ static void (*addrtable[256])() = {
static void (*optable[256])() = { static void (*optable[256])() = {
/* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | */ /* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | */
/* 0 */ brk, ora, nop, slo, nop, ora, asl, slo, php, ora, asl, nop, nop, ora, asl, slo, /* 0 */ /* 0 */ brk, ora, nop, nop, nop, ora, asl, nop, php, ora, asl, nop, nop, ora, asl, nop, /* 0 */
/* 1 */ bpl, ora, nop, slo, nop, ora, asl, slo, clc, ora, nop, slo, nop, ora, asl, slo, /* 1 */ /* 1 */ bpl, ora, nop, nop, nop, ora, asl, nop, clc, ora, nop, nop, nop, ora, asl, nop, /* 1 */
/* 2 */ jsr, and, nop, rla, bit, and, rol, rla, plp, and, rol, nop, bit, and, rol, rla, /* 2 */ /* 2 */ jsr, and, nop, nop, bit, and, rol, nop, plp, and, rol, nop, bit, and, rol, nop, /* 2 */
/* 3 */ bmi, and, nop, rla, nop, and, rol, rla, sec, and, nop, rla, nop, and, rol, rla, /* 3 */ /* 3 */ bmi, and, nop, nop, nop, and, rol, nop, sec, and, nop, nop, nop, and, rol, nop, /* 3 */
/* 4 */ rti, eor, nop, sre, nop, eor, lsr, sre, pha, eor, lsr, nop, jmp, eor, lsr, sre, /* 4 */ /* 4 */ rti, eor, nop, nop, nop, eor, lsr, nop, pha, eor, lsr, nop, jmp, eor, lsr, nop, /* 4 */
/* 5 */ bvc, eor, nop, sre, nop, eor, lsr, sre, cli, eor, nop, sre, nop, eor, lsr, sre, /* 5 */ /* 5 */ bvc, eor, nop, nop, nop, eor, lsr, nop, cli, eor, nop, nop, nop, eor, lsr, nop, /* 5 */
/* 6 */ rts, adc, nop, rra, nop, adc, ror, rra, pla, adc, ror, nop, jmp, adc, ror, rra, /* 6 */ /* 6 */ rts, adc, nop, nop, nop, adc, ror, nop, pla, adc, ror, nop, jmp, adc, ror, nop, /* 6 */
/* 7 */ bvs, adc, nop, rra, nop, adc, ror, rra, sei, adc, nop, rra, nop, adc, ror, rra, /* 7 */ /* 7 */ bvs, adc, nop, nop, nop, adc, ror, nop, sei, adc, nop, nop, nop, adc, ror, nop, /* 7 */
/* 8 */ nop, sta, nop, sax, sty, sta, stx, sax, dey, nop, txa, nop, sty, sta, stx, sax, /* 8 */ /* 8 */ nop, sta, nop, nop, sty, sta, stx, nop, dey, nop, txa, nop, sty, sta, stx, nop, /* 8 */
/* 9 */ bcc, sta, nop, nop, sty, sta, stx, sax, tya, sta, txs, nop, nop, sta, nop, nop, /* 9 */ /* 9 */ bcc, sta, nop, nop, sty, sta, stx, nop, tya, sta, txs, nop, nop, sta, nop, nop, /* 9 */
/* A */ ldy, lda, ldx, lax, ldy, lda, ldx, lax, tay, lda, tax, nop, ldy, lda, ldx, lax, /* A */ /* A */ ldy, lda, ldx, nop, ldy, lda, ldx, nop, tay, lda, tax, nop, ldy, lda, ldx, nop, /* A */
/* B */ bcs, lda, nop, lax, ldy, lda, ldx, lax, clv, lda, tsx, lax, ldy, lda, ldx, lax, /* B */ /* B */ bcs, lda, nop, nop, ldy, lda, ldx, nop, clv, lda, tsx, nop, ldy, lda, ldx, nop, /* B */
/* C */ cpy, cmp, nop, dcp, cpy, cmp, dec, dcp, iny, cmp, dex, nop, cpy, cmp, dec, dcp, /* C */ /* C */ cpy, cmp, nop, nop, cpy, cmp, dec, nop, iny, cmp, dex, nop, cpy, cmp, dec, nop, /* C */
/* D */ bne, cmp, nop, dcp, nop, cmp, dec, dcp, cld, cmp, nop, dcp, nop, cmp, dec, dcp, /* D */ /* D */ bne, cmp, nop, nop, nop, cmp, dec, nop, cld, cmp, nop, nop, nop, cmp, dec, nop, /* D */
/* E */ cpx, sbc, nop, isb, cpx, sbc, inc, isb, inx, sbc, nop, sbc, cpx, sbc, inc, isb, /* E */ /* E */ cpx, sbc, nop, nop, cpx, sbc, inc, nop, inx, sbc, nop, sbc, cpx, sbc, inc, nop, /* E */
/* F */ beq, sbc, nop, isb, nop, sbc, inc, isb, sed, sbc, nop, isb, nop, sbc, inc, isb /* F */ /* F */ beq, sbc, nop, nop, nop, sbc, inc, nop, sed, sbc, nop, nop, nop, sbc, inc, nop /* F */
}; };
static const uint32_t ticktable[256] = { static const uint32_t ticktable[256] = {
@ -835,8 +741,6 @@ void exec6502(uint32_t tickcount) {
clockticks6502 += ticktable[opcode]; clockticks6502 += ticktable[opcode];
if (penaltyop && penaltyaddr) clockticks6502++; if (penaltyop && penaltyaddr) clockticks6502++;
instructions++;
if (callexternal) (*loopexternal)(); if (callexternal) (*loopexternal)();
} }
@ -854,8 +758,6 @@ void step6502() {
if (penaltyop && penaltyaddr) clockticks6502++; if (penaltyop && penaltyaddr) clockticks6502++;
clockgoal6502 = clockticks6502; clockgoal6502 = clockticks6502;
instructions++;
if (callexternal) (*loopexternal)(); if (callexternal) (*loopexternal)();
} }