BizHawk/EMU7800/Core/CartMN16K.cs

136 lines
4.0 KiB
C#

namespace EMU7800.Core
{
/// <summary>
/// M-Network 16KB bankswitched carts with 2KB RAM.
/// </summary>
public sealed class CartMN16K : Cart
{
//
// Cart Format Mapping to ROM Address Space
// Segment1: 0x0000:0x0800 Bank1:0x1000:0x0800 Select Seg: 1fe0-1fe6, 1fe7=RAM Seg1
// Segment2: 0x0800:0x0800 Bank2:0x1800:0x0800 Always Seg8
// Segment3: 0x1000:0x0800
// Segment4: 0x1800:0x0800
// Segment5: 0x2000:0x0800
// Segment6: 0x2800:0x0800
// Segment7: 0x3000:0x0800
// Segment8: 0x3800:0x0800
//
// RAM RAM Segment1 when 1fe7 select is accessed
// Segment1: 0x0000:0x0400 0x1000-0x13FF write port
// Segment2: 0x0400:0x0400 0x1400-0x17FF read port
//
// RAM Segment2: 1ff8-1ffb selects 256-byte block
// 0x1800-0x18ff write port
// 0x1900-0x19ff read port
//
ushort BankBaseAddr, BankBaseRAMAddr;
bool RAMBankOn;
readonly byte[] RAM;
int Bank
{
set
{
BankBaseAddr = (ushort)(value << 11); // multiply by 2048
RAMBankOn = (value == 0x07);
}
}
int BankRAM
{
set { BankBaseRAMAddr = (ushort) (value << 8); } // multiply by 256
}
#region IDevice Members
public override void Reset()
{
Bank = 0;
BankRAM = 0;
}
public override byte this[ushort addr]
{
get
{
addr &= 0x0fff;
UpdateBanks(addr);
if (RAMBankOn && addr >= 0x0400 && addr < 0x0800)
{
return RAM[addr & 0x03ff];
}
if (addr >= 0x0900 && addr < 0x0a00)
{
return RAM[0x400 + BankBaseRAMAddr + (addr & 0xff)];
}
return addr < 0x0800 ? ROM[BankBaseAddr + (addr & 0x07ff)] : ROM[0x3800 + (addr & 0x07ff)];
}
set
{
addr &= 0x0fff;
UpdateBanks(addr);
if (RAMBankOn && addr < 0x0400)
{
RAM[addr & 0x03ff] = value;
}
else if (addr >= 0x0800 && addr < 0x0900)
{
RAM[0x400 + BankBaseRAMAddr + (addr & 0xff)] = value;
}
}
}
#endregion
private CartMN16K()
{
}
public CartMN16K(byte[] romBytes)
{
LoadRom(romBytes, 0x4000);
RAM = new byte[0x800];
Bank = 0;
BankRAM = 0;
}
void UpdateBanks(ushort addr)
{
if (addr >= 0x0fe0 && addr < 0x0fe8)
{
Bank = addr & 0x07;
}
else if (addr >= 0x0fe8 && addr < 0x0fec)
{
BankRAM = addr & 0x03;
}
}
#region Serialization Members
public CartMN16K(DeserializationContext input, MachineBase m) : base(input)
{
input.CheckVersion(1);
LoadRom(input.ReadExpectedBytes(0x4000), 0x4000);
RAM = input.ReadExpectedBytes(0x800);
BankBaseAddr = input.ReadUInt16();
BankBaseRAMAddr = input.ReadUInt16();
RAMBankOn = input.ReadBoolean();
}
public override void GetObjectData(SerializationContext output)
{
base.GetObjectData(output);
output.WriteVersion(1);
output.Write(ROM);
output.Write(RAM);
output.Write(BankBaseAddr);
output.Write(BankBaseRAMAddr);
output.Write(RAMBankOn);
}
#endregion
}
}