From 5ba647a6321596b9d5dfe7bbb6d95ca79da43ae3 Mon Sep 17 00:00:00 2001 From: alyosha-tas Date: Sat, 2 Dec 2017 12:22:48 -0500 Subject: [PATCH] NESHawk: Implement mapper 43 and UNIF_UNL-SMB2J --- .../BizHawk.Emulation.Cores.csproj | 2 + .../Consoles/Nintendo/NES/Boards/Mapper043.cs | 138 ++++++++++++++++++ .../NES/Boards/UNIF/UNIF_UNL_SMB2J.cs | 92 ++++++++++++ 3 files changed, 232 insertions(+) create mode 100644 BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper043.cs create mode 100644 BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/UNIF/UNIF_UNL_SMB2J.cs diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj index 4a00050be4..5a536eb916 100644 --- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj +++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj @@ -664,6 +664,7 @@ + @@ -859,6 +860,7 @@ + diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper043.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper043.cs new file mode 100644 index 0000000000..49e87f21da --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Mapper043.cs @@ -0,0 +1,138 @@ +using System; +using BizHawk.Common; + +namespace BizHawk.Emulation.Cores.Nintendo.NES +{ + public sealed class Mapper043 : NES.NESBoardBase + { + int prg = 0; + int irqcnt = 0; + bool irqenable = false; + bool swap; + + + private static int[] lut = { 4, 3, 5, 3, 6, 3, 7, 3 }; + + public override bool Configure(NES.EDetectionOrigin origin) + { + switch (Cart.board_type) + { + case "MAPPER043": + break; + default: + return false; + } + + Cart.wram_size = 0; + // not sure on initial mirroring + SetMirrorType(EMirrorType.Vertical); + return true; + } + + public override void WriteEXP(int addr, byte value) + { + addr += 0x4000; + + switch (addr & 0xF1FF) + { + case 0x4022: + prg = lut[value & 0x7]; + break; + + case 0x4120: + swap = (value & 1) == 1; + break; + + case 0x4122: + irqenable = (value & 1) == 1; + IRQSignal = false; + irqcnt = 0; + break; + } + } + + public override void WritePRG(int addr, byte value) + { + addr += 0x8000; + switch (addr & 0xF1FF) + { + case 0x8122: + irqenable = (value & 1) == 1; + IRQSignal = false; + irqcnt = 0; + break; + } + } + + public override byte ReadEXP(int addr) + { + if (addr > 0x1000) + { + return ROM[(addr - 0x1000) + 8 * 0x2000]; + } + else return base.ReadEXP(addr); + } + + public override byte ReadWRAM(int addr) + { + if (swap) + { + return ROM[addr]; + } + else + { + return ROM[addr + 0x4000]; + } + } + + public override byte ReadPRG(int addr) + { + if (addr < 0x2000) + { + return ROM[addr + 0x2000]; + } + else if (addr < 0x4000) + { + return ROM[addr - 0x2000]; + } + else if (addr < 0x6000) + { + return ROM[(addr - 0x4000) + prg * 0x2000]; + } + else + { + if (swap) + { + return ROM[(addr - 0x6000) + 8 * 0x2000]; + } + else + { + return ROM[(addr - 0x6000) + 9 * 0x2000]; + } + } + } + + public override void ClockCPU() + { + if (irqenable) + { + irqcnt++; + + if (irqcnt >= 4096) + { + irqenable = false; + IRQSignal = true; + } + } + } + + public override void SyncState(Serializer ser) + { + base.SyncState(ser); + ser.Sync("prg", ref prg); + ser.Sync("irqenable", ref irqenable); + ser.Sync("irqcnt", ref irqcnt); + ser.Sync("swap", ref swap); + } + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/UNIF/UNIF_UNL_SMB2J.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/UNIF/UNIF_UNL_SMB2J.cs new file mode 100644 index 0000000000..41123272c6 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/UNIF/UNIF_UNL_SMB2J.cs @@ -0,0 +1,92 @@ +using System; +using BizHawk.Common; + +namespace BizHawk.Emulation.Cores.Nintendo.NES +{ + public sealed class UNIF_UNL_SMB2J : NES.NESBoardBase + { + int prg = 0; + int prg_count; + int irqcnt = 0; + bool irqenable = false; + bool swap; + + public override bool Configure(NES.EDetectionOrigin origin) + { + switch (Cart.board_type) + { + case "UNIF_UNL-SMB2J": + break; + default: + return false; + } + + prg_count = Cart.prg_size/4; + + Cart.wram_size = 0; + // not sure on initial mirroring + SetMirrorType(EMirrorType.Vertical); + return true; + } + + public override void WriteEXP(int addr, byte value) + { + addr += 0x4000; + + switch (addr) + { + case 0x4022: + if (ROM.Length > 0x10000) { prg = (value & 0x01) << 2; } + break; + + case 0x4122: + irqenable = (value & 3) > 0; + IRQSignal = false; + irqcnt = 0; + break; + } + } + + public override byte ReadEXP(int addr) + { + if (addr > 0x1000) + { + return ROM[(addr - 0x1000) + (prg_count - 3) * 0x1000]; + } + else return base.ReadEXP(addr); + } + + public override byte ReadWRAM(int addr) + { + return ROM[addr + (prg_count - 2) * 0x1000]; + } + + public override byte ReadPRG(int addr) + { + return ROM[(addr + prg * 01000)]; + } + + public override void ClockCPU() + { + if (irqenable) + { + irqcnt++; + + if (irqcnt >= 4096) + { + irqenable = false; + IRQSignal = true; + } + } + } + + public override void SyncState(Serializer ser) + { + base.SyncState(ser); + ser.Sync("prg", ref prg); + ser.Sync("irqenable", ref irqenable); + ser.Sync("irqcnt", ref irqcnt); + ser.Sync("swap", ref swap); + } + } +}