summaryrefslogtreecommitdiff
path: root/cpu.c
diff options
context:
space:
mode:
authorvin <git@vineetk.net>2024-07-04 11:18:38 -0400
committervin <git@vineetk.net>2024-07-04 11:18:38 -0400
commit5cd467eaf6b4f15f28b98c5fa49ab788dac945b3 (patch)
tree73914914cea40bcbb9f3fc6a2e71fe37256343a7 /cpu.c
parentd57acb77c7d617fbfe4e0c2fb6d19e1b60723a97 (diff)
achieve cycle accuracy for official opcodes
Now, the unofficial opcodes can be implemented, and then the PPU and APU.
Diffstat (limited to 'cpu.c')
-rw-r--r--cpu.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/cpu.c b/cpu.c
index 31f4be2..7ef4985 100644
--- a/cpu.c
+++ b/cpu.c
@@ -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:
}