diff options
Diffstat (limited to 'cpu.c')
-rw-r--r-- | cpu.c | 27 |
1 files changed, 22 insertions, 5 deletions
@@ -60,6 +60,8 @@ uint8_t memory[0x16000]; uint32_t cycles = 0; +bool page_crossed = false; + static uint8_t peek(uint16_t addr) { @@ -124,16 +126,26 @@ opcode_mem(enum addressing_mode mode) case AM_ZP_Y: val = (arg + regs.y) % 256; break; - case AM_IMM: case AM_REL: + val = arg + regs.pc; + if ((regs.pc + 1) & 0xFF00 != val & 0xFF00) + page_crossed = true; + break; + case AM_IMM: case AM_ABS: val = arg; break; case AM_ABS_X: val = arg + regs.x; + + if ((arg & 0xFF00) != (val & 0xFF00)) + page_crossed = true; break; case AM_ABS_Y: val = arg + regs.y; + + if ((arg & 0xFF00) != (val & 0xFF00)) + page_crossed = true; break; case AM_IND: val = peek(arg) | (peek(((arg + 1) & 0xFF) | (arg & 0xFF00)) << 8); @@ -143,6 +155,9 @@ opcode_mem(enum addressing_mode mode) break; case AM_IND_Y: val = peek(arg) + peek((arg + 1) % 256) * 256 + regs.y; + + if (((uint16_t)(val - regs.y) & 0xFF00) != (val & 0xFF00)) + page_crossed = true; break; default: fprintf(stderr, "INVALID ADDRESSING MODE %i\n", mode); @@ -159,10 +174,6 @@ branch(uint16_t addr, bool cond) return; cycles++; - addr += regs.pc; - if ((regs.pc + 1) & 0xFF00 != addr & 0xFF00) - cycles++; - regs.pc = addr; } @@ -763,7 +774,13 @@ interpret(void) opcodes[op].instr(peek(arg)); else opcodes[op].instr(arg); + cycles += opcodes[op].cycles; + if (page_crossed) { + if (opcodes[op].page_cross) + cycles++; + page_crossed = false; + } } loop_exit: } |