From b1ec2bd4e4906b35226bdf07497c7458638ba2f0 Mon Sep 17 00:00:00 2001 From: 0xmac Date: Thu, 28 Nov 2024 23:17:10 +0100 Subject: [PATCH] Updated CPU Module --- src/cpu.c | 218 +++++++++++++++--------------------------------------- 1 file changed, 60 insertions(+), 158 deletions(-) diff --git a/src/cpu.c b/src/cpu.c index b843af0..af298ae 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -12,14 +12,6 @@ extern uint8_t read6502(uint16_t address); extern void write6502(uint16_t address, uint8_t value); //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_ZERO 0x02 #define FLAG_INTERRUPT 0x04 @@ -35,18 +27,18 @@ extern void write6502(uint16_t address, uint8_t value); //flag modifier macros -#define setcarry() status |= FLAG_CARRY -#define clearcarry() status &= (~FLAG_CARRY) -#define setzero() status |= FLAG_ZERO -#define clearzero() status &= (~FLAG_ZERO) -#define setinterrupt() status |= FLAG_INTERRUPT -#define clearinterrupt() status &= (~FLAG_INTERRUPT) -#define setdecimal() status |= FLAG_DECIMAL -#define cleardecimal() status &= (~FLAG_DECIMAL) -#define setoverflow() status |= FLAG_OVERFLOW -#define clearoverflow() status &= (~FLAG_OVERFLOW) -#define setsign() status |= FLAG_SIGN -#define clearsign() status &= (~FLAG_SIGN) +#define setcarry() status |= FLAG_CARRY +#define clearcarry() status &= (~FLAG_CARRY) +#define setzero() status |= FLAG_ZERO +#define clearzero() status &= (~FLAG_ZERO) +#define setinterrupt() status |= FLAG_INTERRUPT +#define clearinterrupt() status &= (~FLAG_INTERRUPT) +#define setdecimal() status |= FLAG_DECIMAL +#define cleardecimal() status &= (~FLAG_DECIMAL) +#define setoverflow() status |= FLAG_OVERFLOW +#define clearoverflow() status &= (~FLAG_OVERFLOW) +#define setsign() status |= FLAG_SIGN +#define clearsign() status &= (~FLAG_SIGN) //flag calculation macros @@ -77,10 +69,17 @@ uint8_t sp, a, x, y, status = FLAG_CONSTANT; //helper variables -uint64_t instructions = 0; //keep track of total instructions executed -uint32_t clockticks6502 = 0, clockgoal6502 = 0; -uint16_t oldpc, ea, reladdr, value, result; -uint8_t opcode, oldstatus; +uint32_t clockticks6502 = 0; +uint32_t clockgoal6502 = 0; + +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 void push16(uint16_t pushval) { @@ -157,7 +156,7 @@ static void absx() { //absolute,X startpage = ea & 0xFF00; 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; } @@ -206,12 +205,12 @@ static void indy() { // (indirect),Y static uint16_t getvalue() { if (addrtable[opcode] == acc) return((uint16_t)a); - else return((uint16_t)read6502(ea)); + else return((uint16_t)read6502(ea)); } static void putvalue(uint16_t saveval) { if (addrtable[opcode] == acc) a = (uint8_t)(saveval & 0x00FF); - else write6502(ea, (saveval & 0x00FF)); + else write6502(ea, (saveval & 0x00FF)); } @@ -226,22 +225,6 @@ static void adc() { overflowcalc(result, a, value); 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); } @@ -272,7 +255,7 @@ static void bcc() { oldpc = pc; pc += reladdr; if ((oldpc & 0xFF00) != (pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary - else clockticks6502++; + else clockticks6502++; } } @@ -281,7 +264,7 @@ static void bcs() { oldpc = pc; pc += reladdr; if ((oldpc & 0xFF00) != (pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary - else clockticks6502++; + else clockticks6502++; } } @@ -290,7 +273,7 @@ static void beq() { oldpc = pc; pc += reladdr; if ((oldpc & 0xFF00) != (pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary - else clockticks6502++; + else clockticks6502++; } } @@ -307,7 +290,7 @@ static void bmi() { oldpc = pc; pc += reladdr; if ((oldpc & 0xFF00) != (pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary - else clockticks6502++; + else clockticks6502++; } } @@ -316,7 +299,7 @@ static void bne() { oldpc = pc; pc += reladdr; if ((oldpc & 0xFF00) != (pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary - else clockticks6502++; + else clockticks6502++; } } @@ -325,7 +308,7 @@ static void bpl() { oldpc = pc; pc += reladdr; if ((oldpc & 0xFF00) != (pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary - else clockticks6502++; + else clockticks6502++; } } @@ -342,7 +325,7 @@ static void bvc() { oldpc = pc; pc += reladdr; if ((oldpc & 0xFF00) != (pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary - else clockticks6502++; + else clockticks6502++; } } @@ -351,7 +334,7 @@ static void bvs() { oldpc = pc; pc += reladdr; if ((oldpc & 0xFF00) != (pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary - else clockticks6502++; + else clockticks6502++; } } @@ -377,9 +360,9 @@ static void cmp() { result = (uint16_t)a - value; if (a >= (uint8_t)(value & 0x00FF)) setcarry(); - else clearcarry(); + else clearcarry(); if (a == (uint8_t)(value & 0x00FF)) setzero(); - else clearzero(); + else clearzero(); signcalc(result); } @@ -388,9 +371,9 @@ static void cpx() { result = (uint16_t)x - value; if (x >= (uint8_t)(value & 0x00FF)) setcarry(); - else clearcarry(); + else clearcarry(); if (x == (uint8_t)(value & 0x00FF)) setzero(); - else clearzero(); + else clearzero(); signcalc(result); } @@ -399,9 +382,9 @@ static void cpy() { result = (uint16_t)y - value; if (y >= (uint8_t)(value & 0x00FF)) setcarry(); - else clearcarry(); + else clearcarry(); if (y == (uint8_t)(value & 0x00FF)) setzero(); - else clearzero(); + else clearzero(); signcalc(result); } @@ -505,7 +488,7 @@ static void lsr() { result = value >> 1; if (value & 1) setcarry(); - else clearcarry(); + else clearcarry(); zerocalc(result); signcalc(result); @@ -571,7 +554,8 @@ static void ror() { result = (value >> 1) | ((status & FLAG_CARRY) << 7); if (value & 1) setcarry(); - else clearcarry(); + else clearcarry(); + zerocalc(result); signcalc(result); @@ -599,23 +583,6 @@ static void sbc() { overflowcalc(result, a, value); 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); } @@ -682,67 +649,6 @@ static void tya() { 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])() = { /* | 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 */ @@ -765,22 +671,22 @@ static void (*addrtable[256])() = { static void (*optable[256])() = { /* | 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 */ -/* 1 */ bpl, ora, nop, slo, nop, ora, asl, slo, clc, ora, nop, slo, nop, ora, asl, slo, /* 1 */ -/* 2 */ jsr, and, nop, rla, bit, and, rol, rla, plp, and, rol, nop, bit, and, rol, rla, /* 2 */ -/* 3 */ bmi, and, nop, rla, nop, and, rol, rla, sec, and, nop, rla, nop, and, rol, rla, /* 3 */ -/* 4 */ rti, eor, nop, sre, nop, eor, lsr, sre, pha, eor, lsr, nop, jmp, eor, lsr, sre, /* 4 */ -/* 5 */ bvc, eor, nop, sre, nop, eor, lsr, sre, cli, eor, nop, sre, nop, eor, lsr, sre, /* 5 */ -/* 6 */ rts, adc, nop, rra, nop, adc, ror, rra, pla, adc, ror, nop, jmp, adc, ror, rra, /* 6 */ -/* 7 */ bvs, adc, nop, rra, nop, adc, ror, rra, sei, adc, nop, rra, nop, adc, ror, rra, /* 7 */ -/* 8 */ nop, sta, nop, sax, sty, sta, stx, sax, dey, nop, txa, nop, sty, sta, stx, sax, /* 8 */ -/* 9 */ bcc, sta, nop, nop, sty, sta, stx, sax, 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 */ -/* B */ bcs, lda, nop, lax, ldy, lda, ldx, lax, clv, lda, tsx, lax, ldy, lda, ldx, lax, /* B */ -/* C */ cpy, cmp, nop, dcp, cpy, cmp, dec, dcp, iny, cmp, dex, nop, cpy, cmp, dec, dcp, /* C */ -/* D */ bne, cmp, nop, dcp, nop, cmp, dec, dcp, cld, cmp, nop, dcp, nop, cmp, dec, dcp, /* D */ -/* E */ cpx, sbc, nop, isb, cpx, sbc, inc, isb, inx, sbc, nop, sbc, cpx, sbc, inc, isb, /* E */ -/* F */ beq, sbc, nop, isb, nop, sbc, inc, isb, sed, sbc, nop, isb, nop, sbc, inc, isb /* F */ +/* 0 */ brk, ora, nop, nop, nop, ora, asl, nop, php, ora, asl, nop, nop, ora, asl, nop, /* 0 */ +/* 1 */ bpl, ora, nop, nop, nop, ora, asl, nop, clc, ora, nop, nop, nop, ora, asl, nop, /* 1 */ +/* 2 */ jsr, and, nop, nop, bit, and, rol, nop, plp, and, rol, nop, bit, and, rol, nop, /* 2 */ +/* 3 */ bmi, and, nop, nop, nop, and, rol, nop, sec, and, nop, nop, nop, and, rol, nop, /* 3 */ +/* 4 */ rti, eor, nop, nop, nop, eor, lsr, nop, pha, eor, lsr, nop, jmp, eor, lsr, nop, /* 4 */ +/* 5 */ bvc, eor, nop, nop, nop, eor, lsr, nop, cli, eor, nop, nop, nop, eor, lsr, nop, /* 5 */ +/* 6 */ rts, adc, nop, nop, nop, adc, ror, nop, pla, adc, ror, nop, jmp, adc, ror, nop, /* 6 */ +/* 7 */ bvs, adc, nop, nop, nop, adc, ror, nop, sei, adc, nop, nop, nop, adc, ror, nop, /* 7 */ +/* 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, nop, tya, sta, txs, nop, nop, sta, nop, nop, /* 9 */ +/* A */ ldy, lda, ldx, nop, ldy, lda, ldx, nop, tay, lda, tax, nop, ldy, lda, ldx, nop, /* A */ +/* B */ bcs, lda, nop, nop, ldy, lda, ldx, nop, clv, lda, tsx, nop, ldy, lda, ldx, nop, /* B */ +/* C */ cpy, cmp, nop, nop, cpy, cmp, dec, nop, iny, cmp, dex, nop, cpy, cmp, dec, nop, /* C */ +/* D */ bne, cmp, nop, nop, nop, cmp, dec, nop, cld, cmp, nop, nop, nop, cmp, dec, nop, /* D */ +/* E */ cpx, sbc, nop, nop, cpx, sbc, inc, nop, inx, sbc, nop, sbc, cpx, sbc, inc, nop, /* E */ +/* F */ beq, sbc, nop, nop, nop, sbc, inc, nop, sed, sbc, nop, nop, nop, sbc, inc, nop /* F */ }; static const uint32_t ticktable[256] = { @@ -835,8 +741,6 @@ void exec6502(uint32_t tickcount) { clockticks6502 += ticktable[opcode]; if (penaltyop && penaltyaddr) clockticks6502++; - instructions++; - if (callexternal) (*loopexternal)(); } @@ -854,8 +758,6 @@ void step6502() { if (penaltyop && penaltyaddr) clockticks6502++; clockgoal6502 = clockticks6502; - instructions++; - if (callexternal) (*loopexternal)(); } @@ -864,4 +766,4 @@ void hookexternal(void *funcptr) { loopexternal = funcptr; callexternal = 1; } else callexternal = 0; -} \ No newline at end of file +}