-Separated the logging from the save state function.
-Made it so that the log only opens when logging is true and that the file closes upon destruction. --Still, BizHawk says that it can't open the file again when I load a game again. This is because the emulator class gets recreated without deleting the original one every time you load a game. ---adelikat convinced me not to care about this. -Fixed the initial state of the GB CPU: --It was setting AF to 0x01, not A. This is effectively setting F to 0x01, which gets overwritten later anyway. --Two BIOS flags were used in different places; merging them gets the PC to start in the right place. -By fixing the initial state, most of the log now matches up. --The only differences are the VBA has some repeated records (Where all of the registers, including PC, are the same as the previous record) whereas BizHawk doesn't. --This very well might be an issue with how I'm logging it --Alternatively, it could be some kind of lagging mechanism. --I'm not sure which version is even correct...VBA is far from accruate. --All in all, considering that the vast majority of the diff comes out as the same, I think I fixed the biggest CPU related bug. Will investigate more later.
This commit is contained in:
parent
db1bfcfdfc
commit
b29c9835ff
|
@ -7,27 +7,27 @@ using System;
|
|||
+ The following instructions were rewritten or substantially modified for Z80-GB. They should be
|
||||
treated with caution and checked further when the emulator is farther along.
|
||||
|
||||
ADD
|
||||
ADC
|
||||
SUB
|
||||
SBC
|
||||
AND
|
||||
OR
|
||||
XOR
|
||||
CP
|
||||
SWAP
|
||||
DAA
|
||||
RLCA
|
||||
RLA
|
||||
RRCA
|
||||
RRA
|
||||
RLC
|
||||
RL
|
||||
RRC
|
||||
RR
|
||||
SLA
|
||||
SRA
|
||||
SRL
|
||||
ADD
|
||||
ADC
|
||||
SUB
|
||||
SBC
|
||||
AND
|
||||
OR
|
||||
XOR
|
||||
CP
|
||||
SWAP
|
||||
DAA
|
||||
RLCA
|
||||
RLA
|
||||
RRCA
|
||||
RRA
|
||||
RLC
|
||||
RL
|
||||
RRC
|
||||
RR
|
||||
SLA
|
||||
SRA
|
||||
SRL
|
||||
*/
|
||||
|
||||
namespace BizHawk.Emulation.CPUs.Z80GB
|
||||
|
@ -42,7 +42,7 @@ namespace BizHawk.Emulation.CPUs.Z80GB
|
|||
public void ExecuteInstruction()
|
||||
{
|
||||
LogCPU();
|
||||
byte TB; byte TB2; sbyte TSB; ushort TUS; int TI1; int TI2; int TIR;
|
||||
byte TB; byte TB2; sbyte TSB; ushort TUS; int TI1; int TI2; int TIR;
|
||||
while (RegPC.Word == 0x031A)
|
||||
break;
|
||||
byte op = ReadMemory(RegPC.Word++);
|
||||
|
@ -952,288 +952,288 @@ namespace BizHawk.Emulation.CPUs.Z80GB
|
|||
switch (op)
|
||||
{
|
||||
case 0x00: // RLC B
|
||||
RegAF.Low = (byte)((RegBC.High & 0x80) >> 3);
|
||||
RegBC.High = (byte)((RegBC.High >> 7) | (RegBC.High << 1));
|
||||
if (RegBC.High == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = (byte)((RegBC.High & 0x80) >> 3);
|
||||
RegBC.High = (byte)((RegBC.High >> 7) | (RegBC.High << 1));
|
||||
if (RegBC.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x01: // RLC C
|
||||
RegAF.Low = (byte)((RegBC.Low & 0x80) >> 3);
|
||||
RegBC.Low = (byte)((RegBC.Low >> 7) | (RegBC.Low << 1));
|
||||
if (RegBC.Low == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = (byte)((RegBC.Low & 0x80) >> 3);
|
||||
RegBC.Low = (byte)((RegBC.Low >> 7) | (RegBC.Low << 1));
|
||||
if (RegBC.Low == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x02: // RLC D
|
||||
RegAF.Low = (byte)((RegDE.High & 0x80) >> 3);
|
||||
RegDE.High = (byte)((RegDE.High >> 7) | (RegDE.High << 1));
|
||||
if (RegDE.High == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = (byte)((RegDE.High & 0x80) >> 3);
|
||||
RegDE.High = (byte)((RegDE.High >> 7) | (RegDE.High << 1));
|
||||
if (RegDE.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x03: // RLC E
|
||||
RegAF.Low = (byte)((RegDE.Low & 0x80) >> 3);
|
||||
RegDE.Low = (byte)((RegDE.Low >> 7) | (RegDE.Low << 1));
|
||||
if (RegDE.Low == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = (byte)((RegDE.Low & 0x80) >> 3);
|
||||
RegDE.Low = (byte)((RegDE.Low >> 7) | (RegDE.Low << 1));
|
||||
if (RegDE.Low == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x04: // RLC H
|
||||
RegAF.Low = (byte)((RegHL.High & 0x80) >> 3);
|
||||
RegHL.High = (byte)((RegHL.High >> 7) | (RegHL.High << 1));
|
||||
if (RegHL.High == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = (byte)((RegHL.High & 0x80) >> 3);
|
||||
RegHL.High = (byte)((RegHL.High >> 7) | (RegHL.High << 1));
|
||||
if (RegHL.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x05: // RLC L
|
||||
RegAF.Low = (byte)((RegHL.Low & 0x80) >> 3);
|
||||
RegHL.Low = (byte)((RegHL.Low >> 7) | (RegHL.Low << 1));
|
||||
if (RegHL.Low == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = (byte)((RegHL.Low & 0x80) >> 3);
|
||||
RegHL.Low = (byte)((RegHL.Low >> 7) | (RegHL.Low << 1));
|
||||
if (RegHL.Low == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x06: // RLC (HL)
|
||||
TB = ReadMemory(RegHL.Word);
|
||||
RegAF.Low = (byte)((TB & 0x80) >> 3);
|
||||
TB = (byte)((TB >> 7) | (TB << 1));
|
||||
if (TB == 0) RegAF.Low |= 0x80;
|
||||
WriteMemory(RegHL.Word, TB);
|
||||
TB = ReadMemory(RegHL.Word);
|
||||
RegAF.Low = (byte)((TB & 0x80) >> 3);
|
||||
TB = (byte)((TB >> 7) | (TB << 1));
|
||||
if (TB == 0) RegAF.Low |= 0x80;
|
||||
WriteMemory(RegHL.Word, TB);
|
||||
break;
|
||||
case 0x07: // RLC A
|
||||
RegAF.Low = (byte)((RegAF.High & 0x80) >> 3);
|
||||
RegAF.High = (byte)((RegAF.High >> 7) | (RegAF.High << 1));
|
||||
if (RegAF.High == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = (byte)((RegAF.High & 0x80) >> 3);
|
||||
RegAF.High = (byte)((RegAF.High >> 7) | (RegAF.High << 1));
|
||||
if (RegAF.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x08: // RRC B
|
||||
RegBC.High = (byte)((RegBC.High << 7) | (RegBC.High >> 1));
|
||||
RegAF.Low = (byte)((RegBC.High & 0x80) >> 3);
|
||||
if (RegBC.High == 0) RegAF.Low |= 0x80;
|
||||
RegBC.High = (byte)((RegBC.High << 7) | (RegBC.High >> 1));
|
||||
RegAF.Low = (byte)((RegBC.High & 0x80) >> 3);
|
||||
if (RegBC.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x09: // RRC C
|
||||
RegBC.Low = (byte)((RegBC.Low << 7) | (RegBC.Low >> 1));
|
||||
RegAF.Low = (byte)((RegBC.Low & 0x80) >> 3);
|
||||
if (RegBC.Low == 0) RegAF.Low |= 0x80;
|
||||
RegBC.Low = (byte)((RegBC.Low << 7) | (RegBC.Low >> 1));
|
||||
RegAF.Low = (byte)((RegBC.Low & 0x80) >> 3);
|
||||
if (RegBC.Low == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x0A: // RRC D
|
||||
RegDE.High = (byte)((RegDE.High << 7) | (RegDE.High >> 1));
|
||||
RegAF.Low = (byte)((RegDE.High & 0x80) >> 3);
|
||||
if (RegDE.High == 0) RegAF.Low |= 0x80;
|
||||
RegDE.High = (byte)((RegDE.High << 7) | (RegDE.High >> 1));
|
||||
RegAF.Low = (byte)((RegDE.High & 0x80) >> 3);
|
||||
if (RegDE.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x0B: // RRC E
|
||||
RegDE.Low = (byte)((RegDE.Low << 7) | (RegDE.Low >> 1));
|
||||
RegAF.Low = (byte)((RegDE.Low & 0x80) >> 3);
|
||||
if (RegDE.Low == 0) RegAF.Low |= 0x80;
|
||||
RegDE.Low = (byte)((RegDE.Low << 7) | (RegDE.Low >> 1));
|
||||
RegAF.Low = (byte)((RegDE.Low & 0x80) >> 3);
|
||||
if (RegDE.Low == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x0C: // RRC H
|
||||
RegHL.High = (byte)((RegHL.High << 7) | (RegHL.High >> 1));
|
||||
RegAF.Low = (byte)((RegHL.High & 0x80) >> 3);
|
||||
if (RegHL.High == 0) RegAF.Low |= 0x80;
|
||||
RegHL.High = (byte)((RegHL.High << 7) | (RegHL.High >> 1));
|
||||
RegAF.Low = (byte)((RegHL.High & 0x80) >> 3);
|
||||
if (RegHL.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x0D: // RRC L
|
||||
RegHL.Low = (byte)((RegHL.Low << 7) | (RegHL.Low >> 1));
|
||||
RegAF.Low = (byte)((RegHL.Low & 0x80) >> 3);
|
||||
if (RegHL.Low == 0) RegAF.Low |= 0x80;
|
||||
RegHL.Low = (byte)((RegHL.Low << 7) | (RegHL.Low >> 1));
|
||||
RegAF.Low = (byte)((RegHL.Low & 0x80) >> 3);
|
||||
if (RegHL.Low == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x0E: // RRC (HL)
|
||||
TB = ReadMemory(RegHL.Word);
|
||||
TB = (byte)((TB << 7) | (TB >> 1));
|
||||
RegAF.Low = (byte)((TB & 0x80) >> 3);
|
||||
if (TB == 0) RegAF.Low |= 0x80;
|
||||
WriteMemory(RegHL.Word, TB);
|
||||
TB = ReadMemory(RegHL.Word);
|
||||
TB = (byte)((TB << 7) | (TB >> 1));
|
||||
RegAF.Low = (byte)((TB & 0x80) >> 3);
|
||||
if (TB == 0) RegAF.Low |= 0x80;
|
||||
WriteMemory(RegHL.Word, TB);
|
||||
break;
|
||||
case 0x0F: // RRC A
|
||||
RegAF.High = (byte)((RegAF.High << 7) | (RegAF.High >> 1));
|
||||
RegAF.Low = (byte)((RegAF.High & 0x80) >> 3);
|
||||
if (RegAF.High == 0) RegAF.Low |= 0x80;
|
||||
RegAF.High = (byte)((RegAF.High << 7) | (RegAF.High >> 1));
|
||||
RegAF.Low = (byte)((RegAF.High & 0x80) >> 3);
|
||||
if (RegAF.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x10: // RL B
|
||||
TB = (byte)((RegBC.High & 0x80) >> 3);
|
||||
RegBC.High = (byte)((RegBC.High << 1) | (FlagC ? 1 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegBC.High == 0) RegAF.Low |= 0x80;
|
||||
TB = (byte)((RegBC.High & 0x80) >> 3);
|
||||
RegBC.High = (byte)((RegBC.High << 1) | (FlagC ? 1 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegBC.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x11: // RL C
|
||||
TB = (byte)((RegBC.Low & 0x80) >> 3);
|
||||
RegBC.Low = (byte)((RegBC.Low << 1) | (FlagC ? 1 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegBC.Low == 0) RegAF.Low |= 0x80;
|
||||
TB = (byte)((RegBC.Low & 0x80) >> 3);
|
||||
RegBC.Low = (byte)((RegBC.Low << 1) | (FlagC ? 1 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegBC.Low == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x12: // RL D
|
||||
TB = (byte)((RegDE.High & 0x80) >> 3);
|
||||
RegDE.High = (byte)((RegDE.High << 1) | (FlagC ? 1 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegDE.High == 0) RegAF.Low |= 0x80;
|
||||
TB = (byte)((RegDE.High & 0x80) >> 3);
|
||||
RegDE.High = (byte)((RegDE.High << 1) | (FlagC ? 1 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegDE.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x13: // RL E
|
||||
TB = (byte)((RegDE.Low & 0x80) >> 3);
|
||||
RegDE.Low = (byte)((RegDE.Low << 1) | (FlagC ? 1 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegDE.Low == 0) RegAF.Low |= 0x80;
|
||||
TB = (byte)((RegDE.Low & 0x80) >> 3);
|
||||
RegDE.Low = (byte)((RegDE.Low << 1) | (FlagC ? 1 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegDE.Low == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x14: // RL H
|
||||
TB = (byte)((RegHL.High & 0x80) >> 3);
|
||||
RegHL.High = (byte)((RegHL.High << 1) | (FlagC ? 1 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegHL.High == 0) RegAF.Low |= 0x80;
|
||||
TB = (byte)((RegHL.High & 0x80) >> 3);
|
||||
RegHL.High = (byte)((RegHL.High << 1) | (FlagC ? 1 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegHL.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x15: // RL L
|
||||
TB = (byte)((RegHL.Low & 0x80) >> 3);
|
||||
RegHL.Low = (byte)((RegHL.Low << 1) | (FlagC ? 1 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegHL.Low == 0) RegAF.Low |= 0x80;
|
||||
TB = (byte)((RegHL.Low & 0x80) >> 3);
|
||||
RegHL.Low = (byte)((RegHL.Low << 1) | (FlagC ? 1 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegHL.Low == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x16: // RL (HL)
|
||||
TB2 = ReadMemory(RegHL.Word);
|
||||
TB = (byte)((TB2 & 0x80) >> 3);
|
||||
TB2 = (byte)((TB2 << 1) | (FlagC ? 1 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (TB2 == 0) RegAF.Low |= 0x80;
|
||||
WriteMemory(RegHL.Word, TB2);
|
||||
TB2 = ReadMemory(RegHL.Word);
|
||||
TB = (byte)((TB2 & 0x80) >> 3);
|
||||
TB2 = (byte)((TB2 << 1) | (FlagC ? 1 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (TB2 == 0) RegAF.Low |= 0x80;
|
||||
WriteMemory(RegHL.Word, TB2);
|
||||
break;
|
||||
case 0x17: // RL A
|
||||
TB = (byte)((RegAF.High & 0x80) >> 3);
|
||||
RegAF.High = (byte)((RegAF.High << 1) | (FlagC ? 1 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegAF.High == 0) RegAF.Low |= 0x80;
|
||||
TB = (byte)((RegAF.High & 0x80) >> 3);
|
||||
RegAF.High = (byte)((RegAF.High << 1) | (FlagC ? 1 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegAF.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x18: // RR B
|
||||
TB = (byte)((RegBC.High & 0x1) << 4);
|
||||
RegBC.High = (byte)((RegBC.High >> 1) | (FlagC ? 0x80 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegBC.High == 0) RegAF.Low |= 0x80;
|
||||
TB = (byte)((RegBC.High & 0x1) << 4);
|
||||
RegBC.High = (byte)((RegBC.High >> 1) | (FlagC ? 0x80 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegBC.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x19: // RR C
|
||||
TB = (byte)((RegBC.Low & 0x1) << 4);
|
||||
RegBC.Low = (byte)((RegBC.Low >> 1) | (FlagC ? 0x80 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegBC.Low == 0) RegAF.Low |= 0x80;
|
||||
TB = (byte)((RegBC.Low & 0x1) << 4);
|
||||
RegBC.Low = (byte)((RegBC.Low >> 1) | (FlagC ? 0x80 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegBC.Low == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x1A: // RR D
|
||||
TB = (byte)((RegDE.High & 0x1) << 4);
|
||||
RegDE.High = (byte)((RegDE.High >> 1) | (FlagC ? 0x80 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegDE.High == 0) RegAF.Low |= 0x80;
|
||||
TB = (byte)((RegDE.High & 0x1) << 4);
|
||||
RegDE.High = (byte)((RegDE.High >> 1) | (FlagC ? 0x80 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegDE.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x1B: // RR E
|
||||
TB = (byte)((RegDE.Low & 0x1) << 4);
|
||||
RegDE.Low = (byte)((RegDE.Low >> 1) | (FlagC ? 0x80 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegDE.Low == 0) RegAF.Low |= 0x80;
|
||||
TB = (byte)((RegDE.Low & 0x1) << 4);
|
||||
RegDE.Low = (byte)((RegDE.Low >> 1) | (FlagC ? 0x80 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegDE.Low == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x1C: // RR H
|
||||
TB = (byte)((RegHL.High & 0x1) << 4);
|
||||
RegHL.High = (byte)((RegHL.High >> 1) | (FlagC ? 0x80 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegHL.High == 0) RegAF.Low |= 0x80;
|
||||
TB = (byte)((RegHL.High & 0x1) << 4);
|
||||
RegHL.High = (byte)((RegHL.High >> 1) | (FlagC ? 0x80 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegHL.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x1D: // RR L
|
||||
TB = (byte)((RegHL.Low & 0x1) << 4);
|
||||
RegHL.Low = (byte)((RegHL.Low >> 1) | (FlagC ? 0x80 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegHL.Low == 0) RegAF.Low |= 0x80;
|
||||
TB = (byte)((RegHL.Low & 0x1) << 4);
|
||||
RegHL.Low = (byte)((RegHL.Low >> 1) | (FlagC ? 0x80 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegHL.Low == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x1E: // RR (HL)
|
||||
TB2 = ReadMemory(RegHL.Word);
|
||||
TB = (byte)((TB2 & 0x1) << 4);
|
||||
TB2 = (byte)((TB2 >> 1) | (FlagC ? 0x80 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (TB2 == 0) RegAF.Low |= 0x80;
|
||||
WriteMemory(RegHL.Word, TB2);
|
||||
TB2 = ReadMemory(RegHL.Word);
|
||||
TB = (byte)((TB2 & 0x1) << 4);
|
||||
TB2 = (byte)((TB2 >> 1) | (FlagC ? 0x80 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (TB2 == 0) RegAF.Low |= 0x80;
|
||||
WriteMemory(RegHL.Word, TB2);
|
||||
break;
|
||||
case 0x1F: // RR A
|
||||
TB = (byte)((RegAF.High & 0x1) << 4);
|
||||
RegAF.High = (byte)((RegAF.High >> 1) | (FlagC ? 0x80 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegAF.High == 0) RegAF.Low |= 0x80;
|
||||
TB = (byte)((RegAF.High & 0x1) << 4);
|
||||
RegAF.High = (byte)((RegAF.High >> 1) | (FlagC ? 0x80 : 0));
|
||||
RegAF.Low = TB;
|
||||
if (RegAF.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x20: // SLA B
|
||||
RegAF.Low = 0;
|
||||
if ((RegBC.High & 0x80) != 0) RegAF.Low |= 0x10;
|
||||
RegBC.High <<= 1;
|
||||
if (RegBC.High == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = 0;
|
||||
if ((RegBC.High & 0x80) != 0) RegAF.Low |= 0x10;
|
||||
RegBC.High <<= 1;
|
||||
if (RegBC.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x21: // SLA C
|
||||
RegAF.Low = 0;
|
||||
if ((RegBC.Low & 0x80) != 0) RegAF.Low |= 0x10;
|
||||
RegBC.Low <<= 1;
|
||||
if (RegBC.Low == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = 0;
|
||||
if ((RegBC.Low & 0x80) != 0) RegAF.Low |= 0x10;
|
||||
RegBC.Low <<= 1;
|
||||
if (RegBC.Low == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x22: // SLA D
|
||||
RegAF.Low = 0;
|
||||
if ((RegDE.High & 0x80) != 0) RegAF.Low |= 0x10;
|
||||
RegDE.High <<= 1;
|
||||
if (RegDE.High == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = 0;
|
||||
if ((RegDE.High & 0x80) != 0) RegAF.Low |= 0x10;
|
||||
RegDE.High <<= 1;
|
||||
if (RegDE.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x23: // SLA E
|
||||
RegAF.Low = 0;
|
||||
if ((RegDE.Low & 0x80) != 0) RegAF.Low |= 0x10;
|
||||
RegDE.Low <<= 1;
|
||||
if (RegDE.Low == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = 0;
|
||||
if ((RegDE.Low & 0x80) != 0) RegAF.Low |= 0x10;
|
||||
RegDE.Low <<= 1;
|
||||
if (RegDE.Low == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x24: // SLA H
|
||||
RegAF.Low = 0;
|
||||
if ((RegHL.High & 0x80) != 0) RegAF.Low |= 0x10;
|
||||
RegHL.High <<= 1;
|
||||
if (RegHL.High == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = 0;
|
||||
if ((RegHL.High & 0x80) != 0) RegAF.Low |= 0x10;
|
||||
RegHL.High <<= 1;
|
||||
if (RegHL.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x25: // SLA L
|
||||
RegAF.Low = 0;
|
||||
if ((RegHL.Low & 0x80) != 0) RegAF.Low |= 0x10;
|
||||
RegHL.Low <<= 1;
|
||||
if (RegHL.Low == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = 0;
|
||||
if ((RegHL.Low & 0x80) != 0) RegAF.Low |= 0x10;
|
||||
RegHL.Low <<= 1;
|
||||
if (RegHL.Low == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x26: // SLA (HL)
|
||||
TB = ReadMemory(RegHL.Word);
|
||||
RegAF.Low = 0;
|
||||
if ((TB & 0x80) != 0) RegAF.Low |= 0x10;
|
||||
TB <<= 1;
|
||||
if (TB == 0) RegAF.Low |= 0x80;
|
||||
WriteMemory(RegHL.Word, TB);
|
||||
TB = ReadMemory(RegHL.Word);
|
||||
RegAF.Low = 0;
|
||||
if ((TB & 0x80) != 0) RegAF.Low |= 0x10;
|
||||
TB <<= 1;
|
||||
if (TB == 0) RegAF.Low |= 0x80;
|
||||
WriteMemory(RegHL.Word, TB);
|
||||
break;
|
||||
case 0x27: // SLA A
|
||||
RegAF.Low = 0;
|
||||
if ((RegAF.High & 0x80) != 0) RegAF.Low |= 0x10;
|
||||
RegAF.High <<= 1;
|
||||
if (RegAF.High == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = 0;
|
||||
if ((RegAF.High & 0x80) != 0) RegAF.Low |= 0x10;
|
||||
RegAF.High <<= 1;
|
||||
if (RegAF.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x28: // SRA B
|
||||
RegAF.Low = 0;
|
||||
if ((RegBC.High & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegBC.High = (byte) ((RegBC.High >> 1) | (RegBC.High & 0x80));
|
||||
if (RegBC.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
RegAF.Low = 0;
|
||||
if ((RegBC.High & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegBC.High = (byte)((RegBC.High >> 1) | (RegBC.High & 0x80));
|
||||
if (RegBC.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x29: // SRA C
|
||||
RegAF.Low = 0;
|
||||
if ((RegBC.Low & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegBC.Low = (byte)((RegBC.Low >> 1) | (RegBC.Low & 0x80));
|
||||
if (RegBC.Low == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = 0;
|
||||
if ((RegBC.Low & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegBC.Low = (byte)((RegBC.Low >> 1) | (RegBC.Low & 0x80));
|
||||
if (RegBC.Low == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x2A: // SRA D
|
||||
RegAF.Low = 0;
|
||||
if ((RegDE.High & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegDE.High = (byte)((RegDE.High >> 1) | (RegDE.High & 0x80));
|
||||
if (RegDE.High == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = 0;
|
||||
if ((RegDE.High & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegDE.High = (byte)((RegDE.High >> 1) | (RegDE.High & 0x80));
|
||||
if (RegDE.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x2B: // SRA E
|
||||
RegAF.Low = 0;
|
||||
if ((RegDE.Low & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegDE.Low = (byte)((RegDE.Low >> 1) | (RegDE.Low & 0x80));
|
||||
if (RegDE.Low == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = 0;
|
||||
if ((RegDE.Low & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegDE.Low = (byte)((RegDE.Low >> 1) | (RegDE.Low & 0x80));
|
||||
if (RegDE.Low == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x2C: // SRA H
|
||||
RegAF.Low = 0;
|
||||
if ((RegHL.High & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegHL.High = (byte)((RegHL.High >> 1) | (RegHL.High & 0x80));
|
||||
if (RegHL.High == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = 0;
|
||||
if ((RegHL.High & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegHL.High = (byte)((RegHL.High >> 1) | (RegHL.High & 0x80));
|
||||
if (RegHL.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x2D: // SRA L
|
||||
RegAF.Low = 0;
|
||||
if ((RegHL.Low & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegHL.Low = (byte)((RegHL.Low >> 1) | (RegHL.Low & 0x80));
|
||||
if (RegHL.Low == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = 0;
|
||||
if ((RegHL.Low & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegHL.Low = (byte)((RegHL.Low >> 1) | (RegHL.Low & 0x80));
|
||||
if (RegHL.Low == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x2E: // SRA (HL)
|
||||
TB = ReadMemory(RegHL.Word);
|
||||
RegAF.Low = 0;
|
||||
if ((TB & 1) != 0) RegAF.Low |= 0x10;
|
||||
TB = (byte)((TB >> 1) | (TB & 0x80));
|
||||
if (TB == 0) RegAF.Low |= 0x80;
|
||||
WriteMemory(RegHL.Word, TB);
|
||||
TB = ReadMemory(RegHL.Word);
|
||||
RegAF.Low = 0;
|
||||
if ((TB & 1) != 0) RegAF.Low |= 0x10;
|
||||
TB = (byte)((TB >> 1) | (TB & 0x80));
|
||||
if (TB == 0) RegAF.Low |= 0x80;
|
||||
WriteMemory(RegHL.Word, TB);
|
||||
break;
|
||||
case 0x2F: // SRA A
|
||||
RegAF.Low = 0;
|
||||
if ((RegAF.High & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegAF.High = (byte)((RegAF.High >> 1) | (RegAF.High & 0x80));
|
||||
if (RegAF.High == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = 0;
|
||||
if ((RegAF.High & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegAF.High = (byte)((RegAF.High >> 1) | (RegAF.High & 0x80));
|
||||
if (RegAF.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x30: // SWAP B
|
||||
RegBC.High = SwapTable[RegBC.High];
|
||||
|
@ -1269,54 +1269,54 @@ namespace BizHawk.Emulation.CPUs.Z80GB
|
|||
FlagZ = (RegAF.High == 0);
|
||||
break;
|
||||
case 0x38: // SRL B
|
||||
RegAF.Low = 0;
|
||||
if ((RegBC.High & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegBC.High >>= 1;
|
||||
if (RegBC.High == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = 0;
|
||||
if ((RegBC.High & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegBC.High >>= 1;
|
||||
if (RegBC.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x39: // SRL C
|
||||
RegAF.Low = 0;
|
||||
if ((RegBC.Low & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegBC.Low >>= 1;
|
||||
if (RegBC.Low == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = 0;
|
||||
if ((RegBC.Low & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegBC.Low >>= 1;
|
||||
if (RegBC.Low == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x3A: // SRL D
|
||||
RegAF.Low = 0;
|
||||
if ((RegDE.High & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegDE.High >>= 1;
|
||||
if (RegDE.High == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = 0;
|
||||
if ((RegDE.High & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegDE.High >>= 1;
|
||||
if (RegDE.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x3B: // SRL E
|
||||
RegAF.Low = 0;
|
||||
if ((RegDE.Low & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegDE.Low >>= 1;
|
||||
if (RegDE.Low == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = 0;
|
||||
if ((RegDE.Low & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegDE.Low >>= 1;
|
||||
if (RegDE.Low == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x3C: // SRL H
|
||||
RegAF.Low = 0;
|
||||
if ((RegHL.High & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegHL.High >>= 1;
|
||||
if (RegHL.High == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = 0;
|
||||
if ((RegHL.High & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegHL.High >>= 1;
|
||||
if (RegHL.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x3D: // SRL L
|
||||
RegAF.Low = 0;
|
||||
if ((RegHL.Low & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegHL.Low >>= 1;
|
||||
if (RegHL.Low == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = 0;
|
||||
if ((RegHL.Low & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegHL.Low >>= 1;
|
||||
if (RegHL.Low == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x3E: // SRL (HL)
|
||||
TB = ReadMemory(RegHL.Word);
|
||||
RegAF.Low = 0;
|
||||
if ((TB & 1) != 0) RegAF.Low |= 0x10;
|
||||
TB >>= 1;
|
||||
if (TB == 0) RegAF.Low |= 0x80;
|
||||
WriteMemory(RegHL.Word, TB);
|
||||
TB = ReadMemory(RegHL.Word);
|
||||
RegAF.Low = 0;
|
||||
if ((TB & 1) != 0) RegAF.Low |= 0x10;
|
||||
TB >>= 1;
|
||||
if (TB == 0) RegAF.Low |= 0x80;
|
||||
WriteMemory(RegHL.Word, TB);
|
||||
break;
|
||||
case 0x3F: // SRL A
|
||||
RegAF.Low = 0;
|
||||
if ((RegAF.High & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegAF.High >>= 1;
|
||||
if (RegAF.High == 0) RegAF.Low |= 0x80;
|
||||
RegAF.Low = 0;
|
||||
if ((RegAF.High & 1) != 0) RegAF.Low |= 0x10;
|
||||
RegAF.High >>= 1;
|
||||
if (RegAF.High == 0) RegAF.Low |= 0x80;
|
||||
break;
|
||||
case 0x40: // BIT 0, B
|
||||
FlagZ = (RegBC.High & 0x01) == 0;
|
||||
|
@ -2247,7 +2247,7 @@ namespace BizHawk.Emulation.CPUs.Z80GB
|
|||
|
||||
void CheckIrq()
|
||||
{
|
||||
if (nonMaskableInterruptPending)
|
||||
if (nonMaskableInterruptPending)
|
||||
{
|
||||
halted = false;
|
||||
|
||||
|
|
|
@ -7,150 +7,157 @@ using System.IO;
|
|||
|
||||
namespace BizHawk.Emulation.CPUs.Z80GB
|
||||
{
|
||||
public sealed partial class Z80
|
||||
{
|
||||
public Z80()
|
||||
{
|
||||
public sealed partial class Z80
|
||||
{
|
||||
public Z80()
|
||||
{
|
||||
InitializeTables();
|
||||
Reset();
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
public void Reset()
|
||||
{
|
||||
ResetRegisters();
|
||||
ResetInterrupts();
|
||||
PendingCycles = 0;
|
||||
TotalExecutedCycles = 0;
|
||||
}
|
||||
|
||||
// Memory Access
|
||||
// Memory Access
|
||||
|
||||
public Func<ushort, byte> ReadMemory;
|
||||
public Action<ushort, byte> WriteMemory;
|
||||
private bool logging = false;
|
||||
public Func<ushort, byte> ReadMemory;
|
||||
public Action<ushort, byte> WriteMemory;
|
||||
private bool logging = true;
|
||||
private TextWriter log = File.CreateText("log.txt");
|
||||
|
||||
public void UnregisterMemoryMapper()
|
||||
{
|
||||
ReadMemory = null;
|
||||
WriteMemory = null;
|
||||
}
|
||||
public void UnregisterMemoryMapper()
|
||||
{
|
||||
ReadMemory = null;
|
||||
WriteMemory = null;
|
||||
}
|
||||
|
||||
// State Save/Load
|
||||
// State Save/Load
|
||||
|
||||
public void SaveStateText(TextWriter writer)
|
||||
{
|
||||
writer.WriteLine("[Z80]");
|
||||
writer.WriteLine("AF {0:X4}", RegAF.Word);
|
||||
writer.WriteLine("BC {0:X4}", RegBC.Word);
|
||||
writer.WriteLine("DE {0:X4}", RegDE.Word);
|
||||
writer.WriteLine("HL {0:X4}", RegHL.Word);
|
||||
writer.WriteLine("I {0:X2}", RegI);
|
||||
writer.WriteLine("SP {0:X4}", RegSP.Word);
|
||||
writer.WriteLine("PC {0:X4}", RegPC.Word);
|
||||
writer.WriteLine("IRQ {0}", interrupt);
|
||||
writer.WriteLine("NMI {0}", nonMaskableInterrupt);
|
||||
writer.WriteLine("NMIPending {0}", nonMaskableInterruptPending);
|
||||
writer.WriteLine("IM {0}", InterruptMode);
|
||||
writer.WriteLine("IFF1 {0}", IFF1);
|
||||
writer.WriteLine("IFF2 {0}", IFF2);
|
||||
writer.WriteLine("Halted {0}", Halted);
|
||||
writer.WriteLine("ExecutedCycles {0}", TotalExecutedCycles);
|
||||
writer.WriteLine("PendingCycles {0}", PendingCycles);
|
||||
writer.WriteLine("[/Z80]");
|
||||
writer.WriteLine();
|
||||
}
|
||||
public void SaveStateText(TextWriter writer)
|
||||
{
|
||||
writer.WriteLine("[Z80]");
|
||||
writer.WriteLine("AF {0:X4}", RegAF.Word);
|
||||
writer.WriteLine("BC {0:X4}", RegBC.Word);
|
||||
writer.WriteLine("DE {0:X4}", RegDE.Word);
|
||||
writer.WriteLine("HL {0:X4}", RegHL.Word);
|
||||
writer.WriteLine("I {0:X2}", RegI);
|
||||
writer.WriteLine("SP {0:X4}", RegSP.Word);
|
||||
writer.WriteLine("PC {0:X4}", RegPC.Word);
|
||||
writer.WriteLine("IRQ {0}", interrupt);
|
||||
writer.WriteLine("NMI {0}", nonMaskableInterrupt);
|
||||
writer.WriteLine("NMIPending {0}", nonMaskableInterruptPending);
|
||||
writer.WriteLine("IM {0}", InterruptMode);
|
||||
writer.WriteLine("IFF1 {0}", IFF1);
|
||||
writer.WriteLine("IFF2 {0}", IFF2);
|
||||
writer.WriteLine("Halted {0}", Halted);
|
||||
writer.WriteLine("ExecutedCycles {0}", TotalExecutedCycles);
|
||||
writer.WriteLine("PendingCycles {0}", PendingCycles);
|
||||
writer.WriteLine("[/Z80]");
|
||||
writer.WriteLine();
|
||||
}
|
||||
|
||||
public void LoadStateText(TextReader reader)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
string[] args = reader.ReadLine().Split(' ');
|
||||
if (args[0].Trim() == "") continue;
|
||||
if (args[0] == "[/Z80]") break;
|
||||
if (args[0] == "AF")
|
||||
RegAF.Word = ushort.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "BC")
|
||||
RegBC.Word = ushort.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "DE")
|
||||
RegDE.Word = ushort.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "HL")
|
||||
RegHL.Word = ushort.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "I")
|
||||
RegI = byte.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "SP")
|
||||
RegSP.Word = ushort.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "PC")
|
||||
RegPC.Word = ushort.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "IRQ")
|
||||
interrupt = bool.Parse(args[1]);
|
||||
else if (args[0] == "NMI")
|
||||
nonMaskableInterrupt = bool.Parse(args[1]);
|
||||
else if (args[0] == "NMIPending")
|
||||
nonMaskableInterruptPending = bool.Parse(args[1]);
|
||||
else if (args[0] == "IM")
|
||||
InterruptMode = int.Parse(args[1]);
|
||||
else if (args[0] == "IFF1")
|
||||
IFF1 = bool.Parse(args[1]);
|
||||
else if (args[0] == "IFF2")
|
||||
IFF2 = bool.Parse(args[1]);
|
||||
else if (args[0] == "Halted")
|
||||
Halted = bool.Parse(args[1]);
|
||||
else if (args[0] == "ExecutedCycles")
|
||||
TotalExecutedCycles = int.Parse(args[1]);
|
||||
else if (args[0] == "PendingCycles")
|
||||
PendingCycles = int.Parse(args[1]);
|
||||
public void LoadStateText(TextReader reader)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
string[] args = reader.ReadLine().Split(' ');
|
||||
if (args[0].Trim() == "") continue;
|
||||
if (args[0] == "[/Z80]") break;
|
||||
if (args[0] == "AF")
|
||||
RegAF.Word = ushort.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "BC")
|
||||
RegBC.Word = ushort.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "DE")
|
||||
RegDE.Word = ushort.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "HL")
|
||||
RegHL.Word = ushort.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "I")
|
||||
RegI = byte.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "SP")
|
||||
RegSP.Word = ushort.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "PC")
|
||||
RegPC.Word = ushort.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "IRQ")
|
||||
interrupt = bool.Parse(args[1]);
|
||||
else if (args[0] == "NMI")
|
||||
nonMaskableInterrupt = bool.Parse(args[1]);
|
||||
else if (args[0] == "NMIPending")
|
||||
nonMaskableInterruptPending = bool.Parse(args[1]);
|
||||
else if (args[0] == "IM")
|
||||
InterruptMode = int.Parse(args[1]);
|
||||
else if (args[0] == "IFF1")
|
||||
IFF1 = bool.Parse(args[1]);
|
||||
else if (args[0] == "IFF2")
|
||||
IFF2 = bool.Parse(args[1]);
|
||||
else if (args[0] == "Halted")
|
||||
Halted = bool.Parse(args[1]);
|
||||
else if (args[0] == "ExecutedCycles")
|
||||
TotalExecutedCycles = int.Parse(args[1]);
|
||||
else if (args[0] == "PendingCycles")
|
||||
PendingCycles = int.Parse(args[1]);
|
||||
|
||||
else
|
||||
Console.WriteLine("Skipping unrecognized identifier " + args[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
Console.WriteLine("Skipping unrecognized identifier " + args[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveStateBinary(BinaryWriter writer)
|
||||
{
|
||||
writer.Write(RegAF.Word);
|
||||
writer.Write(RegBC.Word);
|
||||
writer.Write(RegDE.Word);
|
||||
writer.Write(RegHL.Word);
|
||||
writer.Write(RegI);
|
||||
writer.Write(RegSP.Word);
|
||||
writer.Write(RegPC.Word);
|
||||
writer.Write(interrupt);
|
||||
writer.Write(nonMaskableInterrupt);
|
||||
writer.Write(nonMaskableInterruptPending);
|
||||
writer.Write(InterruptMode);
|
||||
writer.Write(IFF1);
|
||||
writer.Write(IFF2);
|
||||
writer.Write(Halted);
|
||||
writer.Write(TotalExecutedCycles);
|
||||
writer.Write(PendingCycles);
|
||||
}
|
||||
public void SaveStateBinary(BinaryWriter writer)
|
||||
{
|
||||
writer.Write(RegAF.Word);
|
||||
writer.Write(RegBC.Word);
|
||||
writer.Write(RegDE.Word);
|
||||
writer.Write(RegHL.Word);
|
||||
writer.Write(RegI);
|
||||
writer.Write(RegSP.Word);
|
||||
writer.Write(RegPC.Word);
|
||||
writer.Write(interrupt);
|
||||
writer.Write(nonMaskableInterrupt);
|
||||
writer.Write(nonMaskableInterruptPending);
|
||||
writer.Write(InterruptMode);
|
||||
writer.Write(IFF1);
|
||||
writer.Write(IFF2);
|
||||
writer.Write(Halted);
|
||||
writer.Write(TotalExecutedCycles);
|
||||
writer.Write(PendingCycles);
|
||||
}
|
||||
|
||||
public void LoadStateBinary(BinaryReader reader)
|
||||
{
|
||||
RegAF.Word = reader.ReadUInt16();
|
||||
RegBC.Word = reader.ReadUInt16();
|
||||
RegDE.Word = reader.ReadUInt16();
|
||||
RegHL.Word = reader.ReadUInt16();
|
||||
RegI = reader.ReadByte();
|
||||
RegSP.Word = reader.ReadUInt16();
|
||||
RegPC.Word = reader.ReadUInt16();
|
||||
interrupt = reader.ReadBoolean();
|
||||
nonMaskableInterrupt = reader.ReadBoolean();
|
||||
nonMaskableInterruptPending = reader.ReadBoolean();
|
||||
InterruptMode = reader.ReadInt32();
|
||||
IFF1 = reader.ReadBoolean();
|
||||
IFF2 = reader.ReadBoolean();
|
||||
Halted = reader.ReadBoolean();
|
||||
TotalExecutedCycles = reader.ReadInt32();
|
||||
PendingCycles = reader.ReadInt32();
|
||||
}
|
||||
public void LoadStateBinary(BinaryReader reader)
|
||||
{
|
||||
RegAF.Word = reader.ReadUInt16();
|
||||
RegBC.Word = reader.ReadUInt16();
|
||||
RegDE.Word = reader.ReadUInt16();
|
||||
RegHL.Word = reader.ReadUInt16();
|
||||
RegI = reader.ReadByte();
|
||||
RegSP.Word = reader.ReadUInt16();
|
||||
RegPC.Word = reader.ReadUInt16();
|
||||
interrupt = reader.ReadBoolean();
|
||||
nonMaskableInterrupt = reader.ReadBoolean();
|
||||
nonMaskableInterruptPending = reader.ReadBoolean();
|
||||
InterruptMode = reader.ReadInt32();
|
||||
IFF1 = reader.ReadBoolean();
|
||||
IFF2 = reader.ReadBoolean();
|
||||
Halted = reader.ReadBoolean();
|
||||
TotalExecutedCycles = reader.ReadInt32();
|
||||
PendingCycles = reader.ReadInt32();
|
||||
}
|
||||
|
||||
private void LogCPU()
|
||||
{
|
||||
if (!logging)
|
||||
return;
|
||||
SaveStateText(log);
|
||||
log.WriteLine("AF {0:X4}", RegAF.Word);
|
||||
log.WriteLine("BC {0:X4}", RegBC.Word);
|
||||
log.WriteLine("DE {0:X4}", RegDE.Word);
|
||||
log.WriteLine("HL {0:X4}", RegHL.Word);
|
||||
log.WriteLine("SP {0:X4}", RegSP.Word);
|
||||
log.WriteLine("PC {0:X4}", RegPC.Word);
|
||||
log.WriteLine("------");
|
||||
log.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -277,8 +277,6 @@ namespace BizHawk.Emulation.Consoles.Gameboy
|
|||
HardReset();
|
||||
}
|
||||
|
||||
public bool BootFromBios = true;
|
||||
|
||||
public void HardReset()
|
||||
{
|
||||
Cpu = new CPUs.Z80GB.Z80();
|
||||
|
@ -296,13 +294,13 @@ namespace BizHawk.Emulation.Consoles.Gameboy
|
|||
{
|
||||
case ESystemType.GB:
|
||||
case ESystemType.SGB:
|
||||
Cpu.RegisterAF = 0x01;
|
||||
Cpu.RegisterA = 0x01;
|
||||
break;
|
||||
case ESystemType.GBP:
|
||||
Cpu.RegisterAF = 0xFF;
|
||||
Cpu.RegisterA = 0xFF;
|
||||
break;
|
||||
case ESystemType.GBC:
|
||||
Cpu.RegisterAF = 0x11;
|
||||
Cpu.RegisterA = 0x11;
|
||||
break;
|
||||
case ESystemType.GBA:
|
||||
throw new NotImplementedException(); //decide what to do
|
||||
|
@ -315,8 +313,8 @@ namespace BizHawk.Emulation.Consoles.Gameboy
|
|||
Cpu.RegisterDE = 0x00D8;
|
||||
Cpu.RegisterHL = 0x014D;
|
||||
Cpu.RegisterSP = 0xFFFE;
|
||||
if (BootFromBios) Cpu.RegisterPC = 0x0000;
|
||||
else Cpu.RegisterPC = 0x0100;
|
||||
if (skipBIOS) Cpu.RegisterPC = 0x0100;
|
||||
else Cpu.RegisterPC = 0x0000;
|
||||
|
||||
WRam = new byte[32 * 1024]; //GB has 4KB of WRam; GBC has 32KB of WRam
|
||||
SRam = new byte[8 * 1024]; //different carts may have different amounts of this
|
||||
|
@ -336,11 +334,11 @@ namespace BizHawk.Emulation.Consoles.Gameboy
|
|||
private void SetupMemoryDomains()
|
||||
{
|
||||
var domains = new List<MemoryDomain>(1);
|
||||
|
||||
|
||||
var SystemBusDomain = new MemoryDomain("System Bus", 0x10000, Endian.Little,
|
||||
addr => Cpu.ReadMemory((ushort)addr),
|
||||
(addr, value) => Cpu.WriteMemory((ushort)addr, value));
|
||||
|
||||
|
||||
var WRAM0Domain = new MemoryDomain("WRAM Bank 0", 0x2000, Endian.Little,
|
||||
addr => WRam[addr & 0x1FFF],
|
||||
(addr, value) => WRam[addr & 0x1FFF] = value);
|
||||
|
@ -377,7 +375,7 @@ namespace BizHawk.Emulation.Consoles.Gameboy
|
|||
domains.Add(OAMDomain);
|
||||
domains.Add(HRAMDomain);
|
||||
domains.Add(SystemBusDomain);
|
||||
|
||||
|
||||
memoryDomains = domains.AsReadOnly();
|
||||
}
|
||||
|
||||
|
@ -450,7 +448,7 @@ namespace BizHawk.Emulation.Consoles.Gameboy
|
|||
{
|
||||
switch (addr)
|
||||
{
|
||||
case 0xFF00: //REG_P1 - Register for reading joy pad info and determining system type. (R/W)
|
||||
case 0xFF00: //REG_P1 - Register for reading joy pad info and determining system type. (R/W)
|
||||
return Registers.Input.Read();
|
||||
case 0xFF01: //REG_SB - Serial transfer data (R/W)
|
||||
return 0xFF;
|
||||
|
@ -565,7 +563,7 @@ namespace BizHawk.Emulation.Consoles.Gameboy
|
|||
{
|
||||
switch (addr)
|
||||
{
|
||||
case 0xFF00: //REG_P1 - Register for reading joy pad info and determining system type. (R/W)
|
||||
case 0xFF00: //REG_P1 - Register for reading joy pad info and determining system type. (R/W)
|
||||
Registers.Input.Write(value);
|
||||
break;
|
||||
case 0xFF01: //REG_SB - Serial transfer data (R/W)
|
||||
|
@ -724,7 +722,7 @@ namespace BizHawk.Emulation.Consoles.Gameboy
|
|||
get { return this; }
|
||||
}
|
||||
|
||||
public int[] GetVideoBuffer()
|
||||
public int[] GetVideoBuffer()
|
||||
{
|
||||
//TODO - these need to be run once per scanline and accumulated into a 160*144 byte buffer held by the core
|
||||
//then, in the call to GetVideoBuffer(), it gets adapted to gray according to the palette and returned
|
||||
|
@ -757,9 +755,9 @@ namespace BizHawk.Emulation.Consoles.Gameboy
|
|||
return buf;
|
||||
}
|
||||
|
||||
public int BufferWidth { get { return 160; } }
|
||||
public int BufferHeight { get { return 144; } }
|
||||
public int BackgroundColor { get { return 0; } }
|
||||
public int BufferWidth { get { return 160; } }
|
||||
public int BufferHeight { get { return 144; } }
|
||||
public int BackgroundColor { get { return 0; } }
|
||||
|
||||
public ISoundProvider SoundProvider
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue