From c9d5ab3695d8c03a7d479d05eca0032bc240a71f Mon Sep 17 00:00:00 2001 From: adelikat Date: Thu, 15 Sep 2016 13:22:20 -0400 Subject: [PATCH] check in a bunch of half finished or bugged attempted at some mappers for crappy roms, mappers 142, 172, 183, 252, and 253. At least most of the grunt work is done --- .../BizHawk.Emulation.Cores.csproj | 4 + .../Consoles/Nintendo/NES/Boards/Mapper132.cs | 27 +++- .../Consoles/Nintendo/NES/Boards/Mapper142.cs | 121 +++++++++++++++ .../Consoles/Nintendo/NES/Boards/Mapper183.cs | 124 ++++++++++++++++ .../Consoles/Nintendo/NES/Boards/Mapper252.cs | 138 ++++++++++++++++++ .../Consoles/Nintendo/NES/Boards/Mapper253.cs | 128 ++++++++++++++++ 6 files changed, 534 insertions(+), 8 deletions(-) create mode 100644 BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper142.cs create mode 100644 BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper183.cs create mode 100644 BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper252.cs create mode 100644 BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper253.cs diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj index 71b27acb6c..9d899f7fb8 100644 --- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj +++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj @@ -615,6 +615,7 @@ + @@ -626,6 +627,7 @@ + @@ -655,6 +657,8 @@ + + diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper132.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper132.cs index 52262fb360..307d7e2eec 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper132.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper132.cs @@ -13,7 +13,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES //state int prg, chr; - bool is173; + bool is172, is173; public override bool Configure(NES.EDetectionOrigin origin) { @@ -22,6 +22,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES case "MAPPER132": case "UNIF_UNL-22211": break; + case "MAPPER172": + is172 = true; + break; case "MAPPER173": is173 = true; break; @@ -35,20 +38,26 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES return true; } - public void sync() + public void sync(byte value) { + prg=reg[2]>>2; + prg &= prg_mask; - prg=reg[2]>>2; - prg &= prg_mask; + if (is172) + { + chr = (((value ^ reg[2]) >> 3) & 2) | (((value ^ reg[2]) >> 5) & 1); + } + else + { chr = (reg[2] & 0x3); - chr &= chr_mask; - + } + chr &= chr_mask; } public override void WritePRG(int addr, byte value) { - sync(); + sync(value); } public override void WriteEXP(int addr, byte value) @@ -80,7 +89,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES { return VROM[addr + (chr << 13)]; } - else return base.ReadPPU(addr); + + return base.ReadPPU(addr); } public override void SyncState(Serializer ser) @@ -88,6 +98,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES base.SyncState(ser); ser.Sync("chr", ref chr); ser.Sync("prg", ref prg); + ser.Sync("is172", ref is172); ser.Sync("is173", ref is173); ser.Sync("reg", ref reg); } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper142.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper142.cs new file mode 100644 index 0000000000..a1c3ecf361 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper142.cs @@ -0,0 +1,121 @@ +using BizHawk.Common; + +namespace BizHawk.Emulation.Cores.Nintendo.NES +{ + public sealed class Mapper142 : NES.NESBoardBase + { + private ByteBuffer reg = new ByteBuffer(8); + private byte cmd; + private int lastBank; + + private bool isirqused = false; + private byte IRQa = 0; + private int IRQCount = 0; + + public override bool Configure(NES.EDetectionOrigin origin) + { + switch (Cart.board_type) + { + case "MAPPER142": + case "UNIF_UNL-KS7032": + break; + default: + return false; + } + + lastBank = Cart.prg_size / 8 - 1; + + return true; + } + + public override byte ReadWRAM(int addr) + { + return ROM[(reg[4] << 13) + (addr & 0x1FFF)]; + } + + public override byte ReadPRG(int addr) + { + if (addr < 0x2000) { return ROM[(reg[1] << 13) + (addr & 0x1FFF)]; } + if (addr < 0x4000) { return ROM[(reg[2] << 13) + (addr & 0x1FFF)]; } + if (addr < 0x6000) { return ROM[(reg[3] << 13) + (addr & 0x1FFF)]; } + + return ROM[(lastBank << 13) + (addr & 0x1FFF)]; + } + + public override void WriteEXP(int addr, byte value) + { + Write(addr + 0x4000, value); + } + + public override void WriteWRAM(int addr, byte value) + { + Write(addr + 0x6000, value); + } + + public override void WritePRG(int addr, byte value) + { + Write(addr + 0x8000, value); + } + + private void IRQHook(int a) + { + if (IRQa > 0) + { + IRQCount += a; + if (IRQCount >= 0xFFFF) + { + IRQa = 0; + IRQCount = 0; + + IRQSignal = true; + } + } + } + + public override void ClockPPU() + { + IRQHook(1); + } + + private void Write(int addr, byte value) + { + switch (addr & 0xF000) + { + case 0x8000: + IRQSignal = false; + IRQCount = (IRQCount & 0x000F) | (value & 0x0F); + isirqused = true; + break; + case 0x9000: + IRQSignal = false; + IRQCount = (IRQCount & 0x00F0) | ((value & 0x0F) << 4); + isirqused = true; + break; + case 0xA000: + IRQSignal = false; + IRQCount = (IRQCount & 0x0F00) | ((value & 0x0F) << 8); + isirqused = true; + break; + case 0xB000: + IRQSignal = false; + IRQCount = (IRQCount & 0xF000) | (value << 12); + isirqused = true; + break; + case 0xC000: + if (isirqused) + { + IRQSignal = false; + IRQa = 1; + } + break; + + case 0xE000: + cmd = (byte)(value & 7); + break; + case 0xF000: + reg[cmd] = value; + break; + } + } + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper183.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper183.cs new file mode 100644 index 0000000000..c035458b65 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper183.cs @@ -0,0 +1,124 @@ +using BizHawk.Common; + +namespace BizHawk.Emulation.Cores.Nintendo.NES +{ + // Adpated from FCEUX src + public sealed class Mapper183 : NES.NESBoardBase + { + private ByteBuffer prg = new ByteBuffer(4); + private ByteBuffer chr = new ByteBuffer(8); + + private int prg_bank_mask_8k, chr_bank_mask_1k; + + public override bool Configure(NES.EDetectionOrigin origin) + { + switch (Cart.board_type) + { + case "MAPPER183": + break; + default: + return false; + } + + prg_bank_mask_8k = Cart.prg_size / 8 - 1; + chr_bank_mask_1k = Cart.chr_size - 1; + + return true; + } + + public override void SyncState(Serializer ser) + { + base.SyncState(ser); + ser.Sync("prg", ref prg); + ser.Sync("chr", ref chr); + } + + private void SetMirroring(int mirr) + { + switch (mirr & 3) + { + case 0: SetMirrorType(EMirrorType.Vertical); break; + case 1: SetMirrorType(EMirrorType.Horizontal); break; + case 2: SetMirrorType(EMirrorType.OneScreenA); break; + case 3: SetMirrorType(EMirrorType.Vertical); break; + } + } + + public override void WriteWRAM(int addr, byte value) + { + WriteReg(addr + 0x6000, value); + } + + public override void WritePRG(int addr, byte value) + { + WriteReg(addr + 0x8000, value); + } + + private void WriteReg(int addr, byte value) + { + if ((addr & 0xF800) == 0x6800) + { + prg[3] = (byte)(addr & 0x3F); + } + else if (((addr & 0xF80C) >= 0xB000) && ((addr & 0xF80C) <= 0xE00C)) + { + int index = (((addr >> 11) - 6) | (addr >> 3)) & 7; + chr[index] = (byte)((chr[index] & (0xF0 >> (addr & 4))) | ((value & 0x0F) << (addr & 4))); + } + else switch (addr & 0xF80C) + { + case 0x8800: prg[0] = value; break; + case 0xA800: prg[1] = value; break; + case 0xA000: prg[2] = value; break; + case 0x9800: SetMirroring(value & 3); break; + + // TODO: IRQ + case 0xF000: break; + case 0xF004: break; + case 0xF008: break; + case 0xF00C: break; + } + } + + public override byte ReadPPU(int addr) + { + if (addr < 0x2000) + { + int x = (addr >> 10) & 7; + int bank = (chr[x] & chr_bank_mask_1k) << 10; + return VROM[bank + (addr & 0x3FF)]; // TODO + } + + return base.ReadPPU(addr); + } + + public override byte ReadWRAM(int addr) + { + return ROM[((prg[3] & prg_bank_mask_8k)) << 13 + (addr & 0x1FFF)]; + } + + public override byte ReadPRG(int addr) + { + int bank_8k; + if (addr < 0x2000) // 0x8000 + { + bank_8k = prg[0] & prg_bank_mask_8k; + + } + else if (addr < 0x4000) // 0xA000 + { + bank_8k = prg[1] & prg_bank_mask_8k; + } + else if (addr < 0x6000) // 0xC000 + { + bank_8k = prg[2] & prg_bank_mask_8k; + } + else + { + bank_8k = prg_bank_mask_8k; + } + + return ROM[(bank_8k << 13) + (addr & 0x1FFF)]; + } + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper252.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper252.cs new file mode 100644 index 0000000000..ace7642525 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper252.cs @@ -0,0 +1,138 @@ +using BizHawk.Common; + +namespace BizHawk.Emulation.Cores.Nintendo.NES +{ + // Adapted from FCEUX src + public sealed class Mapper252 : NES.NESBoardBase + { + private ByteBuffer preg = new ByteBuffer(2); + private ByteBuffer creg = new ByteBuffer(8); + + private int prg_bank_mask_8k, chr_bank_mask_1k; + + public override bool Configure(NES.EDetectionOrigin origin) + { + //analyze board type + switch (Cart.board_type) + { + case "MAPPER252": + break; + default: + return false; + } + + prg_bank_mask_8k = Cart.prg_size / 8 - 1; + chr_bank_mask_1k = Cart.chr_size - 1; + + return true; + } + + public override void SyncState(Serializer ser) + { + base.SyncState(ser); + ser.Sync("preg", ref preg); + ser.Sync("creg", ref creg); + } + + public override void WritePRG(int addr, byte value) + { + WriteReg((addr + 0x8000), value); + } + + public override void WriteWRAM(int addr, byte value) + { + WriteReg((addr + 0x6000), value); + } + + public void WriteReg(int addr, byte value) + { + if (addr >= 0xB000 && addr < 0xF000) + { + var ind = ((((addr & 8) | (addr >> 8)) >> 3) + 2) & 7; + var sar = addr & 4; + creg[ind] = (byte)((creg[ind] & (0xF0 >> sar)) | ((value & 0x0F) << sar)); + } + else + { + switch (addr & 0xF00C) + { + case 0x8000: + case 0x8004: + case 0x8008: + case 0x800C: + preg[0] = value; + break; + + case 0xA000: + case 0xA004: + case 0xA008: + case 0xA00C: + preg[1] = value; + break; + + // TODO IRQ + case 0xF000: break; + case 0xF004: break; + case 0xF008: break; + } + } + } + + public override byte ReadWRAM(int addr) + { + return ROM[addr]; + } + + public override byte ReadPRG(int addr) + { + int bank; + + if (addr < 0x2000) + { + bank = preg[0] & prg_bank_mask_8k; + } + else if (addr < 0x4000) + { + bank = preg[1] & prg_bank_mask_8k; + } + else if (addr < 0x6000) + { + bank = prg_bank_mask_8k - 1; + } + else + { + bank = prg_bank_mask_8k; + } + + + return ROM[(bank << 13) + (addr & 0x1FFF)]; + } + + public override byte ReadPPU(int addr) + { + if (addr < 0x2000) + { + int x = (addr >> 10) & 7; + + int bank; + if (creg[x] == 6 || creg[x] == 7) + { + bank = creg[x] & 1; + } + else + { + bank = (creg[x] & chr_bank_mask_1k) << 10; + } + + if (addr == 0x400) + { + int zzz = 0; + } + + return VROM[bank + (addr & 0x3FF)]; + } + + return base.ReadPPU(addr); + } + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper253.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper253.cs new file mode 100644 index 0000000000..fb476ec808 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper253.cs @@ -0,0 +1,128 @@ +using BizHawk.Common; + +namespace BizHawk.Emulation.Cores.Nintendo.NES +{ + public class Mapper253 : NES.NESBoardBase + { + private ByteBuffer prg = new ByteBuffer(2); + private ByteBuffer chrlo = new ByteBuffer(8); + private ByteBuffer chrhi = new ByteBuffer(8); + private bool vlock; + + private int prg_bank_mask_8k, chr_bank_mask_1k; + + public override bool Configure(NES.EDetectionOrigin origin) + { + //analyze board type + switch (Cart.board_type) + { + case "MAPPER253": + break; + default: + return false; + } + + prg_bank_mask_8k = Cart.prg_size / 8 - 1; + chr_bank_mask_1k = Cart.chr_size - 1; + + return true; + } + + public override void SyncState(Serializer ser) + { + base.SyncState(ser); + ser.Sync("preg", ref prg); + ser.Sync("chrlo", ref chrlo); + ser.Sync("chrhi", ref chrhi); + } + + public override void WritePRG(int addr, byte value) + { + addr += 0x8000; + if ((addr >= 0xB000) && (addr <= 0xE00C)) + { + var ind = ((((addr & 8) | (addr >> 8)) >> 3) + 2) & 7; + var sar = addr & 4; + var clo = (chrlo[ind] & (0xF0 >> sar)) | ((value & 0x0F) << sar); + chrlo[ind] = (byte)clo; + if (ind == 0) + { + if (clo == 0xc8) + vlock = false; + else if (clo == 0x88) + vlock = true; + } + if (sar > 0) + chrhi[ind] = (byte)(value >> 4); + } + else + { + switch (addr) + { + case 0x8010: prg[0] = value; break; + case 0xA010: prg[1] = value; break; + case 0x9400: SetMirroring(value); break; + + // TODO: IRQ + case 0xF000: break; + case 0xF004: break; + case 0xF008: break; + } + } + } + + private void SetMirroring(int mirr) + { + switch(mirr & 3) + { + case 0: SetMirrorType(EMirrorType.Vertical); break; + case 1: SetMirrorType(EMirrorType.Horizontal); break; + case 2: SetMirrorType(EMirrorType.OneScreenA); break; + case 3: SetMirrorType(EMirrorType.Vertical); break; + } + } + + public override byte ReadWRAM(int addr) + { + return ROM[addr]; + } + + public override byte ReadPRG(int addr) + { + int bank; + + if (addr < 0x2000) + { + bank = prg[0]; + } + else if (addr < 0x4000) + { + bank = prg[1]; + } + else if (addr < 0x6000) + { + bank = prg_bank_mask_8k - 1; + } + else + { + bank = prg_bank_mask_8k; + } + + + return ROM[(bank << 13) + (addr & 0x1FFF)]; + } + + public override byte ReadPPU(int addr) + { + if (addr < 0x2000) + { + int x = (addr >> 10) & 7; + var chr = chrlo[x] | (chrhi[x] << 8); + int bank = (chr & chr_bank_mask_1k) << 10; + return VROM[bank + (addr & 0x3FF)]; + } + + return base.ReadPPU(addr); + } + } +}