Add JSR and RTS emulation and tests.

This commit is contained in:
Radosław Kujawa 2017-01-29 11:47:34 +01:00
parent 4a8fbfbaeb
commit bb3f77ec7f
4 changed files with 64 additions and 2 deletions

View File

@ -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

1 opcode_id mnemonic addressing size emulation modify_pc
31 OP_ORA_ABSX ora ABSOLUTEX 3 emul_ora false
32 OP_ASL_ABSX asl ABSOLUTEX 3 emul_asl false
33 OP_BBR1_REL bbr1 ZPR 2 NULL true
34 OP_JSR jsr ABSOLUTE 3 NULL emul_jsr true
35 OP_AND_IZPX and IZPX 2 emul_and false
36 OP_NOPI_23 nop IMMEDIATE 2 NULL false
37 OP_NOPI_24 nop IMPLIED 1 NULL false
95 OP_EOR_ABSX eor ABSOLUTEX 3 emul_eor false
96 OP_LSR_ABSX lsr ABSOLUTEX 3 emul_lsr false
97 OP_BBR5_REL bbr5 ZPR 2 NULL true
98 OP_RTS rts IMPLIED 1 NULL emul_rts false
99 OP_ADC_IZPX adc IZPX 2 NULL false
100 OP_NOPI_63 nop IMMEDIATE 2 NULL false
101 OP_NOPI_64 nop IMPLIED 1 NULL false

View File

@ -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)

View File

@ -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);

View File

@ -0,0 +1,10 @@
.org 0xC000
start: nop
jsr foo
nop
stp
foo: lda #0xAA
rts