166 lines
3.7 KiB
C#
166 lines
3.7 KiB
C#
using BizHawk.Common;
|
|
|
|
namespace BizHawk.Emulation.Cores.PCEngine
|
|
{
|
|
partial class PCEngine
|
|
{
|
|
private bool ArcadeCard, ArcadeCardRewindHack;
|
|
private int ShiftRegister;
|
|
private byte ShiftAmount;
|
|
private byte RotateAmount;
|
|
|
|
private readonly ArcadeCardPage[] ArcadePage = new ArcadeCardPage[4];
|
|
|
|
private class ArcadeCardPage
|
|
{
|
|
public byte Control;
|
|
public int Base;
|
|
public ushort Offset;
|
|
public ushort IncrementValue;
|
|
|
|
public void Increment()
|
|
{
|
|
if ((Control & 1) == 0)
|
|
return;
|
|
|
|
if ((Control & 0x10) != 0)
|
|
{
|
|
Base += IncrementValue;
|
|
Base &= 0xFFFFFF;
|
|
}
|
|
else
|
|
Offset += IncrementValue;
|
|
}
|
|
|
|
public int EffectiveAddress
|
|
{
|
|
get
|
|
{
|
|
int address = Base;
|
|
if ((Control & 2) != 0)
|
|
address += Offset;
|
|
if ((Control & 8) != 0)
|
|
address += 0xFF0000;
|
|
return address & 0x1FFFFF;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void WriteArcadeCard(int addr, byte value)
|
|
{
|
|
if (ArcadeCard == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var page = ArcadePage[(addr >> 4) & 3];
|
|
switch (addr & 0x0F)
|
|
{
|
|
case 0:
|
|
case 1:
|
|
ArcadeRam[page.EffectiveAddress] = value;
|
|
page.Increment();
|
|
break;
|
|
case 2:
|
|
page.Base &= ~0xFF;
|
|
page.Base |= value;
|
|
break;
|
|
case 3:
|
|
page.Base &= ~0xFF00;
|
|
page.Base |= (value << 8);
|
|
break;
|
|
case 4:
|
|
page.Base &= ~0xFF0000;
|
|
page.Base |= (value << 16);
|
|
break;
|
|
case 5:
|
|
page.Offset &= 0xFF00;
|
|
page.Offset |= value;
|
|
break;
|
|
case 6:
|
|
page.Offset &= 0x00FF;
|
|
page.Offset |= (ushort)(value << 8);
|
|
if ((page.Control & 0x60) == 0x40)
|
|
{
|
|
page.Base += page.Offset + (((page.Control & 0x08) == 0) ? 0 : 0xFF00000);
|
|
page.Base &= 0xFFFFFF;
|
|
}
|
|
break;
|
|
case 7:
|
|
page.IncrementValue &= 0xFF00;
|
|
page.IncrementValue |= value;
|
|
break;
|
|
case 8:
|
|
page.IncrementValue &= 0x00FF;
|
|
page.IncrementValue |= (ushort)(value << 8);
|
|
break;
|
|
case 9:
|
|
page.Control = (byte)(value & 0x7F);
|
|
break;
|
|
case 10:
|
|
if ((page.Control & 0x60) == 0x60)
|
|
{
|
|
page.Base += page.Offset;
|
|
page.Base &= 0xFFFFFF;
|
|
if ((page.Control & 8) != 0)
|
|
{
|
|
page.Base += 0xFF0000;
|
|
page.Base &= 0xFFFFFF;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
private byte ReadArcadeCard(int addr)
|
|
{
|
|
if (ArcadeCard == false) return 0xFF;
|
|
var page = ArcadePage[(addr >> 4) & 3];
|
|
switch (addr & 0x0F)
|
|
{
|
|
case 0:
|
|
case 1:
|
|
byte value = ArcadeRam[page.EffectiveAddress];
|
|
page.Increment();
|
|
return value;
|
|
case 2: return (byte)(page.Base >> 0);
|
|
case 3: return (byte)(page.Base >> 8);
|
|
case 4: return (byte)(page.Base >> 16);
|
|
case 5: return (byte)(page.Offset >> 0);
|
|
case 6: return (byte)(page.Offset >> 8);
|
|
case 7: return (byte)(page.IncrementValue >> 0);
|
|
case 8: return (byte)(page.IncrementValue >> 8);
|
|
case 9: return (byte)(page.Control >> 0);
|
|
case 10: return 0;
|
|
}
|
|
|
|
return 0xFF;
|
|
}
|
|
|
|
public void ArcadeCardSyncState(Serializer ser)
|
|
{
|
|
ser.BeginSection("ArcadeCard");
|
|
ser.Sync("ShiftRegister", ref ShiftRegister);
|
|
ser.Sync("ShiftAmount", ref ShiftAmount);
|
|
ser.Sync("RotateAmount", ref RotateAmount);
|
|
|
|
if (ArcadeCardRewindHack == false || ser.IsText)
|
|
{
|
|
ser.Sync("ArcadeRAM", ref ArcadeRam, false);
|
|
}
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
ser.BeginSection("Page" + i);
|
|
|
|
ser.Sync("Control", ref ArcadePage[i].Control);
|
|
ser.Sync("Base", ref ArcadePage[i].Base);
|
|
ser.Sync("Offset", ref ArcadePage[i].Offset);
|
|
ser.Sync("IncrementValue", ref ArcadePage[i].IncrementValue);
|
|
ser.EndSection();
|
|
}
|
|
|
|
ser.EndSection();
|
|
}
|
|
}
|
|
} |