From 4cdcb807214dde3cc6de65a2a3612dbbce0e89ec Mon Sep 17 00:00:00 2001 From: alyosha-tas Date: Sat, 29 Sep 2018 22:08:19 -0500 Subject: [PATCH] z80: rewrite interrupt handling step one in proper line polling for CPC --- BizHawk.Emulation.Cores/CPUs/Z80A/Execute.cs | 4 + .../CPUs/Z80A/Interrupts.cs | 70 +-- .../CPUs/Z80A/Operations.cs | 41 +- BizHawk.Emulation.Cores/CPUs/Z80A/ReadMe.txt | 10 +- .../CPUs/Z80A/Registers.cs | 2 +- .../CPUs/Z80A/Tables_Direct.cs | 486 ++++++++---------- .../CPUs/Z80A/Tables_Indirect.cs | 330 ++++++------ BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs | 453 ++++++++-------- 8 files changed, 677 insertions(+), 719 deletions(-) diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Execute.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Execute.cs index bd5a4928f0..b8b65bdf39 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/Execute.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Execute.cs @@ -17,17 +17,21 @@ namespace BizHawk.Emulation.Cores.Components.Z80A public const ushort IXCBpre = 4; public const ushort IYCBpre = 5; public const ushort IXYprefetch = 6; + public ushort PRE_SRC; // variables for executing instructions public int instr_pntr = 0; public int bus_pntr = 0; public int mem_pntr = 0; + public int irq_pntr = 0; public ushort[] cur_instr; public ushort[] BUSRQ; public ushort[] MEMRQ; + public ushort[] IRQS; public byte opcode; public bool NO_prefix, CB_prefix, IX_prefix, EXTD_prefix, IY_prefix, IXCB_prefix, IYCB_prefix; public bool halted; + public bool I_skip; public void FetchInstruction() { diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Interrupts.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Interrupts.cs index 8b7852812f..dbc90454de 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/Interrupts.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Interrupts.cs @@ -37,21 +37,22 @@ namespace BizHawk.Emulation.Cores.Components.Z80A private void NMI_() { cur_instr = new ushort[] - {DEC16, SPl, SPh, + {IDLE, + IDLE, + IDLE, + IDLE, + DEC16, SPl, SPh, TR, ALU, PCl, WAIT, WR_DEC, SPl, SPh, PCh, TR16, PCl, PCh, NMI_V, ZERO, WAIT, - WR, SPl, SPh, ALU, - IDLE, - WAIT, - OP_F, - OP }; + WR, SPl, SPh, ALU }; - BUSRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0, PCh, 0, 0, 0 }; - } + BUSRQ = new ushort[] { 0, 0, 0, 0, 0, SPh, 0, 0, SPh, 0, 0 }; + MEMRQ = new ushort[] { 0, 0, 0, 0, 0, SPh, 0, 0, SPh, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + } // Mode 0 interrupts only take effect if a CALL or RST is on the data bus // Otherwise operation just continues as normal @@ -62,17 +63,18 @@ namespace BizHawk.Emulation.Cores.Components.Z80A { cur_instr = new ushort[] {IDLE, - WAIT, - RD_INC, ALU, PCl, PCh, + IDLE, + IDLE, + IDLE, IDLE, WAIT, - OP_F, - OP }; + RD_INC, ALU, PCl, PCh }; - BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, 0, 0, 0, PCh, 0, 0 }; + MEMRQ = new ushort[] { 0, 0, 0, 0, PCh, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 1 }; - IRQACKCallback(); + IRQACKCallback(); } // Just jump to $0038 @@ -80,6 +82,10 @@ namespace BizHawk.Emulation.Cores.Components.Z80A { cur_instr = new ushort[] {IDLE, + IDLE, + IDLE, + IDLE, + IDLE, TR, ALU, PCl, DEC16, SPl, SPh, IDLE, @@ -87,23 +93,24 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WR_DEC, SPl, SPh, PCh, TR16, PCl, PCh, IRQ_V, ZERO, WAIT, - WR, SPl, SPh, ALU, - IDLE, - WAIT, - OP_F, - OP }; + WR, SPl, SPh, ALU }; - BUSRQ = new ushort[] { I, 0, 0, SPh, 0, 0, SPh, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { I, 0, 0, SPh, 0, 0, SPh, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, 0, 0, 0, I, 0, 0, SPh, 0, 0, SPh, 0, 0 }; + MEMRQ = new ushort[] { 0, 0, 0, 0, I, 0, 0, SPh, 0, 0, SPh, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; - IRQACKCallback(); + IRQACKCallback(); } // Interrupt mode 2 uses the I vector combined with a byte on the data bus private void INTERRUPT_2() { cur_instr = new ushort[] - {FTCH_DB, + {IDLE, + IDLE, + IDLE, + IDLE, + FTCH_DB, IDLE, DEC16, SPl, SPh, TR16, Z, W, DB, I, @@ -117,16 +124,13 @@ namespace BizHawk.Emulation.Cores.Components.Z80A RD_INC, PCl, Z, W, IDLE, WAIT, - RD, PCh, Z, W, - IDLE, - WAIT, - OP_F, - OP }; + RD, PCh, Z, W }; - BUSRQ = new ushort[] { I, 0, 0, SPh, 0, 0, SPh, 0, 0, W, 0, 0, W, 0 ,0 ,PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { I, 0, 0, SPh, 0, 0, SPh, 0, 0, W, 0, 0, W, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, 0, 0, 0, I, 0, 0, SPh, 0, 0, SPh, 0, 0, W, 0, 0, W, 0 ,0 }; + MEMRQ = new ushort[] { 0, 0, 0, 0, I, 0, 0, SPh, 0, 0, SPh, 0, 0, W, 0, 0, W, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; - IRQACKCallback(); + IRQACKCallback(); } private void ResetInterrupts() diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Operations.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Operations.cs index bd8029baa1..d643ce06c8 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/Operations.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Operations.cs @@ -18,6 +18,14 @@ namespace BizHawk.Emulation.Cores.Components.Z80A INC16_Func(src_l, src_h); } + public void Read_INC_TR_PC_Func(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h) + { + Regs[dest_h] = ReadMemory((ushort)(Regs[src_l] | (Regs[src_h]) << 8)); + Regs[DB] = Regs[dest_h]; + INC16_Func(src_l, src_h); + TR16_Func(PCl, PCh, dest_l, dest_h); + } + public void Write_Func(ushort dest_l, ushort dest_h, ushort src) { Regs[DB] = Regs[src]; @@ -38,12 +46,26 @@ namespace BizHawk.Emulation.Cores.Components.Z80A DEC16_Func(dest_l, dest_h); } + public void Write_TR_PC_Func(ushort dest_l, ushort dest_h, ushort src) + { + Regs[DB] = Regs[src]; + WriteMemory((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)Regs[src]); + TR16_Func(PCl, PCh, Z, W); + } + public void OUT_Func(ushort dest_l, ushort dest_h, ushort src) { Regs[DB] = Regs[src]; WriteHardware((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)(Regs[src])); } + public void OUT_INC_Func(ushort dest_l, ushort dest_h, ushort src) + { + Regs[DB] = Regs[src]; + WriteHardware((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)(Regs[src])); + INC16_Func(dest_l, dest_h); + } + public void IN_Func(ushort dest, ushort src_l, ushort src_h) { Regs[dest] = ReadHardware((ushort)(Regs[src_l] | (Regs[src_h]) << 8)); @@ -58,10 +80,27 @@ namespace BizHawk.Emulation.Cores.Components.Z80A Flag3 = Regs[dest].Bit(3); } - public void IN_A_N_Func(ushort dest, ushort src_l, ushort src_h) + public void IN_INC_Func(ushort dest, ushort src_l, ushort src_h) + { + Regs[dest] = ReadHardware((ushort)(Regs[src_l] | (Regs[src_h]) << 8)); + Regs[DB] = Regs[dest]; + + FlagZ = Regs[dest] == 0; + FlagP = TableParity[Regs[dest]]; + FlagH = false; + FlagN = false; + FlagS = Regs[dest].Bit(7); + Flag5 = Regs[dest].Bit(5); + Flag3 = Regs[dest].Bit(3); + + INC16_Func(src_l, src_h); + } + + public void IN_A_N_INC_Func(ushort dest, ushort src_l, ushort src_h) { Regs[dest] = ReadHardware((ushort)(Regs[src_l] | (Regs[src_h]) << 8)); Regs[DB] = Regs[dest]; + INC16_Func(src_l, src_h); } public void TR_Func(ushort dest, ushort src) diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/ReadMe.txt b/BizHawk.Emulation.Cores/CPUs/Z80A/ReadMe.txt index db37bed6fa..f586c70186 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/ReadMe.txt +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/ReadMe.txt @@ -1,5 +1,5 @@ -TODO: - -Mode 0 (nothing to test with) -IRQ BUS timings (nothing to test with) -BusAQ (nothing to test with) +TODO: + +Mode 0 (nothing to test with) +IRQ BUS timings (nothing to test with) +BusAQ (nothing to test with) diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Registers.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Registers.cs index 339fb6864e..7f392fbe0c 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/Registers.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Registers.cs @@ -58,7 +58,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A public const ushort WIO4 = 108; - public bool FlagI, FlagI1, FlagI2, FlagI3, FlagI4, FlagI5; + public bool FlagI; public bool FlagW; // wait flag, when set to true reads / writes will be delayed diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Direct.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Direct.cs index f1f45ebd8c..6589e525d8 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Direct.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Direct.cs @@ -10,13 +10,11 @@ namespace BizHawk.Emulation.Cores.Components.Z80A private void NOP_() { cur_instr = new ushort[] - { IDLE, - WAIT, - OP_F, - OP }; + {IDLE }; - BUSRQ = new ushort[] { PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0 }; + MEMRQ = new ushort[] { 0 }; + IRQS = new ushort[] { 1 }; } // NOTE: In a real Z80, this operation just flips a switch to choose between 2 registers @@ -24,38 +22,32 @@ namespace BizHawk.Emulation.Cores.Components.Z80A private void EXCH_() { cur_instr = new ushort[] - {EXCH, - WAIT, - OP_F, - OP }; + {EXCH }; - BUSRQ = new ushort[] { PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0 }; + MEMRQ = new ushort[] { 0 }; + IRQS = new ushort[] { 1 }; } private void EXX_() { cur_instr = new ushort[] - {EXX, - WAIT, - OP_F, - OP }; + {EXX }; - BUSRQ = new ushort[] { PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0 }; + MEMRQ = new ushort[] { 0 }; + IRQS = new ushort[] { 1 }; } // this exchanges 2 16 bit registers private void EXCH_16_(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h) { cur_instr = new ushort[] - {EXCH_16, dest_l, dest_h, src_l, src_h, - WAIT, - OP_F, - OP }; + {EXCH_16, dest_l, dest_h, src_l, src_h }; - BUSRQ = new ushort[] { PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0 }; + MEMRQ = new ushort[] { 0 }; + IRQS = new ushort[] { 1 }; } private void INC_16(ushort src_l, ushort src_h) @@ -63,13 +55,11 @@ namespace BizHawk.Emulation.Cores.Components.Z80A cur_instr = new ushort[] {INC16, src_l, src_h, IDLE, - IDLE, - WAIT, - OP_F, - OP }; + IDLE }; - BUSRQ = new ushort[] { I, I, PCh, 0, 0, 0}; - MEMRQ = new ushort[] { 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, I, I }; + MEMRQ = new ushort[] { 0, 0, 0 }; + IRQS = new ushort[] { 0, 0, 1 }; } @@ -78,13 +68,11 @@ namespace BizHawk.Emulation.Cores.Components.Z80A cur_instr = new ushort[] {DEC16, src_l, src_h, IDLE, - IDLE, - WAIT, - OP_F, - OP }; + IDLE }; - BUSRQ = new ushort[] { I, I, PCh, 0, 0, 0}; - MEMRQ = new ushort[] { 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, I, I }; + MEMRQ = new ushort[] { 0, 0, 0 }; + IRQS = new ushort[] { 0, 0, 1 }; } // this is done in two steps technically, but the flags don't work out using existing funcitons @@ -92,32 +80,28 @@ namespace BizHawk.Emulation.Cores.Components.Z80A private void ADD_16(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h) { cur_instr = new ushort[] - {TR16, Z, W, dest_l, dest_h, + {IDLE, + TR16, Z, W, dest_l, dest_h, IDLE, INC16, Z, W, IDLE, ADD16, dest_l, dest_h, src_l, src_h, IDLE, - IDLE, - IDLE, - WAIT, - OP_F, - OP }; + IDLE}; - BUSRQ = new ushort[] { I, I, I, I, I, I, I, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { 0, 0, 0, 0, 0, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, I, I, I, I, I, I, I }; + MEMRQ = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1}; } private void REG_OP(ushort operation, ushort dest, ushort src) { cur_instr = new ushort[] - {operation, dest, src, - WAIT, - OP_F, - OP }; + {operation, dest, src }; - BUSRQ = new ushort[] { PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0 }; + MEMRQ = new ushort[] { 0 }; + IRQS = new ushort[] { 1 }; } // Operations using the I and R registers take one T-cycle longer @@ -125,13 +109,11 @@ namespace BizHawk.Emulation.Cores.Components.Z80A { cur_instr = new ushort[] {operation, dest, src, - SET_FL_IR, dest, - WAIT, - OP_F, - OP }; + SET_FL_IR, dest }; - BUSRQ = new ushort[] { I, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, I }; + MEMRQ = new ushort[] { 0, 0 }; + IRQS = new ushort[] { 0, 1 }; } // note: do not use DEC here since no flags are affected by this operation @@ -141,6 +123,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A { cur_instr = new ushort[] {IDLE, + IDLE, ASGN, B, (ushort)((Regs[B] - 1) & 0xFF), WAIT, RD_INC, Z, PCl, PCh, @@ -148,42 +131,35 @@ namespace BizHawk.Emulation.Cores.Components.Z80A IDLE, ASGN, W, 0, ADDS, PCl, PCh, Z, W, - TR16, Z, W, PCl, PCh, - IDLE, - WAIT, - OP_F, - OP }; + TR16, Z, W, PCl, PCh }; - BUSRQ = new ushort[] { I, PCh, 0, 0, PCh, PCh, PCh, PCh, PCh, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { 0, PCh, 0, 0, 0, 0, 0, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, I, PCh, 0, 0, PCh, PCh, PCh, PCh, PCh }; + MEMRQ = new ushort[] { 0, 0, PCh, 0, 0, 0, 0, 0, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; } else { cur_instr = new ushort[] {IDLE, + IDLE, ASGN, B, (ushort)((Regs[B] - 1) & 0xFF), WAIT, - RD_INC, ALU, PCl, PCh, - IDLE, - WAIT, - OP_F, - OP }; + RD_INC, ALU, PCl, PCh }; - BUSRQ = new ushort[] { I, PCh, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, I, PCh, 0, 0 }; + MEMRQ = new ushort[] { 0, 0, PCh, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 1 }; } } private void HALT_() { cur_instr = new ushort[] - {IDLE, - IDLE, - IDLE, - HALT }; + { HALT }; - BUSRQ = new ushort[] { PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0 }; + MEMRQ = new ushort[] { 0 }; + IRQS = new ushort[] { 1 }; } private void JR_COND(bool cond) @@ -192,34 +168,30 @@ namespace BizHawk.Emulation.Cores.Components.Z80A { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD_INC, Z, PCl, PCh, IDLE, ASGN, W, 0, IDLE, - IDLE, ADDS, PCl, PCh, Z, W, - TR16, Z, W, PCl, PCh, - WAIT, - OP_F, - OP }; + TR16, Z, W, PCl, PCh }; - BUSRQ = new ushort[] { PCh, 0, 0, PCh, PCh, PCh, PCh, PCh, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, 0, 0, 0, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, PCh, PCh, PCh, PCh }; + MEMRQ = new ushort[] { 0, PCh, 0, 0, 0, 0, 0, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 1 }; } else { cur_instr = new ushort[] {IDLE, - WAIT, - RD_INC, ALU, PCl, PCh, IDLE, WAIT, - OP_F, - OP }; + RD_INC, ALU, PCl, PCh }; - BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, PCh, 0, 0 }; + MEMRQ = new ushort[] { 0, PCh, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 1 }; } } @@ -229,35 +201,31 @@ namespace BizHawk.Emulation.Cores.Components.Z80A { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD_INC, Z, PCl, PCh, IDLE, WAIT, - RD_INC, W, PCl, PCh, - TR16, PCl, PCh, Z, W, - WAIT, - OP_F, - OP }; + RD_INC_TR_PC, Z, W, PCl, PCh}; - BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, W, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, W, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0 }; + MEMRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 1 }; } else { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD_INC, Z, PCl, PCh, IDLE, WAIT, - RD_INC, W, PCl, PCh, - IDLE, - WAIT, - OP_F, - OP }; + RD_INC, W, PCl, PCh }; - BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0 }; + MEMRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 1 }; } } @@ -265,54 +233,48 @@ namespace BizHawk.Emulation.Cores.Components.Z80A { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD_INC, Z, SPl, SPh, IDLE, WAIT, - RD_INC, W, SPl, SPh, - TR16, PCl, PCh, Z, W, - WAIT, - OP_F, - OP }; + RD_INC_TR_PC, Z, W, SPl, SPh }; - BUSRQ = new ushort[] { SPh, 0, 0, SPh, 0, 0, W, 0, 0, 0 }; - MEMRQ = new ushort[] { SPh, 0, 0, SPh, 0, 0, W, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0 }; + MEMRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 1 }; } private void RETI_() { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD_INC, Z, SPl, SPh, IDLE, WAIT, - RD_INC, W, SPl, SPh, - TR16, PCl, PCh, Z, W, - WAIT, - OP_F, - OP }; + RD_INC_TR_PC, Z, W, SPl, SPh }; - BUSRQ = new ushort[] { SPh, 0, 0, SPh, 0, 0, W, 0, 0, 0 }; - MEMRQ = new ushort[] { SPh, 0, 0, SPh, 0, 0, W, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0 }; + MEMRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 1 }; } private void RETN_() { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD_INC, Z, SPl, SPh, EI_RETN, WAIT, - RD_INC, W, SPl, SPh, - TR16, PCl, PCh, Z, W, - WAIT, - OP_F, - OP }; + RD_INC_TR_PC, Z, W, SPl, SPh }; - BUSRQ = new ushort[] { SPh, 0, 0, SPh, 0, 0, W, 0, 0, 0 }; - MEMRQ = new ushort[] { SPh, 0, 0, SPh, 0, 0, W, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0 }; + MEMRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 1 }; } @@ -323,30 +285,26 @@ namespace BizHawk.Emulation.Cores.Components.Z80A cur_instr = new ushort[] {IDLE, IDLE, + IDLE, WAIT, RD_INC, Z, SPl, SPh, IDLE, WAIT, - RD_INC, W, SPl, SPh, - TR16, PCl, PCh, Z, W, - WAIT, - OP_F, - OP }; + RD_INC_TR_PC, Z, W, SPl, SPh}; - BUSRQ = new ushort[] { I, SPh, 0, 0, SPh, 0, 0, W, 0, 0, 0 }; - MEMRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0, W, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, I, SPh, 0, 0, SPh, 0, 0 }; + MEMRQ = new ushort[] { 0, 0, SPh, 0, 0, SPh, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1 }; } else { cur_instr = new ushort[] {IDLE, - IDLE, - WAIT, - OP_F, - OP }; + IDLE }; - BUSRQ = new ushort[] { I, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, I }; + MEMRQ = new ushort[] { 0, 0 }; + IRQS = new ushort[] { 0, 1 }; } } @@ -356,6 +314,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD_INC, Z, PCl, PCh, IDLE, @@ -367,75 +326,64 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WR_DEC, SPl, SPh, PCh, IDLE, WAIT, - WR, SPl, SPh, PCl, - TR16, PCl, PCh, Z, W, - WAIT, - OP_F, - OP }; + WR_TR_PC, SPl, SPh, PCl }; - BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, PCh, SPh, 0, 0, SPh, 0, 0, W, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, 0, SPh, 0, 0, SPh, 0, 0, W, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, PCh, SPh, 0, 0, SPh, 0, 0 }; + MEMRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, 0, SPh, 0, 0, SPh, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; } else { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD_INC, Z, PCl, PCh, IDLE, WAIT, - RD_INC, W, PCl, PCh, - IDLE, - WAIT, - OP_F, - OP }; + RD_INC, W, PCl, PCh}; - BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0 }; + MEMRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 1 }; } } private void INT_OP(ushort operation, ushort src) { cur_instr = new ushort[] - {operation, src, - WAIT, - OP_F, - OP }; + {operation, src }; - BUSRQ = new ushort[] { PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0 }; + MEMRQ = new ushort[] { 0 }; + IRQS = new ushort[] { 1 }; } private void BIT_OP(ushort operation, ushort bit, ushort src) { cur_instr = new ushort[] - {operation, bit, src, - WAIT, - OP_F, - OP }; + {operation, bit, src }; - BUSRQ = new ushort[] { PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0 }; + MEMRQ = new ushort[] { 0 }; + IRQS = new ushort[] { 1 }; } private void PUSH_(ushort src_l, ushort src_h) { cur_instr = new ushort[] - {DEC16, SPl, SPh, + {IDLE, + DEC16, SPl, SPh, IDLE, WAIT, WR_DEC, SPl, SPh, src_h, IDLE, WAIT, - WR, SPl, SPh, src_l, - IDLE, - WAIT, - OP_F, - OP }; + WR, SPl, SPh, src_l }; - BUSRQ = new ushort[] { I, SPh, 0, 0, SPh, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, I, SPh, 0, 0, SPh, 0, 0 }; + MEMRQ = new ushort[] { 0, 0, SPh, 0, 0, SPh, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1 }; } @@ -443,49 +391,52 @@ namespace BizHawk.Emulation.Cores.Components.Z80A { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD_INC, src_l, SPl, SPh, IDLE, WAIT, - RD_INC, src_h, SPl, SPh, - IDLE, - WAIT, - OP_F, - OP }; + RD_INC, src_h, SPl, SPh }; - BUSRQ = new ushort[] { SPh, 0, 0, SPh, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { SPh, 0, 0, SPh, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0 }; + MEMRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0 }; + IRQS = new ushort[] {0, 0, 0, 0, 0, 0, 1 }; } private void RST_(ushort n) { cur_instr = new ushort[] - {DEC16, SPl, SPh, + {IDLE, + DEC16, SPl, SPh, IDLE, WAIT, WR_DEC, SPl, SPh, PCh, RST, n, WAIT, - WR, SPl, SPh, PCl, + WR_TR_PC, SPl, SPh, PCl, TR16, PCl, PCh, Z, W, WAIT, OP_F, OP }; - BUSRQ = new ushort[] { I, SPh, 0, 0, SPh, 0, 0, W, 0, 0, 0 }; - MEMRQ = new ushort[] { 0, SPh, 0, 0, SPh, 0, 0, W, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, I, SPh, 0, 0, SPh, 0, 0 }; + MEMRQ = new ushort[] { 0, 0, SPh, 0, 0, SPh, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1 }; } private void PREFIX_(ushort src) { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, - OP_F, - PREFIX, src}; + PREFIX }; - BUSRQ = new ushort[] { PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, 0 }; + PRE_SRC = src; + + BUSRQ = new ushort[] { 0, PCh, 0, 0 }; + MEMRQ = new ushort[] { 0, PCh, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0 }; // prefix does not get interrupted } private void PREFETCH_(ushort src) @@ -503,136 +454,125 @@ namespace BizHawk.Emulation.Cores.Components.Z80A cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD_INC, ALU, PCl, PCh, ADDS, Z, W, ALU, ZERO, WAIT, - OP_F, IDLE, - PREFIX, src,}; + PREFIX}; - BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, PCh, PCh }; - MEMRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, 0, 0 }; + PRE_SRC = src; + + //Console.WriteLine(TotalExecutedCycles); + + BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, PCh }; + MEMRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0 }; // prefetch does not get interrupted } private void DI_() { cur_instr = new ushort[] - {DI, - WAIT, - OP_F, - OP }; + {DI }; - BUSRQ = new ushort[] { PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0 }; + MEMRQ = new ushort[] { 0 }; + IRQS = new ushort[] { 1 }; } private void EI_() { cur_instr = new ushort[] - {EI, - WAIT, - OP_F, - OP }; + {EI }; - BUSRQ = new ushort[] { PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0 }; + MEMRQ = new ushort[] { 0 }; + IRQS = new ushort[] { 1 }; } private void JP_16(ushort src_l, ushort src_h) { cur_instr = new ushort[] - {TR16, PCl, PCh, src_l, src_h, - WAIT, - OP_F, - OP }; + {TR16, PCl, PCh, src_l, src_h }; - BUSRQ = new ushort[] { src_h, 0, 0, 0 }; - MEMRQ = new ushort[] { src_h, 0, 0, 0 }; + BUSRQ = new ushort[] { 0 }; + MEMRQ = new ushort[] { 0 }; + IRQS = new ushort[] { 1 }; } private void LD_SP_16(ushort src_l, ushort src_h) { cur_instr = new ushort[] - {IDLE, + {IDLE, IDLE, - TR16, SPl, SPh, src_l, src_h, - WAIT, - OP_F, - OP }; + TR16, SPl, SPh, src_l, src_h }; - BUSRQ = new ushort[] { I, I, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, I, I }; + MEMRQ = new ushort[] { 0, 0, 0 }; + IRQS = new ushort[] { 0, 0, 1 }; } private void OUT_() { cur_instr = new ushort[] - {TR, W, A, + {IDLE, + TR, W, A, WAIT, RD_INC, Z, PCl, PCh, - IDLE, + TR, ALU, A, WAIT, WAIT, - OUT, Z, W, A, - INC16, Z, ALU, - WAIT, - OP_F, - OP}; + OUT_INC, Z, ALU, A }; - BUSRQ = new ushort[] { PCh, 0, 0, WIO1, WIO2, WIO3, WIO4, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, WIO1, WIO2, WIO3, WIO4, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, PCh, 0, 0, WIO1, WIO2, WIO3, WIO4 }; + MEMRQ = new ushort[] { 0, PCh, 0, 0, WIO1, WIO2, WIO3, WIO4 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1}; } private void OUT_REG_(ushort dest, ushort src) { cur_instr = new ushort[] - {TR16, Z, W, C, B, + {IDLE, + TR16, Z, W, C, B, IDLE, IDLE, - OUT, Z, W, src, - INC16, Z, W, - WAIT, - OP_F, - OP}; + OUT_INC, Z, W, src }; - BUSRQ = new ushort[] { BIO1, BIO2, BIO3, BIO4, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { BIO1, BIO2, BIO3, BIO4, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, BIO1, BIO2, BIO3, BIO4 }; + MEMRQ = new ushort[] { 0, BIO1, BIO2, BIO3, BIO4 }; + IRQS = new ushort[] { 0, 0, 0, 0, 1 }; } private void IN_() { cur_instr = new ushort[] - {TR, W, A, + {IDLE, + TR, W, A, WAIT, RD_INC, Z, PCl, PCh, IDLE, WAIT, WAIT, - IN_A_N, A, Z, W, - INC16, Z, W, - WAIT, - OP_F, - OP}; + IN_A_N_INC, A, Z, W }; - BUSRQ = new ushort[] { PCh, 0, 0, WIO1, WIO2, WIO3, WIO4, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, WIO1, WIO2, WIO3, WIO4, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, PCh, 0, 0, WIO1, WIO2, WIO3, WIO4 }; + MEMRQ = new ushort[] { 0, PCh, 0, 0, WIO1, WIO2, WIO3, WIO4 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1 }; } private void IN_REG_(ushort dest, ushort src) { cur_instr = new ushort[] - {TR16, Z, W, C, B, + {IDLE, + TR16, Z, W, C, B, WAIT, WAIT, - IN, dest, Z, W, - INC16, Z, W, - WAIT, - OP_F, - OP}; + IN_INC, dest, Z, W }; - BUSRQ = new ushort[] { BIO1, BIO2, BIO3, BIO4, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { BIO1, BIO2, BIO3, BIO4, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, BIO1, BIO2, BIO3, BIO4 }; + MEMRQ = new ushort[] { 0, BIO1, BIO2, BIO3, BIO4 }; + IRQS = new ushort[] { 0, 0, 0, 0, 1 }; } private void REG_OP_16_(ushort op, ushort dest_l, ushort dest_h, ushort src_l, ushort src_h) @@ -640,36 +580,33 @@ namespace BizHawk.Emulation.Cores.Components.Z80A cur_instr = new ushort[] {IDLE, IDLE, + IDLE, TR16, Z, W, dest_l, dest_h, INC16, Z, W, IDLE, IDLE, - op, dest_l, dest_h, src_l, src_h, - IDLE, - WAIT, - OP_F, - OP}; + op, dest_l, dest_h, src_l, src_h }; - BUSRQ = new ushort[] { I, I, I, I, I, I, I, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { 0, 0, 0, 0, 0, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, I, I, I, I, I, I, I }; + MEMRQ = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1 }; } private void INT_MODE_(ushort src) { cur_instr = new ushort[] - {INT_MODE, src, - WAIT, - OP_F, - OP }; + {INT_MODE, src }; - BUSRQ = new ushort[] { PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0 }; + MEMRQ = new ushort[] { 0 }; + IRQS = new ushort[] { 1 }; } private void RRD_() { cur_instr = new ushort[] - {TR16, Z, W, L, H, + {IDLE, + TR16, Z, W, L, H, WAIT, RD, ALU, Z, W, IDLE, @@ -678,20 +615,18 @@ namespace BizHawk.Emulation.Cores.Components.Z80A IDLE, IDLE, WAIT, - WR_INC, Z, W, ALU, - IDLE, - WAIT, - OP_F, - OP }; + WR_INC, Z, W, ALU }; - BUSRQ = new ushort[] { H, 0, 0, H, H, H, H, W, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { H, 0, 0, 0, 0, 0, 0, W, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, H, 0, 0, H, H, H, H, W, 0, 0 }; + MEMRQ = new ushort[] { 0, H, 0, 0, 0, 0, 0, 0, W, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; } private void RLD_() { cur_instr = new ushort[] - {TR16, Z, W, L, H, + {IDLE, + TR16, Z, W, L, H, WAIT, RD, ALU, Z, W, IDLE, @@ -700,14 +635,11 @@ namespace BizHawk.Emulation.Cores.Components.Z80A IDLE, IDLE, WAIT, - WR_INC, Z, W, ALU, - IDLE, - WAIT, - OP_F, - OP }; + WR_INC, Z, W, ALU }; - BUSRQ = new ushort[] { H, 0, 0, H, H, H, H, W, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { H, 0, 0, 0, 0, 0, 0, W, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, H, 0, 0, H, H, H, H, W, 0, 0 }; + MEMRQ = new ushort[] { 0, H, 0, 0, 0, 0, 0, 0, W, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; } } } diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Indirect.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Indirect.cs index 9c13e3d062..65e0b607f5 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Indirect.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Indirect.cs @@ -6,38 +6,34 @@ { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD, ALU, src_l, src_h, IDLE, operation, ALU, WAIT, - WR, src_l, src_h, ALU, - IDLE, - WAIT, - OP_F, - OP }; + WR, src_l, src_h, ALU }; - BUSRQ = new ushort[] { src_h, 0, 0, src_h, src_h, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { src_h, 0, 0, 0, src_h, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, src_h, 0, 0, src_h, src_h, 0, 0 }; + MEMRQ = new ushort[] { 0, src_h, 0, 0, 0, src_h, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1 }; } private void BIT_OP_IND(ushort operation, ushort bit, ushort src_l, ushort src_h) { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD, ALU, src_l, src_h, operation, bit, ALU, IDLE, WAIT, - WR, src_l, src_h, ALU, - IDLE, - WAIT, - OP_F, - OP }; + WR, src_l, src_h, ALU }; - BUSRQ = new ushort[] { src_h, 0, 0, src_h, src_h, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { src_h, 0, 0, 0, src_h, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, src_h, 0, 0, src_h, src_h, 0, 0 }; + MEMRQ = new ushort[] { 0, src_h, 0, 0, 0, src_h, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1 }; } // Note that this operation uses I_BIT, same as indexed BIT. @@ -48,46 +44,40 @@ { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD, ALU, src_l, src_h, - IDLE, - I_BIT, bit, ALU, - WAIT, - OP_F, - OP }; + I_BIT, bit, ALU }; - BUSRQ = new ushort[] { src_h, 0, 0, src_h, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { src_h, 0, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, src_h, 0, 0, src_h }; + MEMRQ = new ushort[] { 0, src_h, 0, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 1 }; } private void REG_OP_IND_INC(ushort operation, ushort dest, ushort src_l, ushort src_h) { cur_instr = new ushort[] - {IDLE, + {IDLE, + IDLE, WAIT, - RD_INC, ALU, src_l, src_h, - operation, dest, ALU, - WAIT, - OP_F, - OP }; + RD_OP, 1, ALU, src_l, src_h, operation, dest, ALU }; - BUSRQ = new ushort[] { src_h, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { src_h, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, src_h, 0, 0 }; + MEMRQ = new ushort[] { 0, src_h, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 1}; } private void REG_OP_IND(ushort operation, ushort dest, ushort src_l, ushort src_h) { cur_instr = new ushort[] - {TR16, Z, W, src_l, src_h, + {IDLE, + TR16, Z, W, src_l, src_h, WAIT, - RD_INC, ALU, Z, W, - operation, dest, ALU, - WAIT, - OP_F, - OP }; + RD_OP, 1, ALU, Z, W, operation, dest, ALU }; - BUSRQ = new ushort[] { src_h, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { src_h, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, src_h, 0, 0 }; + MEMRQ = new ushort[] { 0, src_h, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 1 }; } // different because HL doesn't effect WZ @@ -95,21 +85,20 @@ { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, - RD, ALU, L, H, - operation, dest, ALU, - WAIT, - OP_F, - OP }; + RD_OP, 0, ALU, L, H, operation, dest, ALU }; - BUSRQ = new ushort[] { H, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { H, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, H, 0, 0 }; + MEMRQ = new ushort[] { 0, H, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 1 }; } private void LD_16_IND_nn(ushort src_l, ushort src_h) { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD_INC, Z, PCl, PCh, IDLE, @@ -120,20 +109,18 @@ WR_INC, Z, W, src_l, IDLE, WAIT, - WR, Z, W, src_h, - IDLE, - WAIT, - OP_F, - OP }; + WR, Z, W, src_h }; - BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, W, 0, 0, W, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, W, 0, 0, W, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, W, 0, 0, W, 0, 0 }; + MEMRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, W, 0, 0, W, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; } private void LD_IND_16_nn(ushort dest_l, ushort dest_h) { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD_INC, Z, PCl, PCh, IDLE, @@ -144,20 +131,18 @@ RD_INC, dest_l, Z, W, IDLE, WAIT, - RD, dest_h, Z, W, - IDLE, - WAIT, - OP_F, - OP }; + RD, dest_h, Z, W }; - BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, W, 0, 0, W, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, W, 0, 0, W, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, W, 0, 0, W, 0, 0 }; + MEMRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, W, 0, 0, W, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; } private void LD_8_IND_nn(ushort src) { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD_INC, Z, PCl, PCh, IDLE, @@ -165,20 +150,18 @@ RD_INC, W, PCl, PCh, IDLE, WAIT, - WR_INC, Z, W, src, - TR, W, A, - WAIT, - OP_F, - OP }; + WR_INC_WA, Z, W, src }; - BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, W, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, W, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, W, 0, 0 }; + MEMRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, W, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; } private void LD_IND_8_nn(ushort dest) { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD_INC, Z, PCl, PCh, IDLE, @@ -186,29 +169,24 @@ RD_INC, W, PCl, PCh, IDLE, WAIT, - RD_INC, dest, Z, W, - IDLE, - WAIT, - OP_F, - OP }; + RD_INC, dest, Z, W }; - BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, W, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, W, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, W, 0, 0 }; + MEMRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, W, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; } private void LD_8_IND(ushort dest_l, ushort dest_h, ushort src) { cur_instr = new ushort[] - {TR16, Z, W, dest_l, dest_h, + {IDLE, + TR16, Z, W, dest_l, dest_h, WAIT, - WR_INC, Z, W, src, - TR, W, A, - WAIT, - OP_F, - OP }; + WR_INC_WA, Z, W, src }; - BUSRQ = new ushort[] { dest_h, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { dest_h, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, dest_h, 0, 0 }; + MEMRQ = new ushort[] { 0, dest_h, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 1 }; } // seperate HL needed since it doesn't effect the WZ pair @@ -216,104 +194,92 @@ { cur_instr = new ushort[] {IDLE, - WAIT, - WR, L, H, src, IDLE, WAIT, - OP_F, - OP }; + WR, L, H, src }; - BUSRQ = new ushort[] { H, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { H, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, H, 0, 0 }; + MEMRQ = new ushort[] { 0, H, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 1 }; } private void LD_8_IND_IND(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h) { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD_INC, ALU, src_l, src_h, IDLE, WAIT, - WR, dest_l, dest_h, ALU, - IDLE, - WAIT, - OP_F, - OP }; + WR, dest_l, dest_h, ALU }; - BUSRQ = new ushort[] { src_h, 0, 0, dest_h, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { src_h, 0, 0, dest_h, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, src_h, 0, 0, dest_h, 0, 0 }; + MEMRQ = new ushort[] { 0, src_h, 0, 0, dest_h, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 1 }; } private void LD_IND_8_INC(ushort dest, ushort src_l, ushort src_h) { cur_instr = new ushort[] {IDLE, - WAIT, - RD_INC, dest, src_l, src_h, IDLE, WAIT, - OP_F, - OP }; + RD_INC, dest, src_l, src_h }; - BUSRQ = new ushort[] { src_h, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { src_h, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, src_h, 0, 0 }; + MEMRQ = new ushort[] { 0, src_h, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 1 }; } private void LD_IND_16(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h) { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD_INC, dest_l, src_l, src_h, IDLE, WAIT, - RD_INC, dest_h, src_l, src_h, - IDLE, - WAIT, - OP_F, - OP }; + RD_INC, dest_h, src_l, src_h }; - BUSRQ = new ushort[] { src_h, 0, 0, src_h, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { src_h, 0, 0, src_h, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, src_h, 0, 0, src_h, 0, 0 }; + MEMRQ = new ushort[] { 0, src_h, 0, 0, src_h, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 1 }; } private void INC_8_IND(ushort src_l, ushort src_h) { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD, ALU, src_l, src_h, INC8, ALU, IDLE, WAIT, - WR, src_l, src_h, ALU, - IDLE, - WAIT, - OP_F, - OP }; + WR, src_l, src_h, ALU }; - BUSRQ = new ushort[] { src_h, 0, 0, src_h, src_h, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { src_h, 0, 0, 0, src_h, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, src_h, 0, 0, src_h, src_h, 0, 0 }; + MEMRQ = new ushort[] { 0, src_h, 0, 0, 0, src_h, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1 }; } private void DEC_8_IND(ushort src_l, ushort src_h) { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD, ALU, src_l, src_h, DEC8, ALU, IDLE, WAIT, - WR, src_l, src_h, ALU, - IDLE, - WAIT, - OP_F, - OP }; + WR, src_l, src_h, ALU }; - BUSRQ = new ushort[] { src_h, 0, 0, src_h, src_h, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { src_h, 0, 0, 0, src_h, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, src_h, 0, 0, src_h, src_h, 0, 0 }; + MEMRQ = new ushort[] { 0, src_h, 0, 0, 0, src_h, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1 }; } // NOTE: WZ implied for the wollowing 3 functions @@ -321,60 +287,55 @@ { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD, ALU, Z, W, operation, ALU, - IDLE, - WAIT, - WR, Z, W, ALU, TR, dest, ALU, WAIT, - OP_F, - OP }; + WR, Z, W, ALU }; - BUSRQ = new ushort[] { W, 0, 0, W, W, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { W, 0, 0, 0, W, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, W, 0, 0, W, W, 0, 0 }; + MEMRQ = new ushort[] { 0, W, 0, 0, 0, W, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1 }; } private void I_BIT_OP(ushort operation, ushort bit, ushort dest) { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD, ALU, Z, W, - IDLE, operation, bit, ALU, - WAIT, - WR, Z, W, ALU, TR, dest, ALU, WAIT, - OP_F, - OP }; + WR, Z, W, ALU }; - BUSRQ = new ushort[] { W, 0, 0, W, W, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { W, 0, 0, 0, W, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, W, 0, 0, W, W, 0, 0 }; + MEMRQ = new ushort[] { 0, W, 0, 0, 0, W, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 1}; } private void I_BIT_TE(ushort bit) { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD, ALU, Z, W, - IDLE, - I_BIT, bit, ALU, - WAIT, - OP_F, - OP }; + I_BIT, bit, ALU }; - BUSRQ = new ushort[] { W, 0, 0, W, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { W, 0, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, W, 0, 0, W }; + MEMRQ = new ushort[] { 0, W, 0, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 1 }; } private void I_OP_n(ushort operation, ushort src_l, ushort src_h) { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD, ALU, PCl, PCh, IDLE, @@ -388,20 +349,18 @@ operation, ALU, IDLE, WAIT, - WR, Z, W, ALU, - IDLE, - WAIT, - OP_F, - OP }; + WR, Z, W, ALU }; - BUSRQ = new ushort[] { PCh, 0, 0, PCh, PCh, PCh, PCh, PCh, W, 0, 0, W, W, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, 0, 0, 0, 0, 0, W, 0, 0, 0, W, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, PCh, PCh, PCh, PCh, W, 0, 0, W, W, 0, 0 }; + MEMRQ = new ushort[] { 0, PCh, 0, 0, 0, 0, 0, 0, 0, W, 0, 0, 0, W, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; } private void I_OP_n_n(ushort src_l, ushort src_h) { cur_instr = new ushort[] - {TR16, Z, W, src_l, src_h, + {IDLE, + TR16, Z, W, src_l, src_h, WAIT, RD_INC, ALU, PCl, PCh, ADDS, Z, W, ALU, ZERO, @@ -411,20 +370,18 @@ IDLE, INC16, PCl, PCh, WAIT, - WR, Z, W, ALU, - IDLE, - WAIT, - OP_F, - OP }; + WR, Z, W, ALU }; - BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, PCh, PCh, W, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, 0, 0, W, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, PCh, PCh, W, 0, 0 }; + MEMRQ = new ushort[] { 0, PCh, 0, 0, PCh, 0, 0, 0, 0, W, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; } private void I_REG_OP_IND_n(ushort operation, ushort dest, ushort src_l, ushort src_h) { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD, ALU, PCl, PCh, IDLE, @@ -434,20 +391,18 @@ IDLE, INC16, PCl, PCh, WAIT, - RD, ALU, Z, W, - operation, dest, ALU, - WAIT, - OP_F, - OP }; + RD_OP, 0, ALU, Z, W, operation, dest, ALU }; - BUSRQ = new ushort[] { PCh, 0, 0, PCh, PCh, PCh, PCh, PCh, W, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, 0, 0, 0, 0, 0, W, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, PCh, PCh, PCh, PCh, W, 0, 0 }; + MEMRQ = new ushort[] { 0, PCh, 0, 0, 0, 0, 0, 0, 0, W, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; } private void I_LD_8_IND_n(ushort dest_l, ushort dest_h, ushort src) { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD, ALU, PCl, PCh, IDLE, @@ -457,20 +412,18 @@ IDLE, INC16, PCl, PCh, WAIT, - WR, Z, W, src, - IDLE, - WAIT, - OP_F, - OP }; + WR, Z, W, src }; - BUSRQ = new ushort[] { PCh, 0, 0, PCh, PCh, PCh, PCh, PCh, Z, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, 0, 0, 0, 0, 0, Z, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, PCh, 0, 0, PCh, PCh, PCh, PCh, PCh, Z, 0, 0 }; + MEMRQ = new ushort[] { 0, PCh, 0, 0, 0, 0, 0, 0, 0, Z, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; } private void LD_OP_R(ushort operation, ushort repeat_instr) { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD, ALU, L, H, operation, L, H, @@ -479,14 +432,16 @@ IDLE, SET_FL_LD_R, 0, operation, repeat_instr}; - BUSRQ = new ushort[] { H, 0, 0, D, 0, 0, D, D }; - MEMRQ = new ushort[] { H, 0, 0, D, 0, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, H, 0, 0, D, 0, 0, D, D }; + MEMRQ = new ushort[] { 0, H, 0, 0, D, 0, 0, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 1 }; } private void CP_OP_R(ushort operation, ushort repeat_instr) { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD, ALU, L, H, IDLE, @@ -495,8 +450,9 @@ IDLE, SET_FL_CP_R, 1, operation, repeat_instr}; - BUSRQ = new ushort[] { H, 0, 0, H, H, H, H, H }; - MEMRQ = new ushort[] { H, 0, 0, 0, 0, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, H, 0, 0, H, H, H, H, H }; + MEMRQ = new ushort[] { 0, H, 0, 0, 0, 0, 0, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 1 }; } private void IN_OP_R(ushort operation, ushort repeat_instr) @@ -504,6 +460,7 @@ cur_instr = new ushort[] {IDLE, IDLE, + IDLE, WAIT, WAIT, IN, ALU, C, B, @@ -511,14 +468,16 @@ WAIT, REP_OP_I, L, H, ALU, operation, 2, operation, repeat_instr }; - BUSRQ = new ushort[] { I, BIO1, BIO2, BIO3, BIO4, H, 0, 0}; - MEMRQ = new ushort[] { 0, BIO1, BIO2, BIO3, BIO4, H, 0, 0 }; + BUSRQ = new ushort[] { 0, I, BIO1, BIO2, BIO3, BIO4, H, 0, 0}; + MEMRQ = new ushort[] { 0, 0, BIO1, BIO2, BIO3, BIO4, H, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 1 }; } private void OUT_OP_R(ushort operation, ushort repeat_instr) { cur_instr = new ushort[] - {IDLE, + {IDLE, + IDLE, IDLE, WAIT, RD, ALU, L, H, @@ -527,8 +486,9 @@ WAIT, REP_OP_O, C, B, ALU, operation, 3, operation, repeat_instr }; - BUSRQ = new ushort[] { I, H, 0, 0, BIO1, BIO2, BIO3, BIO4 }; - MEMRQ = new ushort[] { 0, H, 0, 0, BIO1, BIO2, BIO3, BIO4 }; + BUSRQ = new ushort[] { 0, I, H, 0, 0, BIO1, BIO2, BIO3, BIO4 }; + MEMRQ = new ushort[] { 0, 0, H, 0, 0, BIO1, BIO2, BIO3, BIO4 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 1 }; } // this is an indirect change of a a 16 bit register with memory @@ -536,6 +496,7 @@ { cur_instr = new ushort[] {IDLE, + IDLE, WAIT, RD_INC, Z, dest_l, dest_h, IDLE, @@ -549,14 +510,11 @@ WAIT, WR, dest_l, dest_h, src_l, IDLE, - IDLE, - TR16, src_l, src_h, Z, W, - WAIT, - OP_F, - OP }; + TR16, src_l, src_h, Z, W }; - BUSRQ = new ushort[] { dest_h, 0, 0, dest_h, 0, 0, dest_h, dest_h, 0, 0, dest_h, 0, 0, dest_h, dest_h, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { dest_h, 0, 0, dest_h, 0, 0, 0, dest_h, 0, 0, dest_h, 0, 0, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { 0, dest_h, 0, 0, dest_h, 0, 0, dest_h, dest_h, 0, 0, dest_h, 0, 0, dest_h, dest_h }; + MEMRQ = new ushort[] { 0, dest_h, 0, 0, dest_h, 0, 0, 0, dest_h, 0, 0, dest_h, 0, 0, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; } } } diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs index 1295bc0296..270b405c1a 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs @@ -76,11 +76,19 @@ namespace BizHawk.Emulation.Cores.Components.Z80A public const ushort I_BIT = 61; public const ushort HL_BIT = 62; public const ushort FTCH_DB = 63; - public const ushort WAIT = 64; // enterred when readin or writing and FlagW is true + public const ushort WAIT = 64; // enterred when reading or writing and FlagW is true public const ushort RST = 65; public const ushort REP_OP_I = 66; public const ushort REP_OP_O = 67; - public const ushort IN_A_N = 68; + public const ushort IN_A_N_INC = 68; + public const ushort IRQ_S_F = 69; // called when IRQ line is polled + public const ushort NMI_S_F = 70; // called for NMI + public const ushort RD_INC_TR_PC = 71; // transfer WZ to PC after read + public const ushort WR_TR_PC = 72; // transfer WZ to PC after write + public const ushort OUT_INC = 73; + public const ushort IN_INC = 74; + public const ushort WR_INC_WA = 75; // A -> W after WR_INC + public const ushort RD_OP = 76; // non-state variables public ushort Ztemp1, Ztemp2, Ztemp3, Ztemp4; @@ -100,15 +108,12 @@ namespace BizHawk.Emulation.Cores.Components.Z80A cur_instr = new ushort[] {IDLE, DEC16, F, A, - DEC16, SPl, SPh, - IDLE, - WAIT, - OP_F, - OP }; + DEC16, SPl, SPh }; - BUSRQ = new ushort[] { 0, 0, 0, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { 0, 0, 0, PCh, 0, 0, 0 }; - instr_pntr = 0; bus_pntr = 0; mem_pntr = 0; + BUSRQ = new ushort[] { 0, 0, 0 }; + MEMRQ = new ushort[] { 0, 0, 0 }; + IRQS = new ushort[] { 0, 0, 1 }; + instr_pntr = mem_pntr = bus_pntr = irq_pntr = 0; NO_prefix = true; } @@ -164,12 +169,6 @@ namespace BizHawk.Emulation.Cores.Components.Z80A // Execute instructions public void ExecuteOne() { - FlagI5 = FlagI4; - FlagI4 = FlagI3; - FlagI3 = FlagI2; - FlagI2 = FlagI1; - FlagI1 = FlagI; - bus_pntr++; mem_pntr++; switch (cur_instr[instr_pntr++]) { @@ -177,134 +176,33 @@ namespace BizHawk.Emulation.Cores.Components.Z80A // do nothing break; case OP: - // Read the opcode of the next instruction - if (EI_pending > 0) - { - EI_pending--; - if (EI_pending == 0) { IFF1 = IFF2 = true; } - } - - // Process interrupt requests. - if (nonMaskableInterruptPending) - { - nonMaskableInterruptPending = false; - - if (TraceCallback != null) - { - TraceCallback(new TraceInfo{Disassembly = "====NMI====", RegisterInfo = ""}); - } - - iff2 = iff1; - iff1 = false; - NMI_(); - NMICallback(); - instr_pntr = 0; bus_pntr = 0; mem_pntr = 0; - } - else if (iff1 && FlagI5) - { - iff1 = iff2 = false; - EI_pending = 0; - - if (TraceCallback != null) - { - TraceCallback(new TraceInfo{Disassembly = "====IRQ====", RegisterInfo = ""}); - } - - switch (interruptMode) - { - case 0: - // Requires something to be pushed onto the data bus - // we'll assume it's a zero for now - INTERRUPT_0(0); - break; - case 1: - INTERRUPT_1(); - break; - case 2: - INTERRUPT_2(); - break; - } - IRQCallback(); - instr_pntr = 0; bus_pntr = 0; mem_pntr = 0; - } - else - { - if (OnExecFetch != null) OnExecFetch(RegPC); - if (TraceCallback != null) TraceCallback(State()); - RegPC++; - FetchInstruction(); - instr_pntr = 0; bus_pntr = 0; mem_pntr = 0; - } - + + + break; + case OP_F: + // Read the opcode of the next instruction + if (OnExecFetch != null) OnExecFetch(RegPC); + if (TraceCallback != null) TraceCallback(State()); + opcode = FetchMemory(RegPC++); + FetchInstruction(); + temp_R = (byte)(Regs[R] & 0x7F); temp_R++; temp_R &= 0x7F; Regs[R] = (byte)((Regs[R] & 0x80) | temp_R); - break; - case OP_F: - opcode = FetchMemory(RegPC); + + instr_pntr = bus_pntr = mem_pntr = irq_pntr = 0; + I_skip = true; break; case HALT: halted = true; // NOTE: Check how halt state effects the DB Regs[DB] = 0xFF; - if (EI_pending > 0) - { - EI_pending--; - if (EI_pending == 0) { IFF1 = IFF2 = true; } - } - - // Process interrupt requests. - if (nonMaskableInterruptPending) - { - nonMaskableInterruptPending = false; - - if (TraceCallback != null) - { - TraceCallback(new TraceInfo{Disassembly = "====NMI====", RegisterInfo = ""}); - } - - iff2 = iff1; - iff1 = false; - NMI_(); - NMICallback(); - halted = false; - } - else if (iff1 && FlagI5) - { - iff1 = iff2 = false; - EI_pending = 0; - - if (TraceCallback != null) - { - TraceCallback(new TraceInfo{Disassembly = "====IRQ====", RegisterInfo = ""}); - } - - switch (interruptMode) - { - case 0: - // Requires something to be pushed onto the data bus - // we'll assume it's a zero for now - INTERRUPT_0(0); - break; - case 1: - INTERRUPT_1(); - break; - case 2: - INTERRUPT_2(); - break; - } - IRQCallback(); - halted = false; - } - temp_R = (byte)(Regs[R] & 0x7F); temp_R++; temp_R &= 0x7F; Regs[R] = (byte)((Regs[R] & 0x80) | temp_R); - - instr_pntr = 0; bus_pntr = 0; mem_pntr = 0; break; case RD: Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); @@ -315,12 +213,57 @@ namespace BizHawk.Emulation.Cores.Components.Z80A case RD_INC: Read_INC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; + case RD_INC_TR_PC: + Read_INC_TR_PC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; + case RD_OP: + if (cur_instr[instr_pntr++] == 1) { Read_INC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); } + else { Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); } + + switch (cur_instr[instr_pntr++]) + { + case ADD8: + ADD8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; + case ADC8: + ADC8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; + case SUB8: + SUB8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; + case SBC8: + SBC8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; + case AND8: + AND8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; + case XOR8: + XOR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; + case OR8: + OR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; + case CP8: + CP8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; + case TR: + TR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; + } + break; case WR_INC: Write_INC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; case WR_DEC: Write_DEC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; + case WR_TR_PC: + Write_TR_PC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; + case WR_INC_WA: + Write_INC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + Regs[W] = Regs[A]; + break; case TR: TR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; @@ -438,26 +381,31 @@ namespace BizHawk.Emulation.Cores.Components.Z80A EXCH_16_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; case PREFIX: - ushort prefix_src = cur_instr[instr_pntr++]; NO_prefix = false; - if (prefix_src == CBpre) { CB_prefix = true; } - if (prefix_src == EXTDpre) { EXTD_prefix = true; } - if (prefix_src == IXpre) { IX_prefix = true; } - if (prefix_src == IYpre) { IY_prefix = true; } - if (prefix_src == IXCBpre) { IXCB_prefix = true; } - if (prefix_src == IYCBpre) { IYCB_prefix = true; } + if (PRE_SRC == CBpre) { CB_prefix = true; } + if (PRE_SRC == EXTDpre) { EXTD_prefix = true; } + if (PRE_SRC == IXpre) { IX_prefix = true; } + if (PRE_SRC == IYpre) { IY_prefix = true; } + if (PRE_SRC == IXCBpre) { IXCB_prefix = true; } + if (PRE_SRC == IYCBpre) { IYCB_prefix = true; } - RegPC++; - FetchInstruction(); - instr_pntr = 0; bus_pntr = 0; mem_pntr = 0; // only the first prefix in a double prefix increases R, although I don't know how / why - if (prefix_src < 4) + if (PRE_SRC < 4) { temp_R = (byte)(Regs[R] & 0x7F); temp_R++; temp_R &= 0x7F; Regs[R] = (byte)((Regs[R] & 0x80) | temp_R); } + + opcode = FetchMemory(RegPC++); + FetchInstruction(); + instr_pntr = bus_pntr = mem_pntr = irq_pntr = 0; + I_skip = true; + + // for prefetched case, the PC stays on the BUS one cycle longer + if ((PRE_SRC == IXCBpre) || (PRE_SRC == IXCBpre)) { BUSRQ[0] = PCh; } + break; case ASGN: ASGN_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); @@ -476,11 +424,17 @@ namespace BizHawk.Emulation.Cores.Components.Z80A case OUT: OUT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; + case OUT_INC: + OUT_INC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; case IN: IN_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; - case IN_A_N: - IN_A_N_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + case IN_INC: + IN_INC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + break; + case IN_A_N_INC: + IN_A_N_INC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; case NEG: NEG_8_Func(cur_instr[instr_pntr++]); @@ -508,28 +462,21 @@ namespace BizHawk.Emulation.Cores.Components.Z80A {DEC16, PCl, PCh, DEC16, PCl, PCh, TR16, Z, W, PCl, PCh, - INC16, Z, W, - IDLE, - Ztemp2, E, D, - WAIT, - OP_F, - OP}; + INC16, Z, W, + Ztemp2, E, D }; - BUSRQ = new ushort[] { D, D, D, D, D, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { 0, 0, 0, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { D, D, D, D, D }; + MEMRQ = new ushort[] { 0, 0, 0, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 1 }; + + instr_pntr = mem_pntr = bus_pntr = irq_pntr = 0; + I_skip = true; } else { - cur_instr = new ushort[] - { Ztemp2, E, D, - WAIT, - OP_F, - OP }; - - BUSRQ = new ushort[] { PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, 0 }; - } - instr_pntr = 0; bus_pntr = 0; mem_pntr = 0; + if (Ztemp2 == INC16) { INC16_Func(E, D); } + else { DEC16_Func(E, D); } + } break; case SET_FL_CP_R: SET_FL_CP_Func(); @@ -545,27 +492,20 @@ namespace BizHawk.Emulation.Cores.Components.Z80A DEC16, PCl, PCh, TR16, Z, W, PCl, PCh, INC16, Z, W, - IDLE, - Ztemp2, L, H, - WAIT, - OP_F, - OP}; + Ztemp2, L, H }; - BUSRQ = new ushort[] { H, H, H, H, H, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { 0, 0, 0, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { H, H, H, H, H }; + MEMRQ = new ushort[] { 0, 0, 0, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 1 }; + + instr_pntr = mem_pntr = bus_pntr = irq_pntr = 0; + I_skip = true; } else { - cur_instr = new ushort[] - { Ztemp2, L, H, - WAIT, - OP_F, - OP }; - - BUSRQ = new ushort[] { PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, 0 }; + if (Ztemp2 == INC16) { INC16_Func(L, H); } + else { DEC16_Func(L, H); } } - instr_pntr = 0; bus_pntr = 0; mem_pntr = 0; break; case SET_FL_IR: SET_FL_IR_Func(cur_instr[instr_pntr++]); @@ -577,6 +517,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A if (FlagW) { instr_pntr--; bus_pntr--; mem_pntr--; + I_skip = true; } break; case RST: @@ -623,27 +564,20 @@ namespace BizHawk.Emulation.Cores.Components.Z80A IDLE, DEC16, PCl, PCh, DEC16, PCl, PCh, - IDLE, - Ztemp2, L, H, - WAIT, - OP_F, - OP}; + Ztemp2, L, H }; - BUSRQ = new ushort[] { H, H, H, H, H, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { 0, 0, 0, 0, 0, PCh, 0, 0, 0 }; + BUSRQ = new ushort[] { H, H, H, H, H }; + MEMRQ = new ushort[] { 0, 0, 0, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 1 }; + + instr_pntr = mem_pntr = bus_pntr = irq_pntr = 0; + I_skip = true; } else { - cur_instr = new ushort[] - { Ztemp2, L, H, - WAIT, - OP_F, - OP }; - - BUSRQ = new ushort[] { PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, 0 }; + if (Ztemp2 == INC16) { INC16_Func(L, H); } + else { DEC16_Func(L, H); } } - instr_pntr = 0; bus_pntr = 0; mem_pntr = 0; break; case REP_OP_O: OUT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); @@ -681,29 +615,117 @@ namespace BizHawk.Emulation.Cores.Components.Z80A IDLE, DEC16, PCl, PCh, DEC16, PCl, PCh, - IDLE, - IDLE, - WAIT, - OP_F, - OP}; + IDLE }; - BUSRQ = new ushort[] { B, B, B, B, B, PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { 0, 0, 0, 0, 0, PCh, 0, 0, 0 }; - } - else - { - cur_instr = new ushort[] - { IDLE, - WAIT, - OP_F, - OP }; + BUSRQ = new ushort[] { B, B, B, B, B }; + MEMRQ = new ushort[] { 0, 0, 0, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 0, 1 }; - BUSRQ = new ushort[] { PCh, 0, 0, 0 }; - MEMRQ = new ushort[] { PCh, 0, 0, 0 }; + instr_pntr = mem_pntr = bus_pntr = irq_pntr = 0; + I_skip = true; } - instr_pntr = 0; bus_pntr = 0; mem_pntr = 0; + break; + + case IRQ_S_F: + + break; + + case NMI_S_F: + break; } + + if (I_skip) + { + I_skip = false; + } + else if (IRQS[irq_pntr++] == 1) + { + if (EI_pending > 0) + { + EI_pending--; + if (EI_pending == 0) { IFF1 = IFF2 = true; } + } + + // NMI has priority + if (nonMaskableInterruptPending) + { + nonMaskableInterruptPending = false; + + if (TraceCallback != null) + { + TraceCallback(new TraceInfo { Disassembly = "====NMI====", RegisterInfo = "" }); + } + + iff2 = iff1; + iff1 = false; + NMI_(); + NMICallback(); + instr_pntr = mem_pntr = bus_pntr = irq_pntr = 0; + + temp_R = (byte)(Regs[R] & 0x7F); + temp_R++; + temp_R &= 0x7F; + Regs[R] = (byte)((Regs[R] & 0x80) | temp_R); + + halted = false; + } + // if we are processing an interrrupt, we need to modify the instruction vector + else if (iff1 && FlagI) + { + iff1 = iff2 = false; + EI_pending = 0; + + if (TraceCallback != null) + { + TraceCallback(new TraceInfo { Disassembly = "====IRQ====", RegisterInfo = "" }); + } + + switch (interruptMode) + { + case 0: + // Requires something to be pushed onto the data bus + // we'll assume it's a zero for now + INTERRUPT_0(0); + break; + case 1: + INTERRUPT_1(); + break; + case 2: + INTERRUPT_2(); + break; + } + IRQCallback(); + instr_pntr = mem_pntr = bus_pntr = irq_pntr = 0; + + temp_R = (byte)(Regs[R] & 0x7F); + temp_R++; + temp_R &= 0x7F; + Regs[R] = (byte)((Regs[R] & 0x80) | temp_R); + + halted = false; + } + // otherwise start a new normal access + else if (!halted) + { + cur_instr = new ushort[] + {IDLE, + WAIT, + OP_F, + OP}; + + BUSRQ = new ushort[] { PCh, 0, 0, 0 }; + MEMRQ = new ushort[] { PCh, 0, 0, 0 }; + IRQS = new ushort[] { 0, 0, 0, 1 }; + + instr_pntr = mem_pntr = bus_pntr = irq_pntr = 0; + } + else + { + instr_pntr = mem_pntr = bus_pntr = irq_pntr = 0; + } + } + TotalExecutedCycles++; } @@ -771,22 +793,20 @@ namespace BizHawk.Emulation.Cores.Components.Z80A ser.Sync("IFF1", ref iff1); ser.Sync("IFF2", ref iff2); ser.Sync("Halted", ref halted); + ser.Sync("I_skip", ref I_skip); ser.Sync("ExecutedCycles", ref TotalExecutedCycles); ser.Sync("EI_pending", ref EI_pending); ser.Sync("instr_pntr", ref instr_pntr); ser.Sync("bus_pntr", ref bus_pntr); ser.Sync("mem_pntr", ref mem_pntr); + ser.Sync("irq_pntr", ref irq_pntr); ser.Sync("cur_instr", ref cur_instr, false); ser.Sync("BUSRQ", ref BUSRQ, false); + ser.Sync("IRQS", ref IRQS, false); ser.Sync("MEMRQ", ref MEMRQ, false); ser.Sync("opcode", ref opcode); ser.Sync("FlagI", ref FlagI); - ser.Sync("FlagI1", ref FlagI1); - ser.Sync("FlagI2", ref FlagI2); - ser.Sync("FlagI3", ref FlagI3); - ser.Sync("FlagI4", ref FlagI4); - ser.Sync("FlagI5", ref FlagI5); ser.Sync("FlagW", ref FlagW); ser.Sync("NO Preifx", ref NO_prefix); @@ -796,6 +816,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A ser.Sync("IXCB_prefix", ref IXCB_prefix); ser.Sync("IYCB_prefix", ref IYCB_prefix); ser.Sync("EXTD_prefix", ref EXTD_prefix); + ser.Sync("PRE_SRC", ref PRE_SRC); ser.EndSection(); }