diff --git a/BizHawk.Emulation/CPUs/Z80-GB/Execute.cs b/BizHawk.Emulation/CPUs/Z80-GB/Execute.cs index 26cea96064..019a25c2a1 100644 --- a/BizHawk.Emulation/CPUs/Z80-GB/Execute.cs +++ b/BizHawk.Emulation/CPUs/Z80-GB/Execute.cs @@ -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; diff --git a/BizHawk.Emulation/CPUs/Z80-GB/Z80.cs b/BizHawk.Emulation/CPUs/Z80-GB/Z80.cs index 9b78d4ea1f..694086cd55 100644 --- a/BizHawk.Emulation/CPUs/Z80-GB/Z80.cs +++ b/BizHawk.Emulation/CPUs/Z80-GB/Z80.cs @@ -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 ReadMemory; - public Action WriteMemory; - private bool logging = false; + public Func ReadMemory; + public Action 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(); } - } + } } \ No newline at end of file diff --git a/BizHawk.Emulation/Consoles/Gameboy/Gameboy.cs b/BizHawk.Emulation/Consoles/Gameboy/Gameboy.cs index 3be0fb3be4..b28107fa35 100644 --- a/BizHawk.Emulation/Consoles/Gameboy/Gameboy.cs +++ b/BizHawk.Emulation/Consoles/Gameboy/Gameboy.cs @@ -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(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 {