BizHawk/BizHawk.Emulation.Cores/Consoles/Intellivision/Cartridge.cs

261 lines
5.0 KiB
C#
Raw Normal View History

using System;
using BizHawk.Common;
using BizHawk.Common.BufferExtensions;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Intellivision
{
public sealed class Cartridge : ICart
{
private readonly ushort[] Data = new ushort[56320];
2016-12-17 23:23:30 +00:00
private ushort[] Cart_Ram = new ushort[0x800];
2016-12-17 19:00:03 +00:00
// There are 10 mappers Intellivision games use (not counting intellicart which is handled seperately)
// we will pick the mapper from the game DB and default to 0
private int _mapper = 0;
public string BoardName => $"Mapper {_mapper}";
public void SyncState(Serializer ser)
{
ser.BeginSection("Cart");
ser.Sync("mapper", ref _mapper);
2019-03-28 03:18:58 +00:00
ser.Sync(nameof(Cart_Ram), ref Cart_Ram, false);
ser.EndSection();
}
public int Parse(byte[] rom)
{
// Combine every two bytes into a word.
int index = 0;
while (index + 1 < rom.Length)
{
Data[(index / 2)] = (ushort)((rom[index++] << 8) | rom[index++]);
}
// look up hash in gamedb to see what mapper to use
// if none found default is zero
string hash_sha1 = null;
string s_mapper = null;
hash_sha1 = "sha1:" + rom.HashSHA1(16, rom.Length - 16);
var gi = Database.CheckDatabase(hash_sha1);
if (gi != null)
{
var dict = gi.GetOptionsDict();
if (!dict.ContainsKey("board"))
{
throw new Exception("INTV gamedb entries must have a board identifier!");
}
s_mapper = dict["board"];
}
else
{
s_mapper = "0";
}
int.TryParse(s_mapper, out _mapper);
return rom.Length;
}
public ushort? ReadCart(ushort addr, bool peek)
{
switch (_mapper)
{
case 0:
if (addr >= 0x5000 && addr <= 0x6FFF)
{
return Data[addr - 0x5000];
}
if (addr >= 0xD000 && addr <= 0xDFFF)
{
return Data[addr - 0xB000];
}
if (addr >= 0xF000 && addr <= 0xFFFF)
{
return Data[addr - 0xC000];
}
break;
2016-12-17 19:00:03 +00:00
case 1:
if (addr >= 0x5000 && addr <= 0x6FFF)
2016-12-17 19:00:03 +00:00
{
return Data[addr - 0x5000];
}
if (addr >= 0xD000 && addr <= 0xFFFF)
2016-12-17 19:00:03 +00:00
{
return Data[addr - 0xB000];
}
break;
case 2:
if (addr >= 0x5000 && addr <= 0x6FFF)
2016-12-17 19:00:03 +00:00
{
return Data[addr - 0x5000];
}
if (addr >= 0x9000 && addr <= 0xBFFF)
2016-12-17 19:00:03 +00:00
{
return Data[addr - 0x7000];
}
if (addr >= 0xD000 && addr <= 0xDFFF)
2016-12-17 19:00:03 +00:00
{
return Data[addr - 0x8000];
}
break;
case 3:
if (addr >= 0x5000 && addr <= 0x6FFF)
2016-12-17 19:00:03 +00:00
{
return Data[addr - 0x5000];
}
if (addr >= 0x9000 && addr <= 0xAFFF)
2016-12-17 19:00:03 +00:00
{
return Data[addr - 0x7000];
}
if (addr >= 0xD000 && addr <= 0xDFFF)
2016-12-17 19:00:03 +00:00
{
return Data[addr - 0x9000];
}
if (addr >= 0xF000 && addr <= 0xFFFF)
2016-12-17 19:00:03 +00:00
{
return Data[addr - 0xA000];
}
break;
case 4:
if (addr >= 0x5000 && addr <= 0x6FFF)
2016-12-17 19:00:03 +00:00
{
return Data[addr - 0x5000];
}
if (addr >= 0xD000 && addr <= 0xD3FF)
2016-12-17 19:00:03 +00:00
{
return Cart_Ram[addr - 0xD000];
}
break;
case 5:
if (addr >= 0x5000 && addr <= 0x7FFF)
{
return Data[addr - 0x5000];
}
if (addr >= 0x9000 && addr <= 0xBFFF)
{
return Data[addr - 0x6000];
}
break;
2016-12-17 19:00:03 +00:00
case 6:
if (addr >= 0x6000 && addr <= 0x7FFF)
2016-12-17 19:00:03 +00:00
{
return Data[addr - 0x6000];
}
break;
case 7:
if (addr >= 0x4800 && addr <= 0x67FF)
2016-12-17 19:00:03 +00:00
{
return Data[addr - 0x4800];
}
break;
case 8:
if (addr >= 0x5000 && addr <= 0x5FFF)
2016-12-17 19:00:03 +00:00
{
return Data[addr - 0x5000];
}
else if (addr >= 0x7000 && addr <= 0x7FFF)
2016-12-17 19:00:03 +00:00
{
return Data[addr - 0x6000];
}
break;
case 9:
if (addr >= 0x5000 && addr <= 0x6FFF)
2016-12-17 19:00:03 +00:00
{
return Data[addr - 0x5000];
}
if (addr >= 0x9000 && addr <= 0xAFFF)
2016-12-17 19:00:03 +00:00
{
return Data[addr - 0x7000];
}
if (addr >= 0xD000 && addr <= 0xDFFF)
2016-12-17 19:00:03 +00:00
{
return Data[addr - 0x9000];
}
if (addr >= 0xF000 && addr <= 0xFFFF)
2016-12-17 19:00:03 +00:00
{
return Data[addr - 0xA000];
}
if (addr >= 0x8800 && addr <= 0x8FFF)
2016-12-17 19:00:03 +00:00
{
return Cart_Ram[addr - 0x8800];
}
break;
case 10:
if (addr >= 0x5000 && addr <= 0x6FFF)
{
return Data[addr - 0x5000];
}
if (addr >= 0x8800 && addr <= 0xB7FF)
{
return Data[addr - 0x6800];
}
if (addr >= 0xD000 && addr <= 0xFFFF)
{
return Data[addr - 0x8000];
}
break;
}
return null;
}
public bool WriteCart(ushort addr, ushort value, bool poke)
{
switch (_mapper)
2016-12-17 19:00:03 +00:00
{
case 4:
if (addr >= 0xD000 && addr <= 0xD3FF)
2016-12-17 19:00:03 +00:00
{
Cart_Ram[addr - 0xD000] = value;
return true;
}
break;
case 9:
if (addr >= 0x8800 && addr <= 0x8FFF)
2016-12-17 19:00:03 +00:00
{
Cart_Ram[addr - 0x8800] = value;
return true;
}
break;
}
return false;
}
}
}