365 lines
8.1 KiB
C#
365 lines
8.1 KiB
C#
namespace BizHawk.Emulation.Cores.Intellivision
|
|
{
|
|
public sealed partial class Intellivision
|
|
{
|
|
private const ushort UNMAPPED = 0xFFFF;
|
|
|
|
private byte[] ScratchpadRam = new byte[240];
|
|
private ushort[] SystemRam = new ushort[352];
|
|
private ushort[] ExecutiveRom = new ushort[4096]; // TODO: Intellivision II support?
|
|
private byte[] GraphicsRom = new byte[2048];
|
|
private byte[] GraphicsRam = new byte[512];
|
|
|
|
public ushort ReadMemory(ushort addr)
|
|
{
|
|
ushort? cart = Cart.ReadCart(addr);
|
|
ushort? stic = Stic.ReadSTIC(addr);
|
|
ushort? psg = Psg.ReadPSG(addr);
|
|
ushort? core = null;
|
|
|
|
switch (addr & 0xF000)
|
|
{
|
|
case 0x0000:
|
|
if (addr <= 0x007F)
|
|
{
|
|
// STIC.
|
|
break;
|
|
}
|
|
else if (addr <= 0x00FF)
|
|
{
|
|
// Unoccupied.
|
|
break;
|
|
}
|
|
else if (addr <= 0x01EF)
|
|
{
|
|
core = (ushort)(ScratchpadRam[addr - 0x0100] & 0x00FF);
|
|
}
|
|
else if (addr <= 0x01FF)
|
|
{
|
|
// PSG.
|
|
break;
|
|
}
|
|
else if (addr <= 0x035F)
|
|
{
|
|
core = SystemRam[addr - 0x0200];
|
|
}
|
|
else if (addr <= 0x03FF)
|
|
{
|
|
// TODO: Garbage values for Intellivision II.
|
|
break;
|
|
}
|
|
else if (addr <= 0x04FF)
|
|
{
|
|
// TODO: Additional EXEC ROM for Intellivision II.
|
|
break;
|
|
}
|
|
break;
|
|
case 0x1000:
|
|
core = (ushort)(ExecutiveRom[addr - 0x1000] & 0x3FF);
|
|
break;
|
|
case 0x3000:
|
|
if (addr <= 0x37FF)
|
|
{
|
|
// TODO: OK only during VBlank Period 2.
|
|
core = (byte)(GraphicsRom[addr - 0x3000] & 0x00FF);
|
|
}
|
|
else if (addr <= 0x39FF)
|
|
{
|
|
// TODO: OK only during VBlank Period 2.
|
|
core = (byte)(GraphicsRam[addr - 0x3800] & 0x00FF);
|
|
}
|
|
else if (addr <= 0x3BFF)
|
|
{
|
|
// TODO: OK only during VBlank Period 2.
|
|
core = (byte)(GraphicsRam[addr - 0x3A00] & 0x00FF);
|
|
}
|
|
else if (addr <= 0x3DFF)
|
|
{
|
|
// TODO: OK only during VBlank Period 2.
|
|
core = (byte)(GraphicsRam[addr - 0x3C00] & 0x00FF);
|
|
}
|
|
else
|
|
{
|
|
// TODO: OK only during VBlank Period 2.
|
|
core = (byte)(GraphicsRam[addr - 0x3E00] & 0x00FF);
|
|
}
|
|
break;
|
|
case 0x7000:
|
|
if (addr <= 0x77FF)
|
|
{
|
|
// Available to cartridges.
|
|
break;
|
|
}
|
|
else if (addr <= 0x79FF)
|
|
{
|
|
// Write-only Graphics RAM.
|
|
break;
|
|
}
|
|
else if (addr <= 0x7BFF)
|
|
{
|
|
// Write-only Graphics RAM.
|
|
break;
|
|
}
|
|
else if (addr <= 0x7DFF)
|
|
{
|
|
// Write-only Graphics RAM.
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// Write-only Graphics RAM.
|
|
break;
|
|
}
|
|
case 0xB000:
|
|
if (addr <= 0xB7FF)
|
|
{
|
|
// Available to cartridges.
|
|
break;
|
|
}
|
|
else if (addr <= 0xB9FF)
|
|
{
|
|
// Write-only Graphics RAM.
|
|
break;
|
|
}
|
|
else if (addr <= 0xBBFF)
|
|
{
|
|
// Write-only Graphics RAM.
|
|
break;
|
|
}
|
|
else if (addr <= 0xBDFF)
|
|
{
|
|
// Write-only Graphics RAM.
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// Write-only Graphics RAM.
|
|
break;
|
|
}
|
|
case 0xF000:
|
|
if (addr <= 0xF7FF)
|
|
{
|
|
// Available to cartridges.
|
|
break;
|
|
}
|
|
else if (addr <= 0xF9FF)
|
|
{
|
|
// Write-only Graphics RAM.
|
|
break;
|
|
}
|
|
else if (addr <= 0xFBFF)
|
|
{
|
|
// Write-only Graphics RAM.
|
|
break;
|
|
}
|
|
else if (addr <= 0xFDFF)
|
|
{
|
|
// Write-only Graphics RAM.
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// Write-only Graphics RAM.
|
|
break;
|
|
}
|
|
}
|
|
|
|
CoreComm.MemoryCallbackSystem.CallRead(addr);
|
|
|
|
if (cart != null)
|
|
{
|
|
return (ushort)cart;
|
|
}
|
|
else if (stic != null)
|
|
{
|
|
return (ushort)stic;
|
|
}
|
|
else if (psg != null)
|
|
{
|
|
return (ushort)psg;
|
|
}
|
|
else if (core != null)
|
|
{
|
|
return (ushort)core;
|
|
}
|
|
return UNMAPPED;
|
|
}
|
|
|
|
public bool WriteMemory(ushort addr, ushort value)
|
|
{
|
|
bool cart = Cart.WriteCart(addr, value);
|
|
bool stic = Stic.WriteSTIC(addr, value);
|
|
bool psg = Psg.WritePSG(addr, value);
|
|
switch (addr & 0xF000)
|
|
{
|
|
case 0x0000:
|
|
if (addr <= 0x007F)
|
|
{
|
|
// STIC.
|
|
break;
|
|
}
|
|
else if (addr <= 0x00FF)
|
|
{
|
|
// Unoccupied.
|
|
break;
|
|
}
|
|
else if (addr <= 0x01EF)
|
|
{
|
|
ScratchpadRam[addr - 0x0100] = (byte)(value & 0x00FF);
|
|
return true;
|
|
}
|
|
else if (addr <= 0x01FF)
|
|
{
|
|
// PSG.
|
|
break;
|
|
}
|
|
else if (addr <= 0x035F)
|
|
{
|
|
SystemRam[addr - 0x0200] = value;
|
|
return true;
|
|
}
|
|
else if (addr <= 0x03FF)
|
|
{
|
|
// Read-only garbage values for Intellivision II.
|
|
break;
|
|
}
|
|
else if (addr <= 0x04FF)
|
|
{
|
|
// Read-only additional EXEC ROM for Intellivision II.
|
|
break;
|
|
}
|
|
break;
|
|
case 0x1000:
|
|
// Read-only Executive ROM.
|
|
break;
|
|
case 0x3000:
|
|
if (addr <= 0x37FF)
|
|
{
|
|
// Read-only Graphics ROM.
|
|
break;
|
|
}
|
|
else if (addr <= 0x39FF)
|
|
{
|
|
// TODO: OK only during VBlank Period 2.
|
|
GraphicsRam[addr - 0x3800] = (byte)(value & 0x00FF);
|
|
return true;
|
|
}
|
|
else if (addr <= 0x3BFF)
|
|
{
|
|
// TODO: OK only during VBlank Period 2.
|
|
GraphicsRam[addr - 0x3A00] = (byte)(value & 0x00FF);
|
|
return true;
|
|
}
|
|
else if (addr <= 0x3DFF)
|
|
{
|
|
// TODO: OK only during VBlank Period 2.
|
|
GraphicsRam[addr - 0x3C00] = (byte)(value & 0x00FF);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
// TODO: OK only during VBlank Period 2.
|
|
GraphicsRam[addr - 0x3E00] = (byte)(value & 0x00FF);
|
|
return true;
|
|
}
|
|
case 0x7000:
|
|
if (addr <= 0x77FF)
|
|
{
|
|
// Available to cartridges.
|
|
break;
|
|
}
|
|
else if (addr <= 0x79FF)
|
|
{
|
|
// TODO: OK only during VBlank Period 2.
|
|
GraphicsRam[addr & 0x01FF] = (byte)(value & 0x00FF);
|
|
return true;
|
|
}
|
|
else if (addr <= 0x7BFF)
|
|
{
|
|
// TODO: OK only during VBlank Period 2.
|
|
GraphicsRam[addr & 0x01FF] = (byte)(value & 0x00FF);
|
|
return true;
|
|
}
|
|
else if (addr <= 0x7DFF)
|
|
{
|
|
// TODO: OK only during VBlank Period 2.
|
|
GraphicsRam[addr & 0x01FF] = (byte)(value & 0x00FF);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
// TODO: OK only during VBlank Period 2.
|
|
GraphicsRam[addr & 0x01FF] = (byte)(value & 0x00FF);
|
|
return true;
|
|
}
|
|
case 0x9000:
|
|
case 0xA000:
|
|
case 0xB000:
|
|
if (addr <= 0xB7FF)
|
|
{
|
|
// Available to cartridges.
|
|
break;
|
|
}
|
|
else if (addr <= 0xB9FF)
|
|
{
|
|
// TODO: OK only during VBlank Period 2.
|
|
GraphicsRam[addr - 0xB800] = (byte)(value & 0x00FF);
|
|
return true;
|
|
}
|
|
else if (addr <= 0xBBFF)
|
|
{
|
|
// TODO: OK only during VBlank Period 2.
|
|
GraphicsRam[addr - 0xBA00] = (byte)(value & 0x00FF);
|
|
return true;
|
|
}
|
|
else if (addr <= 0xBDFF)
|
|
{
|
|
// TODO: OK only during VBlank Period 2.
|
|
GraphicsRam[addr - 0xBC00] = (byte)(value & 0x00FF);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
// TODO: OK only during VBlank Period 2.
|
|
GraphicsRam[addr - 0xBE00] = (byte)(value & 0x00FF);
|
|
return true;
|
|
}
|
|
case 0xF000:
|
|
if (addr <= 0xF7FF)
|
|
{
|
|
// Available to cartridges.
|
|
break;
|
|
}
|
|
else if (addr <= 0xF9FF)
|
|
{
|
|
// TODO: OK only during VBlank Period 2.
|
|
GraphicsRam[addr - 0xF800] = (byte)(value & 0x00FF);
|
|
return true;
|
|
}
|
|
else if (addr <= 0xFBFF)
|
|
{
|
|
// TODO: OK only during VBlank Period 2.
|
|
GraphicsRam[addr - 0xFA00] = (byte)(value & 0x00FF);
|
|
return true;
|
|
}
|
|
else if (addr <= 0xFDFF)
|
|
{
|
|
// TODO: OK only during VBlank Period 2.
|
|
GraphicsRam[addr - 0xFC00] = (byte)(value & 0x00FF);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
// TODO: OK only during VBlank Period 2.
|
|
GraphicsRam[addr - 0xFE00] = (byte)(value & 0x00FF);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
CoreComm.MemoryCallbackSystem.CallWrite(addr);
|
|
|
|
return (cart || stic || psg);
|
|
}
|
|
}
|
|
}
|