mirror of
https://github.com/rkujawa/rk65c02.git
synced 2024-12-04 04:51:27 +00:00
Add RTI emulation and test case.
This commit is contained in:
parent
d29be055f9
commit
5cca703020
@ -63,7 +63,7 @@ OP_BIT_ABSX,"bit",ABSOLUTEX,3,emul_bit,false
|
||||
OP_AND_ABSX,"and",ABSOLUTEX,3,emul_and,false
|
||||
OP_ROL_ABSX,"rol",ABSOLUTEX,3,emul_rol,false
|
||||
OP_BBR3_REL,"bbr3",ZPR,2,emul_bbr3,true
|
||||
OP_RTI,"rti",IMPLIED,1,NULL,false
|
||||
OP_RTI,"rti",IMPLIED,1,emul_rti,true
|
||||
OP_EOR_IZPX,"eor",IZPX,2,emul_eor,false
|
||||
OP_NOPI_43,"invalid",IMMEDIATE,2,NULL,false
|
||||
OP_NOPI_44,"invalid",IMPLIED,1,NULL,false
|
||||
|
|
@ -639,6 +639,20 @@ emul_ply(rk65c02emu_t *e, void *id, instruction_t *i)
|
||||
e->regs.Y = stack_pop(e);
|
||||
}
|
||||
|
||||
/* RTI - return from interrupt */
|
||||
void
|
||||
emul_rti(rk65c02emu_t *e, void *id, instruction_t *i)
|
||||
{
|
||||
uint16_t retaddr;
|
||||
|
||||
/* restore processor status from stack */
|
||||
e->regs.P = stack_pop(e) | P_UNDEFINED;
|
||||
/* restore PC */
|
||||
retaddr = stack_pop(e);
|
||||
retaddr|= stack_pop(e) << 8;
|
||||
e->regs.PC = retaddr;
|
||||
}
|
||||
|
||||
/* RTS - return from subroutine */
|
||||
void
|
||||
emul_rts(rk65c02emu_t *e, void *id, instruction_t *i)
|
||||
|
@ -10,18 +10,19 @@
|
||||
#include "instruction.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define ISR_ADDR 0xC100
|
||||
|
||||
/*
|
||||
* Test case for software generated interrupt (by BRK instruction).
|
||||
*/
|
||||
ATF_TC_WITHOUT_HEAD(intr_brk);
|
||||
ATF_TC_BODY(intr_brk, tc)
|
||||
{
|
||||
const uint16_t isr_addr = 0xC100;
|
||||
const uint16_t isr_addr = ISR_ADDR;
|
||||
|
||||
rk65c02emu_t e;
|
||||
bus_t b;
|
||||
|
||||
|
||||
b = bus_init();
|
||||
e = rk65c02_init(&b);
|
||||
|
||||
@ -61,9 +62,62 @@ ATF_TC_BODY(intr_brk, tc)
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Test case for return from interrupt by RTI instruction.
|
||||
*/
|
||||
ATF_TC_WITHOUT_HEAD(intr_rti);
|
||||
ATF_TC_BODY(intr_rti, tc)
|
||||
{
|
||||
bus_t b;
|
||||
rk65c02emu_t e;
|
||||
uint8_t *asmbuf;
|
||||
uint16_t israsmpc;
|
||||
uint8_t bsize;
|
||||
|
||||
b = bus_init();
|
||||
e = rk65c02_init(&b);
|
||||
|
||||
israsmpc = ISR_ADDR;
|
||||
|
||||
ATF_REQUIRE(assemble_single_implied(&asmbuf, &bsize, "nop"));
|
||||
ATF_REQUIRE(bus_load_buf(&b, israsmpc, asmbuf, bsize));
|
||||
free(asmbuf);
|
||||
israsmpc += bsize;
|
||||
|
||||
ATF_REQUIRE(assemble_single_implied(&asmbuf, &bsize, "rti"));
|
||||
ATF_REQUIRE(bus_load_buf(&b, israsmpc, asmbuf, bsize));
|
||||
free(asmbuf);
|
||||
israsmpc += bsize;
|
||||
|
||||
ATF_REQUIRE(assemble_single_implied(&asmbuf, &bsize, "nop"));
|
||||
ATF_REQUIRE(bus_load_buf(&b, ROM_LOAD_ADDR, asmbuf, bsize));
|
||||
free(asmbuf);
|
||||
|
||||
/* There's a return address and saved processor flags on stack. */
|
||||
e.regs.SP = 0xFF;
|
||||
stack_push(&e, ROM_LOAD_ADDR >> 8);
|
||||
stack_push(&e, ROM_LOAD_ADDR & 0xFF);
|
||||
stack_push(&e, e.regs.P);
|
||||
|
||||
/* We're in the middle of interrupt service routine, just before RTI. */
|
||||
e.regs.PC = ISR_ADDR;
|
||||
rk65c02_step(&e, 1);
|
||||
ATF_CHECK(e.regs.PC == ISR_ADDR + 1);
|
||||
rk65c02_dump_regs(&e);
|
||||
rk65c02_dump_stack(&e, 0x4);
|
||||
|
||||
/* Step onto RTI. */
|
||||
rk65c02_step(&e, 1);
|
||||
rk65c02_dump_regs(&e);
|
||||
/* Check if we're back in the main program. */
|
||||
ATF_CHECK(e.regs.PC == ROM_LOAD_ADDR);
|
||||
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, intr_brk);
|
||||
ATF_TP_ADD_TC(tp, intr_rti);
|
||||
|
||||
return (atf_no_error());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user