170 lines
5.9 KiB
C#
170 lines
5.9 KiB
C#
/*
|
|
* Cart.cs
|
|
*
|
|
* An abstraction of a game cart. Attributable to Kevin Horton's Bankswitching
|
|
* document, the Stella source code, and Eckhard Stolberg's 7800 Bankswitching Guide.
|
|
*
|
|
* Copyright © 2003, 2004, 2010, 2011 Mike Murphy
|
|
*
|
|
*/
|
|
using System;
|
|
|
|
namespace EMU7800.Core
|
|
{
|
|
public abstract class Cart : IDevice
|
|
{
|
|
static int _multicartBankSelector;
|
|
|
|
protected MachineBase M { get; set; }
|
|
protected internal byte[] ROM { get; set; }
|
|
|
|
#region IDevice Members
|
|
|
|
public virtual void Reset() { }
|
|
|
|
public abstract byte this[ushort addr] { get; set; }
|
|
|
|
#endregion
|
|
|
|
public virtual void Attach(MachineBase m)
|
|
{
|
|
if (m == null)
|
|
throw new ArgumentNullException("m");
|
|
if (M != null && M != m)
|
|
throw new InvalidOperationException("Cart already attached to a different machine.");
|
|
M = m;
|
|
}
|
|
|
|
public virtual void StartFrame()
|
|
{
|
|
}
|
|
|
|
public virtual void EndFrame()
|
|
{
|
|
}
|
|
|
|
protected internal virtual bool RequestSnooping
|
|
{
|
|
get { return false; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates an instance of the specified cart.
|
|
/// </summary>
|
|
/// <param name="romBytes"></param>
|
|
/// <param name="cartType"></param>
|
|
/// <exception cref="Emu7800Exception">Specified CartType is unexpected.</exception>
|
|
public static Cart Create(byte[] romBytes, CartType cartType)
|
|
{
|
|
if (cartType == CartType.None)
|
|
{
|
|
switch (romBytes.Length)
|
|
{
|
|
case 2048:
|
|
cartType = CartType.A2K;
|
|
break;
|
|
case 4096:
|
|
cartType = CartType.A4K;
|
|
break;
|
|
case 8192:
|
|
cartType = CartType.A8K;
|
|
break;
|
|
case 16384:
|
|
cartType = CartType.A16K;
|
|
break;
|
|
case 32768:
|
|
cartType = CartType.A32K;
|
|
break;
|
|
}
|
|
}
|
|
|
|
switch (cartType)
|
|
{
|
|
case CartType.A2K: return new CartA2K(romBytes);
|
|
case CartType.A4K: return new CartA4K(romBytes);
|
|
case CartType.A8K: return new CartA8K(romBytes);
|
|
case CartType.A8KR: return new CartA8KR(romBytes);
|
|
case CartType.A16K: return new CartA16K(romBytes);
|
|
case CartType.A16KR: return new CartA16KR(romBytes);
|
|
case CartType.DC8K: return new CartDC8K(romBytes);
|
|
case CartType.PB8K: return new CartPB8K(romBytes);
|
|
case CartType.TV8K: return new CartTV8K(romBytes);
|
|
case CartType.CBS12K: return new CartCBS12K(romBytes);
|
|
case CartType.A32K: return new CartA32K(romBytes);
|
|
case CartType.A32KR: return new CartA32KR(romBytes);
|
|
case CartType.MN16K: return new CartMN16K(romBytes);
|
|
case CartType.DPC: return new CartDPC(romBytes);
|
|
case CartType.M32N12K: return new CartA2K(romBytes, _multicartBankSelector++);
|
|
case CartType.A7808: return new Cart7808(romBytes);
|
|
case CartType.A7816: return new Cart7816(romBytes);
|
|
case CartType.A7832P: return new Cart7832P(romBytes);
|
|
case CartType.A7832: return new Cart7832(romBytes);
|
|
case CartType.A7848: return new Cart7848(romBytes);
|
|
case CartType.A78SGP: return new Cart78SGP(romBytes);
|
|
case CartType.A78SG: return new Cart78SG(romBytes, false);
|
|
case CartType.A78SGR: return new Cart78SG(romBytes, true);
|
|
case CartType.A78S9: return new Cart78S9(romBytes);
|
|
case CartType.A78S4: return new Cart78S4(romBytes, false);
|
|
case CartType.A78S4R: return new Cart78S4(romBytes, true);
|
|
case CartType.A78AB: return new Cart78AB(romBytes);
|
|
case CartType.A78AC: return new Cart78AC(romBytes);
|
|
default:
|
|
throw new Emu7800Exception("Unexpected CartType: " + cartType);
|
|
}
|
|
}
|
|
|
|
protected void LoadRom(byte[] romBytes, int multicartBankSize, int multicartBankNo)
|
|
{
|
|
if (romBytes == null)
|
|
throw new ArgumentNullException("romBytes");
|
|
|
|
ROM = new byte[multicartBankSize];
|
|
Buffer.BlockCopy(romBytes, multicartBankSize*multicartBankNo, ROM, 0, multicartBankSize);
|
|
}
|
|
|
|
protected void LoadRom(byte[] romBytes, int minSize)
|
|
{
|
|
if (romBytes == null)
|
|
throw new ArgumentNullException("romBytes");
|
|
|
|
if (romBytes.Length >= minSize)
|
|
{
|
|
ROM = romBytes;
|
|
}
|
|
else
|
|
{
|
|
ROM = new byte[minSize];
|
|
Buffer.BlockCopy(romBytes, 0, ROM, 0, romBytes.Length);
|
|
}
|
|
}
|
|
|
|
protected void LoadRom(byte[] romBytes)
|
|
{
|
|
LoadRom(romBytes, romBytes.Length);
|
|
}
|
|
|
|
protected Cart()
|
|
{
|
|
}
|
|
|
|
#region Serialization Members
|
|
|
|
protected Cart(DeserializationContext input)
|
|
{
|
|
if (input == null)
|
|
throw new ArgumentNullException("input");
|
|
|
|
input.CheckVersion(1);
|
|
}
|
|
|
|
public virtual void GetObjectData(SerializationContext output)
|
|
{
|
|
if (output == null)
|
|
throw new ArgumentNullException("output");
|
|
|
|
output.WriteVersion(1);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |