From 4c7a15f524aabce1103f9b9857af6b936193aa4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Kujawa?= Date: Thu, 9 Feb 2017 21:53:45 +0100 Subject: [PATCH] Add emulation of WAI instruction. --- src/65c02isa.csv | 2 +- src/emulation.c | 8 ++++++++ src/rk65c02.c | 21 ++++++++++++++++++++- src/rk65c02.h | 1 + 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/65c02isa.csv b/src/65c02isa.csv index ab9d42d..9444b97 100644 --- a/src/65c02isa.csv +++ b/src/65c02isa.csv @@ -202,7 +202,7 @@ OP_SMB4_ZP,"smb4",ZP,2,emul_smb4,false OP_INY,"iny",IMPLIED,1,emul_iny,false OP_CMP_IMM,"cmp",IMMEDIATE,2,emul_cmp,false OP_DEX,"dex",IMPLIED,1,emul_dex,false -OP_WAI,"wai",IMPLIED,1,NULL,false +OP_WAI,"wai",IMPLIED,1,emul_wai,false OP_CPY_ABS,"cpy",ABSOLUTE,3,emul_cpy,false OP_CMP_ABS,"cmp",ABSOLUTE,3,emul_cmp,false OP_DEC_ABS,"dec",ABSOLUTE,3,emul_dec,false diff --git a/src/emulation.c b/src/emulation.c index 710e41b..d47d18f 100644 --- a/src/emulation.c +++ b/src/emulation.c @@ -1014,3 +1014,11 @@ emul_tya(rk65c02emu_t *e, void *id, instruction_t *i) instruction_status_adjust_negative(e, e->regs.A); } +/* WAI - wait for interrupt */ +void +emul_wai(rk65c02emu_t *e, void *id, instruction_t *i) +{ + e->state = STOPPED; + e->stopreason = WAI; +} + diff --git a/src/rk65c02.c b/src/rk65c02.c index f01d784..0226fdc 100644 --- a/src/rk65c02.c +++ b/src/rk65c02.c @@ -22,6 +22,7 @@ rk65c02_init(bus_t *b) e.bus = b; e.state = STOPPED; + e.stopreason = HOST; e.regs.P = P_UNDEFINED|P_IRQ_DISABLE; /* reset also clears the decimal flag */ e.regs.P &= ~P_DECIMAL; @@ -32,7 +33,25 @@ rk65c02_init(bus_t *b) } /* - * Do interrupt'ey things and start the interrupt service routine. + * Assert the IRQ line. + */ +void +rk65c02_assert_irq(rk65c02emu_t *e) +{ + /* + * Clearly this is too simpleton'ish, because more than one device + * might want to assert the interrupt line (on hardware level it is + * active low, so can just be pulled down by any device connected + * to it. + */ + e->irq = true; + + if ((e->state == STOPPED) && (e->stopreason == WAI)) + rk65c02_start(e); +} + +/* + * Respond to interrupt and start the interrupt service routine. */ void rk65c02_irq(rk65c02emu_t *e) diff --git a/src/rk65c02.h b/src/rk65c02.h index a2c9bd4..4f9c52f 100644 --- a/src/rk65c02.h +++ b/src/rk65c02.h @@ -11,6 +11,7 @@ typedef enum { typedef enum { STP, /* due to 65C02 STP instruction */ + WAI, /* waiting for interrupt */ BREAKPOINT, /* due to breakpoint set */ WATCHPOINT, /* due to watchpoint set */ STEPPED, /* stepped appropriate number of instructions */