diff --git a/src/65c02isa.csv b/src/65c02isa.csv index c229a4a..93fa44a 100644 --- a/src/65c02isa.csv +++ b/src/65c02isa.csv @@ -75,7 +75,7 @@ OP_PHA,"pha",IMPLIED,1,emul_pha,false OP_EOR_IMM,"eor",IMMEDIATE,2,emul_eor,false OP_LSR,"lsr",ACCUMULATOR,1,emul_lsr,false OP_NOPI_4C,"nop",IMPLIED,1,NULL,false -OP_JMP_ABS,"jmp",ABSOLUTE,3,NULL,true +OP_JMP_ABS,"jmp",ABSOLUTE,3,emul_jmp,true OP_EOR_ABS,"eor",ABSOLUTE,3,emul_eor,false OP_LSR_ABS,"lsr",ABSOLUTE,3,emul_lsr,false OP_BBR4_REL,"bbr4",ZPR,2,NULL,true @@ -107,7 +107,7 @@ OP_PLA,"pla",IMPLIED,1,emul_pla,false OP_ADC_IMM,"adc",IMMEDIATE,2,NULL,false OP_ROR,"ror",ACCUMULATOR,1,emul_ror,false OP_NOPI_6C,"nop",IMPLIED,1,NULL,false -OP_JMP_IABS,"jmp",IABSOLUTE,3,NULL,true +OP_JMP_IABS,"jmp",IABSOLUTE,3,emul_jmp,true OP_ADC_ABS,"adc",ABSOLUTE,3,NULL,false OP_ROR_ABS,"ror",ABSOLUTE,3,emul_ror,false OP_BBR6_REL,"bbr6",ZPR,2,NULL,true @@ -123,7 +123,7 @@ OP_SEI,"sei",IMPLIED,1,NULL,false OP_ADC_ABSY,"adc",ABSOLUTEY,3,NULL,false OP_PLY,"ply",IMPLIED,1,emul_ply,false OP_NOPI_7C,"nop",IMPLIED,1,NULL,false -OP_JMP_IABSX,"jmp",IABSOLUTEX,3,NULL,true +OP_JMP_IABSX,"jmp",IABSOLUTEX,3,emul_jmp,true OP_ADC_ABSX,"adc",ABSOLUTEX,3,NULL,false OP_ROR_ABSX,"ror",ABSOLUTEX,3,emul_ror,false OP_BBR7_REL,"bbr7",ZPR,2,NULL,true diff --git a/src/emulation.c b/src/emulation.c index 5a17be3..bc47fd2 100644 --- a/src/emulation.c +++ b/src/emulation.c @@ -1,4 +1,5 @@ #include +#include #include "emulation.h" @@ -151,6 +152,29 @@ emul_iny(rk65c02emu_t *e, void *id, instruction_t *i) instruction_status_adjust_negative(e, e->regs.Y); } +/* JMP - JUMP~ */ +void +emul_jmp(rk65c02emu_t *e, void *id, instruction_t *i) +{ + uint16_t target;//, iaddr; + + switch (((instrdef_t *)id)->mode) { + case ABSOLUTE: + target = i->op1 + (i->op2 << 8); + break; + case IABSOLUTE: + target = bus_read_1(e->bus, i->op1); + target |= (bus_read_1(e->bus, i->op2) << 8); +// target = bus_read_1(e->bus, indirect); +// target |= bus_read_1(e->bus, indirect + 1); + default: + assert(false); /* should never happen, lol */ + break; + } + + e->regs.PC = target; +} + /* LDA - load to accumulator */ void emul_lda(rk65c02emu_t *e, void *id, instruction_t *i) diff --git a/test/test_emulation.c b/test/test_emulation.c index dc4b3dd..71717a9 100644 --- a/test/test_emulation.c +++ b/test/test_emulation.c @@ -617,6 +617,30 @@ ATF_TC_BODY(emul_phx_phy_plx_ply, tc) bus_finish(&b); } +ATF_TC_WITHOUT_HEAD(emul_jmp); +ATF_TC_BODY(emul_jmp, tc) +{ + rk65c02emu_t e; + bus_t b; + + b = bus_init(); + e = rk65c02_init(&b); + + e.regs.PC = ROM_LOAD_ADDR; + ATF_REQUIRE(bus_load_file(&b, ROM_LOAD_ADDR, + rom_path("test_emulation_jmp_abs.rom", tc))); + + rk65c02_step(&e, 3); + rk65c02_dump_regs(&e); + +/* + ATF_CHECK(e.regs.SP == 0xFE); + ATF_CHECK(bus_read_1(e.bus, STACK_END) == 0xAA); + + e.regs.X = 0; + */ +} + ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, emul_and); @@ -626,6 +650,7 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, emul_clc_sec); ATF_TP_ADD_TC(tp, emul_inc); ATF_TP_ADD_TC(tp, emul_inx_iny); + ATF_TP_ADD_TC(tp, emul_jmp); ATF_TP_ADD_TC(tp, emul_lda); ATF_TP_ADD_TC(tp, emul_nop); ATF_TP_ADD_TC(tp, emul_ora); diff --git a/test/test_emulation_jmp_abs.s b/test/test_emulation_jmp_abs.s new file mode 100644 index 0000000..dc4acb4 --- /dev/null +++ b/test/test_emulation_jmp_abs.s @@ -0,0 +1,4 @@ +start: nop + nop + jmp 0xC000 +