From 32ae549c70d570972d6bb6b6fd5f3005a2c880ca Mon Sep 17 00:00:00 2001 From: alyosha-tas Date: Sun, 3 Jun 2018 19:14:30 -0400 Subject: [PATCH] z80: Add bus request timing array to work with zx spectrum Also some clean up --- BizHawk.Emulation.Cores/CPUs/Z80A/Execute.cs | 2 + .../CPUs/Z80A/Operations.cs | 11 +- .../CPUs/Z80A/Tables_Direct.cs | 120 ++++++++++-- .../CPUs/Z80A/Tables_Indirect.cs | 66 ++++++- BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs | 182 +++++++++--------- .../SinclairSpectrum/Machine/CPUMonitor.cs | 2 - 6 files changed, 256 insertions(+), 127 deletions(-) diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Execute.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Execute.cs index 57f262bd7a..8feed65cbe 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/Execute.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Execute.cs @@ -18,8 +18,10 @@ namespace BizHawk.Emulation.Cores.Components.Z80A // variables for executing instructions public int instr_pntr = 0; + public int bus_pntr = 0; public ushort instr_swap; public ushort[] cur_instr; + public ushort[] BUSRQ; public byte opcode; public bool NO_prefix, CB_prefix, IX_prefix, EXTD_prefix, IY_prefix, IXCB_prefix, IYCB_prefix; public bool IXCB_prefetch, IYCB_prefetch; // value is fetched before opcode diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Operations.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Operations.cs index f9fe6f797f..4ec81fe298 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/Operations.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Operations.cs @@ -18,12 +18,6 @@ namespace BizHawk.Emulation.Cores.Components.Z80A INC16_Func(src_l, src_h); } - public void I_Read_Func(ushort dest, ushort src_l, ushort src_h, ushort inc) - { - Regs[dest] = ReadMemory((ushort)((Regs[src_l] | (Regs[src_h] << 8)) + inc)); - Regs[DB] = Regs[dest]; - } - public void Write_Func(ushort dest_l, ushort dest_h, ushort src) { Regs[DB] = Regs[src]; @@ -37,10 +31,11 @@ namespace BizHawk.Emulation.Cores.Components.Z80A INC16_Func(dest_l, dest_h); } - public void I_Write_Func(ushort dest_l, ushort dest_h, ushort inc, ushort src) + public void Write_DEC_Func(ushort dest_l, ushort dest_h, ushort src) { Regs[DB] = Regs[src]; - WriteMemory((ushort)((Regs[dest_l] | (Regs[dest_h] << 8)) + inc), (byte)Regs[src]); + WriteMemory((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)Regs[src]); + DEC16_Func(dest_l, dest_h); } public void OUT_Func(ushort dest_l, ushort dest_h, ushort src) diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Direct.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Direct.cs index 4ad6252352..c4ab95abf7 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Direct.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Direct.cs @@ -14,6 +14,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] {PCl, 0, 0, 0 }; } // NOTE: In a real Z80, this operation just flips a switch to choose between 2 registers @@ -25,6 +27,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { PCl, 0, 0, 0 }; } private void EXX_() @@ -34,6 +38,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { PCl, 0, 0, 0 }; } // this exchanges 2 16 bit registers @@ -44,17 +50,21 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { PCl, 0, 0, 0 }; } private void INC_16(ushort src_l, ushort src_h) { cur_instr = new ushort[] - {INC16, src_l, src_h, + {INC16, src_l, src_h, IDLE, IDLE, WAIT, OP_F, OP }; + + BUSRQ = new ushort[] {0, 0, PCl, 0, 0, 0}; } @@ -67,6 +77,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] {0, 0, PCl, 0, 0, 0}; } // this is done in two steps technically, but the flags don't work out using existing funcitons @@ -85,6 +97,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] {0, 0, 0, 0, 0, 0, 0, PCl, 0, 0, 0 }; } private void REG_OP(ushort operation, ushort dest, ushort src) @@ -94,6 +108,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] {PCl, 0, 0, 0 }; } // Operations using the I and R registers take one T-cycle longer @@ -105,6 +121,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] {0, PCl, 0, 0, 0 }; } // note: do not use DEC here since no flags are affected by this operation @@ -126,6 +144,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] {0, PCl, 0, 0, 0, 0, 0, 0, 0, PCl, 0, 0, 0}; } else { @@ -138,6 +158,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] {0, PCl, 0, 0, PCl, 0, 0, 0}; } } @@ -148,6 +170,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A IDLE, IDLE, HALT }; + + BUSRQ = new ushort[] {PCl, 0, 0, 0 }; } private void JR_COND(bool cond) @@ -167,6 +191,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] {PCl, 0, 0, 0, 0, 0, 0, 0, PCl, 0, 0, 0}; } else { @@ -178,6 +204,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] {PCl, 0, 0, PCl, 0, 0, 0}; } } @@ -196,6 +224,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] {PCl, 0, 0, PCl, 0, 0, Z, 0, 0, 0}; } else { @@ -210,6 +240,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] {PCl, 0, 0, PCl, 0, 0, PCl, 0, 0, 0}; } } @@ -226,6 +258,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] {SPl, 0, 0, SPl, 0, 0, Z, 0, 0, 0}; } private void RETI_() @@ -241,6 +275,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] {SPl, 0, 0, SPl, 0, 0, Z, 0, 0, 0}; } private void RETN_() @@ -256,6 +292,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] {SPl, 0, 0, SPl, 0, 0, Z, 0, 0, 0}; } @@ -275,6 +313,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] {0, SPl, 0, 0, SPl, 0, 0, Z, 0, 0, 0}; } else { @@ -284,6 +324,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] {0, PCl, 0, 0, 0}; } } @@ -296,19 +338,21 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, RD_INC, Z, PCl, PCh, IDLE, - IDLE, + DEC16, SPl, SPh, WAIT, RD_INC, W, PCl, PCh, - DEC16, SPl, SPh, + IDLE, WAIT, - WR, SPl, SPh, PCh, - DEC16, SPl, SPh, + WR_DEC, SPl, SPh, PCh, + IDLE, WAIT, WR, SPl, SPh, PCl, TR16, PCl, PCh, Z, W, WAIT, OP_F, OP }; + + BUSRQ = new ushort[] {PCl, 0, 0, PCl, 0, 0, 0, SPl, 0, 0, SPl, 0, 0, Z, 0, 0, 0}; } else { @@ -323,6 +367,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { PCl, 0, 0, PCl, 0, 0, PCl, 0, 0, 0 }; } } @@ -333,6 +379,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { PCl, 0, 0, 0 }; } private void BIT_OP(ushort operation, ushort bit, ushort src) @@ -342,22 +390,26 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { PCl, 0, 0, 0 }; } private void PUSH_(ushort src_l, ushort src_h) { cur_instr = new ushort[] - {IDLE, - DEC16, SPl, SPh, + {DEC16, SPl, SPh, + IDLE, WAIT, - WR, SPl, SPh, src_h, - DEC16, SPl, SPh, + WR_DEC, SPl, SPh, src_h, + IDLE, WAIT, WR, SPl, SPh, src_l, IDLE, WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { 0, SPl, 0, 0, SPl, 0, 0, PCl, 0, 0, 0 }; } @@ -374,22 +426,26 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { SPl, 0, 0, SPl, 0, 0, PCl, 0, 0, 0 }; } private void RST_(ushort n) { cur_instr = new ushort[] - {IDLE, - DEC16, SPl, SPh, + {DEC16, SPl, SPh, + IDLE, WAIT, - WR, SPl, SPh, PCh, - DEC16, SPl, SPh, + WR_DEC, SPl, SPh, PCh, + RST, n, WAIT, WR, SPl, SPh, PCl, - RST, n, + TR16, PCl, PCh, Z, W, WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { 0, SPl, 0, 0, SPl, 0, 0, Z, 0, 0, 0 }; } private void PREFIX_(ushort src) @@ -399,6 +455,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, PREFIX, src}; + + BUSRQ = new ushort[] { PCl, 0, 0, 0 }; } private void PREFETCH_(ushort src_l, ushort src_h) @@ -408,6 +466,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, PREFIX, IXYprefetch }; + + BUSRQ = new ushort[] { PCl, 0, 0, 0 }; } private void DI_() @@ -417,6 +477,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { PCl, 0, 0, 0 }; } private void EI_() @@ -426,6 +488,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { PCl, 0, 0, 0 }; } private void JP_16(ushort src_l, ushort src_h) @@ -435,6 +499,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { src_l, 0, 0, 0 }; } private void LD_SP_16(ushort src_l, ushort src_h) @@ -446,6 +512,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { 0, 0, src_l, 0, 0, 0 }; } private void OUT_() @@ -462,6 +530,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP}; + + BUSRQ = new ushort[] { PCl, 0, 0, 0, 0, 0 ,0, PCl, 0, 0, 0}; } private void OUT_REG_(ushort dest, ushort src) @@ -475,6 +545,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP}; + + BUSRQ = new ushort[] { 0, 0, 0, 0, PCl, 0, 0, 0 }; } private void IN_() @@ -491,6 +563,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP}; + + BUSRQ = new ushort[] { PCl, 0, 0, 0, 0, 0, 0, PCl, 0, 0, 0 }; } private void IN_REG_(ushort dest, ushort src) @@ -504,6 +578,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP}; + + BUSRQ = new ushort[] { 0, 0, 0, 0, PCl, 0, 0, 0 }; } private void REG_OP_16_(ushort op, ushort dest_l, ushort dest_h, ushort src_l, ushort src_h) @@ -520,6 +596,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP}; + + BUSRQ = new ushort[] { 0, 0, 0, 0, 0, 0, 0, PCl, 0, 0, 0 }; } private void INT_MODE_(ushort src) @@ -529,6 +607,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { PCl, 0, 0, 0 }; } private void RRD_() @@ -543,11 +623,13 @@ namespace BizHawk.Emulation.Cores.Components.Z80A IDLE, IDLE, WAIT, - WR, Z, W, ALU, - INC16, Z, W, + WR_INC, Z, W, ALU, + IDLE, WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { L, 0, 0, 0, 0, 0, Z, 0, 0, 0, PCl, 0, 0, 0 }; } private void RLD_() @@ -562,11 +644,13 @@ namespace BizHawk.Emulation.Cores.Components.Z80A IDLE, IDLE, WAIT, - WR, Z, W, ALU, - INC16, Z, W, + WR_INC, Z, W, ALU, + IDLE, WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { L, 0, 0, 0, 0, 0, Z, 0, 0, 0, PCl, 0, 0, 0 }; } } } diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Indirect.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Indirect.cs index 0e0b69801e..25e2f06528 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Indirect.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Tables_Indirect.cs @@ -16,6 +16,8 @@ WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { src_l, 0, 0, src_l, 0, 0, 0, PCl, 0, 0, 0 }; } private void BIT_OP_IND(ushort operation, ushort bit, ushort src_l, ushort src_h) @@ -32,6 +34,8 @@ WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { 0, src_l, 0, 0, src_l, 0, 0, PCl, 0, 0, 0 }; } // Note that this operation uses I_BIT, same as indexed BIT. @@ -49,6 +53,8 @@ WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { 0, src_l, 0, 0, PCl, 0, 0, 0 }; } private void REG_OP_IND_INC(ushort operation, ushort dest, ushort src_l, ushort src_h) @@ -61,6 +67,8 @@ WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { src_l, 0, 0, PCl, 0, 0, 0 }; } private void REG_OP_IND(ushort operation, ushort dest, ushort src_l, ushort src_h) @@ -73,6 +81,8 @@ WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { src_l, 0, 0, PCl, 0, 0, 0 }; } private void LD_16_IND_nn(ushort src_l, ushort src_h) @@ -86,14 +96,16 @@ RD_INC, W, PCl, PCh, IDLE, WAIT, - WR, Z, W, src_l, - INC16, Z, W, + WR_INC, Z, W, src_l, + IDLE, WAIT, WR, Z, W, src_h, IDLE, WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { PCl, 0, 0, PCl, 0, 0, Z, 0, 0, Z, 0, 0, PCl, 0, 0, 0 }; } private void LD_IND_16_nn(ushort dest_l, ushort dest_h) @@ -115,6 +127,8 @@ WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { PCl, 0, 0, PCl, 0, 0, Z, 0, 0, Z, 0, 0, PCl, 0, 0, 0 }; } private void LD_8_IND_nn(ushort src) @@ -133,6 +147,8 @@ WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { PCl, 0, 0, PCl, 0, 0, Z, 0, 0, PCl, 0, 0, 0 }; } private void LD_IND_8_nn(ushort dest) @@ -151,6 +167,8 @@ WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { PCl, 0, 0, PCl, 0, 0, Z, 0, 0, PCl, 0, 0, 0 }; } private void LD_8_IND(ushort dest_l, ushort dest_h, ushort src) @@ -163,6 +181,8 @@ WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { dest_l, 0, 0, PCl, 0, 0, 0 }; } private void LD_8_IND_IND(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h) @@ -178,6 +198,8 @@ WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { src_l, 0, 0, dest_l, 0, 0, PCl, 0, 0, 0 }; } private void LD_IND_8_INC(ushort dest, ushort src_l, ushort src_h) @@ -190,6 +212,8 @@ WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { src_l, 0, 0, PCl, 0, 0, 0 }; } private void LD_IND_16(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h) @@ -205,6 +229,8 @@ WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { src_l, 0, 0, src_l, 0, 0, PCl, 0, 0, 0 }; } private void INC_8_IND(ushort src_l, ushort src_h) @@ -221,6 +247,8 @@ WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { 0, src_l, 0, 0, src_l, 0, 0, PCl, 0, 0, 0 }; } private void DEC_8_IND(ushort src_l, ushort src_h) @@ -237,6 +265,8 @@ WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { 0, src_l, 0, 0, src_l, 0, 0, PCl, 0, 0, 0 }; } // NOTE: WZ implied for the wollowing 3 functions @@ -254,6 +284,8 @@ WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { 0, Z, 0, 0, Z, 0, 0, PCl, 0, 0, 0 }; } private void I_BIT_OP(ushort operation, ushort bit, ushort dest) @@ -270,6 +302,8 @@ WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { 0, Z, 0, 0, Z, 0, 0, PCl, 0, 0, 0 }; } private void I_BIT_TE(ushort bit) @@ -283,6 +317,8 @@ WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { 0, Z, 0, 0, PCl, 0, 0, 0 }; } private void I_OP_n(ushort operation, ushort src_l, ushort src_h) @@ -307,6 +343,8 @@ WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { PCl, 0, 0, 0, 0, 0, 0, 0, 0, Z, 0, 0, Z, 0, 0, PCl, 0, 0, 0 }; } private void I_OP_n_n(ushort src_l, ushort src_h) @@ -327,6 +365,8 @@ WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { PCl, 0, 0, 0, 0, PCl, 0, 0, Z, 0, 0, PCl, 0, 0, 0 }; } private void I_REG_OP_IND_n(ushort operation, ushort dest, ushort src_l, ushort src_h) @@ -347,6 +387,8 @@ WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { PCl, 0, 0, 0, 0, 0, 0, Z, 0, 0, PCl, 0, 0, 0 }; } private void I_LD_8_IND_n(ushort dest_l, ushort dest_h, ushort src) @@ -367,6 +409,8 @@ WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { PCl, 0, 0, 0, 0, 0, 0, Z, 0, 0, 0, PCl, 0, 0, 0 }; } private void LD_OP_R(ushort operation, ushort repeat_instr) @@ -384,6 +428,8 @@ WAIT, OP_F, OP_R, 0, operation, repeat_instr }; + + BUSRQ = new ushort[] { L, 0, 0, E, 0, 0, 0, 0, PCl, 0, 0, 0 }; } private void CP_OP_R(ushort operation, ushort repeat_instr) @@ -401,6 +447,8 @@ WAIT, OP_F, OP_R, 1, operation, repeat_instr }; + + BUSRQ = new ushort[] { L, 0, 0, 0, 0, 0, 0, 0, PCl, 0, 0, 0 }; } private void IN_OP_R(ushort operation, ushort repeat_instr) @@ -418,6 +466,8 @@ WAIT, OP_F, OP_R, 2, operation, repeat_instr }; + + BUSRQ = new ushort[] { 0, 0, 0, 0, L, 0, 0, 0, PCl, 0, 0, 0 }; } private void OUT_OP_R(ushort operation, ushort repeat_instr) @@ -435,6 +485,8 @@ WAIT, OP_F, OP_R, 3, operation, repeat_instr }; + + BUSRQ = new ushort[] { L, 0, 0, 0, 0, 0, 0, 0, PCl, 0, 0, 0 }; } // this is an indirect change of a a 16 bit register with memory @@ -444,22 +496,24 @@ {IDLE, WAIT, RD, Z, dest_l, dest_h, - IDLE, + INC16, dest_l, dest_h, IDLE, WAIT, - I_RD, W, dest_l, dest_h, 1, + RD, W, dest_l, dest_h, IDLE, WAIT, - WR, dest_l, dest_h, src_l, + WR_DEC, dest_l, dest_h, src_h, IDLE, IDLE, IDLE, WAIT, - I_WR, dest_l, dest_h, 1, src_h, + WR, dest_l, dest_h, 1, src_l, TR16, src_l, src_h, Z, W, WAIT, OP_F, OP }; + + BUSRQ = new ushort[] { dest_l, 0, 0, 0, dest_l, 0, 0, dest_l, 0, 0, 0, 0, dest_l, 0, 0, PCl, 0, 0, 0 }; } } } diff --git a/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs b/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs index 867b83a1e0..5291fb597a 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80A/Z80A.cs @@ -18,70 +18,70 @@ namespace BizHawk.Emulation.Cores.Components.Z80A public const ushort HALT = 3; public const ushort RD = 4; public const ushort WR = 5; - public const ushort I_RD = 6; - public const ushort I_WR = 7; - public const ushort TR = 8; - public const ushort TR16 = 9; - public const ushort ADD16 = 10; - public const ushort ADD8 = 11; - public const ushort SUB8 = 12; - public const ushort ADC8 = 13; - public const ushort SBC8 = 14; - public const ushort SBC16 = 15; - public const ushort ADC16 = 16; - public const ushort INC16 = 17; - public const ushort INC8 = 18; - public const ushort DEC16 = 19; - public const ushort DEC8 = 20; - public const ushort RLC = 21; - public const ushort RL = 22; - public const ushort RRC = 23; - public const ushort RR = 24; - public const ushort CPL = 25; - public const ushort DA = 26; - public const ushort SCF = 27; - public const ushort CCF = 28; - public const ushort AND8 = 29; - public const ushort XOR8 = 30; - public const ushort OR8 = 31; - public const ushort CP8 = 32; - public const ushort SLA = 33; - public const ushort SRA = 34; - public const ushort SRL = 35; - public const ushort SLL = 36; - public const ushort BIT = 37; - public const ushort RES = 38; - public const ushort SET = 39; - public const ushort EI = 40; - public const ushort DI = 41; - public const ushort EXCH = 42; - public const ushort EXX = 43; - public const ushort EXCH_16 = 44; - public const ushort PREFIX = 45; - public const ushort PREFETCH = 46; - public const ushort ASGN = 47; - public const ushort ADDS = 48; // signed 16 bit operation used in 2 instructions - public const ushort INT_MODE = 49; - public const ushort EI_RETN = 50; - public const ushort EI_RETI = 51; // reti has no delay in interrupt enable - public const ushort OUT = 52; - public const ushort IN = 53; - public const ushort NEG = 54; - public const ushort RRD = 55; - public const ushort RLD = 56; - public const ushort SET_FL_LD = 57; - public const ushort SET_FL_CP = 58; - public const ushort SET_FL_IR = 59; - public const ushort I_BIT = 60; - public const ushort HL_BIT = 61; - public const ushort FTCH_DB = 62; - public const ushort WAIT = 63; // enterred when readin or writing and FlagW is true - public const ushort OP_F = 64; // fetch the opcode, happens on cycle 3 of fetch cycle - public const ushort RD_INC = 65; // read and increment + public const ushort RD_INC = 6; // read and increment + public const ushort WR_INC = 7; // write and increment + public const ushort WR_DEC = 8; // write and increment (for stack pointer) + public const ushort TR = 9; + public const ushort TR16 = 10; + public const ushort ADD16 = 11; + public const ushort ADD8 = 12; + public const ushort SUB8 = 13; + public const ushort ADC8 = 14; + public const ushort SBC8 = 15; + public const ushort SBC16 = 16; + public const ushort ADC16 = 17; + public const ushort INC16 = 18; + public const ushort INC8 = 19; + public const ushort DEC16 = 20; + public const ushort DEC8 = 21; + public const ushort RLC = 22; + public const ushort RL = 23; + public const ushort RRC = 24; + public const ushort RR = 25; + public const ushort CPL = 26; + public const ushort DA = 27; + public const ushort SCF = 28; + public const ushort CCF = 29; + public const ushort AND8 = 30; + public const ushort XOR8 = 31; + public const ushort OR8 = 32; + public const ushort CP8 = 33; + public const ushort SLA = 34; + public const ushort SRA = 35; + public const ushort SRL = 36; + public const ushort SLL = 37; + public const ushort BIT = 38; + public const ushort RES = 39; + public const ushort SET = 40; + public const ushort EI = 41; + public const ushort DI = 42; + public const ushort EXCH = 43; + public const ushort EXX = 44; + public const ushort EXCH_16 = 45; + public const ushort PREFIX = 46; + public const ushort PREFETCH = 47; + public const ushort ASGN = 48; + public const ushort ADDS = 49; // signed 16 bit operation used in 2 instructions + public const ushort INT_MODE = 50; + public const ushort EI_RETN = 51; + public const ushort EI_RETI = 52; // reti has no delay in interrupt enable + public const ushort OUT = 53; + public const ushort IN = 54; + public const ushort NEG = 55; + public const ushort RRD = 56; + public const ushort RLD = 57; + public const ushort SET_FL_LD = 58; + public const ushort SET_FL_CP = 59; + public const ushort SET_FL_IR = 60; + 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 OP_F = 65; // fetch the opcode, happens on cycle 3 of fetch cycle public const ushort RST = 66; - public const ushort WR_INC = 67; // write and increment - public const ushort REP_OP_I = 68; - public const ushort REP_OP_O = 69; + public const ushort REP_OP_I = 67; + public const ushort REP_OP_O = 68; + public byte temp_R; @@ -101,7 +101,9 @@ namespace BizHawk.Emulation.Cores.Components.Z80A WAIT, OP_F, OP }; - instr_pntr = 0; + + BUSRQ = new ushort[] { PCl, 0, 0, 0 }; + instr_pntr = 0; bus_pntr = 0; NO_prefix = true; } @@ -157,6 +159,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A // Execute instructions public void ExecuteOne() { + bus_pntr++; switch (cur_instr[instr_pntr++]) { case IDLE: @@ -184,7 +187,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A iff1 = false; NMI_(); NMICallback(); - instr_pntr = 0; + instr_pntr = 0; bus_pntr = 0; } else if (iff1 && FlagI) { @@ -211,7 +214,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A break; } IRQCallback(); - instr_pntr = 0; + instr_pntr = 0; bus_pntr = 0; } else { @@ -219,7 +222,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A if (TraceCallback != null) TraceCallback(State()); RegPC++; FetchInstruction(); - instr_pntr = 0; + instr_pntr = 0; bus_pntr = 0; } temp_R = (byte)(Regs[R] & 0x7F); @@ -263,7 +266,9 @@ namespace BizHawk.Emulation.Cores.Components.Z80A OP_F, OP }; - instr_pntr = 0; + BUSRQ = new ushort[] { 0, PCl, 0, 0, 0 }; + + instr_pntr = 0; bus_pntr = 0; // adjust WZ register accordingly switch (temp1) { @@ -311,7 +316,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A iff1 = false; NMI_(); NMICallback(); - instr_pntr = 0; + instr_pntr = 0; bus_pntr = 0; } else if (iff1 && FlagI) { @@ -338,7 +343,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A break; } IRQCallback(); - instr_pntr = 0; + instr_pntr = 0; bus_pntr = 0; } else { @@ -346,7 +351,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A if (TraceCallback != null) TraceCallback(State()); RegPC++; FetchInstruction(); - instr_pntr = 0; + instr_pntr = 0; bus_pntr = 0; } temp_R = (byte)(Regs[R] & 0x7F); @@ -410,20 +415,13 @@ namespace BizHawk.Emulation.Cores.Components.Z80A IRQCallback(); halted = false; } - else - { - cur_instr = new ushort[] - {IDLE, - IDLE, - IDLE, - HALT }; - } + temp_R = (byte)(Regs[R] & 0x7F); temp_R++; temp_R &= 0x7F; Regs[R] = (byte)((Regs[R] & 0x80) | temp_R); - instr_pntr = 0; + instr_pntr = 0; bus_pntr = 0; break; case RD: Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); @@ -431,11 +429,14 @@ namespace BizHawk.Emulation.Cores.Components.Z80A case WR: Write_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; - case I_RD: - I_Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + case RD_INC: + Read_INC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); break; - case I_WR: - I_Write_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); + 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 TR: TR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); @@ -565,7 +566,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A RegPC++; FetchInstruction(); - instr_pntr = 0; + instr_pntr = 0; bus_pntr = 0; // only the first prefix in a double prefix increases R, although I don't know how / why if (prefix_src < 4) { @@ -624,22 +625,15 @@ namespace BizHawk.Emulation.Cores.Components.Z80A if (FlagW) { instr_pntr--; + bus_pntr--; } break; case OP_F: opcode = FetchMemory(RegPC); break; - case RD_INC: - Read_INC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); - break; - case WR_INC: - Write_INC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); - break; case RST: Regs[Z] = cur_instr[instr_pntr++]; Regs[W] = 0; - Regs[PCl] = Regs[Z]; - Regs[PCh] = Regs[W]; break; case REP_OP_I: ushort temp4 = cur_instr[instr_pntr++]; @@ -747,7 +741,9 @@ namespace BizHawk.Emulation.Cores.Components.Z80A ser.Sync("EI_pending", ref EI_pending); ser.Sync("instr_pntr", ref instr_pntr); + ser.Sync("bus_pntr", ref bus_pntr); ser.Sync("cur_instr", ref cur_instr, false); + ser.Sync("BUSRQ", ref BUSRQ, false); ser.Sync("instr_swap", ref instr_swap); ser.Sync("opcode", ref opcode); ser.Sync("FlagI", ref FlagI); diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/CPUMonitor.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/CPUMonitor.cs index d2cff11e0e..d098cc94a4 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/CPUMonitor.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/CPUMonitor.cs @@ -123,8 +123,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum case Z80A.RD_INC: case Z80A.WR: case Z80A.WR_INC: - case Z80A.I_RD: - case Z80A.I_WR: addr = (ushort)(_cpu.Regs[cur_instr[instr_pntr + 4]] | _cpu.Regs[cur_instr[instr_pntr + 5]] << 8); if (_machine.IsContended(addr)) {