From 4cdcb807214dde3cc6de65a2a3612dbbce0e89ec Mon Sep 17 00:00:00 2001 From: alyosha-tas Date: Sat, 29 Sep 2018 22:08:19 -0500 Subject: [PATCH 1/8] 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(); } From 7ba4e8a4378b0a731f148c04ee21d07694ca87e9 Mon Sep 17 00:00:00 2001 From: alyosha-tas Date: Sun, 30 Sep 2018 10:02:50 -0500 Subject: [PATCH 2/8] z80: minor cleanups and bug fixes --- .../CPUs/Z80A/Tables_Direct.cs | 10 ++---- BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs | 32 ++++++++----------- 2 files changed, 16 insertions(+), 26 deletions(-) diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Direct.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Direct.cs index 6589e525d8..6af37ce302 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Direct.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Direct.cs @@ -108,8 +108,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A private void REG_OP_IR(ushort operation, ushort dest, ushort src) { cur_instr = new ushort[] - {operation, dest, src, - SET_FL_IR, dest }; + {IDLE, + SET_FL_IR, dest, src }; BUSRQ = new ushort[] { 0, I }; MEMRQ = new ushort[] { 0, 0 }; @@ -413,11 +413,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WR_DEC, SPl, SPh, PCh, RST, n, WAIT, - WR_TR_PC, SPl, SPh, PCl, - TR16, PCl, PCh, Z, W, - WAIT, - OP_F, - OP }; + WR_TR_PC, SPl, SPh, PCl }; BUSRQ = new ushort[] { 0, I, SPh, 0, 0, SPh, 0, 0 }; MEMRQ = new ushort[] { 0, 0, SPh, 0, 0, SPh, 0, 0 }; diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs index 270b405c1a..3f886389ae 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs @@ -81,14 +81,12 @@ namespace BizHawk.Emulation.Cores.Components.Z80A public const ushort REP_OP_I = 66; public const ushort REP_OP_O = 67; 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; + public const ushort RD_INC_TR_PC = 69; // transfer WZ to PC after read + public const ushort WR_TR_PC = 70; // transfer WZ to PC after write + public const ushort OUT_INC = 71; + public const ushort IN_INC = 72; + public const ushort WR_INC_WA = 73; // A -> W after WR_INC + public const ushort RD_OP = 74; // non-state variables public ushort Ztemp1, Ztemp2, Ztemp3, Ztemp4; @@ -176,7 +174,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A // do nothing break; case OP: - + // should never reach here break; case OP_F: @@ -381,6 +379,8 @@ 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 src_t = PRE_SRC; + NO_prefix = false; if (PRE_SRC == CBpre) { CB_prefix = true; } if (PRE_SRC == EXTDpre) { EXTD_prefix = true; } @@ -404,7 +404,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A 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; } + if ((src_t == IXCBpre) || (src_t == IXCBpre)) { BUSRQ[0] = PCh; } break; case ASGN: @@ -508,7 +508,9 @@ namespace BizHawk.Emulation.Cores.Components.Z80A } break; case SET_FL_IR: - SET_FL_IR_Func(cur_instr[instr_pntr++]); + ushort dest_t = cur_instr[instr_pntr++]; + TR_Func(dest_t, cur_instr[instr_pntr++]); + SET_FL_IR_Func(dest_t); break; case FTCH_DB: FTCH_DB_Func(); @@ -625,14 +627,6 @@ namespace BizHawk.Emulation.Cores.Components.Z80A I_skip = true; } break; - - case IRQ_S_F: - - break; - - case NMI_S_F: - - break; } if (I_skip) From 19a25e55fb8d8b5901cf9e37d8cfd9e95685dfcc Mon Sep 17 00:00:00 2001 From: alyosha-tas Date: Sun, 30 Sep 2018 12:21:47 -0500 Subject: [PATCH 3/8] z80: IORQ signal interrupt acknowledge --- .../CPUs/Z80A/Interrupts.cs | 18 ++++++------------ BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs | 5 +++++ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Interrupts.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Interrupts.cs index dbc90454de..5eec6cf45f 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/Interrupts.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Interrupts.cs @@ -64,8 +64,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A cur_instr = new ushort[] {IDLE, IDLE, - IDLE, - IDLE, + IORQ, + WAIT, IDLE, WAIT, RD_INC, ALU, PCl, PCh }; @@ -73,8 +73,6 @@ namespace BizHawk.Emulation.Cores.Components.Z80A 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(); } // Just jump to $0038 @@ -83,8 +81,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A cur_instr = new ushort[] {IDLE, IDLE, - IDLE, - IDLE, + IORQ, + WAIT, IDLE, TR, ALU, PCl, DEC16, SPl, SPh, @@ -98,8 +96,6 @@ namespace BizHawk.Emulation.Cores.Components.Z80A 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(); } // Interrupt mode 2 uses the I vector combined with a byte on the data bus @@ -108,8 +104,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A cur_instr = new ushort[] {IDLE, IDLE, - IDLE, - IDLE, + IORQ, + WAIT, FTCH_DB, IDLE, DEC16, SPl, SPh, @@ -129,8 +125,6 @@ namespace BizHawk.Emulation.Cores.Components.Z80A 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(); } private void ResetInterrupts() diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs index 3f886389ae..6c7c9f3e50 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs @@ -87,6 +87,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A public const ushort IN_INC = 72; public const ushort WR_INC_WA = 73; // A -> W after WR_INC public const ushort RD_OP = 74; + public const ushort IORQ = 75; // non-state variables public ushort Ztemp1, Ztemp2, Ztemp3, Ztemp4; @@ -627,6 +628,10 @@ namespace BizHawk.Emulation.Cores.Components.Z80A I_skip = true; } break; + + case IORQ: + IRQACKCallback(); + break; } if (I_skip) From a3a5250e39993c66fded2c25e5a5ffadc835b1c1 Mon Sep 17 00:00:00 2001 From: Asnivor Date: Mon, 8 Oct 2018 11:55:58 +0100 Subject: [PATCH 4/8] GameDB: Super KickOff (J) GG_in_SMS - #1157 --- Assets/gamedb/gamedb_sega_gg.txt | 1 + Assets/gamedb/gamedb_sega_sms.txt | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/gamedb/gamedb_sega_gg.txt b/Assets/gamedb/gamedb_sega_gg.txt index 08053af392..0b3837cd2f 100644 --- a/Assets/gamedb/gamedb_sega_gg.txt +++ b/Assets/gamedb/gamedb_sega_gg.txt @@ -408,6 +408,7 @@ F2B15E50EF16B3257C5D08CA0BD17E3B Super Battletank (U) GG USA 8F1DE0CAA864BEED2A61F391795B0A10 Super Columns (UE) GG Puzzle GGLink USA;Europe 3696AB241BBE66846A0AD00A50CA289B Super Columns (J) GG Puzzle GGLink Japan F2B5123B3614388677C9C15ADAAA8D64 Super Golf (J) GG Sports;Golf Japan +91AB09B8B4D25A08DD0EBE13003E54B5 Super Kick Off (J) (SMSGG) GG Sports;Soccer GG_in_SMS Japan D8F9CFDE4ACA117781A931D4FA73FEAF Super Momotarou Dentetsu III (J) GG GGLink Japan 1539563613AE8CDB08BBFE372B3AE1F4 Super Monaco GP II (UE) GG Racing GGLink USA;Europe 5843ABEA9BEFF14EF6FE840CE59DFAA0 Super Monaco GP II (UE) (Beta) GG Racing GGLink USA;Europe diff --git a/Assets/gamedb/gamedb_sega_sms.txt b/Assets/gamedb/gamedb_sega_sms.txt index 7f23ea2449..9f8b0634d2 100644 --- a/Assets/gamedb/gamedb_sega_sms.txt +++ b/Assets/gamedb/gamedb_sega_sms.txt @@ -496,7 +496,6 @@ EB7D7DB5AB98B0B7812552644FB95FE8 Super Boy 4 (K) SMS Korea 6120C9BA0F2C24031C9A836035060717 Super Boy II (K) (Pirate) SMS Korea 355F226E0B0602F1FB8C27ED4BAE3713 Super Golf (E) (Beta) SMS Sports;Golf Europe 6C203C7AA7003A880B80A90D96FC4A33 Super Kick Off (E) (En,Fr,De,Es,It,Nl,Pt,Sv) SMS Sports;Soccer Europe -91AB09B8B4D25A08DD0EBE13003E54B5 Super Kick Off (J) (SMSGG) SMS Sports;Soccer Japan 04ABC524A3B7F7E2E96EB910490E77EC Super Monaco GP II (E) SMS Racing Europe AED300F323AAE6D00878EB6BA21C2EB7 Super Monaco GP (U) SMS Racing USA D18F1C389ED75EFABC44E24B128DA95D Super Monaco GP (U) (Beta 1) SMS Racing USA From c11004cf19a347b77c5e711983803217e5049ffd Mon Sep 17 00:00:00 2001 From: Asnivor Date: Mon, 8 Oct 2018 11:59:11 +0100 Subject: [PATCH 5/8] GameDB: Fantastic Dizzy (Europe) (En,Fr,De,Es,It) GG_in_SMS - #1157 --- Assets/gamedb/gamedb_sega_gg.txt | 1 + Assets/gamedb/gamedb_sega_sms.txt | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/gamedb/gamedb_sega_gg.txt b/Assets/gamedb/gamedb_sega_gg.txt index 0b3837cd2f..6d088a1233 100644 --- a/Assets/gamedb/gamedb_sega_gg.txt +++ b/Assets/gamedb/gamedb_sega_gg.txt @@ -121,6 +121,7 @@ C58D6291DA8A4919328B8F42BE8640A7 Eternal Legend (J) GG SRAM=8192 Japan 8DCFAA8A12425A56F5DE7518B691158B Faceball 2000 (J) GG GGLink Japan 784F3FF02E544E3A9CF18B3B1DA1F062 Factory Panic (E) GG Europe 4D965F99BE3EDD9593AF1C365D6A2653 Factory Panic (J) GG Japan +66A8E3133A047FA7D44968EFD3C30720 Fantastic Dizzy (E) (SMSGG) (En,Fr,De,Es,It) GG CMMapper;CMMapper;GG_in_SMS Europe 9C314C791AD0A98CDA6BD7D39C0A2774 Fantasy Zone (U) GG USA 4C6C42493B5AF22540E6C2014D2C367A Fantasy Zone (JE) GG Europe;Japan 4292C099F98CC0C6D03025F0729F64DF Fatal Fury Special (U) GG GGLink USA diff --git a/Assets/gamedb/gamedb_sega_sms.txt b/Assets/gamedb/gamedb_sega_sms.txt index 9f8b0634d2..a6c61c3393 100644 --- a/Assets/gamedb/gamedb_sega_sms.txt +++ b/Assets/gamedb/gamedb_sega_sms.txt @@ -201,7 +201,6 @@ B88767B3386073FA775A8391B8912010 F-16 Fighter (UE) SMS USA;Europe F3D0D07A2EEA23175D9A8D2B428151E8 FA Tetris (K) (Pirate) SMS F/U not working;Puzzle Korea 03552187D613C1B2A22A8E32476C5254 Family Games (J) SMS FM Japan B8EB0CB6A9D16CFD08D9C03297FCD445 Fantastic Dizzy (E) (En,Fr,De,Es,It) SMS CMMapper;PAL Europe -66A8E3133A047FA7D44968EFD3C30720 Fantastic Dizzy (E) (SMSGG) (En,Fr,De,Es,It) SMS CMMapper;CMMapper Europe D37F86C678B2AD0018518EA7278DB24B Fantasy Zone - The Maze (UE) SMS FM USA;Europe 481A01C4E768C535EE18D6D78815FC89 Fantasy Zone II - The Tears of Opa-Opa (UE) SMS FM USA;Europe F898539F72DB2271FC3385A5EB51A06F Fantasy Zone II - The Tears of Opa-Opa (J) SMS FM Japan From d0f9951634f0432921c7cb02628fbee162f406ae Mon Sep 17 00:00:00 2001 From: Asnivor Date: Mon, 8 Oct 2018 12:01:22 +0100 Subject: [PATCH 6/8] GameDB: Excellent Dizzy Collection, The (Europe) - GG_in_SMS - #1157 --- Assets/gamedb/gamedb_sega_gg.txt | 1 + Assets/gamedb/gamedb_sega_sms.txt | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/gamedb/gamedb_sega_gg.txt b/Assets/gamedb/gamedb_sega_gg.txt index 6d088a1233..bb9d6693aa 100644 --- a/Assets/gamedb/gamedb_sega_gg.txt +++ b/Assets/gamedb/gamedb_sega_gg.txt @@ -115,6 +115,7 @@ A506FC04C7A0DFAF37423FF0A38AEB2E Ecco the Dolphin (J) GG Japan E97C20B86EA73248CC7AED602D46C3A4 Ernie Els Golf (E) (En,Fr,De,Es,It) GG Sports;Golf CMMapperWithRam Europe C58D6291DA8A4919328B8F42BE8640A7 Eternal Legend (J) GG SRAM=8192 Japan 4E63ABB36BE8D86B94B34846B16D9FA3 Evander Holyfield's 'Real Deal' Boxing (UE) GG Sports;Boxing GGLink USA;Europe +613376B7B53E43BA17AE1B62DA3C9251 The Excellent Dizzy Collection (E) (SMSGG) GG CMMapper;GG_in_SMS Europe 309ABE6822C52DF971856912C77A57CC F1 - World Championship Edition (E) GG Racing Europe 93B3E1B682474FFD9985C0A5688D45BF F1 (UE) GG Racing USA;Europe 69CC38014650BDD0AF0A2B7D7E9C46EC F-15 Strike Eagle (UE) GG USA;Europe diff --git a/Assets/gamedb/gamedb_sega_sms.txt b/Assets/gamedb/gamedb_sega_sms.txt index a6c61c3393..16b6e202e0 100644 --- a/Assets/gamedb/gamedb_sega_sms.txt +++ b/Assets/gamedb/gamedb_sega_sms.txt @@ -191,7 +191,6 @@ A94DE92B078911E71C246679C8992DA1 Enduro Racer (J) SMS Racing Japan DE328CDE27324C8D591F740DB0CB2866 E-SWAT - City Under Siege (UE) (Easy Version) SMS USA;Europe 36A5339CEF97D0A5757DB4FD81B4ABF3 E-SWAT - City Under Siege (UE) (Hard Version) SMS USA;Europe C68B86706784801EFF53A4CA4500FF21 The Excellent Dizzy Collection (UE) (En,Fr,De,Es,It) (Proto) SMS CMMapper;PAL USA;Europe -613376B7B53E43BA17AE1B62DA3C9251 The Excellent Dizzy Collection (E) (SMSGG) SMS CMMapper Europe 293EF0398970CFF0A5B4CD419B643F3C F-1 Spirit - The Way to Formula-1 (K) (Pirate) SMS MSXMapper Korea 5D67504B8334A0E36F6119515928717C F1 (E) SMS Racing Europe B88767B3386073FA775A8391B8912010 F-16 Fighter (UE) SMS USA;Europe From abb1242cc902bb3e9bad687a138a5b9adac372f8 Mon Sep 17 00:00:00 2001 From: Asnivor Date: Mon, 8 Oct 2018 12:09:05 +0100 Subject: [PATCH 7/8] GameDB: Jang Pung II (Korean pirated SMSGG) - GG_in_SMS - #1157 --- Assets/gamedb/gamedb_sega_gg.txt | 1 + Assets/gamedb/gamedb_sega_sms.txt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Assets/gamedb/gamedb_sega_gg.txt b/Assets/gamedb/gamedb_sega_gg.txt index bb9d6693aa..77f6b0a1f0 100644 --- a/Assets/gamedb/gamedb_sega_gg.txt +++ b/Assets/gamedb/gamedb_sega_gg.txt @@ -187,6 +187,7 @@ D4034F6604C5DC04EE06E78B913C47FC J.League GG Pro Striker '94 (J) GG Sports;Base 1C88D6F7784EFB05D2548F9F903889F3 James Pond 3 - Operation Starfi5h (E) GG Europe 13F37A4434AEF5140752F1717A1CC936 James Pond II - Codename RoboCod (U) GG USA 607BD5D109FD322168603856258A37C0 James Pond II - Codename RoboCod (E) GG Europe +9B95B6E6609DAA8EA413F223F426C8FF Jang Pung II (K) (Unl) GG CMMapper;GG_in_SMS Korea 5D1351B4F7579D36A1250F5B5F5A507F Jeopardy! - Sports Edition (UE) GG USA;Europe 6E87D0107228AE1B5C582F8595992152 Jeopardy! (U) GG USA C74F379A93E9F667C375A316F8021AFC Joe Montana Football (UE) GG Sports;Football GGLink USA;Europe diff --git a/Assets/gamedb/gamedb_sega_sms.txt b/Assets/gamedb/gamedb_sega_sms.txt index 16b6e202e0..f04b49c423 100644 --- a/Assets/gamedb/gamedb_sega_sms.txt +++ b/Assets/gamedb/gamedb_sega_sms.txt @@ -290,7 +290,7 @@ B3A4815CA9FDC900CF7FE6AD961F8125 James 'Buster' Douglas Knockout Boxing (U) SMS 433FE61368CDF79C1B66CC84D0936599 James 'Buster' Douglas Knockout Boxing (U) (Beta) SMS Sports;Boxing USA 73B92360C3EFDE9D265280F6E157FC33 James Pond 2 - Codename RoboCod (E) SMS Europe F355EC9D0171A4D01356165D2BABA6A1 Jang Pung 3 (K) SMS KoreaMapper Korea -9B95B6E6609DAA8EA413F223F426C8FF Jang Pung II (K) (Unl) SMS CMMapper Korea + 2DB7AAABCA7F62D69DF466797C0D63D9 Janggun-ui Adeul (K) SMS Korea 0ECE8F9C0FDE2EBA92BBE9A500116FF0 Joe Montana Football (UE) SMS Sports;Football USA;Europe ED224898BEFB4FB246175E46F9982821 The Jungle Book (E) SMS Disney Europe From ffcd7993f90a9ae094b99c7b1b3c82c33ab08d1f Mon Sep 17 00:00:00 2001 From: Asnivor Date: Mon, 8 Oct 2018 12:14:42 +0100 Subject: [PATCH 8/8] GameDB: Super Tetris (Pirate) - GG_in_SMS - #1157 --- Assets/gamedb/gamedb_sega_gg.txt | 1 + Assets/gamedb/gamedb_sega_sms.txt | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/gamedb/gamedb_sega_gg.txt b/Assets/gamedb/gamedb_sega_gg.txt index 77f6b0a1f0..2a985e1e03 100644 --- a/Assets/gamedb/gamedb_sega_gg.txt +++ b/Assets/gamedb/gamedb_sega_gg.txt @@ -422,6 +422,7 @@ CE6809A18FB430A2863231B2DAC51DB2 Super Off Road (UE) GG Racing;Arcade GGLink US FC8D04E6975267CDC6BD49A0DEA33C41 Super Return of the Jedi (UE) GG USA;Europe D378D5784B82154BDC7B36976A7C7737 Super Smash T.V. (W) GG Arcade World 6367666402C51229D283AC0CF5BF3FFB Super Space Invaders (UE) GG Arcade GGLink USA;Europe +3AAB83A641BF3A26D68ED44F49C28714 Super Tetris (K) (Pirate) GG GG_in_SMS Korea 1ADF05E9AC786D9B46BB8D2B8043669D Superman - The Man of Steel (E) GG Europe 61808B13D8505470B96B9F7295310BCD Superman - The Man of Steel (E) (Beta) GG Europe 63F72877317FD3C17B0D867EA3169F56 Surf Ninjas (U) GG USA diff --git a/Assets/gamedb/gamedb_sega_sms.txt b/Assets/gamedb/gamedb_sega_sms.txt index f04b49c423..72cfa28c54 100644 --- a/Assets/gamedb/gamedb_sega_sms.txt +++ b/Assets/gamedb/gamedb_sega_sms.txt @@ -504,7 +504,6 @@ BCC2DF04CAC4B713EE48A05669CDFBDD Super Racing (J) SMS Racing FM;PaddleOptional FD65B6794D6778C7948CD9B8B02A12F5 Super Smash T.V. (E) SMS Arcade Europe F36E9758390ED2B781E9A8A7A958E7E3 Super Space Invaders (E) SMS Arcade Europe 2DB9404FE79593FD2379921CA822103A Super Tennis (UE) SMS Sports;Tennis USA;Europe -3AAB83A641BF3A26D68ED44F49C28714 Super Tetris (K) (Pirate) SMS Korea DC1541E54DA2376781E3691784BEFAA9 Superman - The Man of Steel (E) SMS Europe F1983C31F965AA8DE77DF64483883550 T2 - The Arcade Game (E) SMS Europe 5F170677DC0D0229EC3EC7F306BB6303 Taz in Escape from Mars (B) SMS Brazil