From 030724a9aea346e4a9843d5842fb28c6d6c4cf1a Mon Sep 17 00:00:00 2001 From: Peter Fors Date: Thu, 9 Oct 2025 22:07:52 +0200 Subject: Rearrangement and refactoring and optimizations and more accuracy --- cpu_opcodes.c | 2291 --------------------------------------------------------- 1 file changed, 2291 deletions(-) delete mode 100644 cpu_opcodes.c (limited to 'cpu_opcodes.c') diff --git a/cpu_opcodes.c b/cpu_opcodes.c deleted file mode 100644 index 1a70cce..0000000 --- a/cpu_opcodes.c +++ /dev/null @@ -1,2291 +0,0 @@ - - -// ADC -static inline void adc(struct cpu_state *cpu, uint8_t value) { -#ifdef ENABLE_DECIMAL_MODE - if(cpu->d) { - uint8_t al = (cpu->a & 0x0f) + (value & 0x0f) + cpu->c; - uint8_t ah = (cpu->a >> 4) + (value >> 4); - if(al > 9) { - al += 6; - ah++; - } - cpu->c = (ah > 9); - if(cpu->c) { - ah += 6; - } - cpu->a = (ah << 4) | (al & 0x0f); - update_zn(cpu, cpu->a); - // Note: overflow flag behavior in decimal mode is undefined on 6502 - return; - } -#endif - - uint16_t sum = cpu->a + value + cpu->c; - cpu->c = (sum > 0xff); - uint8_t result = sum & 0xff; - cpu->v = (~(cpu->a ^ value) & (cpu->a ^ result)) & 0x80 ? 1 : 0; - cpu->a = result; - update_zn(cpu, result); -} - - -// ADC ($nn,X) -static void opcode_adc_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) & 0xff; - uint8_t lo = memory_read(state, ptr); // T3 - uint8_t hi = memory_read(state, (ptr + 1) & 0xff); // T4 - uint16_t addr = lo | (hi << 8); - - uint8_t value = memory_read(state, addr); // T5 - - adc(cpu, value); // T6+ -} - -// ADC $nn -static void opcode_adc_zp(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t addr = memory_read(state, cpu->pc++); // T1 - uint8_t value = memory_read(state, addr); // T2 - - adc(cpu, value); // T3 -} - -// ADC #$nn -static void opcode_adc_imm(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t value = memory_read(state, cpu->pc++); // T1 - adc(cpu, value); // T2 -} - -// ADC $nnnn -static void opcode_adc_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); - - uint8_t value = memory_read(state, addr); // T3 - adc(cpu, value); // T4 -} - -// ADC ($nn),Y -static void opcode_adc_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; - - if(PAGE_CROSSED(base, addr)) { - memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff)); // T4 (dummy if crossed) - } - - uint8_t value = memory_read(state, addr); // T4 or T5 - adc(cpu, value); // T5 or T6 -} - -// ADC $nn,X -static void opcode_adc_zpx(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t base = memory_read(state, cpu->pc++); // T1 - memory_read_dummy(state, base); // T2 - uint8_t addr = (base + cpu->x) & 0xff; - - uint8_t value = memory_read(state, addr); // T3 - adc(cpu, value); // T4 -} - -// ADC $nnnn,Y -static void opcode_adc_absy(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->y; - - if(PAGE_CROSSED(base, addr)) { - memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff)); // T3 dummy - } - - uint8_t value = memory_read(state, addr); // T3 or T4 - adc(cpu, value); // T4 or T5 -} - -// ADC $nnnn,X -static void opcode_adc_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 - } - - uint8_t value = memory_read(state, addr); // T3 or T4 - adc(cpu, value); // T4 or T5 -} - - -// AND ($nn,X) -static void opcode_and_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) & 0xff; - uint8_t lo = memory_read(state, ptr); // T3 - uint8_t hi = memory_read(state, (ptr + 1) & 0xff); // T4 - uint16_t addr = lo | (hi << 8); - - uint8_t value = memory_read(state, addr); // T5 - - cpu->a &= value; // T6+ - update_zn(cpu, cpu->a); -} - -// AND $nn -static void opcode_and_zp(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t addr = memory_read(state, cpu->pc++); // T1 - uint8_t value = memory_read(state, addr); // T2 - - cpu->a &= value; // T3 - update_zn(cpu, cpu->a); -} - -// AND #$nn -static void opcode_and_imm(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t value = memory_read(state, cpu->pc++); // T1 - cpu->a &= value; // T2 - update_zn(cpu, cpu->a); -} - -// AND $nnnn -static void opcode_and_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); - - uint8_t value = memory_read(state, addr); // T3 - cpu->a &= value; // T4 - update_zn(cpu, cpu->a); -} - -// AND ($nn),Y -static void opcode_and_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; - - if(PAGE_CROSSED(base, addr)) { - memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff)); // T4 dummy - } - - uint8_t value = memory_read(state, addr); // T4 or T5 - cpu->a &= value; // T5 or T6 - update_zn(cpu, cpu->a); -} - -// AND $nn,X -static void opcode_and_zpx(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t base = memory_read(state, cpu->pc++); // T1 - memory_read_dummy(state, base); // T2 - uint8_t addr = (base + cpu->x) & 0xff; - - uint8_t value = memory_read(state, addr); // T3 - cpu->a &= value; // T4 - update_zn(cpu, cpu->a); -} - -// AND $nnnn,Y -static void opcode_and_absy(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->y; - - if(PAGE_CROSSED(base, addr)) { - memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff)); // T3 dummy - } - - uint8_t value = memory_read(state, addr); // T3 or T4 - cpu->a &= value; // T4 or T5 - update_zn(cpu, cpu->a); -} - -// AND $nnnn,X -static void opcode_and_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 - } - - uint8_t value = memory_read(state, addr); // T3 or T4 - cpu->a &= value; // T4 or T5 - update_zn(cpu, cpu->a); -} - - -// ASL - -// ASL $nn -static void opcode_asl_zp(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t addr = memory_read(state, cpu->pc++); // T1 - uint8_t value = memory_read(state, addr); // T2 - - memory_write(state, addr, value); // T3 (dummy write) - - cpu->c = (value >> 7) & 1; - value <<= 1; - - memory_write(state, addr, value); // T4 - update_zn(cpu, value); -} - -// ASL A -static void opcode_asl_acc(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - memory_read_dummy(state, cpu->pc); // T1 (dummy read at PC) - - cpu->c = (cpu->a >> 7) & 1; - cpu->a <<= 1; - - update_zn(cpu, cpu->a); // T2 -} - -// ASL $nnnn -static void opcode_asl_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); - - uint8_t value = memory_read(state, addr); // T3 - memory_write(state, addr, value); // T4 (dummy write) - - cpu->c = (value >> 7) & 1; - value <<= 1; - - memory_write(state, addr, value); // T5 - update_zn(cpu, value); -} - -// ASL $nn,X -static void opcode_asl_zpx(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t base = memory_read(state, cpu->pc++); // T1 - memory_read_dummy(state, base); // T2 - uint8_t addr = (base + cpu->x) & 0xff; - - uint8_t value = memory_read(state, addr); // T3 - memory_write(state, addr, value); // T4 (dummy write) - - cpu->c = (value >> 7) & 1; - value <<= 1; - - memory_write(state, addr, value); // T5 - update_zn(cpu, value); -} - -// ASL $nnnn,X -static void opcode_asl_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; - - memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff)); // T3 - - uint8_t value = memory_read(state, addr); // T4 - memory_write(state, addr, value); // T5 (dummy write) - - cpu->c = (value >> 7) & 1; - value <<= 1; - - memory_write(state, addr, value); // T6 - update_zn(cpu, value); -} - - -// BIT - -// BIT $nn -static void opcode_bit_zp(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t addr = memory_read(state, cpu->pc++); // T1 - uint8_t value = memory_read(state, addr); // T2 - - cpu->z = ((cpu->a & value) == 0); - cpu->n = (value >> 7) & 1; - cpu->v = (value >> 6) & 1; // T3 -} - -// BIT $nnnn -static void opcode_bit_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); - - uint8_t value = memory_read(state, addr); // T3 - - cpu->z = ((cpu->a & value) == 0); - cpu->n = (value >> 7) & 1; - cpu->v = (value >> 6) & 1; // T4 -} - - -// BRK -static void opcode_brk(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - cpu->pc++; // BRK is 1 byte, skip padding byte - memory_read_dummy(state, cpu->pc); // T1 padding read - - uint8_t pcl = cpu->pc & 0xff; - uint8_t pch = cpu->pc >> 8; - - memory_write(state, 0x0100 + cpu->sp--, pch); // T2 - memory_write(state, 0x0100 + cpu->sp--, pcl); // T3 - - memory_write(state, 0x0100 + cpu->sp--, pack_flags(cpu) | 0x10); // T4 - - uint8_t lo = memory_read(state, 0xfffe); // T5 - uint8_t hi = memory_read(state, 0xffff); // T6 - - cpu->pc = lo | (hi << 8); // T7 - cpu->i = 1; -} - - -// BRANCHES -// static inline int page_crossed(uint16_t a, uint16_t b) { -// return (a & 0xff00) != (b & 0xff00); -// } - -static void opcode_bpl(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t offset = memory_read(state, cpu->pc++); // T1 - uint16_t new_pc = cpu->pc + (int8_t)offset; - - if(!cpu->n) { - memory_read_dummy(state, cpu->pc); // T2 - if(PAGE_CROSSED(cpu->pc, new_pc)) { - memory_read_dummy(state, (cpu->pc & 0xff00) | (new_pc & 0x00ff)); // T3 - } - cpu->pc = new_pc; // T3 or T4 - } -} - -static void opcode_bmi(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t offset = memory_read(state, cpu->pc++); - uint16_t new_pc = cpu->pc + (int8_t)offset; - - if(cpu->n) { - memory_read_dummy(state, cpu->pc); - if(PAGE_CROSSED(cpu->pc, new_pc)) { - memory_read_dummy(state, (cpu->pc & 0xff00) | (new_pc & 0x00ff)); - } - cpu->pc = new_pc; - } -} - -static void opcode_bvc(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t offset = memory_read(state, cpu->pc++); - uint16_t new_pc = cpu->pc + (int8_t)offset; - - if(!cpu->v) { - memory_read_dummy(state, cpu->pc); - if(PAGE_CROSSED(cpu->pc, new_pc)) { - memory_read_dummy(state, (cpu->pc & 0xff00) | (new_pc & 0x00ff)); - } - cpu->pc = new_pc; - } -} - -static void opcode_bvs(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t offset = memory_read(state, cpu->pc++); - uint16_t new_pc = cpu->pc + (int8_t)offset; - - if(cpu->v) { - memory_read_dummy(state, cpu->pc); - if(PAGE_CROSSED(cpu->pc, new_pc)) { - memory_read_dummy(state, (cpu->pc & 0xff00) | (new_pc & 0x00ff)); - } - cpu->pc = new_pc; - } -} - -static void opcode_bcc(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t offset = memory_read(state, cpu->pc++); - uint16_t new_pc = cpu->pc + (int8_t)offset; - - if(!cpu->c) { - memory_read_dummy(state, cpu->pc); - if(PAGE_CROSSED(cpu->pc, new_pc)) { - memory_read_dummy(state, (cpu->pc & 0xff00) | (new_pc & 0x00ff)); - } - cpu->pc = new_pc; - } -} - -static void opcode_bcs(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t offset = memory_read(state, cpu->pc++); - uint16_t new_pc = cpu->pc + (int8_t)offset; - - if(cpu->c) { - memory_read_dummy(state, cpu->pc); - if(PAGE_CROSSED(cpu->pc, new_pc)) { - memory_read_dummy(state, (cpu->pc & 0xff00) | (new_pc & 0x00ff)); - } - cpu->pc = new_pc; - } -} - -static void opcode_bne(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t offset = memory_read(state, cpu->pc++); - uint16_t new_pc = cpu->pc + (int8_t)offset; - - if(!cpu->z) { - memory_read_dummy(state, cpu->pc); - if(PAGE_CROSSED(cpu->pc, new_pc)) { - memory_read_dummy(state, (cpu->pc & 0xff00) | (new_pc & 0x00ff)); - } - cpu->pc = new_pc; - } -} - -static void opcode_beq(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t offset = memory_read(state, cpu->pc++); - uint16_t new_pc = cpu->pc + (int8_t)offset; - - if(cpu->z) { - memory_read_dummy(state, cpu->pc); - if(PAGE_CROSSED(cpu->pc, new_pc)) { - memory_read_dummy(state, (cpu->pc & 0xff00) | (new_pc & 0x00ff)); - } - cpu->pc = new_pc; - } -} - - -// SET/CLEAR flags - -static void opcode_clc(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - memory_read_dummy(state, cpu->pc); - cpu->c = 0; -} - -static void opcode_cld(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - memory_read_dummy(state, cpu->pc); -#ifdef ENABLE_DECIMAL_MODE - cpu->d = 0; -#endif -} - -static void opcode_cli(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - memory_read_dummy(state, cpu->pc); - cpu->i = 0; -} - -static void opcode_clv(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - memory_read_dummy(state, cpu->pc); - cpu->v = 0; -} - -static void opcode_sec(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - memory_read_dummy(state, cpu->pc); - cpu->c = 1; -} - -static void opcode_sed(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - memory_read_dummy(state, cpu->pc); -#ifdef ENABLE_DECIMAL_MODE - cpu->d = 1; -#endif -} - -static void opcode_sei(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - memory_read_dummy(state, cpu->pc); - cpu->i = 1; -} - - -// CMP -static inline void cmp(struct cpu_state * restrict cpu, uint8_t value) { - uint8_t result = cpu->a - value; - cpu->c = (cpu->a >= value); - cpu->z = (result == 0); - cpu->n = (result & 0x80) != 0; - // update_zn(cpu, result); -} - -static void opcode_cmp_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) & 0xff; - uint8_t lo = memory_read(state, ptr); // T3 - uint8_t hi = memory_read(state, (ptr + 1) & 0xff); // T4 - uint16_t addr = lo | (hi << 8); - - uint8_t value = memory_read(state, addr); // T5 - - cmp(cpu, value); // T6 -} - -static void opcode_cmp_zp(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t addr = memory_read(state, cpu->pc++); // T1 - uint8_t value = memory_read(state, addr); // T2 - - cmp(cpu, value); // T3 -} - -static void opcode_cmp_imm(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t value = memory_read(state, cpu->pc++); // T1 - cmp(cpu, value); // T2 -} - -static void opcode_cmp_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); - - uint8_t value = memory_read(state, addr); // T3 - cmp(cpu, value); // T4 -} - -static void opcode_cmp_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; - - if(PAGE_CROSSED(base, addr)) { - memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff)); // T4 dummy - } - - uint8_t value = memory_read(state, addr); // T4 or T5 - cmp(cpu, value); // T5 or T6 -} - -static void opcode_cmp_zpx(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t base = memory_read(state, cpu->pc++); // T1 - memory_read_dummy(state, base); // T2 - uint8_t addr = (base + cpu->x) & 0xff; - - uint8_t value = memory_read(state, addr); // T3 - cmp(cpu, value); // T4 -} - -static void opcode_cmp_absy(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->y; - - if(PAGE_CROSSED(base, addr)) { - memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff)); // T3 dummy - } - - uint8_t value = memory_read(state, addr); // T3 or T4 - cmp(cpu, value); // T4 or T5 -} - -static void opcode_cmp_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 - } - - uint8_t value = memory_read(state, addr); // T3 or T4 - cmp(cpu, value); // T4 or T5 -} - - -// CPX -static inline void cpx(struct cpu_state * restrict cpu, uint8_t value) { - uint8_t result = cpu->x - value; - cpu->c = (cpu->x >= value); - update_zn(cpu, result); -} - -static void opcode_cpx_imm(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t value = memory_read(state, cpu->pc++); // T1 - cpx(cpu, value); // T2 -} - -static void opcode_cpx_zp(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t addr = memory_read(state, cpu->pc++); // T1 - uint8_t value = memory_read(state, addr); // T2 - - cpx(cpu, value); // T3 -} - -static void opcode_cpx_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); - - uint8_t value = memory_read(state, addr); // T3 - cpx(cpu, value); // T4 -} - - -// CPY -static inline void cpy(struct cpu_state * restrict cpu, uint8_t value) { - uint8_t result = cpu->y - value; - cpu->c = (cpu->y >= value); - update_zn(cpu, result); -} - -static void opcode_cpy_imm(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t value = memory_read(state, cpu->pc++); // T1 - cpy(cpu, value); // T2 -} - -static void opcode_cpy_zp(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t addr = memory_read(state, cpu->pc++); // T1 - uint8_t value = memory_read(state, addr); // T2 - - cpy(cpu, value); // T3 -} - -static void opcode_cpy_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); - - uint8_t value = memory_read(state, addr); // T3 - cpy(cpu, value); // T4 -} - - -// DEC - -static void opcode_dec_zp(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t addr = memory_read(state, cpu->pc++); // T1 - uint8_t value = memory_read(state, addr); // T2 - - memory_write(state, addr, value); // T3 (dummy write) - value--; - memory_write(state, addr, value); // T4 - - update_zn(cpu, value); // T5 -} - -static void opcode_dec_zpx(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t base = memory_read(state, cpu->pc++); // T1 - memory_read_dummy(state, base); // T2 - uint8_t addr = (base + cpu->x) & 0xff; - - uint8_t value = memory_read(state, addr); // T3 - memory_write(state, addr, value); // T4 (dummy write) - - value--; - memory_write(state, addr, value); // T5 - update_zn(cpu, value); // T6 -} - -static void opcode_dec_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); - - uint8_t value = memory_read(state, addr); // T3 - memory_write(state, addr, value); // T4 (dummy write) - - value--; - memory_write(state, addr, value); // T5 - update_zn(cpu, value); // T6 -} - -static void opcode_dec_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; - - memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff)); // T3 - - uint8_t value = memory_read(state, addr); // T4 - memory_write(state, addr, value); // T5 (dummy write) - - value--; - memory_write(state, addr, value); // T6 - update_zn(cpu, value); // T7 -} - - -// EOR - -static void opcode_eor_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) & 0xff; - uint8_t lo = memory_read(state, ptr); // T3 - uint8_t hi = memory_read(state, (ptr + 1) & 0xff); // T4 - uint16_t addr = lo | (hi << 8); - - uint8_t value = memory_read(state, addr); // T5 - - cpu->a ^= value; // T6 - update_zn(cpu, cpu->a); -} - -static void opcode_eor_zp(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t addr = memory_read(state, cpu->pc++); // T1 - uint8_t value = memory_read(state, addr); // T2 - - cpu->a ^= value; // T3 - update_zn(cpu, cpu->a); -} - -static void opcode_eor_imm(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t value = memory_read(state, cpu->pc++); // T1 - cpu->a ^= value; // T2 - update_zn(cpu, cpu->a); -} - -static void opcode_eor_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); - - uint8_t value = memory_read(state, addr); // T3 - cpu->a ^= value; // T4 - update_zn(cpu, cpu->a); -} - -static void opcode_eor_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; - - if(PAGE_CROSSED(base, addr)) { - memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff)); // T4 dummy - } - - uint8_t value = memory_read(state, addr); // T4 or T5 - cpu->a ^= value; // T5 or T6 - update_zn(cpu, cpu->a); -} - -static void opcode_eor_zpx(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t base = memory_read(state, cpu->pc++); // T1 - memory_read_dummy(state, base); // T2 - uint8_t addr = (base + cpu->x) & 0xff; - - uint8_t value = memory_read(state, addr); // T3 - cpu->a ^= value; // T4 - update_zn(cpu, cpu->a); -} - -static void opcode_eor_absy(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->y; - - if(PAGE_CROSSED(base, addr)) { - memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff)); // T3 dummy - } - - uint8_t value = memory_read(state, addr); // T3 or T4 - cpu->a ^= value; // T4 or T5 - update_zn(cpu, cpu->a); -} - -static void opcode_eor_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 - } - - uint8_t value = memory_read(state, addr); // T3 or T4 - cpu->a ^= value; // T4 or T5 - update_zn(cpu, cpu->a); -} - - -// INC - -static void opcode_inc_zp(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t addr = memory_read(state, cpu->pc++); // T1 - uint8_t value = memory_read(state, addr); // T2 - - memory_write(state, addr, value); // T3 (dummy write) - value++; - memory_write(state, addr, value); // T4 - - update_zn(cpu, value); // T5 -} - -static void opcode_inc_zpx(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t base = memory_read(state, cpu->pc++); // T1 - memory_read_dummy(state, base); // T2 - uint8_t addr = (base + cpu->x) & 0xff; - - uint8_t value = memory_read(state, addr); // T3 - memory_write(state, addr, value); // T4 (dummy write) - - value++; - memory_write(state, addr, value); // T5 - update_zn(cpu, value); // T6 -} - -static void opcode_inc_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); - - uint8_t value = memory_read(state, addr); // T3 - memory_write(state, addr, value); // T4 (dummy write) - - value++; - memory_write(state, addr, value); // T5 - update_zn(cpu, value); // T6 -} - -static void opcode_inc_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; - - memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff)); // T3 - - uint8_t value = memory_read(state, addr); // T4 - memory_write(state, addr, value); // T5 (dummy write) - - value++; - memory_write(state, addr, value); // T6 - update_zn(cpu, value); // T7 -} - - -// JMP/JSR - -static void opcode_jmp_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 - cpu->pc = lo | (hi << 8); // T3 -} - -static void opcode_jmp_ind(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t ptr_lo = memory_read(state, cpu->pc++); // T1 - uint8_t ptr_hi = memory_read(state, cpu->pc++); // T2 - uint16_t ptr = ptr_lo | (ptr_hi << 8); - - uint8_t lo = memory_read(state, ptr); // T3 - uint8_t hi; - - if((ptr & 0x00ff) == 0x00ff) { - hi = memory_read(state, ptr & 0xff00); // Emulate 6502 bug - } else { - hi = memory_read(state, ptr + 1); - } // T4 - - cpu->pc = lo | (hi << 8); // T5 -} - -static void opcode_jsr(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 return_addr = cpu->pc - 1; - - memory_read_dummy(state, 0x0100 | cpu->sp); // T4 - memory_write(state, 0x0100 | cpu->sp--, (return_addr >> 8)); // T5 - memory_write(state, 0x0100 | cpu->sp--, (return_addr & 0xff)); // T6 - - cpu->pc = lo | (hi << 8); -} - - - -// LDA - -static void opcode_lda_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) & 0xff; - uint8_t lo = memory_read(state, ptr); // T3 - uint8_t hi = memory_read(state, (ptr + 1) & 0xff); // T4 - uint16_t addr = lo | (hi << 8); - - uint8_t value = memory_read(state, addr); // T5 - cpu->a = value; // T6 - update_zn(cpu, value); -} - -static void opcode_lda_zp(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t addr = memory_read(state, cpu->pc++); // T1 - uint8_t value = memory_read(state, addr); // T2 - - cpu->a = value; // T3 - update_zn(cpu, value); -} - -static void opcode_lda_imm(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t value = memory_read(state, cpu->pc++); // T1 - cpu->a = value; // T2 - update_zn(cpu, value); -} - -static void opcode_lda_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); - - uint8_t value = memory_read(state, addr); // T3 - cpu->a = value; // T4 - update_zn(cpu, value); -} - -static void opcode_lda_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; - - if(PAGE_CROSSED(base, addr)) { - memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff)); // T4 dummy - } - - uint8_t value = memory_read(state, addr); // T4 or T5 - cpu->a = value; // T5 or T6 - update_zn(cpu, value); -} - -static void opcode_lda_zpx(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t base = memory_read(state, cpu->pc++); // T1 - memory_read_dummy(state, base); // T2 - uint8_t addr = (base + cpu->x) & 0xff; - - uint8_t value = memory_read(state, addr); // T3 - cpu->a = value; // T4 - update_zn(cpu, value); -} - -static void opcode_lda_absy(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->y; - - if(PAGE_CROSSED(base, addr)) { - memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff)); // T3 - } - - uint8_t value = memory_read(state, addr); // T3 or T4 - cpu->a = value; // T4 or T5 - update_zn(cpu, value); -} - -static void opcode_lda_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 - } - - uint8_t value = memory_read(state, addr); // T3 or T4 - cpu->a = value; // T4 or T5 - update_zn(cpu, value); -} - - -// LDX - -static void opcode_ldx_imm(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t value = memory_read(state, cpu->pc++); - cpu->x = value; - update_zn(cpu, value); -} - -static void opcode_ldx_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->x = value; - update_zn(cpu, value); -} - -static void opcode_ldx_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->x = value; - update_zn(cpu, value); -} - -static void opcode_ldx_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->x = value; - update_zn(cpu, value); -} - -static void opcode_ldx_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->x = value; - update_zn(cpu, value); -} - - -// LDY - -static void opcode_ldy_imm(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t value = memory_read(state, cpu->pc++); - cpu->y = value; - update_zn(cpu, value); -} - -static void opcode_ldy_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->y = value; - update_zn(cpu, value); -} - -static void opcode_ldy_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); - cpu->y = value; - update_zn(cpu, value); -} - -static void opcode_ldy_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->y = value; - update_zn(cpu, value); -} - -static void opcode_ldy_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; - - if(PAGE_CROSSED(base, addr)) { - memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff)); - } - - uint8_t value = memory_read(state, addr); - cpu->y = value; - update_zn(cpu, value); -} - - -// LSR - - -static void opcode_lsr_zp(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t addr = memory_read(state, cpu->pc++); // T1 - uint8_t value = memory_read(state, addr); // T2 - - memory_write(state, addr, value); // T3 (dummy write) - cpu->c = value & 1; - value >>= 1; - memory_write(state, addr, value); // T4 - - update_zn(cpu, value); // T5 -} - -static void opcode_lsr_acc(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - memory_read_dummy(state, cpu->pc); // T1 - cpu->c = cpu->a & 1; - cpu->a >>= 1; - update_zn(cpu, cpu->a); // T2 -} - -static void opcode_lsr_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); - - uint8_t value = memory_read(state, addr); // T3 - memory_write(state, addr, value); // T4 (dummy write) - - cpu->c = value & 1; - value >>= 1; - - memory_write(state, addr, value); // T5 - update_zn(cpu, value); // T6 -} - -static void opcode_lsr_zpx(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t base = memory_read(state, cpu->pc++); // T1 - memory_read_dummy(state, base); // T2 - uint8_t addr = (base + cpu->x) & 0xff; - - uint8_t value = memory_read(state, addr); // T3 - memory_write(state, addr, value); // T4 (dummy write) - - cpu->c = value & 1; - value >>= 1; - - memory_write(state, addr, value); // T5 - update_zn(cpu, value); // T6 -} - -static void opcode_lsr_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; - - memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff)); // T3 - - uint8_t value = memory_read(state, addr); // T4 - memory_write(state, addr, value); // T5 (dummy write) - - cpu->c = value & 1; - value >>= 1; - - memory_write(state, addr, value); // T6 - update_zn(cpu, value); // T7 -} - - -// NOP - -static void opcode_nop(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - memory_read_dummy(state, cpu->pc); // T1: dummy read - // T2: nothing changes -} - - -// ORA - -static void opcode_ora_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) & 0xff; - uint8_t lo = memory_read(state, ptr); // T3 - uint8_t hi = memory_read(state, (ptr + 1) & 0xff); // T4 - uint16_t addr = lo | (hi << 8); - - uint8_t value = memory_read(state, addr); // T5 - cpu->a |= value; // T6 - update_zn(cpu, cpu->a); -} - -static void opcode_ora_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; - update_zn(cpu, cpu->a); -} - -static void opcode_ora_imm(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t value = memory_read(state, cpu->pc++); - cpu->a |= value; - update_zn(cpu, cpu->a); -} - -static void opcode_ora_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; - update_zn(cpu, cpu->a); -} - -static void opcode_ora_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; - update_zn(cpu, cpu->a); -} - -static void opcode_ora_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); - cpu->a |= value; - update_zn(cpu, cpu->a); -} - -static void opcode_ora_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; - update_zn(cpu, cpu->a); -} - -static void opcode_ora_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; - - if(PAGE_CROSSED(base, addr)) { - memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff)); - } - - uint8_t value = memory_read(state, addr); - cpu->a |= value; - update_zn(cpu, cpu->a); -} - -// PHA - -static void opcode_pha(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - memory_read_dummy(state, cpu->pc); // T1 - memory_write(state, 0x0100 + cpu->sp--, cpu->a); // T2 -} - - -// PHP - -static void opcode_php(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - memory_read_dummy(state, cpu->pc); // T1 - memory_write(state, 0x0100 + cpu->sp--, pack_flags(cpu) | 0x10); -} - - -// PLA - -static void opcode_pla(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - memory_read_dummy(state, cpu->pc); // T1 - memory_read_dummy(state, 0x0100 + ((cpu->sp + 1) & 0xff)); // T2 - uint8_t value = memory_read(state, 0x0100 + ((cpu->sp + 1) & 0xff)); // T3 - cpu->sp++; - cpu->a = value; - update_zn(cpu, value); // T4 -} - - -// PLP - -static void opcode_plp(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - memory_read_dummy(state, cpu->pc); // T1 - memory_read_dummy(state, 0x0100 + ((cpu->sp + 1) & 0xff)); // T2 - uint8_t value = memory_read(state, 0x0100 + ((cpu->sp + 1) & 0xff)); // T3 - cpu->sp++; - unpack_flags(cpu, value); // T4 -} - - -// RTI - -static void opcode_rti(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - memory_read_dummy(state, cpu->pc); // T1 - memory_read_dummy(state, 0x0100 + ((cpu->sp + 1) & 0xff)); // T2 - uint8_t flags = memory_read(state, 0x0100 + ((cpu->sp + 1) & 0xff)); // T3 - cpu->sp++; - unpack_flags(cpu, flags); // T4 - - uint8_t lo = memory_read(state, 0x0100 + ((cpu->sp + 1) & 0xff)); // T5 - cpu->sp++; - uint8_t hi = memory_read(state, 0x0100 + ((cpu->sp + 1) & 0xff)); // T6 - cpu->sp++; - - cpu->pc = lo | (hi << 8); -} - - -// RTS - -static void opcode_rts(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - memory_read_dummy(state, cpu->pc); // T1 - memory_read_dummy(state, 0x0100 | cpu->sp); // T2 (discard) - uint8_t lo = memory_read(state, 0x0100 | ++cpu->sp); // T3 - uint8_t hi = memory_read(state, 0x0100 | ++cpu->sp); // T4 - uint16_t ret = (hi << 8) | lo; - memory_read_dummy(state, ret); // T5 - cpu->pc = ret + 1; // Final PC set -} - - -// ROL - -static void opcode_rol_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); - update_zn(cpu, value); -} - -static void opcode_rol_acc(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - memory_read_dummy(state, cpu->pc); - - uint8_t in = cpu->c; - cpu->c = (cpu->a >> 7) & 1; - cpu->a = (cpu->a << 1) | in; - - update_zn(cpu, cpu->a); -} - -static void opcode_rol_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); - update_zn(cpu, value); -} - -static void opcode_rol_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); - update_zn(cpu, value); -} - -static void opcode_rol_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); - update_zn(cpu, value); -} - - -// ROR - -static void opcode_ror_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 & 1; - value = (value >> 1) | (in << 7); - - memory_write(state, addr, value); - update_zn(cpu, value); -} - -static void opcode_ror_acc(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - memory_read_dummy(state, cpu->pc); - - uint8_t in = cpu->c; - cpu->c = cpu->a & 1; - cpu->a = (cpu->a >> 1) | (in << 7); - - update_zn(cpu, cpu->a); -} - -static void opcode_ror_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 & 1; - value = (value >> 1) | (in << 7); - - memory_write(state, addr, value); - update_zn(cpu, value); -} - -static void opcode_ror_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 & 1; - value = (value >> 1) | (in << 7); - - memory_write(state, addr, value); - update_zn(cpu, value); -} - -static void opcode_ror_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 & 1; - value = (value >> 1) | (in << 7); - - memory_write(state, addr, value); - update_zn(cpu, value); -} - - -// SBC -static inline void sbc(struct cpu_state * restrict cpu, uint8_t value) { -#ifdef ENABLE_DECIMAL_MODE - if(cpu->d) { - uint8_t al = (cpu->a & 0x0f) - (value & 0x0f) - (cpu->c ? 0 : 1); - uint8_t ah = (cpu->a >> 4) - (value >> 4); - if((int8_t)al < 0) { - al -= 6; - ah--; - } - cpu->c = ((int8_t)ah >= 0); - if(!cpu->c) { - ah -= 6; - } - cpu->a = (ah << 4) | (al & 0x0f); - update_zn(cpu, cpu->a); - // Note: overflow flag behavior in decimal mode is undefined on 6502 - return; - } -#endif - - uint16_t tmp = cpu->a - value - (cpu->c ? 0 : 1); - cpu->v = ((cpu->a ^ value) & (cpu->a ^ tmp)) & 0x80 ? 1 : 0; - cpu->c = (tmp < 0x100); - cpu->a = tmp & 0xff; - update_zn(cpu, cpu->a); -} - - -static void opcode_sbc_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); - sbc(cpu, value); -} - -static void opcode_sbc_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); - - sbc(cpu, value); -} - -static void opcode_sbc_imm(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - uint8_t value = memory_read(state, cpu->pc++); - sbc(cpu, value); -} - -static void opcode_sbc_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); - sbc(cpu, value); -} - -static void opcode_sbc_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); - sbc(cpu, value); -} - -static void opcode_sbc_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); - sbc(cpu, value); -} - -static void opcode_sbc_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); - sbc(cpu, value); -} - -static void opcode_sbc_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; - - if(PAGE_CROSSED(base, addr)) { - memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff)); - } - - uint8_t value = memory_read(state, addr); - sbc(cpu, value); -} - - -// TAX - -static void opcode_tax(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - memory_read_dummy(state, cpu->pc); - cpu->x = cpu->a; - update_zn(cpu, cpu->x); -} - -static void opcode_tay(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - memory_read_dummy(state, cpu->pc); - cpu->y = cpu->a; - update_zn(cpu, cpu->y); -} - -static void opcode_txa(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - memory_read_dummy(state, cpu->pc); - cpu->a = cpu->x; - update_zn(cpu, cpu->a); -} - -static void opcode_tya(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - memory_read_dummy(state, cpu->pc); - cpu->a = cpu->y; - update_zn(cpu, cpu->a); -} - -static void opcode_tsx(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - memory_read_dummy(state, cpu->pc); - cpu->x = cpu->sp; - update_zn(cpu, cpu->x); -} - -static void opcode_txs(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - memory_read_dummy(state, cpu->pc); - cpu->sp = cpu->x; -} - - -// INX - -static void opcode_inx(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - memory_read_dummy(state, cpu->pc); - cpu->x++; - update_zn(cpu, cpu->x); -} - - -// INY - -static void opcode_iny(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - memory_read_dummy(state, cpu->pc); - cpu->y++; - update_zn(cpu, cpu->y); -} - - -// DEX - -static void opcode_dex(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - memory_read_dummy(state, cpu->pc); - cpu->x--; - update_zn(cpu, cpu->x); -} - - -// DEY - -static void opcode_dey(struct nes_state *state) { - struct cpu_state * restrict cpu = &state->cpu; - - memory_read_dummy(state, cpu->pc); - cpu->y--; - update_zn(cpu, cpu->y); -} - - -// STA - -static void opcode_sta_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); - - memory_write(state, addr, cpu->a); -} - -static void opcode_sta_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); -} - -static void opcode_sta_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); -} - -static void opcode_sta_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)); - memory_write(state, addr, cpu->a); // T5 -} - -static void opcode_sta_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; - - memory_write(state, addr, cpu->a); -} - -static void opcode_sta_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); -} - -static void opcode_sta_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; - - memory_read_dummy(state, (base & 0xff00) | (addr & 0x00ff)); // T3 (always) - memory_write(state, addr, cpu->a); // T4 -} - - -// STX - -static void opcode_stx_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->x); -} - -static void opcode_stx_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->x); -} - -static void opcode_stx_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->x); -} - - -// STY - -static void opcode_sty_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->y); -} - -static void opcode_sty_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->y); -} - -static void opcode_sty_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; - - memory_write(state, addr, cpu->y); -} - - -__attribute__((noinline)) -static void init_opcode_lut(void) { - for(uint32_t i = 0; i < 256; ++i) { - opcode_lut[i] = opcode_nop; // make sure erroneous opcodes just do "NOP", this might change in the future! - } - opcode_lut[0x00] = opcode_brk; - opcode_lut[0x01] = opcode_ora_indx; - opcode_lut[0x05] = opcode_ora_zp; - opcode_lut[0x06] = opcode_asl_zp; - opcode_lut[0x08] = opcode_php; - opcode_lut[0x09] = opcode_ora_imm; - opcode_lut[0x0a] = opcode_asl_acc; - opcode_lut[0x0d] = opcode_ora_abs; - opcode_lut[0x0e] = opcode_asl_abs; - opcode_lut[0x10] = opcode_bpl; - opcode_lut[0x11] = opcode_ora_indy; - opcode_lut[0x15] = opcode_ora_zpx; - opcode_lut[0x16] = opcode_asl_zpx; - opcode_lut[0x18] = opcode_clc; - opcode_lut[0x19] = opcode_ora_absy; - opcode_lut[0x1d] = opcode_ora_absx; - opcode_lut[0x1e] = opcode_asl_absx; - opcode_lut[0x20] = opcode_jsr; - opcode_lut[0x21] = opcode_and_indx; - opcode_lut[0x24] = opcode_bit_zp; - opcode_lut[0x25] = opcode_and_zp; - opcode_lut[0x26] = opcode_rol_zp; - opcode_lut[0x28] = opcode_plp; - opcode_lut[0x29] = opcode_and_imm; - opcode_lut[0x2a] = opcode_rol_acc; - opcode_lut[0x2c] = opcode_bit_abs; - opcode_lut[0x2d] = opcode_and_abs; - opcode_lut[0x2e] = opcode_rol_abs; - opcode_lut[0x30] = opcode_bmi; - opcode_lut[0x31] = opcode_and_indy; - opcode_lut[0x35] = opcode_and_zpx; - opcode_lut[0x36] = opcode_rol_zpx; - opcode_lut[0x38] = opcode_sec; - opcode_lut[0x39] = opcode_and_absy; - opcode_lut[0x3d] = opcode_and_absx; - opcode_lut[0x3e] = opcode_rol_absx; - opcode_lut[0x40] = opcode_rti; - opcode_lut[0x41] = opcode_eor_indx; - opcode_lut[0x45] = opcode_eor_zp; - opcode_lut[0x46] = opcode_lsr_zp; - opcode_lut[0x48] = opcode_pha; - opcode_lut[0x49] = opcode_eor_imm; - opcode_lut[0x4a] = opcode_lsr_acc; - opcode_lut[0x4c] = opcode_jmp_abs; - opcode_lut[0x4d] = opcode_eor_abs; - opcode_lut[0x4e] = opcode_lsr_abs; - opcode_lut[0x50] = opcode_bvc; - opcode_lut[0x51] = opcode_eor_indy; - opcode_lut[0x55] = opcode_eor_zpx; - opcode_lut[0x56] = opcode_lsr_zpx; - opcode_lut[0x58] = opcode_cli; - opcode_lut[0x59] = opcode_eor_absy; - opcode_lut[0x5d] = opcode_eor_absx; - opcode_lut[0x5e] = opcode_lsr_absx; - opcode_lut[0x60] = opcode_rts; - opcode_lut[0x61] = opcode_adc_indx; - opcode_lut[0x65] = opcode_adc_zp; - opcode_lut[0x66] = opcode_ror_zp; - opcode_lut[0x68] = opcode_pla; - opcode_lut[0x69] = opcode_adc_imm; - opcode_lut[0x6a] = opcode_ror_acc; - opcode_lut[0x6c] = opcode_jmp_ind; - opcode_lut[0x6d] = opcode_adc_abs; - opcode_lut[0x6e] = opcode_ror_abs; - opcode_lut[0x70] = opcode_bvs; - opcode_lut[0x71] = opcode_adc_indy; - opcode_lut[0x75] = opcode_adc_zpx; - opcode_lut[0x76] = opcode_ror_zpx; - opcode_lut[0x78] = opcode_sei; - opcode_lut[0x79] = opcode_adc_absy; - opcode_lut[0x7d] = opcode_adc_absx; - opcode_lut[0x7e] = opcode_ror_absx; - opcode_lut[0x81] = opcode_sta_indx; - opcode_lut[0x84] = opcode_sty_zp; - opcode_lut[0x85] = opcode_sta_zp; - opcode_lut[0x86] = opcode_stx_zp; - opcode_lut[0x88] = opcode_dey; - opcode_lut[0x8a] = opcode_txa; - opcode_lut[0x8c] = opcode_sty_abs; - opcode_lut[0x8d] = opcode_sta_abs; - opcode_lut[0x8e] = opcode_stx_abs; - opcode_lut[0x90] = opcode_bcc; - opcode_lut[0x91] = opcode_sta_indy; - opcode_lut[0x94] = opcode_sty_zpx; - opcode_lut[0x95] = opcode_sta_zpx; - opcode_lut[0x96] = opcode_stx_zpy; - opcode_lut[0x98] = opcode_tya; - opcode_lut[0x99] = opcode_sta_absy; - opcode_lut[0x9a] = opcode_txs; - opcode_lut[0x9d] = opcode_sta_absx; - opcode_lut[0xa0] = opcode_ldy_imm; - opcode_lut[0xa1] = opcode_lda_indx; - opcode_lut[0xa2] = opcode_ldx_imm; - opcode_lut[0xa4] = opcode_ldy_zp; - opcode_lut[0xa5] = opcode_lda_zp; - opcode_lut[0xa6] = opcode_ldx_zp; - opcode_lut[0xa8] = opcode_tay; - opcode_lut[0xa9] = opcode_lda_imm; - opcode_lut[0xaa] = opcode_tax; - opcode_lut[0xac] = opcode_ldy_abs; - opcode_lut[0xad] = opcode_lda_abs; - opcode_lut[0xae] = opcode_ldx_abs; - opcode_lut[0xb0] = opcode_bcs; - opcode_lut[0xb1] = opcode_lda_indy; - opcode_lut[0xb4] = opcode_ldy_zpx; - opcode_lut[0xb5] = opcode_lda_zpx; - opcode_lut[0xb6] = opcode_ldx_zpy; - opcode_lut[0xb8] = opcode_clv; - opcode_lut[0xb9] = opcode_lda_absy; - opcode_lut[0xba] = opcode_tsx; - opcode_lut[0xbc] = opcode_ldy_absx; - opcode_lut[0xbd] = opcode_lda_absx; - opcode_lut[0xbe] = opcode_ldx_absy; - opcode_lut[0xc0] = opcode_cpy_imm; - opcode_lut[0xc1] = opcode_cmp_indx; - opcode_lut[0xc4] = opcode_cpy_zp; - opcode_lut[0xc5] = opcode_cmp_zp; - opcode_lut[0xc6] = opcode_dec_zp; - opcode_lut[0xc8] = opcode_iny; - opcode_lut[0xc9] = opcode_cmp_imm; - opcode_lut[0xca] = opcode_dex; - opcode_lut[0xcc] = opcode_cpy_abs; - opcode_lut[0xcd] = opcode_cmp_abs; - opcode_lut[0xce] = opcode_dec_abs; - opcode_lut[0xd0] = opcode_bne; - opcode_lut[0xd1] = opcode_cmp_indy; - opcode_lut[0xd5] = opcode_cmp_zpx; - opcode_lut[0xd6] = opcode_dec_zpx; - opcode_lut[0xd8] = opcode_cld; - opcode_lut[0xd9] = opcode_cmp_absy; - opcode_lut[0xdd] = opcode_cmp_absx; - opcode_lut[0xde] = opcode_dec_absx; - opcode_lut[0xe0] = opcode_cpx_imm; - opcode_lut[0xe1] = opcode_sbc_indx; - opcode_lut[0xe4] = opcode_cpx_zp; - opcode_lut[0xe5] = opcode_sbc_zp; - opcode_lut[0xe6] = opcode_inc_zp; - opcode_lut[0xe8] = opcode_inx; - opcode_lut[0xe9] = opcode_sbc_imm; - opcode_lut[0xea] = opcode_nop; - opcode_lut[0xeb] = opcode_sbc_imm; - opcode_lut[0xec] = opcode_cpx_abs; - opcode_lut[0xed] = opcode_sbc_abs; - opcode_lut[0xee] = opcode_inc_abs; - opcode_lut[0xf0] = opcode_beq; - opcode_lut[0xf1] = opcode_sbc_indy; - opcode_lut[0xf5] = opcode_sbc_zpx; - opcode_lut[0xf6] = opcode_inc_zpx; - opcode_lut[0xf8] = opcode_sed; - opcode_lut[0xf9] = opcode_sbc_absy; - opcode_lut[0xfd] = opcode_sbc_absx; - opcode_lut[0xfe] = opcode_inc_absx; -} - - - - - - - - - - - - -- cgit v1.2.3