From b14332d352128aac5a29d9d7bb7547ae0f7cd8ad Mon Sep 17 00:00:00 2001 From: alyosha-tas Date: Sun, 7 Apr 2019 15:57:24 -0500 Subject: [PATCH] mc6809: wire up interrupts --- .../CPUs/MC6809/Execute.cs | 9 +- .../CPUs/MC6809/Indexed_Modes.cs | 45 ++-- .../CPUs/MC6809/Interrupts.cs | 79 ++++++- BizHawk.Emulation.Cores/CPUs/MC6809/MC6809.cs | 202 +++++++++++++----- .../CPUs/MC6809/OP_Tables.cs | 119 ++++++++++- 5 files changed, 369 insertions(+), 85 deletions(-) diff --git a/BizHawk.Emulation.Cores/CPUs/MC6809/Execute.cs b/BizHawk.Emulation.Cores/CPUs/MC6809/Execute.cs index 74c63d4428..910dcb9cea 100644 --- a/BizHawk.Emulation.Cores/CPUs/MC6809/Execute.cs +++ b/BizHawk.Emulation.Cores/CPUs/MC6809/Execute.cs @@ -6,16 +6,13 @@ namespace BizHawk.Emulation.Common.Components.MC6809 { public ulong TotalExecutedCycles; - public int EI_pending; - public bool interrupts_enabled; - // variables for executing instructions public int instr_pntr = 0; public ushort[] cur_instr; public int opcode; - public bool halted; - public bool stopped; - public bool jammed; + + public int IRQS; + public int irq_pntr; public void FetchInstruction(byte opcode) { diff --git a/BizHawk.Emulation.Cores/CPUs/MC6809/Indexed_Modes.cs b/BizHawk.Emulation.Cores/CPUs/MC6809/Indexed_Modes.cs index 6c73502f15..97cb87682b 100644 --- a/BizHawk.Emulation.Cores/CPUs/MC6809/Indexed_Modes.cs +++ b/BizHawk.Emulation.Cores/CPUs/MC6809/Indexed_Modes.cs @@ -52,6 +52,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 indexed_op = oper; PopulateCURINSTR(RD_INC_OP, ALU, PC, IDX_DCDE); + + IRQS = 0; } private void INDEX_OP_REG(ushort oper, ushort src) @@ -60,11 +62,15 @@ namespace BizHawk.Emulation.Common.Components.MC6809 indexed_op_reg = src; PopulateCURINSTR(RD_INC_OP, ALU, PC, IDX_DCDE); + + IRQS = 0; } private void INDEX_OP_JMP() { PopulateCURINSTR(TR, PC, IDX_EA); + + IRQS = irq_pntr + 2; } private void INDEX_OP_JSR() @@ -74,12 +80,16 @@ namespace BizHawk.Emulation.Common.Components.MC6809 TR, PC, IDX_EA, WR_DEC_LO, SP, ADDR, WR_HI, SP, ADDR); + + IRQS = irq_pntr + 6; } private void INDEX_OP_LEA(ushort dest) { PopulateCURINSTR(TR, dest, IDX_EA, IDLE); + + IRQS = irq_pntr + 3; } private void INDEX_OP_LD() @@ -87,6 +97,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 PopulateCURINSTR(IDLE, RD_INC, ALU, IDX_EA, RD_INC_OP, ALU2, IDX_EA, SET_ADDR, indexed_op_reg, ALU, ALU2); + + IRQS = irq_pntr + 4; } private void INDEX_OP_ST() @@ -94,6 +106,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 PopulateCURINSTR(IDLE, WR_HI_INC, IDX_EA, indexed_op_reg, WR_DEC_LO, IDX_EA, indexed_op_reg); + + IRQS = irq_pntr + 4; } private void INDEX_OP_LDD() @@ -101,6 +115,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 PopulateCURINSTR(IDLE, RD_INC, A, IDX_EA, RD_INC, B, IDX_EA); + + IRQS = irq_pntr + 4; } private void INDEX_OP_STD() @@ -108,23 +124,24 @@ namespace BizHawk.Emulation.Common.Components.MC6809 PopulateCURINSTR(SET_ADDR, ADDR, A, A, WR_HI_INC, IDX_EA, ADDR, WR_DEC_LO, IDX_EA, B); + + IRQS = irq_pntr + 4; } private void INDEX_OP_EX4(ushort oper) { PopulateCURINSTR(IDLE, RD_INC_OP, ALU, IDX_EA, oper, indexed_op_reg, ALU); + + IRQS = irq_pntr + 3; } private void INDEX_OP_EX4_ST() { PopulateCURINSTR(IDLE, WR, ALU, IDX_EA, indexed_op_reg); - } - private void INDEX_OP_EX5() - { - PopulateCURINSTR(RD_INC_OP, ALU, PC, IDX_DCDE); + IRQS = irq_pntr + 3; } private void INDEX_OP_EX6(ushort oper) @@ -133,6 +150,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 RD, ALU, IDX_EA, oper, ALU, WR, IDX_EA, ALU); + + IRQS = irq_pntr + 5; } private void INDEX_OP_EX6D(ushort oper) @@ -141,6 +160,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 RD_INC, ALU, IDX_EA, RD_INC_OP, ALU2, IDX_EA, SET_ADDR, ADDR, ALU, ALU2, oper, ADDR); + + IRQS = irq_pntr + 5; } private void INDEX_CMP_EX6(ushort oper) @@ -149,16 +170,10 @@ namespace BizHawk.Emulation.Common.Components.MC6809 RD_INC, ALU, IDX_EA, RD_INC_OP, ALU2, IDX_EA, SET_ADDR, ADDR, ALU, ALU2, oper, indexed_op_reg, ADDR); + + IRQS = irq_pntr + 5; } - - - private void INDEX_OP_EX7() - { - PopulateCURINSTR(RD_INC_OP, ALU, PC, IDX_DCDE); - } - - // ALU holds the post byte public void Index_decode() { @@ -384,6 +399,9 @@ namespace BizHawk.Emulation.Common.Components.MC6809 } } } + + instr_pntr = 0; + irq_pntr = 100; } public void Index_Op_Builder() @@ -427,6 +445,9 @@ namespace BizHawk.Emulation.Common.Components.MC6809 case I_ST16D: INDEX_OP_STD(); break; // ST D case I_CMP16D: INDEX_OP_EX6D(CMP16D); break; // CMP D } + + instr_pntr = 0; + irq_pntr = 100; } } } diff --git a/BizHawk.Emulation.Cores/CPUs/MC6809/Interrupts.cs b/BizHawk.Emulation.Cores/CPUs/MC6809/Interrupts.cs index ca1b9691ba..d443e83065 100644 --- a/BizHawk.Emulation.Cores/CPUs/MC6809/Interrupts.cs +++ b/BizHawk.Emulation.Cores/CPUs/MC6809/Interrupts.cs @@ -4,28 +4,87 @@ namespace BizHawk.Emulation.Common.Components.MC6809 { public partial class MC6809 { - private void INTERRUPT_() + private void IRQ_() { + Regs[ADDR] = 0xFFF8; + PopulateCURINSTR(IDLE, + IDLE, + DEC16, SP, + WR_DEC_LO, SP, PC, + WR_DEC_HI, SP, PC, + WR_DEC_LO, SP, US, + WR_DEC_HI, SP, US, + WR_DEC_LO, SP, Y, + WR_DEC_HI, SP, Y, + WR_DEC_LO, SP, X, + WR_DEC_HI, SP, X, + WR_DEC_LO, SP, DP, + WR_DEC_LO, SP, B, + WR_DEC_LO, SP, A, + WR, SP, CC, + SET_F_I, + RD_INC, ALU, ADDR, + RD_INC, ALU2, ADDR, + SET_ADDR, PC, ALU, ALU2); + IRQS = 19; } - private void INTERRUPT_GBC_NOP() + private void FIRQ_() { + Regs[ADDR] = 0xFFF6; + PopulateCURINSTR(IDLE, + IDLE, + DEC16, SP, + WR_DEC_LO, SP, PC, + WR_DEC_HI, SP, PC, + WR, SP, CC, + SET_F_I, + RD_INC, ALU, ADDR, + RD_INC, ALU2, ADDR, + SET_ADDR, PC, ALU, ALU2); + IRQS = 10; } - private static ushort[] INT_vectors = new ushort[] {0x40, 0x48, 0x50, 0x58, 0x60, 0x00}; + private void NMI_() + { + Regs[ADDR] = 0xFFFC; + PopulateCURINSTR(IDLE, + IDLE, + DEC16, SP, + WR_DEC_LO, SP, PC, + WR_DEC_HI, SP, PC, + WR_DEC_LO, SP, US, + WR_DEC_HI, SP, US, + WR_DEC_LO, SP, Y, + WR_DEC_HI, SP, Y, + WR_DEC_LO, SP, X, + WR_DEC_HI, SP, X, + WR_DEC_LO, SP, DP, + WR_DEC_LO, SP, B, + WR_DEC_LO, SP, A, + WR, SP, CC, + SET_F_I, + RD_INC, ALU, ADDR, + RD_INC, ALU2, ADDR, + SET_ADDR, PC, ALU, ALU2); - public ushort int_src; - public int stop_time; - public bool stop_check; - public bool I_use; // in halt mode, the I flag is checked earlier then when deicision to IRQ is taken - public bool skip_once; + IRQS = 19; + } + + public bool NMIPending; + public bool FIRQPending; + public bool IRQPending; + public bool IN_SYNC; + + public Action IRQCallback = delegate () { }; + public Action FIRQCallback = delegate () { }; + public Action NMICallback = delegate () { }; private void ResetInterrupts() { - I_use = false; - skip_once = false; + IN_SYNC = false; } } } \ No newline at end of file diff --git a/BizHawk.Emulation.Cores/CPUs/MC6809/MC6809.cs b/BizHawk.Emulation.Cores/CPUs/MC6809/MC6809.cs index 911564a028..f3c8ee7cf2 100644 --- a/BizHawk.Emulation.Cores/CPUs/MC6809/MC6809.cs +++ b/BizHawk.Emulation.Cores/CPUs/MC6809/MC6809.cs @@ -84,9 +84,17 @@ namespace BizHawk.Emulation.Common.Components.MC6809 { ResetRegisters(); ResetInterrupts(); - TotalExecutedCycles = 8; - stop_check = false; - cur_instr = new ushort[] { IDLE, IDLE, HALT_CHK, OP }; + TotalExecutedCycles = 0; + Regs[ADDR] = 0xFFFE; + PopulateCURINSTR(IDLE, + IDLE, + IDLE, + RD_INC, ALU, ADDR, + RD_INC, ALU2, ADDR, + SET_ADDR, PC, ALU, ALU2); + + IRQS = 6; + instr_pntr = irq_pntr = 0; } // Memory Access @@ -146,44 +154,13 @@ namespace BizHawk.Emulation.Common.Components.MC6809 // do nothing break; case OP: - // Read the opcode of the next instruction - if (EI_pending > 0) - { - EI_pending--; - if (EI_pending == 0) - { - interrupts_enabled = true; - } - } - - if (I_use && interrupts_enabled && !jammed) - { - interrupts_enabled = false; - - if (TraceCallback != null) - { - TraceCallback(new TraceInfo - { - Disassembly = "====IRQ====", - RegisterInfo = "" - }); - } - - // call interrupt processor - // lowest bit set is highest priority - INTERRUPT_(); - } - else - { - if (OnExecFetch != null) OnExecFetch(PC); - if (TraceCallback != null) TraceCallback(State()); - if (CDLCallback != null) CDLCallback(PC, eCDLogMemFlags.FetchFirst); - FetchInstruction(ReadMemory(Regs[PC]++)); - } + // Read the opcode of the next instruction + if (OnExecFetch != null) OnExecFetch(PC); + if (TraceCallback != null) TraceCallback(State()); + if (CDLCallback != null) CDLCallback(PC, eCDLogMemFlags.FetchFirst); + FetchInstruction(ReadMemory(Regs[PC]++)); instr_pntr = 0; - I_use = false; break; - case OP_PG_2: FetchInstruction2(ReadMemory(Regs[PC]++)); break; @@ -234,7 +211,7 @@ namespace BizHawk.Emulation.Common.Components.MC6809 Regs[cur_instr[instr_pntr++]] = (ushort)((Regs[cur_instr[instr_pntr++]] << 8) | Regs[cur_instr[instr_pntr++]]); break; case JPE: - if (!FlagE) { instr_pntr = 35; }; + if (!FlagE) { instr_pntr = 45; }; break; case IDX_DCDE: Index_decode(); @@ -422,10 +399,52 @@ namespace BizHawk.Emulation.Common.Components.MC6809 BIT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; case CWAI: + if (NMIPending) + { + Regs[ADDR] = 0xFFFC; + PopulateCURINSTR(RD_INC, ALU, ADDR, + RD_INC, ALU2, ADDR, + SET_ADDR, PC, ALU, ALU2); + irq_pntr = -1; + IRQS = 3; + if (TraceCallback != null) { TraceCallback(new TraceInfo { Disassembly = "====CWAI NMI====", RegisterInfo = "" }); } + } + else if (FIRQPending && !FlagF) + { + Regs[ADDR] = 0xFFF6; + PopulateCURINSTR(RD_INC, ALU, ADDR, + RD_INC, ALU2, ADDR, + SET_ADDR, PC, ALU, ALU2); + irq_pntr = -1; + IRQS = 3; + + if (TraceCallback != null) { TraceCallback(new TraceInfo { Disassembly = "====CWAI FIRQ====", RegisterInfo = "" }); } + } + else if (IRQPending && !FlagI) + { + Regs[ADDR] = 0xFFF8; + PopulateCURINSTR(RD_INC, ALU, ADDR, + RD_INC, ALU2, ADDR, + SET_ADDR, PC, ALU, ALU2); + irq_pntr = -1; + IRQS = 3; + + if (TraceCallback != null) { TraceCallback(new TraceInfo { Disassembly = "====CWAI IRQ====", RegisterInfo = "" }); } + } + else + { + PopulateCURINSTR(CWAI); + irq_pntr = 0; + IRQS = 0; + } + instr_pntr = 0; break; case SYNC: - + IN_SYNC = true; + IRQS = 1; + instr_pntr = irq_pntr = 0; + PopulateCURINSTR(SYNC); break; case INT_GET: @@ -434,6 +453,81 @@ namespace BizHawk.Emulation.Common.Components.MC6809 break; } + + if (++irq_pntr == IRQS) + { + // NMI has priority + if (NMIPending) + { + NMIPending = false; + + if (TraceCallback != null) { TraceCallback(new TraceInfo { Disassembly = "====NMI====", RegisterInfo = "" }); } + + IN_SYNC = false; + NMI_(); + NMICallback(); + instr_pntr = irq_pntr = 0; + } + // fast IRQ has next priority + else if (FIRQPending) + { + if (!FlagF) + { + FIRQPending = false; + + if (TraceCallback != null) { TraceCallback(new TraceInfo { Disassembly = "====FIRQ====", RegisterInfo = "" }); } + + IN_SYNC = false; + FIRQ_(); + FIRQCallback(); + instr_pntr = irq_pntr = 0; + } + else if (IN_SYNC) + { + FIRQPending = false; + + if (TraceCallback != null) { TraceCallback(new TraceInfo { Disassembly = "====SYNC====", RegisterInfo = "" }); } + + IN_SYNC = false; + IRQS = 1; + instr_pntr = irq_pntr = 0; + PopulateCURINSTR(IDLE); + } + } + // then regular IRQ + else if (IRQPending && !FlagI) + { + if (!FlagI) + { + IRQPending = false; + + if (TraceCallback != null) { TraceCallback(new TraceInfo { Disassembly = "====IRQ====", RegisterInfo = "" }); } + + IN_SYNC = false; + IRQ_(); + IRQCallback(); + instr_pntr = irq_pntr = 0; + } + else if (IN_SYNC) + { + IRQPending = false; + + if (TraceCallback != null) { TraceCallback(new TraceInfo { Disassembly = "====SYNC====", RegisterInfo = "" }); } + + IN_SYNC = false; + IRQS = 1; + instr_pntr = irq_pntr = 0; + PopulateCURINSTR(IDLE); + } + } + // otherwise start the next instruction + else + { + PopulateCURINSTR(OP); + instr_pntr = irq_pntr = 0; + } + } + TotalExecutedCycles++; } @@ -514,21 +608,25 @@ namespace BizHawk.Emulation.Common.Components.MC6809 public void SyncState(Serializer ser) { ser.BeginSection("MC6809"); - ser.Sync("IRQ", ref interrupts_enabled); - ser.Sync("I_use", ref I_use); - ser.Sync("skip_once", ref skip_once); - ser.Sync("Halted", ref halted); - ser.Sync("TotalExecutedCycles", ref TotalExecutedCycles); - ser.Sync("EI_pending", ref EI_pending); - ser.Sync("int_src", ref int_src); - ser.Sync("stop_time", ref stop_time); - ser.Sync("stop_check", ref stop_check); + + ser.Sync("IN_SYNC", ref IN_SYNC); + ser.Sync("NMIPending", ref NMIPending); + ser.Sync("FIRQPending", ref FIRQPending); + ser.Sync("IRQPending", ref IRQPending); + + ser.Sync("indexed_op", ref indexed_op); + ser.Sync("indexed_reg", ref indexed_reg); + ser.Sync("indexed_op_reg", ref indexed_op_reg); + ser.Sync("temp", ref temp); ser.Sync("instr_pntr", ref instr_pntr); ser.Sync("cur_instr", ref cur_instr, false); - ser.Sync("Stopped", ref stopped); ser.Sync("opcode", ref opcode); - ser.Sync("jammped", ref jammed); + ser.Sync("IRQS", ref IRQS); + ser.Sync("irq_pntr", ref irq_pntr); + + ser.Sync("Regs", ref Regs, false); + ser.Sync("TotalExecutedCycles", ref TotalExecutedCycles); ser.EndSection(); } diff --git a/BizHawk.Emulation.Cores/CPUs/MC6809/OP_Tables.cs b/BizHawk.Emulation.Cores/CPUs/MC6809/OP_Tables.cs index b220b09583..91d83517a9 100644 --- a/BizHawk.Emulation.Cores/CPUs/MC6809/OP_Tables.cs +++ b/BizHawk.Emulation.Cores/CPUs/MC6809/OP_Tables.cs @@ -11,6 +11,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 private void NOP_() { PopulateCURINSTR(IDLE); + + IRQS = 1; } private void ILLEGAL() @@ -21,13 +23,16 @@ namespace BizHawk.Emulation.Common.Components.MC6809 private void SYNC_() { PopulateCURINSTR(IDLE, - IDLE, SYNC); + + IRQS = 0; } private void REG_OP(ushort oper, ushort src) { PopulateCURINSTR(oper, src); + + IRQS = 1; } private void DIRECT_MEM(ushort oper) @@ -37,6 +42,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 RD, ALU, ADDR, oper, ALU, WR, ADDR, ALU); + + IRQS = 5; } private void DIRECT_ST_4(ushort dest) @@ -44,6 +51,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 PopulateCURINSTR(RD_INC_OP, ALU, PC, SET_ADDR, ADDR, DP, ALU, IDLE, WR, ADDR, dest); + + IRQS = 3; } private void DIRECT_MEM_4(ushort oper, ushort dest) @@ -51,6 +60,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 PopulateCURINSTR(RD_INC_OP, ALU, PC, SET_ADDR, ADDR, DP, ALU, IDLE, RD_INC_OP, ALU, ADDR, oper, dest, ALU); + + IRQS = 3; } private void EXT_MEM(ushort oper) @@ -61,6 +72,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 RD, ALU, ADDR, oper, ALU, WR, ADDR, ALU); + + IRQS = 6; } private void EXT_REG(ushort oper, ushort dest) @@ -69,6 +82,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 RD_INC_OP, ALU2, PC, SET_ADDR, ADDR, ALU, ALU2, RD, ALU, ADDR, oper, dest, ALU); + + IRQS = 4; } private void EXT_ST(ushort dest) @@ -77,6 +92,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 RD_INC_OP, ALU2, PC, SET_ADDR, ADDR, ALU, ALU2, IDLE, WR, ADDR, dest); + + IRQS = 4; } private void REG_OP_IMD_CC(ushort oper) @@ -84,11 +101,15 @@ namespace BizHawk.Emulation.Common.Components.MC6809 Regs[ALU2] = Regs[CC]; PopulateCURINSTR(RD_INC_OP, ALU, PC, oper, ALU2, ALU, TR, CC, ALU2); + + IRQS = 2; } private void REG_OP_IMD(ushort oper, ushort dest) { PopulateCURINSTR(RD_INC_OP, ALU, PC, oper, dest, ALU); + + IRQS = 1; } private void IMD_OP_D(ushort oper, ushort dest) @@ -96,6 +117,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 PopulateCURINSTR(RD_INC, ALU, PC, RD_INC_OP, ALU2, PC, SET_ADDR, ADDR, ALU, ALU2, oper, ADDR); + + IRQS = 3; } private void DIR_OP_D(ushort oper, ushort dest) @@ -105,6 +128,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 RD, ALU2, ADDR, SET_ADDR, ADDR, ALU, ALU2, oper, ADDR); + + IRQS = 5; } private void EXT_OP_D(ushort oper, ushort dest) @@ -115,12 +140,16 @@ namespace BizHawk.Emulation.Common.Components.MC6809 RD, ALU2, ADDR, SET_ADDR, ADDR, ALU, ALU2, oper, ADDR); + + IRQS = 6; } private void REG_OP_LD_16D() { PopulateCURINSTR(RD_INC, A, PC, RD_INC, B, PC); + + IRQS = 2; } private void DIR_OP_LD_16D() @@ -129,6 +158,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 IDLE, RD_INC, A, ADDR, RD_INC, B, ADDR); + + IRQS = 4; } private void DIR_OP_ST_16D() @@ -137,6 +168,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 SET_ADDR, ALU, A, A, WR_HI_INC, ADDR, ALU, WR, ADDR, B); + + IRQS = 4; } private void DIR_CMP_16(ushort oper, ushort dest) @@ -146,6 +179,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 RD, ALU2, ADDR, SET_ADDR, ADDR, ALU, ALU2, oper, dest, ADDR); + + IRQS = 5; } private void IMD_CMP_16(ushort oper, ushort dest) @@ -153,12 +188,16 @@ namespace BizHawk.Emulation.Common.Components.MC6809 PopulateCURINSTR(RD_INC, ALU, PC, RD_INC_OP, ALU2, PC, SET_ADDR, ADDR, ALU, ALU2, oper, dest, ADDR); + + IRQS = 3; } private void REG_OP_LD_16(ushort dest) { PopulateCURINSTR(RD_INC, ALU, PC, RD_INC_OP, ALU2, PC, SET_ADDR, dest, ALU, ALU2); + + IRQS = 2; } private void DIR_OP_LD_16(ushort dest) @@ -167,6 +206,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 IDLE, RD_INC, ALU, ADDR, RD_INC_OP, ALU2, ADDR, SET_ADDR, dest, ALU, ALU2); + + IRQS = 4; } private void DIR_OP_ST_16(ushort src) @@ -175,6 +216,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 IDLE, WR_HI_INC, ADDR, src, WR_DEC_LO, ADDR, src); + + IRQS = 4; } private void EXT_OP_LD_16(ushort dest) @@ -184,6 +227,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 IDLE, RD_INC, ALU, ADDR, RD_INC_OP, ALU2, ADDR, SET_ADDR, dest, ALU, ALU2); + + IRQS = 5; } private void EXT_OP_ST_16(ushort src) @@ -193,6 +238,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 IDLE, WR_HI_INC, ADDR, src, WR_DEC_LO, ADDR, src); + + IRQS = 5; } private void EXT_OP_LD_16D() @@ -202,6 +249,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 IDLE, RD_INC, A, ADDR, RD_INC, B, ADDR); + + IRQS = 5; } private void EXT_OP_ST_16D() @@ -211,6 +260,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 SET_ADDR, ALU, A, A, WR_HI_INC, ADDR, ALU, WR, ADDR, B); + + IRQS = 5; } private void EXT_CMP_16(ushort oper, ushort dest) @@ -221,6 +272,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 RD, ALU2, ADDR, SET_ADDR, ADDR, ALU, ALU2, oper, dest, ADDR); + + IRQS = 6; } private void EXG_() @@ -232,6 +285,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 IDLE, IDLE, IDLE); + + IRQS = 7; } private void TFR_() @@ -241,12 +296,16 @@ namespace BizHawk.Emulation.Common.Components.MC6809 IDLE, IDLE, IDLE); + + IRQS = 5; } private void JMP_DIR_() { PopulateCURINSTR(RD_INC, ALU, PC, SET_ADDR, PC, DP, ALU); + + IRQS = 2; } private void JMP_EXT_() @@ -254,6 +313,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 PopulateCURINSTR(RD_INC, ALU, PC, RD_INC, ALU2, PC, SET_ADDR, PC, ALU, ALU2); + + IRQS = 3; } private void JSR_() @@ -264,6 +325,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 TR, PC, ADDR, WR_DEC_LO, SP, ADDR, WR_HI, SP, ADDR); + + IRQS = 6; } private void JSR_EXT() @@ -275,6 +338,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 TR, PC, ADDR, WR_DEC_LO, SP, ADDR, WR_HI, SP, ADDR); + + IRQS = 7; } private void LBR_(bool cond) @@ -285,12 +350,16 @@ namespace BizHawk.Emulation.Common.Components.MC6809 RD_INC, ALU2, PC, SET_ADDR, ADDR, ALU, ALU2, ADD16BR, PC, ADDR); + + IRQS = 4; } else { PopulateCURINSTR(RD_INC, ALU, PC, RD_INC, ALU2, PC, SET_ADDR, PC, ALU, ALU2); + + IRQS = 3; } } @@ -300,11 +369,15 @@ namespace BizHawk.Emulation.Common.Components.MC6809 { PopulateCURINSTR(RD_INC, ALU, PC, ADD8BR, PC, ALU); + + IRQS = 2; } else { PopulateCURINSTR(RD_INC, ALU, PC, IDLE); + + IRQS = 2; } } @@ -316,6 +389,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 DEC16, SP, WR_DEC_LO, SP, ADDR, WR_HI, SP, ADDR); + + IRQS = 6; } private void LBSR_() @@ -328,22 +403,30 @@ namespace BizHawk.Emulation.Common.Components.MC6809 DEC16, SP, WR_DEC_LO, SP, ADDR, WR_HI, SP, ADDR); + + IRQS = 8; } private void PAGE_2() { PopulateCURINSTR(OP_PG_2); + + IRQS = 0; } private void PAGE_3() { PopulateCURINSTR(OP_PG_3); + + IRQS = 0; } private void ABX_() { PopulateCURINSTR(ABX, IDLE); + + IRQS = 2; } private void MUL_() @@ -358,6 +441,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 IDLE, IDLE, IDLE); + + IRQS = 10; } private void RTS() @@ -366,6 +451,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 RD_INC, ALU, SP, RD_INC, ALU2, SP, SET_ADDR, PC, ALU, ALU2); + + IRQS = 4; } private void RTI() @@ -381,7 +468,11 @@ namespace BizHawk.Emulation.Common.Components.MC6809 RD_INC_OP, ALU2, SP, SET_ADDR, Y, ALU, ALU2, RD_INC, ALU, SP, RD_INC_OP, ALU2, SP, SET_ADDR, US, ALU, ALU2, - SET_ADDR, PC, ALU2, ALU); + RD_INC, ALU, SP, + RD_INC_OP, ALU2, SP, + SET_ADDR, PC, ALU, ALU2); + + IRQS = 14; } private void PSH(ushort src) @@ -390,6 +481,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 IDLE, DEC16, SP, PSH_n, src); + + IRQS = 0; } // Post byte info is in ALU @@ -457,7 +550,11 @@ namespace BizHawk.Emulation.Common.Components.MC6809 else { Regs[src] += 1; // we decremented an extra time overall, regardless of what was run + + IRQS = irq_pntr + 1; } + + instr_pntr = 0; } private void PUL(ushort src) @@ -465,6 +562,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 PopulateCURINSTR(RD_INC, ALU, PC, IDLE, PSH_n, src); + + IRQS = 0; } // Post byte info is in ALU @@ -533,8 +632,12 @@ namespace BizHawk.Emulation.Common.Components.MC6809 else { // extra end cycle - PopulateCURINSTR(RD_INC_OP, IDLE); + PopulateCURINSTR(IDLE); + + IRQS = irq_pntr + 2; } + + instr_pntr = 0; } private void SWI1() @@ -557,7 +660,9 @@ namespace BizHawk.Emulation.Common.Components.MC6809 SET_F_I, RD_INC, ALU, ADDR, RD_INC, ALU2, ADDR, - SET_ADDR, ADDR, ALU, ALU2); + SET_ADDR, PC, ALU, ALU2); + + IRQS = 18; } private void SWI2_3(ushort pick) @@ -580,7 +685,9 @@ namespace BizHawk.Emulation.Common.Components.MC6809 IDLE, RD_INC, ALU, ADDR, RD_INC, ALU2, ADDR, - SET_ADDR, ADDR, ALU, ALU2); + SET_ADDR, PC, ALU, ALU2); + + IRQS = 18; } private void CWAI_() @@ -601,6 +708,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809 WR_DEC_LO, SP, A, WR, SP, CC, CWAI); + + IRQS = 16; } } }