diff --git a/include/mos6502.h b/include/mos6502.h index 3fc40b1..e4574e0 100644 --- a/include/mos6502.h +++ b/include/mos6502.h @@ -92,6 +92,12 @@ typedef struct { */ typedef vm_8bit (*mos6502_address_resolver)(mos6502 *); +/* + * Another convenience; this type definition is for the functions we + * write to handle instruction logic. + */ +typedef void (*mos6502_instruction_handler)(mos6502 *, vm_8bit); + extern mos6502 *mos6502_create(); extern void mos6502_free(mos6502 *); extern vm_8bit mos6502_next_byte(mos6502 *); @@ -101,6 +107,7 @@ extern void mos6502_set_status(mos6502 *, vm_8bit); extern void mos6502_modify_status(mos6502 *, vm_8bit, vm_8bit); extern int mos6502_cycles(mos6502 *, vm_8bit); extern int mos6502_instruction(vm_8bit); +extern mos6502_instruction_handler mos6502_get_instruction_handler(vm_8bit); /* * Below are some functions that are defined in mos6502.addr.c diff --git a/src/mos6502.c b/src/mos6502.c index 967fed5..512a75d 100644 --- a/src/mos6502.c +++ b/src/mos6502.c @@ -49,6 +49,69 @@ static int instructions[] = { BEQ, SBC, NOP, NOP, NOP, SBC, INC, NOP, SED, SBC, NOP, NOP, NOP, SBC, INC, NOP, // Fx }; +// I just don't want to type out the literal function name every time +#define INST_HANDLER(x) \ + mos6502_handle_##x + +static mos6502_instruction_handler instruction_handlers[] = { + INST_HANDLER(adc), + INST_HANDLER(and), + INST_HANDLER(asl), + INST_HANDLER(bcc), + INST_HANDLER(bcs), + INST_HANDLER(beq), + INST_HANDLER(bit), + INST_HANDLER(bmi), + INST_HANDLER(bne), + INST_HANDLER(bpl), + INST_HANDLER(brk), + INST_HANDLER(bvc), + INST_HANDLER(bvs), + INST_HANDLER(clc), + INST_HANDLER(cld), + INST_HANDLER(cli), + INST_HANDLER(clv), + INST_HANDLER(cmp), + INST_HANDLER(cpx), + INST_HANDLER(cpy), + INST_HANDLER(dec), + INST_HANDLER(dex), + INST_HANDLER(dey), + INST_HANDLER(eor), + INST_HANDLER(inc), + INST_HANDLER(inx), + INST_HANDLER(iny), + INST_HANDLER(jmp), + INST_HANDLER(jsr), + INST_HANDLER(lda), + INST_HANDLER(ldx), + INST_HANDLER(ldy), + INST_HANDLER(lsr), + INST_HANDLER(nop), + INST_HANDLER(ora), + INST_HANDLER(pha), + INST_HANDLER(php), + INST_HANDLER(pla), + INST_HANDLER(plp), + INST_HANDLER(rol), + INST_HANDLER(ror), + INST_HANDLER(rti), + INST_HANDLER(rts), + INST_HANDLER(sbc), + INST_HANDLER(sec), + INST_HANDLER(sed), + INST_HANDLER(sei), + INST_HANDLER(sta), + INST_HANDLER(stx), + INST_HANDLER(sty), + INST_HANDLER(tax), + INST_HANDLER(tay), + INST_HANDLER(tsx), + INST_HANDLER(txa), + INST_HANDLER(txs), + INST_HANDLER(tya), +}; + static int cycles[] = { // 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 7, 6, 0, 0, 0, 3, 5, 0, 3, 2, 2, 0, 0, 4, 6, 0, // 0x @@ -199,9 +262,7 @@ mos6502_instruction(vm_8bit opcode) int mos6502_cycles(mos6502 *cpu, vm_8bit opcode) { - /* - * In some contexts, we may need to return an additional cycle. - */ + // In some contexts, we may need to return an additional cycle. int modif = 0; int addr_mode; @@ -236,3 +297,13 @@ mos6502_cycles(mos6502 *cpu, vm_8bit opcode) return cycles[opcode] + modif; } + +/* + * Here we intend to return the proper resolver function for any given + * instruction. + */ +mos6502_instruction_handler +mos6502_get_instruction_handler(vm_8bit opcode) +{ + return instruction_handlers[mos6502_instruction(opcode)]; +} diff --git a/tests/mos6502.c b/tests/mos6502.c index 7ba325d..1719612 100644 --- a/tests/mos6502.c +++ b/tests/mos6502.c @@ -121,3 +121,10 @@ Test(mos6502, cycles) END_CPU_TEST(mos6502); } + +Test(mos6502, get_instruction_handler) +{ + cr_assert_eq(mos6502_get_instruction_handler(0x00), mos6502_handle_brk); + cr_assert_eq(mos6502_get_instruction_handler(0x1D), mos6502_handle_ora); + cr_assert_eq(mos6502_get_instruction_handler(0x20), mos6502_handle_jsr); +}