BizHawk/BizHawk.Emulation.Cores/Consoles/Atari/2600/Mappers/mAR.cs

202 lines
6.5 KiB
C#

using System;
using BizHawk.Common;
/**
This is the cartridge class for Arcadia (aka Starpath) Supercharger
games. Christopher Salomon provided most of the technical details
used in creating this class. A good description of the Supercharger
is provided in the Cuttle Cart's manual.
The Supercharger has four 2K banks. There are three banks of RAM
and one bank of ROM. All 6K of the RAM can be read and written.
D7-D5 of this byte: Write Pulse Delay (n/a for emulator)
D4-D0: RAM/ROM configuration:
$F000-F7FF $F800-FFFF Address range that banks map into
000wp 2 ROM
001wp 0 ROM
010wp 2 0 as used in Commie Mutants and many others
011wp 0 2 as used in Suicide Mission
100wp 2 ROM
101wp 1 ROM
110wp 2 1 as used in Killer Satellites
111wp 1 2 as we use for 2k/4k ROM cloning
w = Write Enable (1 = enabled; accesses to $F000-$F0FF cause writes
to happen. 0 = disabled, and the cart acts like ROM.)
p = ROM Power (0 = enabled, 1 = off.) Only power the ROM if you're
wanting to access the ROM for multiloads. Otherwise set to 1.
*/
namespace BizHawk.Emulation.Cores.Atari.Atari2600
{
internal class mAR : MapperBase
{
public mAR()
{
throw new NotImplementedException();
}
private int _bank2k;
private ByteBuffer _ram = new ByteBuffer(6144);
private IntBuffer _offsets = new IntBuffer(2);
private bool _writePending = false;
private readonly byte[] _RomCode = {
0xa5, 0xfa, 0x85, 0x80, 0x4c, 0x18, 0xf8, 0xff,
0xff, 0xff, 0x78, 0xd8, 0xa0, 0x00, 0xa2, 0x00,
0x94, 0x00, 0xe8, 0xd0, 0xfb, 0x4c, 0x50, 0xf8,
0xa2, 0x00, 0xbd, 0x06, 0xf0, 0xad, 0xf8, 0xff,
0xa2, 0x00, 0xad, 0x00, 0xf0, 0xea, 0xbd, 0x00,
0xf7, 0xca, 0xd0, 0xf6, 0x4c, 0x50, 0xf8, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xa2, 0x03, 0xbc, 0x22, 0xf9, 0x94, 0xfa, 0xca,
0x10, 0xf8, 0xa0, 0x00, 0xa2, 0x28, 0x94, 0x04,
0xca, 0x10, 0xfb, 0xa2, 0x1c, 0x94, 0x81, 0xca,
0x10, 0xfb, 0xa9, 0xff, 0xc9, 0x00, 0xd0, 0x03,
0x4c, 0x13, 0xf9, 0xa9, 0x00, 0x85, 0x1b, 0x85,
0x1c, 0x85, 0x1d, 0x85, 0x1e, 0x85, 0x1f, 0x85,
0x19, 0x85, 0x1a, 0x85, 0x08, 0x85, 0x01, 0xa9,
0x10, 0x85, 0x21, 0x85, 0x02, 0xa2, 0x07, 0xca,
0xca, 0xd0, 0xfd, 0xa9, 0x00, 0x85, 0x20, 0x85,
0x10, 0x85, 0x11, 0x85, 0x02, 0x85, 0x2a, 0xa9,
0x05, 0x85, 0x0a, 0xa9, 0xff, 0x85, 0x0d, 0x85,
0x0e, 0x85, 0x0f, 0x85, 0x84, 0x85, 0x85, 0xa9,
0xf0, 0x85, 0x83, 0xa9, 0x74, 0x85, 0x09, 0xa9,
0x0c, 0x85, 0x15, 0xa9, 0x1f, 0x85, 0x17, 0x85,
0x82, 0xa9, 0x07, 0x85, 0x19, 0xa2, 0x08, 0xa0,
0x00, 0x85, 0x02, 0x88, 0xd0, 0xfb, 0x85, 0x02,
0x85, 0x02, 0xa9, 0x02, 0x85, 0x02, 0x85, 0x00,
0x85, 0x02, 0x85, 0x02, 0x85, 0x02, 0xa9, 0x00,
0x85, 0x00, 0xca, 0x10, 0xe4, 0x06, 0x83, 0x66,
0x84, 0x26, 0x85, 0xa5, 0x83, 0x85, 0x0d, 0xa5,
0x84, 0x85, 0x0e, 0xa5, 0x85, 0x85, 0x0f, 0xa6,
0x82, 0xca, 0x86, 0x82, 0x86, 0x17, 0xe0, 0x0a,
0xd0, 0xc3, 0xa9, 0x02, 0x85, 0x01, 0xa2, 0x1c,
0xa0, 0x00, 0x84, 0x19, 0x84, 0x09, 0x94, 0x81,
0xca, 0x10, 0xfb, 0xa6, 0x80, 0xdd, 0x00, 0xf0,
0xa9, 0x9a, 0xa2, 0xff, 0xa0, 0x00, 0x9a, 0x4c,
0xfa, 0x00, 0xcd, 0xf8, 0xff, 0x4c
};
private readonly byte[] RomHeader = {
0xac, 0xfa, 0x0f, 0x18, 0x62, 0x00, 0x24, 0x02,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x18, 0x1c,
0x01, 0x05, 0x09, 0x0d, 0x11, 0x15, 0x19, 0x1d,
0x02, 0x06, 0x0a, 0x0e, 0x12, 0x16, 0x1a, 0x1e,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
};
public override bool HasCartRam
{
get { return true; }
}
public override ByteBuffer CartRam
{
get { return _ram; }
}
public override void SyncState(Serializer ser)
{
base.SyncState(ser);
ser.Sync("bank4k", ref _bank2k);
ser.Sync("ram", ref _ram);
}
public override void HardReset()
{
_bank2k = 0;
_ram = new ByteBuffer(6144);
base.HardReset();
}
public override void Dispose()
{
base.Dispose();
_ram.Dispose();
}
private byte ReadMem(ushort addr, bool peek)
{
if (!peek)
{
Address(addr);
}
if (addr < 0x1000)
{
return base.ReadMemory(addr);
}
if (addr == 0x1850 && _offsets[1] == (3 << 11))
{
/// TODO: weird stuff goes here
///
return Core.Rom[(addr & 0x7FF) + _offsets[1]];
}
// TODO: cancel pending writes
if (addr == 0x1FF8)
{
_writePending = false;
}
return Core.Rom[(_bank2k << 12) + (addr & 0xFFF)];
}
public override byte ReadMemory(ushort addr)
{
return ReadMem(addr, false);
}
public override byte PeekMemory(ushort addr)
{
return ReadMem(addr, true);
}
private void Address(ushort addr)
{
if (addr == 0x1FF8)
{
_bank2k = 0;
}
else if (addr == 0x1FF9)
{
_bank2k = 1;
}
}
}
}