BizHawk/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/Camerica.cs

177 lines
4.1 KiB
C#

using BizHawk.Common;
using BizHawk.Common.NumberExtensions;
namespace BizHawk.Emulation.Cores.Nintendo.NES
{
//AKA mapper 071
//TODO - apparently this mapper contains good nes timing test cases
public sealed class Camerica_Mapper071 : NES.NESBoardBase
{
//configuration
int prg_bank_mask_16k;
bool mirror_control_enabled;
//state
IntBuffer prg_banks_16k = new IntBuffer(2);
public override void Dispose()
{
base.Dispose();
prg_banks_16k.Dispose();
}
public override void SyncState(Serializer ser)
{
base.SyncState(ser);
ser.Sync("prg_banks_16k", ref prg_banks_16k);
}
public override bool Configure(NES.EDetectionOrigin origin)
{
//configure
switch (Cart.board_type)
{
case "MAPPER071":
break;
case "CAMERICA-ALGN": //Linus Spacehead's Cosmic Crusade (U)
AssertPrg(128,256); AssertChr(0); AssertWram(0);
AssertVram(8,16); //zero 22-mar-2012 - added 16 here as a hack to make micro machines (aladdin) load. should remove this after it is fixed in the DB
break;
case "CAMERICA-BF9093": //Big Nose Freaks Out (U)
AssertPrg(64,128,256); AssertChr(0); AssertWram(0); AssertVram(8);
break;
case "CAMERICA-BF9097": //Fire Hawk
AssertPrg(128); AssertChr(0); AssertWram(0); AssertVram(8);
mirror_control_enabled = true;
break;
case "CODEMASTERS-NR8N": // untested
AssertPrg(256); AssertChr(0); AssertWram(0); AssertVram(8);
break;
default:
return false;
}
prg_bank_mask_16k = Cart.prg_size / 16 - 1;
prg_banks_16k[0] = 0x00;
prg_banks_16k[1] = 0xFF & prg_bank_mask_16k;
SetMirrorType(Cart.pad_h, Cart.pad_v);
return true;
}
public override void WritePRG(int addr, byte value)
{
addr &= 0x7000;
switch (addr)
{
//$8000-9FFF: [...M ....] Mirroring (for Fire Hawk only!)
case 0x0000:
case 0x1000:
if(mirror_control_enabled)
SetMirrorType(value.Bit(4) ? EMirrorType.OneScreenB : EMirrorType.OneScreenA);
break;
//$C000-FFFF: PRG Select (16k @ $8000)
case 0x4000: case 0x5000:
case 0x6000: case 0x7000:
prg_banks_16k[0] = value & prg_bank_mask_16k;
break;
}
}
public override byte ReadPRG(int addr)
{
int bank_16k = addr >> 14;
int ofs = addr & ((1 << 14) - 1);
bank_16k = prg_banks_16k[bank_16k];
addr = (bank_16k << 14) | ofs;
return ROM[addr];
}
}
//AKA mapper 232
class Camerica_Mapper232 : NES.NESBoardBase
{
//configuration
int prg_bank_mask_16k;
//state
IntBuffer prg_banks_16k = new IntBuffer(2);
int prg_block, prg_page;
public override void Dispose()
{
base.Dispose();
prg_banks_16k.Dispose();
}
public override void SyncState(Serializer ser)
{
base.SyncState(ser);
ser.Sync("prg_banks_16k", ref prg_banks_16k);
ser.Sync("prg_block", ref prg_block);
ser.Sync("prg_page", ref prg_page);
}
public override bool Configure(NES.EDetectionOrigin origin)
{
//configure
switch (Cart.board_type)
{
case "MAPPER232":
break;
case "CAMERICA-ALGQ": //Quattro Adventure (U)
case "CAMERICA-BF9096": //Quattro Arcade (U)
AssertPrg(256); AssertChr(0); AssertWram(0); AssertVram(8);
break;
default:
return false;
}
prg_bank_mask_16k = Cart.prg_size / 16 - 1;
SetMirrorType(Cart.pad_h, Cart.pad_v);
SyncPRG();
return true;
}
public override void WritePRG(int addr, byte value)
{
addr &= 0x4000;
switch (addr)
{
case 0x0000:
prg_block = (value>>3)&3;
SyncPRG();
break;
case 0x4000:
prg_page = value & 3;
SyncPRG();
break;
}
}
void SyncPRG()
{
prg_banks_16k[0] = (prg_block << 2) | prg_page;
prg_banks_16k[1] = (prg_block << 2) | 3;
prg_banks_16k[0] &= prg_bank_mask_16k;
prg_banks_16k[1] &= prg_bank_mask_16k;
}
public override byte ReadPRG(int addr)
{
int bank_16k = addr >> 14;
int ofs = addr & ((1 << 14) - 1);
bank_16k = prg_banks_16k[bank_16k];
addr = (bank_16k<<14) | ofs;
return ROM[addr];
}
}
}