Fix UNIF FK23C

Works except for Dipswitches
This commit is contained in:
alyosha-tas 2016-10-01 16:49:51 -04:00 committed by GitHub
parent 5ed5613826
commit 20bc25acd2
1 changed files with 252 additions and 55 deletions

View File

@ -1,55 +1,252 @@
using BizHawk.Common;
namespace BizHawk.Emulation.Cores.Nintendo.NES
{
public sealed class UNIF_BMC_FK23C : MMC3Board_Base
{
private ByteBuffer exRegs = new ByteBuffer(8);
public override bool Configure(NES.EDetectionOrigin origin)
{
switch (Cart.board_type)
{
case "UNIF_BMC-FK23C":
break;
default:
return false;
}
exRegs[4] = 0xFF;
exRegs[5] = 0xFF;
exRegs[6] = 0xFF;
exRegs[7] = 0xFF;
exRegs[8] = 0xFF;
BaseSetup();
return true;
}
public override void SyncState(Serializer ser)
{
base.SyncState(ser);
ser.Sync("exRegs", ref exRegs);
}
public override void WriteEXP(int addr, byte value)
{
base.WriteEXP(addr, value);
}
public override void WritePRG(int addr, byte value)
{
base.WritePRG(addr, value);
}
protected override int Get_PRGBank_8K(int addr)
{
return base.Get_PRGBank_8K(addr);
}
protected override int Get_CHRBank_1K(int addr)
{
return base.Get_CHRBank_1K(addr);
}
}
}
using BizHawk.Common;
using System;
namespace BizHawk.Emulation.Cores.Nintendo.NES
{
public sealed class UNIF_BMC_FK23C : MMC3Board_Base
{
private ByteBuffer exRegs = new ByteBuffer(8);
private IntBuffer chr_regs_1k = new IntBuffer(8);
public IntBuffer prg_regs_8k = new IntBuffer(4);
private bool dip_switch;
private byte dip_switch_setting;
private int unromChr;
private int prg_mask_8k, chr_mask_1k;
public override bool Configure(NES.EDetectionOrigin origin)
{
switch (Cart.board_type)
{
case "UNIF_BMC-FK23C":
break;
default:
return false;
}
exRegs[0] = 0;//xFF;
exRegs[1] = 0;// xFF;
exRegs[2] = 0;// xFF;
exRegs[3] = 0;// x FF;
exRegs[4] = 0xFF;
exRegs[5] = 0xFF;
exRegs[6] = 0xFF;
exRegs[7] = 0xFF;
BaseSetup();
prg_mask_8k = Cart.prg_size / 8 - 1;
chr_mask_1k = Cart.chr_size - 1;
prg_regs_8k[0] = 0;
prg_regs_8k[1] = 1;
prg_regs_8k[2] = (byte)(0xFE & prg_mask_8k);
prg_regs_8k[3] = (byte)(0xFF & prg_mask_8k);
byte r0_0 = (byte)(mmc3.regs[0] & ~1);
byte r0_1 = (byte)(mmc3.regs[0] | 1);
byte r1_0 = (byte)(mmc3.regs[1] & ~1);
byte r1_1 = (byte)(mmc3.regs[1] | 1);
chr_regs_1k[0] = r0_0;
chr_regs_1k[1] = r0_1;
chr_regs_1k[2] = r1_0;
chr_regs_1k[3] = r1_1;
chr_regs_1k[4] = mmc3.regs[2];
chr_regs_1k[5] = mmc3.regs[3];
chr_regs_1k[6] = mmc3.regs[4];
chr_regs_1k[7] = mmc3.regs[5];
UpdateChr_2();
UpdatePrg_2();
return true;
}
public override void SyncState(Serializer ser)
{
base.SyncState(ser);
ser.Sync("exRegs", ref exRegs);
ser.Sync("prg_regs_8k", ref prg_regs_8k);
ser.Sync("prg_mask", ref prg_mask_8k);
ser.Sync("chr_mask", ref chr_mask_1k);
}
void UpdateChr()
{
for (int i = 0; i < 8; i++)
{
int bank = mmc3.chr_regs_1k[i];
if (((exRegs[0] & 0x40) == 0) && (((exRegs[3] & 0x2) == 0) || (i != 1 && i != 3)))
chr_regs_1k[i] = ((exRegs[2] & 0x7F) << 3 | bank );
}
}
void UpdateChr_2()
{
if ((exRegs[0] & 0x40) > 0)
{
int bank = (exRegs[2] | unromChr);
chr_regs_1k[0] = bank;
chr_regs_1k[1] = bank;//(bank + 1);
chr_regs_1k[2] = bank;//(bank + 2);
chr_regs_1k[3] = bank;//(bank + 3);
chr_regs_1k[4] = bank;//(bank + 4);
chr_regs_1k[5] = bank;//(bank + 5);
chr_regs_1k[6] = bank;//(bank + 6);
chr_regs_1k[7] = bank;//(bank + 7);
}
else
{
if ((exRegs[3] & 0x2) > 0)
{
int bank = (exRegs[2] & 0x7F) << 3;
chr_regs_1k[1] = (bank | exRegs[6]);
chr_regs_1k[3] = (bank | exRegs[7]);
}
UpdateChr();
}
}
void UpdatePrg()
{
for (int i = 0; i < 4; i++)
{
int bank = mmc3.prg_regs_8k[i];
uint check = (uint)(exRegs[0] & 0x7) - 3;
if ((check > 1) && (((exRegs[3] & 0x2) == 0) || (i < 2)))
{
if ((exRegs[0] & 0x3) > 0)
bank = (bank & (0x3F >> (exRegs[0] & 0x3))) | (exRegs[1] << 1);
prg_regs_8k[i] = (byte)(bank & prg_mask_8k);
}
}
}
void UpdatePrg_2()
{
if ((exRegs[0] & 0x7) == 4)
{
int bank = exRegs[1]>>1;
bank *= 4;
bank &= prg_mask_8k;
prg_regs_8k[0] = (byte)bank;
prg_regs_8k[1] = (byte)(bank + 1);
prg_regs_8k[2] = (byte)(bank + 2);
prg_regs_8k[3] = (byte)(bank + 3);
}
else if ((exRegs[0] & 0x7) == 3)
{
int bank = exRegs[1];
bank *= 2;
bank &= prg_mask_8k;
prg_regs_8k[0] = (byte)bank;
prg_regs_8k[1] = (byte)(bank + 1);
prg_regs_8k[2] = (byte)bank;
prg_regs_8k[3] = (byte)(bank + 1);
}
else
{
if ((exRegs[3] & 0x2)>0)
{
prg_regs_8k[2] = (byte)(exRegs[4]);
prg_regs_8k[3] = (byte)(exRegs[5]);
}
UpdatePrg();
}
}
public override void WriteEXP(int addr, byte value)
{
if (addr>0x1000)
{
addr += 0x4000;
if ((addr & (1 << ((dip_switch ? dip_switch_setting : 0) + 4)))>0)
{
exRegs[addr & 0x3] = value;
UpdateChr_2();
UpdatePrg_2();
}
}
else
base.WriteEXP(addr, value);
}
public override void WritePRG(int addr, byte value)
{
if ((exRegs[0] & 0x40)>0)
{
unromChr = ((exRegs[0] & 0x30)>0) ? 0x0 : (value & 0x3);
UpdateChr_2();
}
else switch ((addr+0x8000) & 0xE001)
{
case 0x8000: base.WritePRG(addr,value); UpdatePrg(); UpdateChr(); break;
case 0x8001:
if (((exRegs[3] << 2) & (mmc3.cmd & 0x8))>0)
{
exRegs[4 | mmc3.cmd & 0x3] = value;
UpdatePrg_2();
UpdateChr_2();
}
else
{
base.WritePRG(addr, value);
UpdatePrg();
UpdateChr();
}
break;
case 0xA000:
if (value == 0)
{
SetMirrorType(EMirrorType.Vertical);
}
else
{
SetMirrorType(EMirrorType.Horizontal);
}
break;
case 0xA001: base.WritePRG(addr, value); break;
case 0xC000: base.WritePRG(addr, value); break;
case 0xC001: base.WritePRG(addr, value); break;
case 0xE000: base.WritePRG(addr, value); break;
case 0xE001: base.WritePRG(addr, value); break;
}
}
public override byte ReadPPU(int addr)
{
if (addr < 0x2000)
{
int bank_1k = addr >> 10;
bank_1k = chr_regs_1k[bank_1k];
if ((exRegs[0] & 0x40) > 0)
addr = (bank_1k << 13) | (addr & 0x1FFF);
else
addr = (bank_1k << 10) | (addr & 0x3FF);
return VROM[addr];
}
else return base.ReadPPU(addr);
}
public override byte ReadPRG(int addr)
{
int bank = addr >> 13;
bank = prg_regs_8k[bank];
return ROM[(bank << 13) + (addr & 0x1FFF)];
}
}
}