summaryrefslogtreecommitdiff
path: root/cpu_opcodes_ud.c
diff options
context:
space:
mode:
authorPeter Fors <peter.fors@mindkiller.com>2025-10-09 22:07:52 +0200
committerPeter Fors <peter.fors@mindkiller.com>2025-10-09 22:07:52 +0200
commit030724a9aea346e4a9843d5842fb28c6d6c4cf1a (patch)
treef06fb84aaef64b2f4e2d81b3d2d3eef71bad83ec /cpu_opcodes_ud.c
parent412b2ef851516c1de8ba5006ddd284192cbcaf9b (diff)
Rearrangement and refactoring and optimizations and more accuracy
Diffstat (limited to 'cpu_opcodes_ud.c')
-rw-r--r--cpu_opcodes_ud.c1232
1 files changed, 0 insertions, 1232 deletions
diff --git a/cpu_opcodes_ud.c b/cpu_opcodes_ud.c
deleted file mode 100644
index e884ed4..0000000
--- a/cpu_opcodes_ud.c
+++ /dev/null
@@ -1,1232 +0,0 @@
-
-
-
-// NOP
-
-static void opcode_nop_imm(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- memory_read(state, cpu->pc++); // T1: consume operand
-}
-
-static void opcode_nop_zp(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t addr = memory_read(state, cpu->pc++); // T1
- memory_read_dummy(state, addr); // T2
-}
-
-static void opcode_nop_abs(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t lo = memory_read(state, cpu->pc++); // T1
- uint8_t hi = memory_read(state, cpu->pc++); // T2
- uint16_t addr = lo | (hi << 8);
-
- memory_read_dummy(state, addr); // T3
-}
-
-static void opcode_nop_zpx(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t base = memory_read(state, cpu->pc++); // T1: fetch operand
- memory_read_dummy(state, base); // T2: internal timing quirk (not used, but real)
- uint8_t addr = (base + cpu->x) & 0xff;
- memory_read_dummy(state, addr); // T3: final bus read to correct address
-}
-
-static void opcode_nop_absx(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t lo = memory_read(state, cpu->pc++); // T1
- uint8_t hi = memory_read(state, cpu->pc++); // T2
- uint16_t base = lo | (hi << 8);
- uint16_t addr = base + cpu->x;
-
- if(PAGE_CROSSED(base, addr)) {
- memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff)); // T3 dummy read
- }
-
- memory_read_dummy(state, addr); // T4 — final bus cycle (even if not used)
-}
-
-
-static void opcode_nop_implied(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- memory_read_dummy(state, cpu->pc); // T1
-}
-
-
-// LAX
-
-static void opcode_lax_imm(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t value = memory_read(state, cpu->pc++);
- cpu->a = value;
- cpu->x = value;
- update_zn(cpu, value);
-}
-
-static void opcode_lax_indx(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t zp = memory_read(state, cpu->pc++);
- memory_read_dummy(state, zp);
-
- uint8_t ptr = (zp + cpu->x) & 0xff;
- uint8_t lo = memory_read(state, ptr);
- uint8_t hi = memory_read(state, (ptr + 1) & 0xff);
- uint16_t addr = lo | (hi << 8);
-
- uint8_t value = memory_read(state, addr);
- cpu->a = value;
- cpu->x = value;
- update_zn(cpu, value);
-}
-
-static void opcode_lax_zp(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t addr = memory_read(state, cpu->pc++);
- uint8_t value = memory_read(state, addr);
-
- cpu->a = value;
- cpu->x = value;
- update_zn(cpu, value);
-}
-
-static void opcode_lax_zpy(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t base = memory_read(state, cpu->pc++);
- memory_read_dummy(state, base);
- uint8_t addr = (base + cpu->y) & 0xff;
-
- uint8_t value = memory_read(state, addr);
- cpu->a = value;
- cpu->x = value;
- update_zn(cpu, value);
-}
-
-static void opcode_lax_abs(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t lo = memory_read(state, cpu->pc++);
- uint8_t hi = memory_read(state, cpu->pc++);
- uint16_t addr = lo | (hi << 8);
-
- uint8_t value = memory_read(state, addr);
- cpu->a = value;
- cpu->x = value;
- update_zn(cpu, value);
-}
-
-static void opcode_lax_absy(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t lo = memory_read(state, cpu->pc++);
- uint8_t hi = memory_read(state, cpu->pc++);
- uint16_t base = lo | (hi << 8);
- uint16_t addr = base + cpu->y;
-
- if(PAGE_CROSSED(base, addr)) {
- memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff));
- }
-
- uint8_t value = memory_read(state, addr);
- cpu->a = value;
- cpu->x = value;
- update_zn(cpu, value);
-}
-
-static void opcode_lax_indy(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t zp = memory_read(state, cpu->pc++);
- uint8_t lo = memory_read(state, zp);
- uint8_t hi = memory_read(state, (zp + 1) & 0xff);
- uint16_t base = lo | (hi << 8);
- uint16_t addr = base + cpu->y;
-
- if(PAGE_CROSSED(base, addr)) {
- memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff));
- }
-
- uint8_t value = memory_read(state, addr);
- cpu->a = value;
- cpu->x = value;
- update_zn(cpu, value);
-}
-
-
-// SAX
-
-static void opcode_sax_indx(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t zp = memory_read(state, cpu->pc++); // T1
- memory_read_dummy(state, zp); // T2
- uint8_t ptr = zp + cpu->x;
- uint8_t lo = memory_read(state, ptr & 0xff); // T3
- uint8_t hi = memory_read(state, (ptr + 1) & 0xff); // T4
- uint16_t addr = lo | (hi << 8);
- memory_write(state, addr, cpu->a & cpu->x); // T5
-}
-
-
-static void opcode_sax_zp(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t addr = memory_read(state, cpu->pc++);
- memory_write(state, addr, cpu->a & cpu->x);
-}
-
-static void opcode_sax_abs(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t lo = memory_read(state, cpu->pc++);
- uint8_t hi = memory_read(state, cpu->pc++);
- uint16_t addr = lo | (hi << 8);
-
- memory_write(state, addr, cpu->a & cpu->x);
-}
-
-static void opcode_sax_zpy(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t base = memory_read(state, cpu->pc++);
- memory_read_dummy(state, base);
- uint8_t addr = (base + cpu->y) & 0xff;
-
- memory_write(state, addr, cpu->a & cpu->x);
-}
-
-static void opcode_sax_absy(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t lo = memory_read(state, cpu->pc++);
- uint8_t hi = memory_read(state, cpu->pc++);
- uint16_t base = lo | (hi << 8);
- uint16_t addr = base + cpu->y;
-
- memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff));
- memory_write(state, addr, cpu->a & cpu->x);
-}
-
-static void opcode_sax_indy(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t zp = memory_read(state, cpu->pc++); // T1
- uint8_t lo = memory_read(state, zp); // T2
- uint8_t hi = memory_read(state, (zp + 1) & 0xff); // T3
- uint16_t base = lo | (hi << 8);
- uint16_t addr = base + cpu->y;
-
- memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff)); // T4 (always)
- memory_write(state, addr, cpu->a & cpu->x); // T5
-}
-
-
-
-// DCP
-
-static void opcode_dcp_indx(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t zp = memory_read(state, cpu->pc++);
- memory_read_dummy(state, zp);
-
- uint8_t ptr = (zp + cpu->x) & 0xff;
- uint8_t lo = memory_read(state, ptr);
- uint8_t hi = memory_read(state, (ptr + 1) & 0xff);
- uint16_t addr = lo | (hi << 8);
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
- value--;
- memory_write(state, addr, value);
-
- uint16_t tmp = cpu->a - value;
- cpu->c = (cpu->a >= value);
- update_zn(cpu, tmp & 0xff);
-}
-
-static void opcode_dcp_zp(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t addr = memory_read(state, cpu->pc++);
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
- value--;
- memory_write(state, addr, value);
-
- uint16_t tmp = cpu->a - value;
- cpu->c = (cpu->a >= value);
- update_zn(cpu, tmp & 0xff);
-}
-
-static void opcode_dcp_abs(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t lo = memory_read(state, cpu->pc++);
- uint8_t hi = memory_read(state, cpu->pc++);
- uint16_t addr = lo | (hi << 8);
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
- value--;
- memory_write(state, addr, value);
-
- uint16_t tmp = cpu->a - value;
- cpu->c = (cpu->a >= value);
- update_zn(cpu, tmp & 0xff);
-}
-
-static void opcode_dcp_indy(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t zp = memory_read(state, cpu->pc++);
- uint8_t lo = memory_read(state, zp);
- uint8_t hi = memory_read(state, (zp + 1) & 0xff);
- uint16_t base = lo | (hi << 8);
- uint16_t addr = base + cpu->y;
-
- if(PAGE_CROSSED(base, addr)) {
- memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff));
- }
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
- value--;
- memory_write(state, addr, value);
-
- uint16_t tmp = cpu->a - value;
- cpu->c = (cpu->a >= value);
- update_zn(cpu, tmp & 0xff);
-}
-
-static void opcode_dcp_zpx(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t base = memory_read(state, cpu->pc++);
- memory_read_dummy(state, base);
- uint8_t addr = (base + cpu->x) & 0xff;
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
- value--;
- memory_write(state, addr, value);
-
- uint16_t tmp = cpu->a - value;
- cpu->c = (cpu->a >= value);
- update_zn(cpu, tmp & 0xff);
-}
-
-static void opcode_dcp_absy(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t lo = memory_read(state, cpu->pc++);
- uint8_t hi = memory_read(state, cpu->pc++);
- uint16_t base = lo | (hi << 8);
- uint16_t addr = base + cpu->y;
-
- memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff));
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
- value--;
- memory_write(state, addr, value);
-
- uint16_t tmp = cpu->a - value;
- cpu->c = (cpu->a >= value);
- update_zn(cpu, tmp & 0xff);
-}
-
-static void opcode_dcp_absx(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t lo = memory_read(state, cpu->pc++);
- uint8_t hi = memory_read(state, cpu->pc++);
- uint16_t base = lo | (hi << 8);
- uint16_t addr = base + cpu->x;
-
- memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff));
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
- value--;
- memory_write(state, addr, value);
-
- uint16_t tmp = cpu->a - value;
- cpu->c = (cpu->a >= value);
- update_zn(cpu, tmp & 0xff);
-}
-
-
-// ISC
-
-static void opcode_isc_indx(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t zp = memory_read(state, cpu->pc++);
- memory_read_dummy(state, zp);
-
- uint8_t ptr = (zp + cpu->x) & 0xff;
- uint8_t lo = memory_read(state, ptr);
- uint8_t hi = memory_read(state, (ptr + 1) & 0xff);
- uint16_t addr = lo | (hi << 8);
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
- value++;
- memory_write(state, addr, value);
-
- sbc(cpu, value);
-}
-
-static void opcode_isc_zp(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t addr = memory_read(state, cpu->pc++);
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
- value++;
- memory_write(state, addr, value);
-
- sbc(cpu, value);
-}
-
-static void opcode_isc_abs(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t lo = memory_read(state, cpu->pc++);
- uint8_t hi = memory_read(state, cpu->pc++);
- uint16_t addr = lo | (hi << 8);
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
- value++;
- memory_write(state, addr, value);
-
- sbc(cpu, value);
-}
-
-static void opcode_isc_indy(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t zp = memory_read(state, cpu->pc++);
- uint8_t lo = memory_read(state, zp);
- uint8_t hi = memory_read(state, (zp + 1) & 0xff);
- uint16_t base = lo | (hi << 8);
- uint16_t addr = base + cpu->y;
-
- if(PAGE_CROSSED(base, addr)) {
- memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff));
- }
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
- value++;
- memory_write(state, addr, value);
-
- sbc(cpu, value);
-}
-
-static void opcode_isc_zpx(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t base = memory_read(state, cpu->pc++);
- memory_read_dummy(state, base);
- uint8_t addr = (base + cpu->x) & 0xff;
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
- value++;
- memory_write(state, addr, value);
-
- sbc(cpu, value);
-}
-
-static void opcode_isc_absy(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t lo = memory_read(state, cpu->pc++);
- uint8_t hi = memory_read(state, cpu->pc++);
- uint16_t base = lo | (hi << 8);
- uint16_t addr = base + cpu->y;
-
- memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff));
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
- value++;
- memory_write(state, addr, value);
-
- sbc(cpu, value);
-}
-
-static void opcode_isc_absx(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t lo = memory_read(state, cpu->pc++);
- uint8_t hi = memory_read(state, cpu->pc++);
- uint16_t base = lo | (hi << 8);
- uint16_t addr = base + cpu->x;
-
- memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff));
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
- value++;
- memory_write(state, addr, value);
-
- sbc(cpu, value);
-}
-
-
-// SLO
-
-static void opcode_slo_indx(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t zp = memory_read(state, cpu->pc++);
- memory_read_dummy(state, zp);
-
- uint8_t ptr = (zp + cpu->x) & 0xff;
- uint8_t lo = memory_read(state, ptr);
- uint8_t hi = memory_read(state, (ptr + 1) & 0xff);
- uint16_t addr = lo | (hi << 8);
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- cpu->c = (value >> 7) & 1;
- value <<= 1;
-
- memory_write(state, addr, value);
- cpu->a |= value;
- update_zn(cpu, cpu->a);
-}
-
-static void opcode_slo_zp(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t addr = memory_read(state, cpu->pc++);
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- cpu->c = (value >> 7) & 1;
- value <<= 1;
-
- memory_write(state, addr, value);
- cpu->a |= value;
- update_zn(cpu, cpu->a);
-}
-
-static void opcode_slo_abs(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t lo = memory_read(state, cpu->pc++);
- uint8_t hi = memory_read(state, cpu->pc++);
- uint16_t addr = lo | (hi << 8);
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- cpu->c = (value >> 7) & 1;
- value <<= 1;
-
- memory_write(state, addr, value);
- cpu->a |= value;
- update_zn(cpu, cpu->a);
-}
-
-static void opcode_slo_indy(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t zp = memory_read(state, cpu->pc++);
- uint8_t lo = memory_read(state, zp);
- uint8_t hi = memory_read(state, (zp + 1) & 0xff);
- uint16_t base = lo | (hi << 8);
- uint16_t addr = base + cpu->y;
-
- if(PAGE_CROSSED(base, addr)) {
- memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff));
- }
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- cpu->c = (value >> 7) & 1;
- value <<= 1;
-
- memory_write(state, addr, value);
- cpu->a |= value;
- update_zn(cpu, cpu->a);
-}
-
-static void opcode_slo_zpx(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t base = memory_read(state, cpu->pc++);
- memory_read_dummy(state, base);
- uint8_t addr = (base + cpu->x) & 0xff;
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- cpu->c = (value >> 7) & 1;
- value <<= 1;
-
- memory_write(state, addr, value);
- cpu->a |= value;
- update_zn(cpu, cpu->a);
-}
-
-static void opcode_slo_absy(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t lo = memory_read(state, cpu->pc++);
- uint8_t hi = memory_read(state, cpu->pc++);
- uint16_t base = lo | (hi << 8);
- uint16_t addr = base + cpu->y;
-
- memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff));
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- cpu->c = (value >> 7) & 1;
- value <<= 1;
-
- memory_write(state, addr, value);
- cpu->a |= value;
- update_zn(cpu, cpu->a);
-}
-
-static void opcode_slo_absx(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t lo = memory_read(state, cpu->pc++);
- uint8_t hi = memory_read(state, cpu->pc++);
- uint16_t base = lo | (hi << 8);
- uint16_t addr = base + cpu->x;
-
- memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff));
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- cpu->c = (value >> 7) & 1;
- value <<= 1;
-
- memory_write(state, addr, value);
- cpu->a |= value;
- update_zn(cpu, cpu->a);
-}
-
-
-// RLA
-
-static void opcode_rla_indx(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t zp = memory_read(state, cpu->pc++);
- memory_read_dummy(state, zp);
-
- uint8_t ptr = (zp + cpu->x) & 0xff;
- uint8_t lo = memory_read(state, ptr);
- uint8_t hi = memory_read(state, (ptr + 1) & 0xff);
- uint16_t addr = lo | (hi << 8);
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- uint8_t in = cpu->c;
- cpu->c = (value >> 7) & 1;
- value = (value << 1) | in;
-
- memory_write(state, addr, value);
- cpu->a &= value;
- update_zn(cpu, cpu->a);
-}
-
-static void opcode_rla_zp(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t addr = memory_read(state, cpu->pc++);
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- uint8_t in = cpu->c;
- cpu->c = (value >> 7) & 1;
- value = (value << 1) | in;
-
- memory_write(state, addr, value);
- cpu->a &= value;
- update_zn(cpu, cpu->a);
-}
-
-static void opcode_rla_abs(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t lo = memory_read(state, cpu->pc++);
- uint8_t hi = memory_read(state, cpu->pc++);
- uint16_t addr = lo | (hi << 8);
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- uint8_t in = cpu->c;
- cpu->c = (value >> 7) & 1;
- value = (value << 1) | in;
-
- memory_write(state, addr, value);
- cpu->a &= value;
- update_zn(cpu, cpu->a);
-}
-
-static void opcode_rla_indy(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t zp = memory_read(state, cpu->pc++);
- uint8_t lo = memory_read(state, zp);
- uint8_t hi = memory_read(state, (zp + 1) & 0xff);
- uint16_t base = lo | (hi << 8);
- uint16_t addr = base + cpu->y;
-
- if(PAGE_CROSSED(base, addr)) {
- memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff));
- }
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- uint8_t in = cpu->c;
- cpu->c = (value >> 7) & 1;
- value = (value << 1) | in;
-
- memory_write(state, addr, value);
- cpu->a &= value;
- update_zn(cpu, cpu->a);
-}
-
-static void opcode_rla_zpx(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t base = memory_read(state, cpu->pc++);
- memory_read_dummy(state, base);
- uint8_t addr = (base + cpu->x) & 0xff;
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- uint8_t in = cpu->c;
- cpu->c = (value >> 7) & 1;
- value = (value << 1) | in;
-
- memory_write(state, addr, value);
- cpu->a &= value;
- update_zn(cpu, cpu->a);
-}
-
-static void opcode_rla_absy(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t lo = memory_read(state, cpu->pc++);
- uint8_t hi = memory_read(state, cpu->pc++);
- uint16_t base = lo | (hi << 8);
- uint16_t addr = base + cpu->y;
-
- memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff));
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- uint8_t in = cpu->c;
- cpu->c = (value >> 7) & 1;
- value = (value << 1) | in;
-
- memory_write(state, addr, value);
- cpu->a &= value;
- update_zn(cpu, cpu->a);
-}
-
-static void opcode_rla_absx(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t lo = memory_read(state, cpu->pc++);
- uint8_t hi = memory_read(state, cpu->pc++);
- uint16_t base = lo | (hi << 8);
- uint16_t addr = base + cpu->x;
-
- memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff));
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- uint8_t in = cpu->c;
- cpu->c = (value >> 7) & 1;
- value = (value << 1) | in;
-
- memory_write(state, addr, value);
- cpu->a &= value;
- update_zn(cpu, cpu->a);
-}
-
-
-// SRE
-
-static void opcode_sre_indx(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t zp = memory_read(state, cpu->pc++);
- memory_read_dummy(state, zp);
-
- uint8_t ptr = (zp + cpu->x) & 0xff;
- uint8_t lo = memory_read(state, ptr);
- uint8_t hi = memory_read(state, (ptr + 1) & 0xff);
- uint16_t addr = lo | (hi << 8);
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- cpu->c = value & 1;
- value >>= 1;
-
- memory_write(state, addr, value);
- cpu->a ^= value;
- update_zn(cpu, cpu->a);
-}
-
-static void opcode_sre_zp(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t addr = memory_read(state, cpu->pc++);
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- cpu->c = value & 1;
- value >>= 1;
-
- memory_write(state, addr, value);
- cpu->a ^= value;
- update_zn(cpu, cpu->a);
-}
-
-static void opcode_sre_abs(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t lo = memory_read(state, cpu->pc++);
- uint8_t hi = memory_read(state, cpu->pc++);
- uint16_t addr = lo | (hi << 8);
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- cpu->c = value & 1;
- value >>= 1;
-
- memory_write(state, addr, value);
- cpu->a ^= value;
- update_zn(cpu, cpu->a);
-}
-
-static void opcode_sre_indy(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t zp = memory_read(state, cpu->pc++);
- uint8_t lo = memory_read(state, zp);
- uint8_t hi = memory_read(state, (zp + 1) & 0xff);
- uint16_t base = lo | (hi << 8);
- uint16_t addr = base + cpu->y;
-
- if(PAGE_CROSSED(base, addr)) {
- memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff));
- }
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- cpu->c = value & 1;
- value >>= 1;
-
- memory_write(state, addr, value);
- cpu->a ^= value;
- update_zn(cpu, cpu->a);
-}
-
-static void opcode_sre_zpx(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t base = memory_read(state, cpu->pc++);
- memory_read_dummy(state, base);
- uint8_t addr = (base + cpu->x) & 0xff;
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- cpu->c = value & 1;
- value >>= 1;
-
- memory_write(state, addr, value);
- cpu->a ^= value;
- update_zn(cpu, cpu->a);
-}
-
-static void opcode_sre_absy(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t lo = memory_read(state, cpu->pc++);
- uint8_t hi = memory_read(state, cpu->pc++);
- uint16_t base = lo | (hi << 8);
- uint16_t addr = base + cpu->y;
-
- memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff));
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- cpu->c = value & 1;
- value >>= 1;
-
- memory_write(state, addr, value);
- cpu->a ^= value;
- update_zn(cpu, cpu->a);
-}
-
-static void opcode_sre_absx(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t lo = memory_read(state, cpu->pc++);
- uint8_t hi = memory_read(state, cpu->pc++);
- uint16_t base = lo | (hi << 8);
- uint16_t addr = base + cpu->x;
-
- memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff));
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- cpu->c = value & 1;
- value >>= 1;
-
- memory_write(state, addr, value);
- cpu->a ^= value;
- update_zn(cpu, cpu->a);
-}
-
-
-// opcode_rra
-
-static void opcode_rra_indx(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t zp = memory_read(state, cpu->pc++);
- memory_read_dummy(state, zp);
-
- uint8_t ptr = (zp + cpu->x) & 0xff;
- uint8_t lo = memory_read(state, ptr);
- uint8_t hi = memory_read(state, (ptr + 1) & 0xff);
- uint16_t addr = lo | (hi << 8);
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- uint8_t new_c = value & 1;
- value = (value >> 1) | (cpu->c << 7);
- cpu->c = new_c;
-
- memory_write(state, addr, value);
- adc(cpu, value);
-}
-
-static void opcode_rra_zp(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t addr = memory_read(state, cpu->pc++);
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- uint8_t new_c = value & 1;
- value = (value >> 1) | (cpu->c << 7);
- cpu->c = new_c;
-
- memory_write(state, addr, value);
- adc(cpu, value);
-}
-
-static void opcode_rra_abs(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t lo = memory_read(state, cpu->pc++);
- uint8_t hi = memory_read(state, cpu->pc++);
- uint16_t addr = lo | (hi << 8);
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- uint8_t new_c = value & 1;
- value = (value >> 1) | (cpu->c << 7);
- cpu->c = new_c;
-
- memory_write(state, addr, value);
- adc(cpu, value);
-}
-
-static void opcode_rra_indy(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t zp = memory_read(state, cpu->pc++);
- uint8_t lo = memory_read(state, zp);
- uint8_t hi = memory_read(state, (zp + 1) & 0xff);
- uint16_t base = lo | (hi << 8);
- uint16_t addr = base + cpu->y;
-
- if(PAGE_CROSSED(base, addr)) {
- memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff));
- }
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- uint8_t new_c = value & 1;
- value = (value >> 1) | (cpu->c << 7);
- cpu->c = new_c;
-
- memory_write(state, addr, value);
- adc(cpu, value);
-}
-
-static void opcode_rra_zpx(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t base = memory_read(state, cpu->pc++);
- memory_read_dummy(state, base);
- uint8_t addr = (base + cpu->x) & 0xff;
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- uint8_t new_c = value & 1;
- value = (value >> 1) | (cpu->c << 7);
- cpu->c = new_c;
-
- memory_write(state, addr, value);
- adc(cpu, value);
-}
-
-static void opcode_rra_absy(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t lo = memory_read(state, cpu->pc++);
- uint8_t hi = memory_read(state, cpu->pc++);
- uint16_t base = lo | (hi << 8);
- uint16_t addr = base + cpu->y;
-
- memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff));
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- uint8_t new_c = value & 1;
- value = (value >> 1) | (cpu->c << 7);
- cpu->c = new_c;
-
- memory_write(state, addr, value);
- adc(cpu, value);
-}
-
-static void opcode_rra_absx(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t lo = memory_read(state, cpu->pc++);
- uint8_t hi = memory_read(state, cpu->pc++);
- uint16_t base = lo | (hi << 8);
- uint16_t addr = base + cpu->x;
-
- memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff));
-
- uint8_t value = memory_read(state, addr);
- memory_write(state, addr, value); // dummy write
-
- uint8_t new_c = value & 1;
- value = (value >> 1) | (cpu->c << 7);
- cpu->c = new_c;
-
- memory_write(state, addr, value);
- adc(cpu, value);
-}
-
-
-// ALR
-
-static void opcode_alr_imm(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
- uint8_t value = memory_read(state, cpu->pc++);
- cpu->a &= value;
- cpu->c = cpu->a & 1;
- cpu->a >>= 1;
- update_zn(cpu, cpu->a);
-}
-
-
-// ANC
-
-static void opcode_anc_imm(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
- uint8_t value = memory_read(state, cpu->pc++);
- cpu->a &= value;
- cpu->c = (cpu->a >> 7) & 1;
- update_zn(cpu, cpu->a);
-}
-
-
-// ARR
-
-static void opcode_arr_imm(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t value = memory_read(state, cpu->pc++);
- cpu->a &= value;
-
- uint8_t in = cpu->c << 7;
- cpu->c = (cpu->a >> 0) & 1;
- cpu->a = (cpu->a >> 1) | in;
-
- update_zn(cpu, cpu->a);
- cpu->v = ((cpu->a >> 6) ^ (cpu->a >> 5)) & 1;
-}
-
-
-// XAA
-
-static void opcode_xaa_imm(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t value = memory_read(state, cpu->pc++);
- cpu->a = cpu->a & cpu->x & value;
- update_zn(cpu, cpu->a);
-}
-
-
-// AXS
-
-static void opcode_axs_imm(struct nes_state *state) {
- struct cpu_state * restrict cpu = &state->cpu;
-
- uint8_t value = memory_read(state, cpu->pc++);
- cpu->a = cpu->x & value;
- update_zn(cpu, cpu->a);
-}
-
-
-
-
-__attribute__((noinline))
-static void init_opcode_ud_lut(void) {
- opcode_lut[0x80] = opcode_nop_imm;
- opcode_lut[0x82] = opcode_nop_imm;
- opcode_lut[0x89] = opcode_nop_imm;
- opcode_lut[0xc2] = opcode_nop_imm;
- opcode_lut[0xe2] = opcode_nop_imm;
-
- opcode_lut[0x04] = opcode_nop_zp;
- opcode_lut[0x44] = opcode_nop_zp;
- opcode_lut[0x64] = opcode_nop_zp;
-
- opcode_lut[0x0c] = opcode_nop_abs;
-
- opcode_lut[0x14] = opcode_nop_zpx;
- opcode_lut[0x34] = opcode_nop_zpx;
- opcode_lut[0x54] = opcode_nop_zpx;
- opcode_lut[0x74] = opcode_nop_zpx;
- opcode_lut[0xd4] = opcode_nop_zpx;
- opcode_lut[0xf4] = opcode_nop_zpx;
-
- opcode_lut[0x1c] = opcode_nop_absx;
- opcode_lut[0x3c] = opcode_nop_absx;
- opcode_lut[0x5c] = opcode_nop_absx;
- opcode_lut[0x7c] = opcode_nop_absx;
- opcode_lut[0xdc] = opcode_nop_absx;
- opcode_lut[0xfc] = opcode_nop_absx;
-
- opcode_lut[0x1a] = opcode_nop_implied;
- opcode_lut[0x3a] = opcode_nop_implied;
- opcode_lut[0x5a] = opcode_nop_implied;
- opcode_lut[0x7a] = opcode_nop_implied;
- opcode_lut[0xda] = opcode_nop_implied;
- opcode_lut[0xfa] = opcode_nop_implied;
-
- opcode_lut[0xab] = opcode_lax_imm;
- opcode_lut[0xa3] = opcode_lax_indx;
- opcode_lut[0xaf] = opcode_lax_abs;
- opcode_lut[0xbb] = opcode_lax_absy;
- opcode_lut[0xbf] = opcode_lax_absy;
- opcode_lut[0xa7] = opcode_lax_zp;
- opcode_lut[0xb7] = opcode_lax_zpy;
- opcode_lut[0xb3] = opcode_lax_indy;
-
- opcode_lut[0x83] = opcode_sax_indx;
- opcode_lut[0x8f] = opcode_sax_abs;
- opcode_lut[0x9f] = opcode_sax_absy;
- opcode_lut[0x87] = opcode_sax_zp;
- opcode_lut[0x97] = opcode_sax_zpy;
- opcode_lut[0x93] = opcode_sax_indy;
-
- opcode_lut[0xc3] = opcode_dcp_indx;
- opcode_lut[0xc7] = opcode_dcp_zp;
- opcode_lut[0xcf] = opcode_dcp_abs;
- opcode_lut[0xd3] = opcode_dcp_indy;
- opcode_lut[0xd7] = opcode_dcp_zpx;
- opcode_lut[0xdb] = opcode_dcp_absy;
- opcode_lut[0xdf] = opcode_dcp_absx;
-
- opcode_lut[0xe3] = opcode_isc_indx;
- opcode_lut[0xe7] = opcode_isc_zp;
- opcode_lut[0xef] = opcode_isc_abs;
- opcode_lut[0xf3] = opcode_isc_indy;
- opcode_lut[0xf7] = opcode_isc_zpx;
- opcode_lut[0xfb] = opcode_isc_absy;
- opcode_lut[0xff] = opcode_isc_absx;
-
- opcode_lut[0x03] = opcode_slo_indx;
- opcode_lut[0x07] = opcode_slo_zp;
- opcode_lut[0x0f] = opcode_slo_abs;
- opcode_lut[0x13] = opcode_slo_indy;
- opcode_lut[0x17] = opcode_slo_zpx;
- opcode_lut[0x1b] = opcode_slo_absy;
- opcode_lut[0x1f] = opcode_slo_absx;
-
- opcode_lut[0x23] = opcode_rla_indx;
- opcode_lut[0x27] = opcode_rla_zp;
- opcode_lut[0x2f] = opcode_rla_abs;
- opcode_lut[0x33] = opcode_rla_indy;
- opcode_lut[0x37] = opcode_rla_zpx;
- opcode_lut[0x3b] = opcode_rla_absy;
- opcode_lut[0x3f] = opcode_rla_absx;
-
- opcode_lut[0x43] = opcode_sre_indx;
- opcode_lut[0x47] = opcode_sre_zp;
- opcode_lut[0x4f] = opcode_sre_abs;
- opcode_lut[0x53] = opcode_sre_indy;
- opcode_lut[0x57] = opcode_sre_zpx;
- opcode_lut[0x5b] = opcode_sre_absy;
- opcode_lut[0x5f] = opcode_sre_absx;
-
- opcode_lut[0x63] = opcode_rra_indx;
- opcode_lut[0x67] = opcode_rra_zp;
- opcode_lut[0x6f] = opcode_rra_abs;
- opcode_lut[0x73] = opcode_rra_indy;
- opcode_lut[0x77] = opcode_rra_zpx;
- opcode_lut[0x7b] = opcode_rra_absy;
- opcode_lut[0x7f] = opcode_rra_absx;
-
- opcode_lut[0x32] = opcode_anc_imm;
- opcode_lut[0x4b] = opcode_alr_imm;
- opcode_lut[0x8b] = opcode_xaa_imm;
- opcode_lut[0xcb] = opcode_axs_imm;
- opcode_lut[0x6b] = opcode_arr_imm;
-}