Z80: Fix R register operation

This commit is contained in:
alyosha-tas 2017-10-19 12:08:34 -04:00 committed by GitHub
parent be6aa52bc8
commit 28cce355bf
4 changed files with 55 additions and 70 deletions

View File

@ -15,6 +15,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
public const ushort IYpre = 3;
public const ushort IXCBpre = 4;
public const ushort IYCBpre = 5;
public const ushort IXYprefetch = 6;
// variables for executing instructions
public int instr_pntr = 0;
@ -1194,8 +1195,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
IYCB_prefetch = false;
PF = opcode;
Regs[ALU] = PF;
PREFETCH_(Iyl, Iyh);
PREFETCH_(Iyl, Iyh);
return;
}

View File

@ -34,7 +34,6 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
char sign = neg ? '-' : '+';
int val = neg ? 256 - B : B;
format = format.Replace("d", string.Format("{0}{1:X2}h", sign, val));
addr++;
}
return format;
@ -397,6 +396,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
public string Disassemble(ushort addr, Func<ushort, byte> read, out ushort size)
{
ushort start_addr = addr;
ushort extra_inc = 0;
byte A = read(addr++);
string format;
switch (A)
@ -409,7 +409,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
A = read(addr++);
switch (A)
{
case 0xCB: format = mnemonicsDDCB[A]; break;
case 0xCB: format = mnemonicsDDCB[A]; extra_inc = 1; break;
case 0xED: format = mnemonicsED[A]; break;
default: format = mnemonicsDD[A]; break;
}
@ -422,7 +422,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
A = read(addr++);
switch (A)
{
case 0xCB: format = mnemonicsFDCB[A]; break;
case 0xCB: format = mnemonicsFDCB[A]; extra_inc = 1; break;
case 0xED: format = mnemonicsED[A]; break;
default: format = mnemonicsFD[A]; break;
}
@ -432,6 +432,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
string temp = Result(format, read, ref addr);
addr += extra_inc;
size = (ushort)(addr - start_addr);
return temp;
}

View File

@ -395,10 +395,10 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
private void PREFIX_(ushort src)
{
cur_instr = new ushort[]
{PREFIX, src,
{IDLE,
IDLE,
IDLE,
OP };
PREFIX, src};
}
private void PREFETCH_(ushort src_l, ushort src_h)
@ -407,7 +407,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{TR16, Z, W, src_l, src_h,
ADDS, Z, W, ALU, ZERO,
IDLE,
OP };
PREFIX, IXYprefetch };
}
private void DI_()

View File

@ -75,7 +75,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
public const ushort I_BIT = 60;
public const ushort HL_BIT = 61;
public byte temp_R;
public Z80A()
{
@ -147,27 +147,20 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
break;
case OP:
// Read the opcode of the next instruction
if (EI_pending > 0 && NO_prefix)
if (EI_pending > 0)
{
EI_pending--;
if (EI_pending == 0)
{
IFF1 = IFF2 = true;
}
if (EI_pending == 0) { IFF1 = IFF2 = true; }
}
// Process interrupt requests.
if (nonMaskableInterruptPending && NO_prefix)
if (nonMaskableInterruptPending)
{
nonMaskableInterruptPending = false;
if (TraceCallback != null)
{
TraceCallback(new TraceInfo
{
Disassembly = "====NMI====",
RegisterInfo = ""
});
TraceCallback(new TraceInfo{Disassembly = "====NMI====", RegisterInfo = ""});
}
iff2 = iff1;
@ -175,18 +168,14 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
NMI_();
NMICallback();
}
else if (iff1 && FlagI && NO_prefix)
else if (iff1 && FlagI)
{
iff1 = iff2 = false;
EI_pending = 0;
if (TraceCallback != null)
{
TraceCallback(new TraceInfo
{
Disassembly = "====IRQ====",
RegisterInfo = ""
});
TraceCallback(new TraceInfo{Disassembly = "====IRQ====", RegisterInfo = ""});
}
switch (interruptMode)
@ -210,12 +199,15 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
else
{
if (OnExecFetch != null) OnExecFetch(RegPC);
if (TraceCallback != null && NO_prefix) TraceCallback(State());
if (TraceCallback != null) TraceCallback(State());
FetchInstruction(ReadMemory(RegPC++));
}
instr_pntr = 0;
Regs[R]++;
Regs[R] &= 0xFF;
temp_R = (byte)(Regs[R] & 0x7F);
temp_R++;
temp_R &= 0x7F;
Regs[R] = (byte)((Regs[R] & 0x80) | temp_R);
break;
case OP_R:
// determine if we repeat based on what operation we are doing
@ -280,47 +272,35 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
{
// Interrupts can occur at this point, so process them accordingly
// Read the opcode of the next instruction
if (EI_pending > 0 && NO_prefix)
if (EI_pending > 0)
{
EI_pending--;
if (EI_pending == 0)
{
IFF1 = IFF2 = true;
}
if (EI_pending == 0) { IFF1 = IFF2 = true; }
}
// Process interrupt requests.
if (nonMaskableInterruptPending && NO_prefix)
if (nonMaskableInterruptPending)
{
nonMaskableInterruptPending = false;
if (TraceCallback != null)
{
TraceCallback(new TraceInfo
{
Disassembly = "====NMI====",
RegisterInfo = ""
});
TraceCallback(new TraceInfo{Disassembly = "====NMI====", RegisterInfo = ""});
}
iff2 = iff1;
iff1 = false;
NMI_();
NMICallback();
}
else if (iff1 && FlagI && NO_prefix)
else if (iff1 && FlagI)
{
iff1 = iff2 = false;
EI_pending = 0;
if (TraceCallback != null)
{
TraceCallback(new TraceInfo
{
Disassembly = "====IRQ====",
RegisterInfo = ""
});
TraceCallback(new TraceInfo{Disassembly = "====IRQ====", RegisterInfo = ""});
}
switch (interruptMode)
@ -346,36 +326,32 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
if (OnExecFetch != null) OnExecFetch(RegPC);
if (TraceCallback != null) TraceCallback(State());
FetchInstruction(ReadMemory(RegPC++));
Regs[R]++;
Regs[R] &= 0xFF;
}
temp_R = (byte)(Regs[R] & 0x7F);
temp_R++;
temp_R &= 0x7F;
Regs[R] = (byte)((Regs[R] & 0x80) | temp_R);
}
instr_pntr = 0;
break;
case HALT:
halted = true;
if (EI_pending > 0 && NO_prefix)
if (EI_pending > 0)
{
EI_pending--;
if (EI_pending == 0)
{
IFF1 = IFF2 = true;
}
if (EI_pending == 0) { IFF1 = IFF2 = true; }
}
// Process interrupt requests.
if (nonMaskableInterruptPending && NO_prefix)
if (nonMaskableInterruptPending)
{
nonMaskableInterruptPending = false;
if (TraceCallback != null)
{
TraceCallback(new TraceInfo
{
Disassembly = "====NMI====",
RegisterInfo = ""
});
TraceCallback(new TraceInfo{Disassembly = "====NMI====", RegisterInfo = ""});
}
iff2 = iff1;
@ -384,18 +360,14 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
NMICallback();
halted = false;
}
else if (iff1 && FlagI && NO_prefix)
else if (iff1 && FlagI)
{
iff1 = iff2 = false;
EI_pending = 0;
if (TraceCallback != null)
{
TraceCallback(new TraceInfo
{
Disassembly = "====IRQ====",
RegisterInfo = ""
});
TraceCallback(new TraceInfo{Disassembly = "====IRQ====", RegisterInfo = ""});
}
switch (interruptMode)
@ -419,14 +391,16 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
}
else
{
Regs[R]++;
Regs[R] &= 0xFF;
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;
break;
@ -567,8 +541,17 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
if (prefix_src == IYpre) { IY_prefix = true; }
if (prefix_src == IXCBpre) { IXCB_prefix = true; IXCB_prefetch = true; }
if (prefix_src == IYCBpre) { IYCB_prefix = true; IYCB_prefetch = true; }
Regs[R]++;
Regs[R] &= 0xFF;
FetchInstruction(ReadMemory(RegPC++));
instr_pntr = 0;
// only the first prefix in a double prefix increases R, although I don't know how / why
if (prefix_src < 4)
{
temp_R = (byte)(Regs[R] & 0x7F);
temp_R++;
temp_R &= 0x7F;
Regs[R] = (byte)((Regs[R] & 0x80) | temp_R);
}
break;
case ASGN:
ASGN_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);