BizHawk/BizHawk.Emulation.Cores/Consoles/Sega/SMS/MemoryMap.CodeMasters.cs

98 lines
3.2 KiB
C#

namespace BizHawk.Emulation.Cores.Sega.MasterSystem
{
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 < 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];
}
void WriteMemoryCM(ushort address, byte value)
{
if (address >= 0xC000)
SystemRam[address & RamSizeMask] = value;
else if (address == 0x0000) RomBank0 = (byte)(value % RomBanks);
else if (address == 0x4000) RomBank1 = (byte)(value % RomBanks);
else if (address == 0x8000) RomBank2 = (byte)(value % RomBanks);
}
void InitCodeMastersMapper()
{
Cpu.ReadMemory = ReadMemoryCM;
Cpu.WriteMemory = WriteMemoryCM;
WriteMemoryCM(0x0000, 0);
WriteMemoryCM(0x4000, 1);
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;
}
}
}