z80:more contention work, only IN/OUT to go

This commit is contained in:
alyosha-tas 2018-06-05 18:04:19 -04:00
parent 978a93b681
commit 620c4b3c2e
3 changed files with 127 additions and 171 deletions

View File

@ -145,7 +145,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
OP_F,
OP };
BUSRQ = new ushort[] {0, PCh, 0, 0, 0, 0, 0, 0, 0, PCh, 0, 0, 0};
BUSRQ = new ushort[] {I, PCh, 0, 0, PCh, PCh, PCh, PCh, PCh, PCh, 0, 0, 0};
}
else
{
@ -159,7 +159,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
OP_F,
OP };
BUSRQ = new ushort[] {0, PCh, 0, 0, PCh, 0, 0, 0};
BUSRQ = new ushort[] {I, PCh, 0, 0, PCh, 0, 0, 0};
}
}
@ -482,7 +482,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
IDLE,
PREFIX, src,};
BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, 0, 0 };
BUSRQ = new ushort[] { PCh, 0, 0, PCh, 0, 0, PCh, PCh };
}
private void DI_()

View File

@ -292,9 +292,9 @@
{
cur_instr = new ushort[]
{IDLE,
IDLE,
WAIT,
RD, ALU, Z, W,
IDLE,
operation, bit, ALU,
WAIT,
WR, Z, W, ALU,
@ -303,22 +303,22 @@
OP_F,
OP };
BUSRQ = new ushort[] { 0, W, 0, 0, W, 0, 0, PCh, 0, 0, 0 };
BUSRQ = new ushort[] { W, 0, 0, W, W, 0, 0, PCh, 0, 0, 0 };
}
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 };
BUSRQ = new ushort[] { 0, W, 0, 0, PCh, 0, 0, 0 };
BUSRQ = new ushort[] { W, 0, 0, W, PCh, 0, 0, 0 };
}
private void I_OP_n(ushort operation, ushort src_l, ushort src_h)
@ -333,10 +333,10 @@
ADDS, Z, W, ALU, ZERO,
IDLE,
IDLE,
IDLE,
WAIT,
RD, ALU, Z, W,
operation, ALU,
IDLE,
WAIT,
WR, Z, W, ALU,
IDLE,
@ -344,7 +344,7 @@
OP_F,
OP };
BUSRQ = new ushort[] { PCh, 0, 0, 0, 0, 0, 0, 0, 0, W, 0, 0, W, 0, 0, PCh, 0, 0, 0 };
BUSRQ = new ushort[] { PCh, 0, 0, PCh, PCh, PCh, PCh, PCh, W, 0, 0, W, W, 0, 0, PCh, 0, 0, 0 };
}
private void I_OP_n_n(ushort src_l, ushort src_h)
@ -419,74 +419,58 @@
{IDLE,
WAIT,
RD, ALU, L, H,
IDLE,
operation, L, H,
WAIT,
WR, E, D, ALU,
operation, L, H,
operation, E, D,
SET_FL_LD, // BC gets decremented in here
WAIT,
OP_F,
OP_R, 0, operation, repeat_instr };
SET_FL_LD_R, 0, operation, repeat_instr};
BUSRQ = new ushort[] { H, 0, 0, D, 0, 0, 0, 0, PCh, 0, 0, 0 };
BUSRQ = new ushort[] { H, 0, 0, D, 0, 0, D, D};
}
private void CP_OP_R(ushort operation, ushort repeat_instr)
{
cur_instr = new ushort[]
{IDLE,
{IDLE,
WAIT,
RD, ALU, L, H,
operation, L, H,
DEC16, C, B,
SET_FL_CP,
operation, Z, W,
IDLE,
IDLE,
WAIT,
OP_F,
OP_R, 1, operation, repeat_instr };
SET_FL_CP_R, 1, operation, repeat_instr};
BUSRQ = new ushort[] { H, 0, 0, 0, 0, 0, 0, 0, PCh, 0, 0, 0 };
BUSRQ = new ushort[] { H, 0, 0, H, H, H, H, H };
}
private void IN_OP_R(ushort operation, ushort repeat_instr)
{
cur_instr = new ushort[]
{IDLE,
IDLE,
WAIT,
WAIT,
IN, ALU, C, B,
IDLE,
WAIT,
WR, L, H, ALU,
REP_OP_I, operation,
IDLE,
WAIT,
OP_F,
OP_R, 2, operation, repeat_instr };
REP_OP_I, operation, 2, operation, repeat_instr };
BUSRQ = new ushort[] { 0, 0, 0, 0, H, 0, 0, 0, PCh, 0, 0, 0 };
BUSRQ = new ushort[] { I, 0, 0, 0, H, 0, 0, 0};
}
private void OUT_OP_R(ushort operation, ushort repeat_instr)
{
cur_instr = new ushort[]
{IDLE,
{IDLE,
IDLE,
WAIT,
RD, ALU, L, H,
IDLE,
IDLE,
WAIT,
OUT, C, B, ALU,
REP_OP_O, operation,
IDLE,
WAIT,
OP_F,
OP_R, 3, operation, repeat_instr };
REP_OP_O, operation, 3, operation, repeat_instr };
BUSRQ = new ushort[] { H, 0, 0, 0, 0, 0, 0, 0, PCh, 0, 0, 0 };
BUSRQ = new ushort[] { I, H, 0, 0, 0, 0, 0, 0};
}
// this is an indirect change of a a 16 bit register with memory

View File

@ -70,8 +70,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
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_LD_R = 58;
public const ushort SET_FL_CP_R = 59;
public const ushort SET_FL_IR = 60;
public const ushort I_BIT = 61;
public const ushort HL_BIT = 62;
@ -102,7 +102,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
OP_F,
OP };
BUSRQ = new ushort[] { PCl, 0, 0, 0 };
BUSRQ = new ushort[] { PCh, 0, 0, 0 };
instr_pntr = 0; bus_pntr = 0;
NO_prefix = true;
}
@ -231,134 +231,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
Regs[R] = (byte)((Regs[R] & 0x80) | temp_R);
break;
case OP_R:
// determine if we repeat based on what operation we are doing
// single execution versions also come here, but never repeat
ushort temp1 = cur_instr[instr_pntr++];
ushort temp2 = cur_instr[instr_pntr++];
ushort temp3 = cur_instr[instr_pntr++];
bool repeat = false;
int Reg16_d = Regs[C] | (Regs[B] << 8);
switch (temp1)
{
case 0:
repeat = Reg16_d != 0;
break;
case 1:
repeat = (Reg16_d != 0) && !FlagZ;
break;
case 2:
repeat = Regs[B] != 0;
break;
case 3:
repeat = Regs[B] != 0;
break;
}
// if we repeat, we do a 5 cycle refresh which decrements PC by 2
// if we don't repeat, continue on as a normal opcode fetch
if (repeat && temp3 > 0)
{
cur_instr = new ushort[]
{DEC16, PCl, PCh,
DEC16, PCl, PCh,
WAIT,
OP_F,
OP };
BUSRQ = new ushort[] { 0, PCh, 0, 0, 0 };
instr_pntr = 0; bus_pntr = 0;
// adjust WZ register accordingly
switch (temp1)
{
case 0:
// TEST: PC before or after the instruction?
Regs[Z] = Regs[PCl];
Regs[W] = Regs[PCh];
INC16_Func(Z, W);
break;
case 1:
// TEST: PC before or after the instruction?
Regs[Z] = Regs[PCl];
Regs[W] = Regs[PCh];
INC16_Func(Z, W);
break;
case 2:
// Nothing
break;
case 3:
// Nothing
break;
}
}
else
{
// Interrupts can occur at this point, so process them accordingly
// 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;
}
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 = 0; bus_pntr = 0;
}
else
{
if (OnExecFetch != null) OnExecFetch(RegPC);
if (TraceCallback != null) TraceCallback(State());
RegPC++;
FetchInstruction();
instr_pntr = 0; bus_pntr = 0;
}
temp_R = (byte)(Regs[R] & 0x7F);
temp_R++;
temp_R &= 0x7F;
Regs[R] = (byte)((Regs[R] & 0x80) | temp_R);
}
break;
case HALT:
@ -608,12 +481,14 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
case RLD:
RLD_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case SET_FL_LD:
case SET_FL_LD_R:
DEC16_Func(C, B);
SET_FL_LD_Func();
Repeat_Op();
break;
case SET_FL_CP:
case SET_FL_CP_R:
SET_FL_CP_Func();
Repeat_Op();
break;
case SET_FL_IR:
SET_FL_IR_Func(cur_instr[instr_pntr++]);
@ -651,6 +526,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
INC16_Func(Z, W);
DEC8_Func(B);
}
Repeat_Op();
break;
case REP_OP_O:
ushort temp5 = cur_instr[instr_pntr++];
@ -668,11 +544,107 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
TR16_Func(Z, W, C, B);
INC16_Func(Z, W);
}
Repeat_Op();
break;
}
TotalExecutedCycles++;
}
public void Repeat_Op()
{
// determine if we repeat based on what operation we are doing
// single execution versions also come here, but never repeat
ushort temp1 = cur_instr[instr_pntr++];
ushort temp2 = cur_instr[instr_pntr++];
ushort temp3 = cur_instr[instr_pntr++];
bool repeat = false;
int Reg16_d = Regs[C] | (Regs[B] << 8);
switch (temp1)
{
case 0:
repeat = Reg16_d != 0;
break;
case 1:
repeat = (Reg16_d != 0) && !FlagZ;
break;
case 2:
repeat = Regs[B] != 0;
break;
case 3:
repeat = Regs[B] != 0;
break;
}
// if we repeat, we do a 5 cycle refresh which decrements PC by 2
// if we don't repeat, continue on as a normal opcode fetch
if (repeat && temp3 > 0)
{
cur_instr = new ushort[]
{DEC16, PCl, PCh,
DEC16, PCl, PCh,
IDLE,
IDLE,
IDLE,
IDLE,
WAIT,
OP_F,
OP};
if (temp1 == 0)
{
BUSRQ = new ushort[] { D, D, D, D, D, PCh, 0, 0, 0 };
}
else if (temp1 == 1)
{
BUSRQ = new ushort[] { H, H, H, H, H, PCh, 0, 0, 0 };
}
else if (temp1 == 2)
{
BUSRQ = new ushort[] { H, H, H, H, H, PCh, 0, 0, 0 };
}
else if (temp1 == 3)
{
BUSRQ = new ushort[] { B, B, B, B, B, PCh, 0, 0, 0 };
}
instr_pntr = 0; bus_pntr = 0;
// adjust WZ register accordingly
switch (temp1)
{
case 0:
// TEST: PC before or after the instruction?
Regs[Z] = Regs[PCl];
Regs[W] = Regs[PCh];
INC16_Func(Z, W);
break;
case 1:
// TEST: PC before or after the instruction?
Regs[Z] = Regs[PCl];
Regs[W] = Regs[PCh];
INC16_Func(Z, W);
break;
case 2:
// Nothing
break;
case 3:
// Nothing
break;
}
}
else
{
cur_instr = new ushort[]
{ IDLE,
WAIT,
OP_F,
OP };
BUSRQ = new ushort[] { PCh, 0, 0, 0 };
instr_pntr = 0; bus_pntr = 0;
}
}
// tracer stuff
public Action<TraceInfo> TraceCallback;