z80: Add bus request timing array to work with zx spectrum

Also some clean up
This commit is contained in:
alyosha-tas 2018-06-03 19:14:30 -04:00
parent 1637ab3953
commit 32ae549c70
6 changed files with 256 additions and 127 deletions

View File

@ -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

View File

@ -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)

View File

@ -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 };
}
}
}

View File

@ -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 };
}
}
}

View File

@ -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);

View File

@ -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))
{