diff --git a/BizHawk.Emulation/BizHawk.Emulation.csproj b/BizHawk.Emulation/BizHawk.Emulation.csproj
index ec52725159..0ad74513c6 100644
--- a/BizHawk.Emulation/BizHawk.Emulation.csproj
+++ b/BizHawk.Emulation/BizHawk.Emulation.csproj
@@ -62,6 +62,7 @@
+
diff --git a/BizHawk.Emulation/CPUs/MOS 6502/Disassembler.cs b/BizHawk.Emulation/CPUs/MOS 6502/Disassembler.cs
index f65f1bcdf5..62dd9c3bf2 100644
--- a/BizHawk.Emulation/CPUs/MOS 6502/Disassembler.cs
+++ b/BizHawk.Emulation/CPUs/MOS 6502/Disassembler.cs
@@ -14,19 +14,24 @@ namespace BizHawk.Emulation.CPUs.M6502
{
case 0x00: bytesToAdvance = 1; return "BRK";
case 0x01: bytesToAdvance = 2; return string.Format("ORA (${0:X2},X)", ReadMemory(++pc));
+ case 0x04: bytesToAdvance = 2; return string.Format("NOP ${0:X2}", ReadMemory(++pc));
case 0x05: bytesToAdvance = 2; return string.Format("ORA ${0:X2}", ReadMemory(++pc));
case 0x06: bytesToAdvance = 2; return string.Format("ASL ${0:X2}", ReadMemory(++pc));
case 0x08: bytesToAdvance = 1; return "PHP";
case 0x09: bytesToAdvance = 2; return string.Format("ORA #${0:X2}", ReadMemory(++pc));
case 0x0A: bytesToAdvance = 1; return "ASL A";
+ case 0x0C: bytesToAdvance = 3; return string.Format("NOP (${0:X4})", ReadWord(++pc));
case 0x0D: bytesToAdvance = 3; return string.Format("ORA ${0:X4}", ReadWord(++pc));
case 0x0E: bytesToAdvance = 3; return string.Format("ASL ${0:X4}", ReadWord(++pc));
case 0x10: bytesToAdvance = 2; return string.Format("BPL {0}", (sbyte)ReadMemory(++pc));
case 0x11: bytesToAdvance = 2; return string.Format("ORA (${0:X2}),Y", ReadMemory(++pc));
+ case 0x14: bytesToAdvance = 2; return string.Format("NOP ${0:X2},X", ReadMemory(++pc));
case 0x15: bytesToAdvance = 2; return string.Format("ORA ${0:X2},X", ReadMemory(++pc));
case 0x16: bytesToAdvance = 2; return string.Format("ASL ${0:X2},X", ReadMemory(++pc));
case 0x18: bytesToAdvance = 1; return "CLC";
case 0x19: bytesToAdvance = 3; return string.Format("ORA ${0:X4},Y", ReadWord(++pc));
+ case 0x1A: bytesToAdvance = 1; return "NOP";
+ case 0x1C: bytesToAdvance = 2; return string.Format("NOP (${0:X2},X)", ReadMemory(++pc));
case 0x1D: bytesToAdvance = 3; return string.Format("ORA ${0:X4},X", ReadWord(++pc));
case 0x1E: bytesToAdvance = 3; return string.Format("ASL ${0:X4},X", ReadWord(++pc));
case 0x20: bytesToAdvance = 3; return string.Format("JSR ${0:X4}", ReadWord(++pc));
@@ -42,14 +47,18 @@ namespace BizHawk.Emulation.CPUs.M6502
case 0x2E: bytesToAdvance = 3; return string.Format("ROL ${0:X4}", ReadWord(++pc));
case 0x30: bytesToAdvance = 2; return string.Format("BMI {0}", (sbyte)ReadMemory(++pc));
case 0x31: bytesToAdvance = 2; return string.Format("AND (${0:X2}),Y", ReadMemory(++pc));
+ case 0x34: bytesToAdvance = 2; return string.Format("NOP ${0:X2},X", ReadMemory(++pc));
case 0x35: bytesToAdvance = 2; return string.Format("AND ${0:X2},X", ReadMemory(++pc));
case 0x36: bytesToAdvance = 2; return string.Format("ROL ${0:X2},X", ReadMemory(++pc));
case 0x38: bytesToAdvance = 1; return "SEC";
case 0x39: bytesToAdvance = 3; return string.Format("AND ${0:X4},Y", ReadWord(++pc));
+ case 0x3A: bytesToAdvance = 1; return "NOP";
+ case 0x3C: bytesToAdvance = 2; return string.Format("NOP (${0:X2},X)", ReadMemory(++pc));
case 0x3D: bytesToAdvance = 3; return string.Format("AND ${0:X4},X", ReadWord(++pc));
case 0x3E: bytesToAdvance = 3; return string.Format("ROL ${0:X4},X", ReadWord(++pc));
case 0x40: bytesToAdvance = 1; return "RTI";
case 0x41: bytesToAdvance = 2; return string.Format("EOR (${0:X2},X)", ReadMemory(++pc));
+ case 0x44: bytesToAdvance = 2; return string.Format("NOP ${0:X2}", ReadMemory(++pc));
case 0x45: bytesToAdvance = 2; return string.Format("EOR ${0:X2}", ReadMemory(++pc));
case 0x46: bytesToAdvance = 2; return string.Format("LSR ${0:X2}", ReadMemory(++pc));
case 0x48: bytesToAdvance = 1; return "PHA";
@@ -60,14 +69,18 @@ namespace BizHawk.Emulation.CPUs.M6502
case 0x4E: bytesToAdvance = 3; return string.Format("LSR ${0:X4}", ReadWord(++pc));
case 0x50: bytesToAdvance = 2; return string.Format("BVC {0}", (sbyte)ReadMemory(++pc));
case 0x51: bytesToAdvance = 2; return string.Format("EOR (${0:X2}),Y", ReadMemory(++pc));
+ case 0x54: bytesToAdvance = 2; return string.Format("NOP ${0:X2},X", ReadMemory(++pc));
case 0x55: bytesToAdvance = 2; return string.Format("EOR ${0:X2},X", ReadMemory(++pc));
case 0x56: bytesToAdvance = 2; return string.Format("LSR ${0:X2},X", ReadMemory(++pc));
case 0x58: bytesToAdvance = 1; return "CLI";
case 0x59: bytesToAdvance = 3; return string.Format("EOR ${0:X4},Y", ReadWord(++pc));
+ case 0x5A: bytesToAdvance = 1; return "NOP";
+ case 0x5C: bytesToAdvance = 2; return string.Format("NOP (${0:X2},X)", ReadMemory(++pc));
case 0x5D: bytesToAdvance = 3; return string.Format("EOR ${0:X4},X", ReadWord(++pc));
case 0x5E: bytesToAdvance = 3; return string.Format("LSR ${0:X4},X", ReadWord(++pc));
case 0x60: bytesToAdvance = 1; return "RTS";
case 0x61: bytesToAdvance = 2; return string.Format("ADC (${0:X2},X)", ReadMemory(++pc));
+ case 0x64: bytesToAdvance = 2; return string.Format("NOP ${0:X2}", ReadMemory(++pc));
case 0x65: bytesToAdvance = 2; return string.Format("ADC ${0:X2}", ReadMemory(++pc));
case 0x66: bytesToAdvance = 2; return string.Format("ROR ${0:X2}", ReadMemory(++pc));
case 0x68: bytesToAdvance = 1; return "PLA";
@@ -78,17 +91,23 @@ namespace BizHawk.Emulation.CPUs.M6502
case 0x6E: bytesToAdvance = 3; return string.Format("ROR ${0:X4}", ReadWord(++pc));
case 0x70: bytesToAdvance = 2; return string.Format("BVS {0}", (sbyte)ReadMemory(++pc));
case 0x71: bytesToAdvance = 2; return string.Format("ADC (${0:X2}),Y", ReadMemory(++pc));
+ case 0x74: bytesToAdvance = 2; return string.Format("NOP ${0:X2},X", ReadMemory(++pc));
case 0x75: bytesToAdvance = 2; return string.Format("ADC ${0:X2},X", ReadMemory(++pc));
case 0x76: bytesToAdvance = 2; return string.Format("ROR ${0:X2},X", ReadMemory(++pc));
case 0x78: bytesToAdvance = 1; return "SEI";
case 0x79: bytesToAdvance = 3; return string.Format("ADC ${0:X4},Y", ReadWord(++pc));
+ case 0x7A: bytesToAdvance = 1; return "NOP";
+ case 0x7C: bytesToAdvance = 2; return string.Format("NOP (${0:X2},X)", ReadMemory(++pc));
case 0x7D: bytesToAdvance = 3; return string.Format("ADC ${0:X4},X", ReadWord(++pc));
case 0x7E: bytesToAdvance = 3; return string.Format("ROR ${0:X4},X", ReadWord(++pc));
+ case 0x80: bytesToAdvance = 2; return string.Format("NOP #${0:X2}", ReadMemory(++pc));
case 0x81: bytesToAdvance = 2; return string.Format("STA (${0:X2},X)", ReadMemory(++pc));
+ case 0x82: bytesToAdvance = 2; return string.Format("NOP #${0:X2}", ReadMemory(++pc));
case 0x84: bytesToAdvance = 2; return string.Format("STY ${0:X2}", ReadMemory(++pc));
case 0x85: bytesToAdvance = 2; return string.Format("STA ${0:X2}", ReadMemory(++pc));
case 0x86: bytesToAdvance = 2; return string.Format("STX ${0:X2}", ReadMemory(++pc));
case 0x88: bytesToAdvance = 1; return "DEY";
+ case 0x89: bytesToAdvance = 2; return string.Format("NOP #${0:X2}", ReadMemory(++pc));
case 0x8A: bytesToAdvance = 1; return "TXA";
case 0x8C: bytesToAdvance = 3; return string.Format("STY ${0:X4}", ReadWord(++pc));
case 0x8D: bytesToAdvance = 3; return string.Format("STA ${0:X4}", ReadWord(++pc));
@@ -127,6 +146,7 @@ namespace BizHawk.Emulation.CPUs.M6502
case 0xBE: bytesToAdvance = 3; return string.Format("LDX ${0:X4},Y", ReadWord(++pc));
case 0xC0: bytesToAdvance = 2; return string.Format("CPY #${0:X2}", ReadMemory(++pc));
case 0xC1: bytesToAdvance = 2; return string.Format("CMP (${0:X2},X)", ReadMemory(++pc));
+ case 0xC2: bytesToAdvance = 2; return string.Format("NOP #${0:X2}", ReadMemory(++pc));
case 0xC4: bytesToAdvance = 2; return string.Format("CPY ${0:X2}", ReadMemory(++pc));
case 0xC5: bytesToAdvance = 2; return string.Format("CMP ${0:X2}", ReadMemory(++pc));
case 0xC6: bytesToAdvance = 2; return string.Format("DEC ${0:X2}", ReadMemory(++pc));
@@ -138,14 +158,18 @@ namespace BizHawk.Emulation.CPUs.M6502
case 0xCE: bytesToAdvance = 3; return string.Format("DEC ${0:X4}", ReadWord(++pc));
case 0xD0: bytesToAdvance = 2; return string.Format("BNE {0}", (sbyte)ReadMemory(++pc));
case 0xD1: bytesToAdvance = 2; return string.Format("CMP (${0:X2}),Y", ReadMemory(++pc));
+ case 0xD4: bytesToAdvance = 2; return string.Format("NOP ${0:X2},X", ReadMemory(++pc));
case 0xD5: bytesToAdvance = 2; return string.Format("CMP ${0:X2},X", ReadMemory(++pc));
case 0xD6: bytesToAdvance = 2; return string.Format("DEC ${0:X2},X", ReadMemory(++pc));
case 0xD8: bytesToAdvance = 1; return "CLD";
case 0xD9: bytesToAdvance = 3; return string.Format("CMP ${0:X4},Y", ReadWord(++pc));
+ case 0xDA: bytesToAdvance = 1; return "NOP";
+ case 0xDC: bytesToAdvance = 2; return string.Format("NOP (${0:X2},X)", ReadMemory(++pc));
case 0xDD: bytesToAdvance = 3; return string.Format("CMP ${0:X4},X", ReadWord(++pc));
case 0xDE: bytesToAdvance = 3; return string.Format("DEC ${0:X4},X", ReadWord(++pc));
case 0xE0: bytesToAdvance = 2; return string.Format("CPX #${0:X2}", ReadMemory(++pc));
case 0xE1: bytesToAdvance = 2; return string.Format("SBC (${0:X2},X)", ReadMemory(++pc));
+ case 0xE2: bytesToAdvance = 2; return string.Format("NOP #${0:X2}", ReadMemory(++pc));
case 0xE4: bytesToAdvance = 2; return string.Format("CPX ${0:X2}", ReadMemory(++pc));
case 0xE5: bytesToAdvance = 2; return string.Format("SBC ${0:X2}", ReadMemory(++pc));
case 0xE6: bytesToAdvance = 2; return string.Format("INC ${0:X2}", ReadMemory(++pc));
@@ -157,10 +181,13 @@ namespace BizHawk.Emulation.CPUs.M6502
case 0xEE: bytesToAdvance = 3; return string.Format("INC ${0:X4}", ReadWord(++pc));
case 0xF0: bytesToAdvance = 2; return string.Format("BEQ {0}", (sbyte)ReadMemory(++pc));
case 0xF1: bytesToAdvance = 2; return string.Format("SBC (${0:X2}),Y", ReadMemory(++pc));
+ case 0xF4: bytesToAdvance = 2; return string.Format("NOP ${0:X2},X", ReadMemory(++pc));
case 0xF5: bytesToAdvance = 2; return string.Format("SBC ${0:X2},X", ReadMemory(++pc));
case 0xF6: bytesToAdvance = 2; return string.Format("INC ${0:X2},X", ReadMemory(++pc));
case 0xF8: bytesToAdvance = 1; return "SED";
case 0xF9: bytesToAdvance = 3; return string.Format("SBC ${0:X4},Y", ReadWord(++pc));
+ case 0xFA: bytesToAdvance = 1; return "NOP";
+ case 0xFC: bytesToAdvance = 2; return string.Format("NOP (${0:X2},X)", ReadMemory(++pc));
case 0xFD: bytesToAdvance = 3; return string.Format("SBC ${0:X4},X", ReadWord(++pc));
case 0xFE: bytesToAdvance = 3; return string.Format("INC ${0:X4},X", ReadWord(++pc));
}
diff --git a/BizHawk.Emulation/CPUs/MOS 6502/Execute.cs b/BizHawk.Emulation/CPUs/MOS 6502/Execute.cs
index 9a8cfe6fe0..e21d4dee46 100644
--- a/BizHawk.Emulation/CPUs/MOS 6502/Execute.cs
+++ b/BizHawk.Emulation/CPUs/MOS 6502/Execute.cs
@@ -38,6 +38,9 @@ TriggerException(ExceptionType.BRK);
P = (byte)((P & 0x7D) | TableNZ[A]);
PendingCycles -= 6; TotalExecutedCycles += 6;
break;
+ case 0x04: // NOP zp
+ PendingCycles -= 3; TotalExecutedCycles += 3;
+ break;
case 0x05: // ORA zp
value8 = ReadMemory(ReadMemory(PC++));
A |= value8;
@@ -69,6 +72,9 @@ TriggerException(ExceptionType.BRK);
P = (byte)((P & 0x7D) | TableNZ[A]);
PendingCycles -= 2; TotalExecutedCycles += 2;
break;
+ case 0x0C: // NOP (addr)
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
case 0x0D: // ORA addr
value8 = ReadMemory(ReadWord(PC)); PC += 2;
A |= value8;
@@ -104,6 +110,9 @@ TriggerException(ExceptionType.BRK);
P = (byte)((P & 0x7D) | TableNZ[A]);
PendingCycles -= 5; TotalExecutedCycles += 5;
break;
+ case 0x14: // NOP zp,X
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
case 0x15: // ORA zp,X
value8 = ReadMemory((byte)(ReadMemory(PC++)+X));
A |= value8;
@@ -132,6 +141,12 @@ TriggerException(ExceptionType.BRK);
P = (byte)((P & 0x7D) | TableNZ[A]);
PendingCycles -= 4; TotalExecutedCycles += 4;
break;
+ case 0x1A: // NOP
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x1C: // NOP (addr,X)
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
case 0x1D: // ORA addr,X
value8 = ReadMemory((ushort)(ReadWord(PC)+X));
if ((PC & 0xFF00) != ((PC+Y) & 0xFF00))
@@ -248,6 +263,9 @@ FlagT = true;//this seems wrong
P = (byte)((P & 0x7D) | TableNZ[A]);
PendingCycles -= 5; TotalExecutedCycles += 5;
break;
+ case 0x34: // NOP zp,X
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
case 0x35: // AND zp,X
value8 = ReadMemory((byte)(ReadMemory(PC++)+X));
A &= value8;
@@ -276,6 +294,12 @@ FlagT = true;//this seems wrong
P = (byte)((P & 0x7D) | TableNZ[A]);
PendingCycles -= 4; TotalExecutedCycles += 4;
break;
+ case 0x3A: // NOP
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x3C: // NOP (addr,X)
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
case 0x3D: // AND addr,X
value8 = ReadMemory((ushort)(ReadWord(PC)+X));
if ((PC & 0xFF00) != ((PC+Y) & 0xFF00))
@@ -310,6 +334,9 @@ FlagT = true;// this seems wrong
P = (byte)((P & 0x7D) | TableNZ[A]);
PendingCycles -= 6; TotalExecutedCycles += 6;
break;
+ case 0x44: // NOP zp
+ PendingCycles -= 3; TotalExecutedCycles += 3;
+ break;
case 0x45: // EOR zp
value8 = ReadMemory(ReadMemory(PC++));
A ^= value8;
@@ -380,6 +407,9 @@ FlagT = true;// this seems wrong
P = (byte)((P & 0x7D) | TableNZ[A]);
PendingCycles -= 5; TotalExecutedCycles += 5;
break;
+ case 0x54: // NOP zp,X
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
case 0x55: // EOR zp,X
value8 = ReadMemory((byte)(ReadMemory(PC++)+X));
A ^= value8;
@@ -408,6 +438,12 @@ FlagT = true;// this seems wrong
P = (byte)((P & 0x7D) | TableNZ[A]);
PendingCycles -= 4; TotalExecutedCycles += 4;
break;
+ case 0x5A: // NOP
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x5C: // NOP (addr,X)
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
case 0x5D: // EOR addr,X
value8 = ReadMemory((ushort)(ReadWord(PC)+X));
if ((PC & 0xFF00) != ((PC+Y) & 0xFF00))
@@ -444,6 +480,9 @@ FlagT = true;// this seems wrong
P = (byte)((P & 0x7D) | TableNZ[A]);
PendingCycles -= 6; TotalExecutedCycles += 6;
break;
+ case 0x64: // NOP zp
+ PendingCycles -= 3; TotalExecutedCycles += 3;
+ break;
case 0x65: // ADC zp
value8 = ReadMemory(ReadMemory(PC++));
temp = value8 + A + (FlagC ? 1 : 0);
@@ -528,6 +567,9 @@ FlagT = true;// this seems wrong
P = (byte)((P & 0x7D) | TableNZ[A]);
PendingCycles -= 5; TotalExecutedCycles += 5;
break;
+ case 0x74: // NOP zp,X
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
case 0x75: // ADC zp,X
value8 = ReadMemory((byte)(ReadMemory(PC++)+X));
temp = value8 + A + (FlagC ? 1 : 0);
@@ -562,6 +604,12 @@ FlagT = true;// this seems wrong
P = (byte)((P & 0x7D) | TableNZ[A]);
PendingCycles -= 4; TotalExecutedCycles += 4;
break;
+ case 0x7A: // NOP
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x7C: // NOP (addr,X)
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
case 0x7D: // ADC addr,X
value8 = ReadMemory((ushort)(ReadWord(PC)+X));
if ((PC & 0xFF00) != ((PC+Y) & 0xFF00))
@@ -586,11 +634,17 @@ FlagT = true;// this seems wrong
P = (byte)((P & 0x7D) | TableNZ[value8]);
PendingCycles -= 7; TotalExecutedCycles += 7;
break;
+ case 0x80: // NOP #nn
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
case 0x81: // STA (addr,X)
value16 = ReadWordPageWrap((byte)(ReadMemory(PC++)+X));
WriteMemory(value16, A);
PendingCycles -= 6; TotalExecutedCycles += 6;
break;
+ case 0x82: // NOP #nn
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
case 0x84: // STY zp
value16 = ReadMemory(PC++);
WriteMemory(value16, Y);
@@ -610,6 +664,9 @@ FlagT = true;// this seems wrong
P = (byte)((P & 0x7D) | TableNZ[--Y]);
PendingCycles -= 2; TotalExecutedCycles += 2;
break;
+ case 0x89: // NOP #nn
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
case 0x8A: // TXA
A = X;
P = (byte)((P & 0x7D) | TableNZ[A]);
@@ -838,6 +895,9 @@ FlagT = true;// this seems wrong
P = (byte)((P & 0x7D) | TableNZ[(byte)value16]);
PendingCycles -= 6;
break;
+ case 0xC2: // NOP #nn
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
case 0xC4: // CPY zp
value8 = ReadMemory(ReadMemory(PC++));
value16 = (ushort) (Y - value8);
@@ -916,6 +976,9 @@ FlagT = true;// this seems wrong
P = (byte)((P & 0x7D) | TableNZ[(byte)value16]);
PendingCycles -= 5;
break;
+ case 0xD4: // NOP zp,X
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
case 0xD5: // CMP zp,X
value8 = ReadMemory((byte)(ReadMemory(PC++)+X));
value16 = (ushort) (A - value8);
@@ -944,6 +1007,12 @@ FlagT = true;// this seems wrong
P = (byte)((P & 0x7D) | TableNZ[(byte)value16]);
PendingCycles -= 4;
break;
+ case 0xDA: // NOP
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0xDC: // NOP (addr,X)
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
case 0xDD: // CMP addr,X
value8 = ReadMemory((ushort)(ReadWord(PC)+X));
if ((PC & 0xFF00) != ((PC+Y) & 0xFF00))
@@ -980,6 +1049,9 @@ FlagT = true;// this seems wrong
P = (byte)((P & 0x7D) | TableNZ[A]);
PendingCycles -= 6; TotalExecutedCycles += 6;
break;
+ case 0xE2: // NOP #nn
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
case 0xE4: // CPX zp
value8 = ReadMemory(ReadMemory(PC++));
value16 = (ushort) (X - value8);
@@ -1065,6 +1137,9 @@ FlagT = true;// this seems wrong
P = (byte)((P & 0x7D) | TableNZ[A]);
PendingCycles -= 5; TotalExecutedCycles += 5;
break;
+ case 0xF4: // NOP zp,X
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
case 0xF5: // SBC zp,X
value8 = ReadMemory((byte)(ReadMemory(PC++)+X));
temp = A - value8 - (FlagC?0:1);
@@ -1097,6 +1172,12 @@ FlagT = true;// this seems wrong
P = (byte)((P & 0x7D) | TableNZ[A]);
PendingCycles -= 4; TotalExecutedCycles += 4;
break;
+ case 0xFA: // NOP
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0xFC: // NOP (addr,X)
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
case 0xFD: // SBC addr,X
value8 = ReadMemory((ushort)(ReadWord(PC)+X));
if ((PC & 0xFF00) != ((PC+Y) & 0xFF00))
@@ -1120,7 +1201,9 @@ FlagT = true;// this seems wrong
PendingCycles -= 7; TotalExecutedCycles += 7;
break;
default:
- throw new Exception(String.Format("Unhandled opcode: {0:X2}", opcode));
+ //throw new Exception(String.Format("Unhandled opcode: {0:X2}", opcode));
+ //Console.WriteLine(String.Format("Unhandled opcode: {0:X2}", opcode));
+ break;
}
}
}
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/BoardDetector.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/BoardDetector.cs
index b5f94f4cf7..280351f4f3 100644
--- a/BizHawk.Emulation/Consoles/Nintendo/NES/BoardDetector.cs
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/BoardDetector.cs
@@ -55,4 +55,19 @@ namespace BizHawk.Emulation.Consoles.Nintendo
}
}
-}
\ No newline at end of file
+}
+
+ //STD_SAROM = MakeId< 1, 64, 64, 8, 0, CRM_0, NMT_H, 0 >::ID,
+ //STD_SBROM = MakeId< 1, 64, 64, 0, 0, CRM_0, NMT_H, 0 >::ID,
+ //STD_SCROM = MakeId< 1, 64, 128, 0, 0, CRM_0, NMT_H, 0 >::ID,
+ //STD_SEROM = MakeId< 1, 32, 64, 0, 0, CRM_0, NMT_H, 0 >::ID,
+ //STD_SFROM = MakeId< 1, 256, 64, 0, 0, CRM_0, NMT_H, 0 >::ID,
+ //STD_SGROM = MakeId< 1, 256, 0, 0, 0, CRM_8, NMT_H, 0 >::ID,
+ //STD_SHROM = MakeId< 1, 32, 128, 0, 0, CRM_0, NMT_H, 0 >::ID,
+ //STD_SJROM = MakeId< 1, 256, 64, 8, 0, CRM_0, NMT_H, 0 >::ID,
+ //STD_SKROM = MakeId< 1, 256, 128, 8, 0, CRM_0, NMT_H, 0 >::ID,
+ //STD_SLROM = MakeId< 1, 256, 128, 0, 0, CRM_0, NMT_H, 0 >::ID,
+ //STD_SNROM = MakeId< 1, 256, 0, 8, 0, CRM_8, NMT_H, 0 >::ID,
+ //STD_SOROM = MakeId< 1, 256, 0, 8, 8, CRM_8, NMT_H, 0 >::ID,
+ //STD_SUROM = MakeId< 1, 512, 0, 8, 0, CRM_8, NMT_H, 0 >::ID,
+ //STD_SXROM = MakeId< 1, 512, 0, 32, 0, CRM_8, NMT_H, 0 >::ID,
\ No newline at end of file
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/GxROM.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/GxROM.cs
index 7cc2b31bff..fb50d311d3 100644
--- a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/GxROM.cs
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/GxROM.cs
@@ -3,6 +3,8 @@ using System.Diagnostics;
namespace BizHawk.Emulation.Consoles.Nintendo.Boards
{
+ //should this be called GNROM? there is no other Gx anything AFAIK..
+
public class GxROM : NES.NESBoardBase
{
int prg_mask, chr_mask;
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/SxROM.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/SxROM.cs
new file mode 100644
index 0000000000..86dbc2fa0f
--- /dev/null
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/SxROM.cs
@@ -0,0 +1,311 @@
+using System;
+using System.Diagnostics;
+
+namespace BizHawk.Emulation.Consoles.Nintendo.Boards
+{
+ //AKA MMC1
+ //http://wiki.nesdev.com/w/index.php/SxROM
+
+ //consult nestopia as well.
+ //the initial conditions for MMC1 games are known to be different. this may have to do with which MMC1 rev it is.
+ //but how do we know which revision a game is? i don't know which revision is on which board
+ //check UNIF for more information.. it may specify board and MMC1 rev independently because boards may have any MMC1 rev
+ //in that case, we need to capture MMC1 rev in the game database (maybe add a new `chip` parameter)
+
+ //this board is a little more convoluted than it might otherwise be because i switched to a more chip-centered way of modeling it partway through
+ //perhaps i will make other boards work that way, and perhaps not
+
+ class MMC1
+ {
+ public MMC1()
+ {
+ //collect data about whether this is required here:
+ //megaman 2 requires it
+ StandardReset();
+ }
+
+ public enum Rev
+ {
+ A, B1, B2, B3
+ }
+
+ //shift register
+ int shift_count, shift_val;
+
+ //register 0:
+ public int chr_mode;
+ public int prg_mode;
+ public int prg_slot; //complicated
+ public NES.EMirrorType mirror;
+ static NES.EMirrorType[] _mirrorTypes = new NES.EMirrorType[] { NES.EMirrorType.OneScreenA, NES.EMirrorType.OneScreenB, NES.EMirrorType.Vertical, NES.EMirrorType.Horizontal };
+
+ //register 1,2:
+ int chr_0, chr_1;
+
+ //register 3:
+ int wram_disable;
+ int prg;
+
+ void StandardReset()
+ {
+ prg_mode = 1;
+ prg_slot = 1;
+ }
+
+ public void Write(int addr, byte value)
+ {
+ int data = value & 1;
+ int reset = (value >> 7) & 1;
+ if (reset == 1)
+ {
+ shift_count = 0;
+ shift_val = 0;
+ StandardReset();
+ }
+ else
+ {
+ shift_val >>= 1;
+ shift_val |= (data<<4);
+ shift_count++;
+ if (shift_count == 5)
+ {
+ WriteRegister(addr >> 13, shift_val);
+ shift_count = 0;
+ shift_val = 0;
+ }
+ }
+ }
+
+ void WriteRegister(int addr, int value)
+ {
+ switch (addr)
+ {
+ case 0: //8000-9FFF
+ mirror = _mirrorTypes[value & 3];
+ prg_slot = ((value >> 2) & 1);
+ prg_mode = ((value >> 3) & 1);
+ chr_mode = ((value >> 4) & 1);
+ break;
+ case 1: //A000-BFFF
+ chr_0 = value & 0x1F;
+ break;
+ case 2: //C000-DFFF
+ chr_1 = value & 0x1F;
+ break;
+ case 3: //E000-FFFF
+ prg = value & 0xF;
+ wram_disable = (value >> 4) & 1;
+ break;
+ }
+ //Console.WriteLine("mapping.. chr_mode={0}, chr={1},{2}", chr_mode, chr_0, chr_1);
+ //Console.WriteLine("mapping.. prg_mode={0}, prg_slot{1}, prg={2}", prg_mode, prg_slot, prg);
+ }
+
+ public int Get_PRGBank(int addr)
+ {
+ int PRG_A14 = (addr >> 14) & 1;
+ if (prg_mode == 0)
+ if (PRG_A14 == 0)
+ return prg;
+ else
+ {
+ Debug.Assert(false, "not tested yet, and had to guess");
+ return (prg + 1) & 0xF;
+ }
+ else if (prg_slot == 0)
+ if (PRG_A14 == 0)
+ return 0;
+ else return prg;
+ else
+ if (PRG_A14 == 0)
+ return prg;
+ else return 0xF;
+ }
+
+ public int Get_CHRBank_4K(int addr)
+ {
+ int CHR_A12 = (addr >> 12) & 1;
+ if (chr_mode == 0)
+ return chr_0;
+ else if (CHR_A12 == 0)
+ return chr_0;
+ else return chr_1;
+ }
+ }
+
+ public class SxROM : NES.NESBoardBase
+ {
+ string type;
+ MMC1 mmc1;
+ int prg_mask, chr_mask;
+ byte[] cram, pram;
+ int cram_mask, pram_mask;
+
+
+ public SxROM(string type)
+ {
+ this.type = type;
+ mmc1 = new MMC1();
+ }
+
+ public override void Initialize(NES.RomInfo romInfo, NES nes)
+ {
+ base.Initialize(romInfo, nes);
+
+ Debug.Assert(RomInfo.PRG_Size == 8 || RomInfo.PRG_Size == 16);
+ prg_mask = RomInfo.PRG_Size - 1;
+
+ Debug.Assert(RomInfo.CRAM_Size == -1, "don't specify in gamedb, it is redundant");
+ Debug.Assert(RomInfo.PRAM_Size == -1, "don't specify in gamedb, it is redundant");
+
+ //analyze board type
+ switch (type)
+ {
+ case "SGROM":
+ Debug.Assert(RomInfo.CHR_Size == -1, "don't specify in gamedb, it is redundant");
+ romInfo.CHR_Size = 0; RomInfo.CRAM_Size = 8; romInfo.PRAM_Size = 0;
+ break;
+ case "SNROM":
+ Debug.Assert(RomInfo.CHR_Size == -1, "don't specify in gamedb, it is redundant");
+ romInfo.CHR_Size = 0; RomInfo.CRAM_Size = 8; RomInfo.PRAM_Size = 8;
+ break;
+ case "SL2ROM":
+ RomInfo.CRAM_Size = 0;
+ RomInfo.PRAM_Size = 0;
+ break;
+ default: throw new InvalidOperationException();
+ }
+
+ Debug.Assert(RomInfo.CRAM_Size == 0 || RomInfo.CRAM_Size == 8);
+ if (RomInfo.CRAM_Size != 0)
+ {
+ cram = new byte[RomInfo.CRAM_Size * 1024];
+ cram_mask = cram.Length - 1;
+ }
+
+ Debug.Assert(RomInfo.PRAM_Size == 0 || RomInfo.PRAM_Size == 8);
+ if (RomInfo.PRAM_Size != 0)
+ {
+ pram = new byte[RomInfo.CRAM_Size * 1024];
+ pram_mask = pram.Length - 1;
+ }
+
+ if (RomInfo.CHR_Size != 0)
+ {
+ Debug.Assert(RomInfo.CHR_Size == 16);
+ chr_mask = (RomInfo.CHR_Size*2) - 1;
+ }
+ }
+
+ public override void WritePRG(int addr, byte value)
+ {
+ mmc1.Write(addr, value);
+ SetMirrorType(mmc1.mirror); //often redundant, but gets the job done
+ }
+
+ public override byte ReadPRG(int addr)
+ {
+ int bank = mmc1.Get_PRGBank(addr) & prg_mask;
+ addr = (bank << 14) | (addr & 0x3FFF);
+ return RomInfo.ROM[addr];
+ }
+
+ int Gen_CHR_Address(int addr)
+ {
+ int bank = mmc1.Get_CHRBank_4K(addr);
+ addr = ((bank & chr_mask) << 12) | (addr & 0x0FFF);
+ return addr;
+ }
+
+ public override byte ReadPPU(int addr)
+ {
+ if (addr < 0x2000)
+ {
+ if (RomInfo.CRAM_Size != 0)
+ return cram[addr & cram_mask];
+ else return RomInfo.VROM[Gen_CHR_Address(addr)];
+ }
+ else return base.ReadPPU(addr);
+ }
+
+ public override void WritePPU(int addr, byte value)
+ {
+ if (addr < 0x2000)
+ {
+ if (RomInfo.CRAM_Size != 0)
+ cram[addr & cram_mask] = value;
+ }
+ else base.WritePPU(addr, value);
+ }
+
+ public override byte ReadPRAM(int addr)
+ {
+ if (RomInfo.PRAM_Size != 0)
+ return pram[addr & pram_mask];
+ else return 0xFF;
+ }
+
+ public override void WritePRAM(int addr, byte value)
+ {
+ if (RomInfo.PRAM_Size != 0)
+ pram[addr & pram_mask] = value;
+ }
+
+ public override byte[] SaveRam
+ {
+ get
+ {
+ if (!RomInfo.Battery) return null;
+ return pram;
+ //some boards have a pram that is backed-up or not backed-up. need to handle that somehow
+ //(nestopia splits it into NVWRAM and WRAM but i didnt like that at first.. but it may player better with this architecture)
+ }
+ }
+
+
+ }
+}
+
+//http://wiki.nesdev.com/w/index.php/Cartridge_connector
+//http://benheck.com/Downloads/NES_Famicom_Pinouts.pdf
+//http://kevtris.org/mappers/mmc1/index.html
+//one day, i will redo mappers at the pin level and it will look something like this:
+//public void Strobe(int PRG_A, int PRG_D, int PRG_READ, int CHR_A)
+//{
+// if (PRG_READ == 1)
+// {
+// int PRG_A14 = (PRG_A >> 14) & 1;
+
+// int tmp_prg_A17_A14;
+// if (prg_mode == 0)
+// if (PRG_A14 == 0)
+// tmp_prg_A17_A14 = prg;
+// else
+// tmp_prg_A17_A14 = ((prg + 1) & 0xF);
+// else if (prg_slot == 0)
+// if (PRG_A14 == 0) tmp_prg_A17_A14 = 0;
+// else tmp_prg_A17_A14 = prg;
+// else if (PRG_A14 == 0)
+// tmp_prg_A17_A14 = prg;
+// else tmp_prg_A17_A14 = 0xF;
+
+// out_PRG_A = PRG_A;
+// out_PRG_A &= ~0x4000;
+// out_PRG_A |= (tmp_prg_A17_A14 << 14);
+// }
+//}
+//public int Read_CHR_A(int addr)
+//{
+// int CHR_A10 = (addr >> 10) & 1;
+// int CHR_A11 = (addr >> 10) & 1;
+// int out_CIRAM_A10;
+// switch (mirror)
+// {
+// case 0: out_CIRAM_A10 = 0; break;
+// case 1: out_CIRAM_A10 = 1; break;
+// case 2: out_CIRAM_A10 = CHR_A10; break;
+// case 3: out_CIRAM_A10 = CHR_A11; break;
+// }
+
+// addr
+//}
\ No newline at end of file
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs
index c1d1061aa2..cb419c4730 100644
--- a/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs
@@ -19,7 +19,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
public EHeaderType HeaderType;
public int PRG_Size = -1, CHR_Size = -1;
- public int CRAM_Size = -1, NVWRAM_Size = -1, WRAM_Size = -1;
+ public int CRAM_Size = -1, PRAM_Size = -1;
public string BoardName;
public EMirrorType MirrorType;
public bool Battery;
@@ -43,11 +43,12 @@ namespace BizHawk.Emulation.Consoles.Nintendo
{
byte ReadPRG(int addr);
byte ReadPPU(int addr);
- byte ReadWRAM(int addr);
+ byte ReadPRAM(int addr);
void WritePRG(int addr, byte value);
void WritePPU(int addr, byte value);
- void WriteWRAM(int addr, byte value);
+ void WritePRAM(int addr, byte value);
void Initialize(RomInfo romInfo, NES nes);
+ byte[] SaveRam { get; }
};
public abstract class NESBoardBase : INESBoard
@@ -101,8 +102,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo
public virtual byte ReadPRG(int addr) { return RomInfo.ROM[addr];}
public virtual void WritePRG(int addr, byte value) { }
- public virtual void WriteWRAM(int addr, byte value) { }
- public virtual byte ReadWRAM(int addr) { return 0xFF; }
+ public virtual void WritePRAM(int addr, byte value) { }
+ public virtual byte ReadPRAM(int addr) { return 0xFF; }
public virtual void WritePPU(int addr, byte value)
@@ -127,6 +128,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo
return NES.ppu.ppu_defaultRead(ApplyMirroring(addr));
}
}
+
+ public virtual byte[] SaveRam { get { return null; } }
}
//hardware
@@ -214,7 +217,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
else if (addr < 0x4000) return ReadPPUReg(addr & 7);
else if (addr < 0x4020) return ReadReg(addr); //we're not rebasing the register just to keep register names canonical
else if (addr < 0x6000) return 0xFF; //exp rom
- else if (addr < 0x8000) return 0xFF; //sram
+ else if (addr < 0x8000) return board.ReadPRAM(addr);
else return board.ReadPRG(addr - 0x8000);
}
@@ -227,7 +230,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
else if (addr < 0x4000) WritePPUReg(addr & 7,value);
else if (addr < 0x4020) WriteReg(addr, value); //we're not rebasing the register just to keep register names canonical
else if (addr < 0x6000) { } //exp rom
- else if (addr < 0x8000) { } //sram
+ else if (addr < 0x8000) board.WritePRAM(addr,value);
else board.WritePRG(addr - 0x8000, value);
}
@@ -398,10 +401,17 @@ namespace BizHawk.Emulation.Consoles.Nintendo
}
public bool DeterministicEmulation { get { return true; } set { } }
- public byte[] SaveRam { get { return null; } }
+ public byte[] SaveRam
+ {
+ get
+ {
+ if(board==null) return null;
+ return board.SaveRam;
+ }
+ }
public bool SaveRamModified
{
- get { return false; }
+ get { if (board == null) return false; if (board.SaveRam == null) return false; return true; }
set { }
}
@@ -562,11 +572,11 @@ namespace BizHawk.Emulation.Consoles.Nintendo
ret.CHR_Size = VROM_size;
ret.Battery = (ROM_type & 2) != 0;
- fixed (iNES_HEADER* self = &this) ret.WRAM_Size = self->reserve[0] * 8;
+ fixed (iNES_HEADER* self = &this) ret.PRAM_Size = self->reserve[0] * 8;
//0 is supposed to mean 1 (for compatibility, as this is an extension to original iNES format)
- if (ret.WRAM_Size == 0) ret.WRAM_Size = 8;
+ if (ret.PRAM_Size == 0) ret.PRAM_Size = 8;
- Console.WriteLine("iNES header: map:{0}, mirror:{1}, PRG:{2}, CHR:{3}, CRAM:{4}, WRAM:{5}, NVWRAM:{6}, bat:{7}", ret.MapperNumber, ret.MirrorType, ret.PRG_Size, ret.CHR_Size, ret.CRAM_Size, ret.WRAM_Size, ret.NVWRAM_Size, ret.Battery ? 1 : 0);
+ Console.WriteLine("iNES header: map:{0}, mirror:{1}, PRG:{2}, CHR:{3}, CRAM:{4}, PRAM:{5}, bat:{6}", ret.MapperNumber, ret.MirrorType, ret.PRG_Size, ret.CHR_Size, ret.CRAM_Size, ret.PRAM_Size, ret.Battery ? 1 : 0);
//fceux calls uppow2(PRG_Banks) here, and also ups the chr size as well
//then it does something complicated that i don't understand with making sure it doesnt read too much data
@@ -618,18 +628,25 @@ namespace BizHawk.Emulation.Consoles.Nintendo
var dict = gi.ParseOptionsDictionary();
if (dict.ContainsKey("board"))
romInfo.BoardName = dict["board"];
- switch (dict["mirror"])
- {
- case "V": romInfo.MirrorType = EMirrorType.Vertical; break;
- case "H": romInfo.MirrorType = EMirrorType.Horizontal; break;
- case "X": romInfo.MirrorType = EMirrorType.External; break;
- }
+ if(dict.ContainsKey("mirror"))
+ switch (dict["mirror"])
+ {
+ case "V": romInfo.MirrorType = EMirrorType.Vertical; break;
+ case "H": romInfo.MirrorType = EMirrorType.Horizontal; break;
+ case "X": romInfo.MirrorType = EMirrorType.External; break;
+ default: throw new InvalidOperationException();
+ }
+
if (dict.ContainsKey("PRG"))
romInfo.PRG_Size = int.Parse(dict["PRG"]);
if (dict.ContainsKey("CHR"))
romInfo.CHR_Size = int.Parse(dict["CHR"]);
if (dict.ContainsKey("CRAM"))
romInfo.CRAM_Size = int.Parse(dict["CRAM"]);
+ if (dict.ContainsKey("PRAM"))
+ romInfo.PRAM_Size = int.Parse(dict["PRAM"]);
+ if (dict.ContainsKey("bat"))
+ romInfo.Battery = true;
if (dict.ContainsKey("bug"))
Console.WriteLine("game is known to be BUGGED!!!");
}
@@ -645,16 +662,22 @@ namespace BizHawk.Emulation.Consoles.Nintendo
case "AOROM": board = new Boards.AxROM("AOROM"); break;
case "Discrete_74x377": board = new Boards.Discrete_74x377(); break;
case "CPROM": board = new Boards.CPROM(); break;
- case "GxROM": board = new Boards.GxROM(); break;
+ case "GxROM": board = new Boards.GxROM(); break;
+ case "SGROM": board = new Boards.SxROM("SGROM"); break;
+ case "SNROM": board = new Boards.SxROM("SNROM"); break;
+ case "SL2ROM": board = new Boards.SxROM("SL2ROM"); break;
}
if (board == null) throw new InvalidOperationException("Couldn't classify NES rom");
//we're going to go ahead and copy these out, just in case we need to pad them alter
romInfo.ROM = new byte[romInfo.PRG_Size * 16 * 1024];
- romInfo.VROM = new byte[romInfo.CHR_Size * 8 * 1024];
Array.Copy(file, 16, romInfo.ROM, 0, romInfo.ROM.Length);
- Array.Copy(file, 16 + romInfo.ROM.Length, romInfo.VROM, 0, romInfo.VROM.Length);
+ if (romInfo.CHR_Size > 0)
+ {
+ romInfo.VROM = new byte[romInfo.CHR_Size * 8 * 1024];
+ Array.Copy(file, 16 + romInfo.ROM.Length, romInfo.VROM, 0, romInfo.VROM.Length);
+ }
board.Initialize(romInfo, this);
}
@@ -666,4 +689,16 @@ namespace BizHawk.Emulation.Consoles.Nintendo
//todo
//http://blog.ntrq.net/?p=428
-//cpu bus junk bits
\ No newline at end of file
+//cpu bus junk bits
+
+//UBER DOC
+//http://nocash.emubase.de/everynes.htm
+
+//A VERY NICE board assignments list
+//http://personales.epsg.upv.es/~jogilmo1/nes/TEXTOS/ARXIUS/BOARDTABLE.TXT
+
+//why not make boards communicate over the actual board pinouts
+//http://wiki.nesdev.com/w/index.php/Cartridge_connector
+
+//a mappers list
+//http://tuxnes.sourceforge.net/nesmapper.txt
diff --git a/BizHawk.MultiClient/output/gamedb.txt b/BizHawk.MultiClient/output/gamedb.txt
index 63737d864e..0955d251e3 100644
--- a/BizHawk.MultiClient/output/gamedb.txt
+++ b/BizHawk.MultiClient/output/gamedb.txt
@@ -2321,9 +2321,14 @@ FA57750AD33815E99C40986F26FC697E Tag Team Wrestling (U) NES board=NROM;mirror=
E7D7225DAD044B624FBAD9C9CA96E835 Wrecking Crew (JUE) NES board=NROM;mirror=H;PRG=2;CHR=1
7A528FA727623BA7704FDBB519F3419F Xevious (U) NES board=NROM;mirror=H;PRG=2;CHR=1
-;todo videomation(mapper13)
-;starting at arkanoid we have mappers
-;http://tuxnes.sourceforge.net/nesmapper.txt a mappers list
+;SxROM
+24AE5EDF8375162F91A6846D3202E3D6 Final Fantasy (U) NES board=SNROM;PRG=16
+881ECC27F0D3B10ED63DCC68C2B20ADC Final Fantasy (J) NES board=SNROM;PRG=16
+9A857B52042A11D021D596E5EE528585 Kid Icarus (UE) NES board=SNROM;PRG=8
+D9A1631D5C32D35594B9484862A26CBA Legend of Zelda, The (Rev 0) (U) NES board=SNROM;PRG=8;bat
+0527A0EE512F69E08B8DB6DC97964632 Mega Man 2 (U) NES board=SGROM;PRG=16
+B2D2D9ED68B3E5E0D29053EA525BD37C Metroid (U) NES board=SNROM;PRG=8
+12B0DBC4F2B22A50D0BB53C4929217F0 Blaster Master (U) NES board=SL2ROM;PRG=8;CHR=16
;UNROM
4DE82CFCEADBF1A5E693B669B1221107 Mega Man (U) NES board=UNROM;mirror=V;PRG=8;CHR=0;CRAM=8
@@ -2364,4 +2369,24 @@ C6809FA829814A356446CE0B36F60EBF Time Lord (E) NES board=AOROM;mirror=X;PRG=8;
;AOROM 16,0
DBF8909B943AB0F7ED0F210CE85FAFAF Battletoads (E) NES board=AOROM;mirror=X;PRG=16;CHR=0
318D9C03FB183F6F8CD2FC89FDD0DBB2 Battletoads (J) NES board=AOROM;mirror=X;PRG=16;CHR=0
-EEFAC97AC3B85048F3685E1623210EFB Battletoads (U) NES board=AOROM;mirror=X;PRG=16;CHR=0
\ No newline at end of file
+EEFAC97AC3B85048F3685E1623210EFB Battletoads (U) NES board=AOROM;mirror=X;PRG=16;CHR=0
+
+;COLORDREAMS 2,4 (mapper 11)
+2956B171112843033E608A152DE6297B Metal Fighter (U) NES board=Discrete_74x377;mirror=V;PRG=2;CHR=4
+
+;COLORDREAMS 4,2 (mapper 11)
+6477C54B7340D77C25AA012480C0B321 Crystal Mines (U) NES board=Discrete_74x377;mirror=V;PRG=4;CHR=2
+
+;CPROM (mapper 13)
+;4C92E4F0C6BF73FAB372C5A86BB60021 Videomation (U) NES board=CPROM;mirror=V;PRG=2;CHR=0
+
+;GxROM 4,2 (MHROM? wtf?) (mapper 66) ;this frequently needs to be corrected to V
+D821FB982CE47299FDB08A027EC0B8BE Super Mario Bros - Duck Hunt (U) NES board=GxROM;mirror=V;PRG=4;CHR=2
+
+;GxROM 8,4 (mapper 66) ;these frequently needs to be corrected to V
+ADD4E9F5ED4391A6B3FDFC5F0E300E71 Doraemon (J) NES board=GxROM;mirror=V;PRG=8;CHR=4
+4E9D128C63A41C8CC20FF1114A67A2DD Dragon Power (U) NES board=GxROM;mirror=V;PRG=8;CHR=4
+8F43E7D7BD3DBDF6D8ADF3E046DE3562 Gumshoe (UE) NES board=GxROM;mirror=H;PRG=8;CHR=4
+
+;GxROM 8,16 (mapper 66)
+BE40E77C5532AF8E2C1EA7B96831CCEA Thunder & Lightning (U).nes NES board=GxROM;mirror=H;PRG=8;CHR=16
\ No newline at end of file
diff --git a/CpuCoreGenerator/MOS 6502/CoreGenerator.cs b/CpuCoreGenerator/MOS 6502/CoreGenerator.cs
index 58990fe568..001c6dae3c 100644
--- a/CpuCoreGenerator/MOS 6502/CoreGenerator.cs
+++ b/CpuCoreGenerator/MOS 6502/CoreGenerator.cs
@@ -215,7 +215,37 @@ namespace M6502
Set(0x5E, "LSR", AddrMode.AbsoluteX, 7);
// No Operation
- Set(0xEA, "NOP", AddrMode.Implicit, 2);
+ Set(0xEA, "NOP", AddrMode.Implicit, 2);
+
+ // Illegal NOPs
+ Set(0x1A, "NOP", AddrMode.Implicit, 2);
+ Set(0x3A, "NOP", AddrMode.Implicit, 2);
+ Set(0x5A, "NOP", AddrMode.Implicit, 2);
+ Set(0x7A, "NOP", AddrMode.Implicit, 2);
+ Set(0xDA, "NOP", AddrMode.Implicit, 2);
+ Set(0xFA, "NOP", AddrMode.Implicit, 2);
+ Set(0x80, "NOP", AddrMode.Immediate, 2);
+ Set(0x82, "NOP", AddrMode.Immediate, 2);
+ Set(0x89, "NOP", AddrMode.Immediate, 2);
+ Set(0xC2, "NOP", AddrMode.Immediate, 2);
+ Set(0xE2, "NOP", AddrMode.Immediate, 2);
+ Set(0x04, "NOP", AddrMode.ZeroPage, 3);
+ Set(0x44, "NOP", AddrMode.ZeroPage, 3);
+ Set(0x64, "NOP", AddrMode.ZeroPage, 3);
+ Set(0x14, "NOP", AddrMode.ZeroPageX, 4);
+ Set(0x34, "NOP", AddrMode.ZeroPageX, 4);
+ Set(0x54, "NOP", AddrMode.ZeroPageX, 4);
+ Set(0x74, "NOP", AddrMode.ZeroPageX, 4);
+ Set(0xD4, "NOP", AddrMode.ZeroPageX, 4);
+ Set(0xF4, "NOP", AddrMode.ZeroPageX, 4);
+ //do the following issue a read or write? if so, we need to emulate with another instruction
+ Set(0x0C, "NOP", AddrMode.Indirect, 4);
+ Set(0x1C, "NOP", AddrMode.IndirectX, 4);
+ Set(0x3C, "NOP", AddrMode.IndirectX, 4);
+ Set(0x5C, "NOP", AddrMode.IndirectX, 4);
+ Set(0x7C, "NOP", AddrMode.IndirectX, 4);
+ Set(0xDC, "NOP", AddrMode.IndirectX, 4);
+ Set(0xFC, "NOP", AddrMode.IndirectX, 4);
// Bitwise OR with Accumulator
Set(0x09, "ORA", AddrMode.Immediate, 2);