133 lines
2.6 KiB
C#
133 lines
2.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
|
|
using BizHawk.Common;
|
|
using BizHawk.Common.NumberExtensions;
|
|
|
|
namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|
{
|
|
public sealed class CoolBoy : MMC3Board_Base
|
|
{
|
|
// eldritch horror pirate multicart
|
|
// 32MB prg rom, no prg ram, no chr rom, 128KB chr ram
|
|
|
|
// behavior directly from fceu-mm
|
|
|
|
// this could be broken down into more sensibly named variables
|
|
byte[] exp = new byte[4];
|
|
|
|
public override bool Configure(NES.EDetectionOrigin origin)
|
|
{
|
|
switch (Cart.board_type)
|
|
{
|
|
case "UNIF_COOLBOY":
|
|
AssertChr(0);
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
Cart.vram_size = 128;
|
|
Cart.wram_size = 0;
|
|
|
|
BaseSetup();
|
|
|
|
// normally base mmc3 sets this right, but it has a hardcoded assumption
|
|
// that no chr rom => 8K of chr ram, not 128K. i'd change the base class,
|
|
// but not sure if that would break something else
|
|
chr_mask = 127;
|
|
|
|
return true;
|
|
}
|
|
|
|
public override void WriteWRAM(int addr, byte value)
|
|
{
|
|
if (addr < 0x1000)
|
|
{
|
|
if (!exp[3].Bit(7))
|
|
{
|
|
exp[addr & 3] = value;
|
|
/*
|
|
if (exp[3].Bit(7))
|
|
{
|
|
Console.WriteLine("EXP Write Protect Activated");
|
|
}
|
|
if (exp[3].Bit(4))
|
|
{
|
|
Console.WriteLine("Funky Mode Active");
|
|
}
|
|
*/
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override int Get_PRGBank_8K(int addr)
|
|
{
|
|
int mask = 0, shift = 0;
|
|
int baseaddr = exp[0] & 0x07 | (exp[1] & 0x10) >> 1 | (exp[1] & 0x0c) << 2 | (exp[0] & 0x30) << 2;
|
|
|
|
switch (exp[0] & 0xc0)
|
|
{
|
|
case 0x00:
|
|
baseaddr >>= 2;
|
|
mask = 0x3f;
|
|
shift = 6;
|
|
break;
|
|
case 0x80:
|
|
baseaddr >>= 1;
|
|
mask = 0x1f;
|
|
shift = 5;
|
|
break;
|
|
case 0xc0:
|
|
shift = 4;
|
|
if (exp[3].Bit(4))
|
|
{
|
|
mask = 1 | exp[1] & 2;
|
|
}
|
|
else
|
|
{
|
|
mask = 0xf;
|
|
}
|
|
break;
|
|
case 0x40:
|
|
// ??
|
|
throw new InvalidOperationException();
|
|
}
|
|
|
|
int v = base.Get_PRGBank_8K(addr);
|
|
|
|
int ret = baseaddr << shift | v & mask;
|
|
if (exp[3].Bit(4))
|
|
{
|
|
ret |= exp[3] & (0x0e ^ exp[1] & 2);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
protected override int Get_CHRBank_1K(int addr)
|
|
{
|
|
if (exp[3].Bit(4))
|
|
{
|
|
return (exp[2] & 15) << 3 | addr >> 10 & 7;
|
|
}
|
|
else
|
|
{
|
|
return base.Get_CHRBank_1K(addr);
|
|
}
|
|
}
|
|
|
|
public override void SyncState(Serializer ser)
|
|
{
|
|
base.SyncState(ser);
|
|
ser.Sync("exp", ref exp, false);
|
|
}
|
|
|
|
public override void NESSoftReset()
|
|
{
|
|
Array.Clear(exp, 0, 4);
|
|
}
|
|
}
|
|
}
|