From 41d1db14ef0c4f5d3c829e36de84e814053e43bc Mon Sep 17 00:00:00 2001 From: alyosha-tas Date: Sun, 14 Oct 2018 09:45:13 -0500 Subject: [PATCH] GBHawk: HuC1 support --- .../Nintendo/GBHawk/Mappers/Mapper_HuC1.cs | 108 ++++++++++++++++-- 1 file changed, 98 insertions(+), 10 deletions(-) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_HuC1.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_HuC1.cs index cef7f2bbdc..6f63e13541 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_HuC1.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_HuC1.cs @@ -4,31 +4,75 @@ using System; namespace BizHawk.Emulation.Cores.Nintendo.GBHawk { - // Default mapper with no bank switching + // hudson mapper used in ex Daikaijuu monogatari public class MapperHuC1 : MapperBase { + public int ROM_bank; + public int RAM_bank; + public bool RAM_enable; + public int ROM_mask; + public int RAM_mask; + public bool IR_signal; + public override void Initialize() { - // nothing to initialize + ROM_bank = 0; + RAM_bank = 0; + RAM_enable = false; + ROM_mask = Core._rom.Length / 0x4000 - 1; + + // some games have sizes that result in a degenerate ROM, account for it here + if (ROM_mask > 4) { ROM_mask |= 3; } + + RAM_mask = 0; + if (Core.cart_RAM != null) + { + RAM_mask = Core.cart_RAM.Length / 0x2000 - 1; + if (Core.cart_RAM.Length == 0x800) { RAM_mask = 0; } + } } public override byte ReadMemory(ushort addr) { - if (addr < 0x8000) + if (addr < 0x4000) { return Core._rom[addr]; } - else + else if (addr < 0x8000) { - if (Core.cart_RAM != null) + return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000]; + } + else if ((addr >= 0xA000) && (addr < 0xC000)) + { + if (RAM_enable) { - return Core.cart_RAM[addr - 0xA000]; + if (Core.cart_RAM != null) + { + if (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length) + { + return Core.cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000]; + } + else + { + return 0xFF; + } + } + else + { + return 0xFF; + } } else { - return 0; + // when RAM isn't enabled, reading from this area will return IR sensor reading + // for now we'll assume it never sees light (0xC0) + return 0xC0; } } + else + { + return 0xFF; + } } public override byte PeekMemory(ushort addr) @@ -40,13 +84,47 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk { if (addr < 0x8000) { - // no mapping hardware available + if (addr < 0x2000) + { + RAM_enable = (value & 0xF) != 0xE; + } + else if (addr < 0x4000) + { + value &= 0x3F; + + ROM_bank &= 0xC0; + ROM_bank |= value; + ROM_bank &= ROM_mask; + } + else if (addr < 0x6000) + { + RAM_bank = value & 3; + RAM_bank &= RAM_mask; + } } else { - if (Core.cart_RAM != null) + if (RAM_enable) { - Core.cart_RAM[addr - 0xA000] = value; + if (Core.cart_RAM != null) + { + if (((addr - 0xA000) + RAM_bank * 0x2000) < Core.cart_RAM.Length) + { + Core.cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000] = value; + } + } + } + else + { + // I don't know if other bits here have an effect + if (value == 1) + { + IR_signal = true; + } + else if (value == 0) + { + IR_signal = false; + } } } } @@ -55,5 +133,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk { WriteMemory(addr, value); } + + public override void SyncState(Serializer ser) + { + ser.Sync("ROM_Bank", ref ROM_bank); + ser.Sync("ROM_Mask", ref ROM_mask); + ser.Sync("RAM_Bank", ref RAM_bank); + ser.Sync("RAM_Mask", ref RAM_mask); + ser.Sync("RAM_enable", ref RAM_enable); + ser.Sync("IR_signal", ref IR_signal); + } } }