From bb3f77ec7fd184803f1fa3fdd687a77ba969c1f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Kujawa?= Date: Sun, 29 Jan 2017 11:47:34 +0100 Subject: [PATCH] Add JSR and RTS emulation and tests. --- src/65c02isa.csv | 4 ++-- src/emulation.c | 30 ++++++++++++++++++++++++++++++ test/test_emulation.c | 22 ++++++++++++++++++++++ test/test_emulation_jsr_rts.s | 10 ++++++++++ 4 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 test/test_emulation_jsr_rts.s diff --git a/src/65c02isa.csv b/src/65c02isa.csv index e86bed9..0eac917 100644 --- a/src/65c02isa.csv +++ b/src/65c02isa.csv @@ -31,7 +31,7 @@ OP_TRB_ABS,"trb",ABSOLUTE,3,NULL,false OP_ORA_ABSX,"ora",ABSOLUTEX,3,emul_ora,false OP_ASL_ABSX,"asl",ABSOLUTEX,3,emul_asl,false OP_BBR1_REL,"bbr1",ZPR,2,NULL,true -OP_JSR,"jsr",ABSOLUTE,3,NULL,true +OP_JSR,"jsr",ABSOLUTE,3,emul_jsr,true OP_AND_IZPX,"and",IZPX,2,emul_and,false OP_NOPI_23,"nop",IMMEDIATE,2,NULL,false OP_NOPI_24,"nop",IMPLIED,1,NULL,false @@ -95,7 +95,7 @@ OP_NOPI_5D,"nop",ABSOLUTE,3,NULL,false OP_EOR_ABSX,"eor",ABSOLUTEX,3,emul_eor,false OP_LSR_ABSX,"lsr",ABSOLUTEX,3,emul_lsr,false OP_BBR5_REL,"bbr5",ZPR,2,NULL,true -OP_RTS,"rts",IMPLIED,1,NULL,false +OP_RTS,"rts",IMPLIED,1,emul_rts,false OP_ADC_IZPX,"adc",IZPX,2,NULL,false OP_NOPI_63,"nop",IMMEDIATE,2,NULL,false OP_NOPI_64,"nop",IMPLIED,1,NULL,false diff --git a/src/emulation.c b/src/emulation.c index 5ec5334..8bc4299 100644 --- a/src/emulation.c +++ b/src/emulation.c @@ -248,6 +248,24 @@ emul_jmp(rk65c02emu_t *e, void *id, instruction_t *i) e->regs.PC = target; } +/* JSR - jump to subroutine */ +void +emul_jsr(rk65c02emu_t *e, void *id, instruction_t *i) +{ + uint16_t jumpaddr; /* addres to jump to */ + uint16_t retaddr; /* return address */ + + jumpaddr = i->op1 + (i->op2 << 8); + retaddr = e->regs.PC + 2; /* XXX */ + + /* push return address to stack */ + stack_push(e, retaddr >> 8); + stack_push(e, retaddr & 0xFF); + + /* change program counter to point to the new location */ + e->regs.PC = jumpaddr; +} + /* LDA - load to accumulator */ void emul_lda(rk65c02emu_t *e, void *id, instruction_t *i) @@ -376,6 +394,18 @@ emul_ply(rk65c02emu_t *e, void *id, instruction_t *i) e->regs.Y = stack_pop(e); } +/* RTS - return from subroutine */ +void +emul_rts(rk65c02emu_t *e, void *id, instruction_t *i) +{ + uint16_t retaddr; + + retaddr = stack_pop(e); + retaddr|= stack_pop(e) << 8; + + e->regs.PC = retaddr; +} + /* RMBx - reset or set memory bit (handles RMB0-RMB7) */ void emul_rmb(rk65c02emu_t *e, void *id, instruction_t *i, uint8_t bit) diff --git a/test/test_emulation.c b/test/test_emulation.c index 4dc3a26..f31ef0b 100644 --- a/test/test_emulation.c +++ b/test/test_emulation.c @@ -870,6 +870,27 @@ ATF_TC_BODY(emul_jmp, tc) ATF_CHECK(e.regs.PC = 0xC000); } +ATF_TC_WITHOUT_HEAD(emul_jsr_rts); +ATF_TC_BODY(emul_jsr_rts, tc) +{ + rk65c02emu_t e; + bus_t b; + + b = bus_init(); + e = rk65c02_init(&b); + + /* JSR and RTS */ + e.regs.PC = ROM_LOAD_ADDR; + ATF_REQUIRE(bus_load_file(&b, ROM_LOAD_ADDR, + rom_path("test_emulation_jsr_rts.rom", tc))); + + rk65c02_step(&e, 2); + ATF_CHECK(e.regs.PC = 0xC006); + rk65c02_start(&e); + ATF_CHECK(e.regs.PC = 0xC006); + +} + ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, emul_and); @@ -885,6 +906,7 @@ ATF_TP_ADD_TCS(tp) 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_jsr_rts); 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_jsr_rts.s b/test/test_emulation_jsr_rts.s new file mode 100644 index 0000000..db4de11 --- /dev/null +++ b/test/test_emulation_jsr_rts.s @@ -0,0 +1,10 @@ +.org 0xC000 + +start: nop + jsr foo + nop + stp + +foo: lda #0xAA + rts +