From c825720d33ec8fc3d2501f41690490d7e4ad122f Mon Sep 17 00:00:00 2001 From: beirich Date: Tue, 18 Mar 2014 02:23:10 +0000 Subject: [PATCH] SMS: Fix Ernie Els Golf GG (has on-cart volatile ram) --- .../Sega/SMS/MemoryMap.CodeMasters.cs | 65 +++++++++++++++++-- .../Consoles/Sega/SMS/SMS.cs | 2 + output/gamedb/gamedb_sega_gg.txt | 2 +- 3 files changed, 64 insertions(+), 5 deletions(-) diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.CodeMasters.cs b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.CodeMasters.cs index 876e63fc82..50a281dd2b 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.CodeMasters.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.CodeMasters.cs @@ -2,18 +2,20 @@ { public partial class SMS { + // ======================================================================= // The CodeMasters mapper has 3 banks of 16kb, like the Sega mapper. // The differences are that the paging control addresses are different, and the first 1K of ROM is not protected. // Bank 0: Control Address $0000 - Maps $0000 - $3FFF // Bank 1: Control Address $4000 - Maps $4000 - $7FFF // Bank 2: Control Address $8000 - Maps $8000 - $BFFF // System RAM is at $C000+ as in the Sega mapper. + // ======================================================================= byte ReadMemoryCM(ushort address) { - if (address < BankSize * 1) return RomData[(RomBank0 * BankSize) + address]; - if (address < BankSize * 2) return RomData[(RomBank1 * BankSize) + (address & BankSizeMask)]; - if (address < BankSize * 3) return RomData[(RomBank2 * BankSize) + (address & BankSizeMask)]; + if (address < 0x4000) return RomData[(RomBank0 * BankSize) + address]; + if (address < 0x8000) return RomData[(RomBank1 * BankSize) + (address & BankSizeMask)]; + if (address < 0xC000) return RomData[(RomBank2 * BankSize) + (address & BankSizeMask)]; return SystemRam[address & RamSizeMask]; } @@ -34,7 +36,62 @@ Cpu.WriteMemory = WriteMemoryCM; WriteMemoryCM(0x0000, 0); WriteMemoryCM(0x4000, 1); - WriteMemoryCM(0x8000, 2); + WriteMemoryCM(0x8000, 0); + } + + // ======================================================================= + // CodeMasters with on-board volatile RAM + // ======================================================================= + + byte ReadMemoryCMRam(ushort address) + { + if (address < 0x4000) + return RomData[(RomBank0 * BankSize) + address]; + if (address < 0x8000) + { + if (address >= 0x6000 && RomBank3 == 1) + return ExtRam[address & 0x1FFF]; + return RomData[(RomBank1 * BankSize) + (address & BankSizeMask)]; + } + if (address < 0xC000) + { + if (address >= 0xA000 && RomBank3 == 1) + return ExtRam[address & 0x1FFF]; + return RomData[(RomBank2 * BankSize) + (address & BankSizeMask)]; + } + + return SystemRam[address & RamSizeMask]; + } + + void WriteMemoryCMRam(ushort address, byte value) + { + if (address >= 0xC000) + SystemRam[address & RamSizeMask] = value; + + else if (address == 0x0000) + RomBank0 = (byte)(value & 0xF); + else if (address == 0x4000) + { + RomBank1 = (byte)(value & 0xF); + RomBank3 = (byte)(((value & 0x80) != 0) ? 1 : 0); + } + else if (address == 0x8000) + RomBank2 = (byte)(value & 0xF); + else if (address >= 0x6000 && address < 0x8000 && RomBank3 == 1) + ExtRam[address & 0x1FFF] = value; + else if (address >= 0xA000 && address < 0xC000 && RomBank3 == 1) + ExtRam[address & 0x1FFF] = value; + } + + void InitCodeMastersMapperRam() + { + Cpu.ReadMemory = ReadMemoryCMRam; + Cpu.WriteMemory = WriteMemoryCMRam; + WriteMemoryCM(0x0000, 0); + WriteMemoryCM(0x4000, 1); + WriteMemoryCM(0x8000, 0); + ExtRam = new byte[8192]; + RomBank3 = 0; } } } diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.cs b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.cs index 8913be0a21..2f11ed5964 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.cs @@ -145,6 +145,8 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem if (game["CMMapper"]) InitCodeMastersMapper(); + else if (game["CMMapperWithRam"]) + InitCodeMastersMapperRam(); else if (game["ExtRam"]) InitExt2kMapper(int.Parse(game.OptionValue("ExtRam"))); else if (game["KoreaMapper"]) diff --git a/output/gamedb/gamedb_sega_gg.txt b/output/gamedb/gamedb_sega_gg.txt index 3c1b04afda..7b00d25e9c 100644 --- a/output/gamedb/gamedb_sega_gg.txt +++ b/output/gamedb/gamedb_sega_gg.txt @@ -111,7 +111,7 @@ E35A0B3D9A4A3BB6B2E72FAB5A8C1712 Earthworm Jim (E) GG Europe E4E654AA1730565220120844DAD6B444 Ecco the Dolphin II (J) GG Japan CCD970B22303887734FAFB8E45B1E43F Ecco the Dolphin (UE) GG USA;Europe A506FC04C7A0DFAF37423FF0A38AEB2E Ecco the Dolphin (J) GG Japan -E97C20B86EA73248CC7AED602D46C3A4 Ernie Els Golf (E) (En,Fr,De,Es,It) GG Sports;Golf CMMapper;SRAM=8192 Europe +E97C20B86EA73248CC7AED602D46C3A4 Ernie Els Golf (E) (En,Fr,De,Es,It) GG Sports;Golf CMMapperWithRam Europe C58D6291DA8A4919328B8F42BE8640A7 Eternal Legend - Eien no Densetsu (J) GG Japan 4E63ABB36BE8D86B94B34846B16D9FA3 Evander Holyfield's 'Real Deal' Boxing (UE) GG USA;Europe 309ABE6822C52DF971856912C77A57CC F1 - World Championship Edition (E) GG Europe