mirror of
https://github.com/rkujawa/rk65c02.git
synced 2025-03-03 14:29:23 +00:00
Add preliminary support for interrupts.
This commit is contained in:
parent
4ed2016621
commit
ac48e5435f
@ -271,31 +271,14 @@ emul_bra(rk65c02emu_t *e, void *id, instruction_t *i)
|
||||
program_counter_branch(e, (int8_t) i->op1);
|
||||
}
|
||||
|
||||
/* BRK - break! or rather, jump to break vector */
|
||||
/* BRK - break! or rather cause an IRQ in software */
|
||||
void
|
||||
emul_brk(rk65c02emu_t *e, void *id, instruction_t *i)
|
||||
{
|
||||
uint16_t retaddr;
|
||||
|
||||
retaddr = e->regs.PC + 2;
|
||||
|
||||
/* push return address to the stack */
|
||||
stack_push(e, retaddr >> 8);
|
||||
stack_push(e, retaddr & 0xFF);
|
||||
/* push processor status to the stack with break flag set */
|
||||
stack_push(e, e->regs.P | P_BREAK);
|
||||
|
||||
/*
|
||||
* The IRQ disable is set, decimal flags is cleared _after_ pushing
|
||||
* the P register to the stack.
|
||||
*/
|
||||
e->regs.P |= P_IRQ_DISABLE;
|
||||
e->regs.P &= ~P_DECIMAL;
|
||||
|
||||
/* load address from IRQ vector into program counter */
|
||||
e->regs.PC = bus_read_1(e->bus, VECTOR_IRQ);
|
||||
e->regs.PC |= bus_read_1(e->bus, VECTOR_IRQ + 1) << 8;
|
||||
e->regs.PC += 2;
|
||||
e->regs.P |= P_BREAK;
|
||||
|
||||
rk65c02_irq(e);
|
||||
}
|
||||
|
||||
/* BVC - branch on overflow clear */
|
||||
|
@ -26,9 +26,38 @@ rk65c02_init(bus_t *b)
|
||||
/* reset also clears the decimal flag */
|
||||
e.regs.P &= ~P_DECIMAL;
|
||||
|
||||
e.irq = false;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do interrupt'ey things and start the interrupt service routine.
|
||||
*/
|
||||
void
|
||||
rk65c02_irq(rk65c02emu_t *e)
|
||||
{
|
||||
/* push return address to the stack */
|
||||
stack_push(e, e->regs.PC >> 8);
|
||||
stack_push(e, e->regs.PC & 0xFF);
|
||||
/* push processor status to the stack with break flag set */
|
||||
stack_push(e, e->regs.P);
|
||||
|
||||
/*
|
||||
* The IRQ disable is set, decimal flags is cleared _after_ pushing
|
||||
* the P register to the stack.
|
||||
*/
|
||||
e->regs.P |= P_IRQ_DISABLE;
|
||||
e->regs.P &= ~P_DECIMAL;
|
||||
|
||||
/* break flag is only saved to the stack, it is not present in the ISR... */
|
||||
e->regs.P &= ~P_BREAK;
|
||||
|
||||
/* load address from IRQ vector into program counter */
|
||||
e->regs.PC = bus_read_1(e->bus, VECTOR_IRQ);
|
||||
e->regs.PC |= bus_read_1(e->bus, VECTOR_IRQ + 1) << 8;
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute a single instruction within emulator.
|
||||
*/
|
||||
@ -38,6 +67,9 @@ rk65c02_exec(rk65c02emu_t *e)
|
||||
instruction_t i;
|
||||
instrdef_t id;
|
||||
|
||||
if (e->irq && (!(e->regs.P & P_IRQ_DISABLE)))
|
||||
rk65c02_irq(e);
|
||||
|
||||
/* XXX: handle breakpoints and watch points */
|
||||
|
||||
/* if disassembly-when-running enabled */
|
||||
|
@ -53,6 +53,7 @@ struct rk65c02emu {
|
||||
bus_t *bus;
|
||||
reg_state_t regs;
|
||||
emu_stop_reason_t stopreason;
|
||||
bool irq; /* interrupt request line state, true is asserted */
|
||||
};
|
||||
|
||||
typedef struct rk65c02emu rk65c02emu_t;
|
||||
@ -61,6 +62,7 @@ rk65c02emu_t rk65c02_init(bus_t *);
|
||||
void rk65c02_start(rk65c02emu_t *);
|
||||
void rk65c02_step(rk65c02emu_t *, uint16_t);
|
||||
void rk65c02_dump_regs(rk65c02emu_t *);
|
||||
void rk65c02_irq(rk65c02emu_t *e);
|
||||
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user