fix missing savestate data in some NESHawk mappers, note this is a breaking savestate change for these boards, but they were broken anyway, these were critical fields to savestate

This commit is contained in:
adelikat 2020-03-19 19:51:59 -05:00
parent 8bcab5af79
commit 659831c534
8 changed files with 201 additions and 191 deletions

View File

@ -9,7 +9,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
public class ConyA : NesBoardBase public class ConyA : NesBoardBase
{ {
private byte[] prg_regs = new byte[4]; private byte[] prg_regs = new byte[4];
private byte[] low = new byte[4]; // some kind of security feature? private byte[] _low = new byte[4]; // some kind of security feature?
private byte[] chr_regs = new byte[8]; private byte[] chr_regs = new byte[8];
private int prg_bank_mask_16k, prg_bank_mask_8k, chr_bank_mask_2k; private int prg_bank_mask_16k, prg_bank_mask_8k, chr_bank_mask_2k;
@ -51,6 +51,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
ser.Sync(nameof(mode), ref mode); ser.Sync(nameof(mode), ref mode);
ser.Sync(nameof(is_2k_bank), ref is_2k_bank); ser.Sync(nameof(is_2k_bank), ref is_2k_bank);
ser.Sync(nameof(is_not_2k_bank), ref is_not_2k_bank); ser.Sync(nameof(is_not_2k_bank), ref is_not_2k_bank);
ser.Sync(nameof(_low), ref _low, false);
} }
public void Mirroring() public void Mirroring()
@ -158,10 +159,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
bank = prg_bank_mask_8k; bank = prg_bank_mask_8k;
return Rom[(bank << 13) + (addr & 0x1FFF)]; return Rom[(bank << 13) + (addr & 0x1FFF)];
} }
} }
public override void ClockCpu() public override void ClockCpu()
@ -181,7 +179,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
public override void WriteExp(int addr, byte value) public override void WriteExp(int addr, byte value)
{ {
if (addr >= 0x1100 && addr <= 0x1103) if (addr >= 0x1100 && addr <= 0x1103)
low[addr & 0x3] = value; _low[addr & 0x3] = value;
else else
base.WriteExp(addr, value); base.WriteExp(addr, value);
} }
@ -191,7 +189,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
if (addr == 0x1000) if (addr == 0x1000)
return (byte)((NES.DB & 0xFC) | 0); return (byte)((NES.DB & 0xFC) | 0);
else if (addr >= 0x1100 && addr <= 0x1103) else if (addr >= 0x1100 && addr <= 0x1103)
return low[addr & 0x3]; return _low[addr & 0x3];
else else
return base.ReadExp(addr); return base.ReadExp(addr);
@ -201,7 +199,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
public class ConyB : NesBoardBase public class ConyB : NesBoardBase
{ {
private byte[] prg_regs = new byte[4]; private byte[] prg_regs = new byte[4];
private byte[] low = new byte[4]; // some kind of security feature? private byte[] _low = new byte[4]; // some kind of security feature?
private byte[] chr_regs = new byte[8]; private byte[] chr_regs = new byte[8];
private int prg_bank_mask_16k, prg_bank_mask_8k, chr_bank_mask_2k; private int prg_bank_mask_16k, prg_bank_mask_8k, chr_bank_mask_2k;
@ -242,6 +240,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
ser.Sync(nameof(mode), ref mode); ser.Sync(nameof(mode), ref mode);
ser.Sync(nameof(is_2k_bank), ref is_2k_bank); ser.Sync(nameof(is_2k_bank), ref is_2k_bank);
ser.Sync(nameof(is_not_2k_bank), ref is_not_2k_bank); ser.Sync(nameof(is_not_2k_bank), ref is_not_2k_bank);
ser.Sync(nameof(_low), ref _low, false);
} }
public void Mirroring() public void Mirroring()
@ -370,7 +369,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
public override void WriteExp(int addr, byte value) public override void WriteExp(int addr, byte value)
{ {
if (addr >= 0x1100 && addr <= 0x1103) if (addr >= 0x1100 && addr <= 0x1103)
low[addr & 0x3] = value; _low[addr & 0x3] = value;
else else
base.WriteExp(addr, value); base.WriteExp(addr, value);
} }
@ -380,7 +379,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
if (addr == 0x1000) if (addr == 0x1000)
return (byte)((NES.DB & 0xFC) | 0); return (byte)((NES.DB & 0xFC) | 0);
else if (addr >= 0x1100 && addr <= 0x1103) else if (addr >= 0x1100 && addr <= 0x1103)
return low[addr & 0x3]; return _low[addr & 0x3];
else else
return base.ReadExp(addr); return base.ReadExp(addr);
@ -395,8 +394,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
private byte[] chr_regs = new byte[8]; private byte[] chr_regs = new byte[8];
private int prg_bank_mask_16k; private int prg_bank_mask_16k;
private int IRQCount; private int _irqCount;
private bool IRQa, IRQ_enable; private bool _irqA, _irqEnable;
public override bool Configure(NES.EDetectionOrigin origin) public override bool Configure(NES.EDetectionOrigin origin)
{ {
@ -427,6 +426,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
base.SyncState(ser); base.SyncState(ser);
ser.Sync(nameof(chr_regs), ref chr_regs, false); ser.Sync(nameof(chr_regs), ref chr_regs, false);
ser.Sync(nameof(prg_regs), ref prg_regs, false); ser.Sync(nameof(prg_regs), ref prg_regs, false);
ser.Sync(nameof(_irqCount), ref _irqCount);
ser.Sync(nameof(_irqA), ref _irqA);
ser.Sync(nameof(_irqEnable), ref _irqEnable);
} }
public override void WritePrg(int addr, byte value) public override void WritePrg(int addr, byte value)
@ -443,19 +445,19 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
else if (addr == 0x200) else if (addr == 0x200)
{ {
IRQCount &= 0xFF00; IRQCount |= value; _irqCount &= 0xFF00; _irqCount |= value;
IrqSignal = false; IrqSignal = false;
} }
else if (addr == 0x201) else if (addr == 0x201)
{ {
IRQCount &= 0xFF; _irqCount &= 0xFF;
IRQCount |= value << 8; _irqCount |= value << 8;
IRQa = true; _irqA = true;
} }
else if (addr == 0x0100) else if (addr == 0x0100)
{ {
IRQ_enable = value.Bit(7); _irqEnable = value.Bit(7);
} }
} }
@ -483,13 +485,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
public override void ClockCpu() public override void ClockCpu()
{ {
if (IRQa) if (_irqA)
{ {
IRQCount--; _irqCount--;
if (IRQCount == 0) if (_irqCount == 0)
{ {
IRQCount = 0xFFFF; _irqCount = 0xFFFF;
IrqSignal = IRQ_enable; IrqSignal = _irqEnable;
} }
} }
} }

View File

@ -4,13 +4,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
{ {
public sealed class Mapper142 : NesBoardBase public sealed class Mapper142 : NesBoardBase
{ {
private byte[] reg = new byte[8]; private byte[] _reg = new byte[8];
private byte cmd; private byte _cmd;
private int lastBank; private int _lastBank;
private bool isirqused = false; private bool _isIrqUsed;
private byte IRQa = 0; private byte _irqA;
private int IRQCount = 0; private int _irqCount;
public override bool Configure(NES.EDetectionOrigin origin) public override bool Configure(NES.EDetectionOrigin origin)
{ {
@ -22,25 +22,37 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
default: default:
return false; return false;
} }
SetMirrorType(EMirrorType.Horizontal); SetMirrorType(EMirrorType.Horizontal);
lastBank = Cart.prg_size / 8 - 1; _lastBank = Cart.prg_size / 8 - 1;
return true; return true;
} }
public override void SyncState(Serializer ser)
{
base.SyncState(ser);
ser.Sync(nameof(_reg), ref _reg, false);
ser.Sync(nameof(_cmd), ref _cmd);
ser.Sync(nameof(_lastBank), ref _lastBank);
ser.Sync(nameof(_isIrqUsed), ref _isIrqUsed);
ser.Sync(nameof(_irqA), ref _irqA);
ser.Sync(nameof(_irqCount), ref _irqCount);
}
public override byte ReadWram(int addr) public override byte ReadWram(int addr)
{ {
return Rom[(reg[4] << 13) + (addr & 0x1FFF)]; return Rom[(_reg[4] << 13) + (addr & 0x1FFF)];
} }
public override byte ReadPrg(int addr) public override byte ReadPrg(int addr)
{ {
if (addr < 0x2000) { return Rom[(reg[1] << 13) + (addr & 0x1FFF)]; } if (addr < 0x2000) { return Rom[(_reg[1] << 13) + (addr & 0x1FFF)]; }
if (addr < 0x4000) { return Rom[(reg[2] << 13) + (addr & 0x1FFF)]; } if (addr < 0x4000) { return Rom[(_reg[2] << 13) + (addr & 0x1FFF)]; }
if (addr < 0x6000) { return Rom[(reg[3] << 13) + (addr & 0x1FFF)]; } if (addr < 0x6000) { return Rom[(_reg[3] << 13) + (addr & 0x1FFF)]; }
return Rom[(lastBank << 13) + (addr & 0x1FFF)]; return Rom[(_lastBank << 13) + (addr & 0x1FFF)];
} }
public override void WriteExp(int addr, byte value) public override void WriteExp(int addr, byte value)
@ -60,13 +72,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
private void IRQHook(int a) private void IRQHook(int a)
{ {
if (IRQa > 0) if (_irqA > 0)
{ {
IRQCount += a; _irqCount += a;
if (IRQCount >= 0xFFFF) if (_irqCount >= 0xFFFF)
{ {
IRQa = 0; _irqA = 0;
IRQCount = 0; _irqCount = 0;
IrqSignal = true; IrqSignal = true;
} }
@ -84,37 +96,37 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
{ {
case 0x8000: case 0x8000:
IrqSignal = false; IrqSignal = false;
IRQCount = (IRQCount & 0x000F) | (value & 0x0F); _irqCount = (_irqCount & 0x000F) | (value & 0x0F);
isirqused = true; _isIrqUsed = true;
break; break;
case 0x9000: case 0x9000:
IrqSignal = false; IrqSignal = false;
IRQCount = (IRQCount & 0x00F0) | ((value & 0x0F) << 4); _irqCount = (_irqCount & 0x00F0) | ((value & 0x0F) << 4);
isirqused = true; _isIrqUsed = true;
break; break;
case 0xA000: case 0xA000:
IrqSignal = false; IrqSignal = false;
IRQCount = (IRQCount & 0x0F00) | ((value & 0x0F) << 8); _irqCount = (_irqCount & 0x0F00) | ((value & 0x0F) << 8);
isirqused = true; _isIrqUsed = true;
break; break;
case 0xB000: case 0xB000:
IrqSignal = false; IrqSignal = false;
IRQCount = (IRQCount & 0xF000) | (value << 12); _irqCount = (_irqCount & 0xF000) | (value << 12);
isirqused = true; _isIrqUsed = true;
break; break;
case 0xC000: case 0xC000:
if (isirqused) if (_isIrqUsed)
{ {
IrqSignal = false; IrqSignal = false;
IRQa = 1; _irqA = 1;
} }
break; break;
case 0xE000: case 0xE000:
cmd = (byte)(value & 7); _cmd = (byte)(value & 7);
break; break;
case 0xF000: case 0xF000:
reg[cmd] = value; _reg[_cmd] = value;
break; break;
} }
} }

View File

@ -5,17 +5,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
{ {
public sealed class Mapper227 : NesBoardBase public sealed class Mapper227 : NesBoardBase
{ {
//configuration private int _prgBankMask16K;
int prg_bank_mask_16k; private int prg;
private bool _vramProtected;
//state private byte[] _prgBanks16K = new byte[2];
int prg;
bool vram_protected;
byte[] prg_banks_16k = new byte[2];
//1200-in-1
//[NJXXX] Xiang Shuai Chuan Qi
// 1200-in-1
// [NJXXX] Xiang Shuai Chuan Qi
public override bool Configure(NES.EDetectionOrigin origin) public override bool Configure(NES.EDetectionOrigin origin)
{ {
//configure //configure
@ -28,20 +24,27 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
default: default:
return false; return false;
} }
prg_bank_mask_16k = (Cart.prg_size / 16) - 1; _prgBankMask16K = (Cart.prg_size / 16) - 1;
SetMirrorType(EMirrorType.Vertical); SetMirrorType(EMirrorType.Vertical);
vram_protected = false; _vramProtected = false;
prg_banks_16k[0] = prg_banks_16k[1] = 0; _prgBanks16K[0] = _prgBanks16K[1] = 0;
return true; return true;
} }
public override void SyncState(Serializer ser)
{
base.SyncState(ser);
ser.Sync(nameof(prg), ref prg);
ser.Sync(nameof(_prgBanks16K), ref _prgBanks16K, false);
}
public override byte ReadPrg(int addr) public override byte ReadPrg(int addr)
{ {
int bank_16k = addr >> 14; int bank_16k = addr >> 14;
int ofs = addr & ((1 << 14) - 1); int ofs = addr & ((1 << 14) - 1);
bank_16k = prg_banks_16k[bank_16k]; bank_16k = _prgBanks16K[bank_16k];
bank_16k &= prg_bank_mask_16k; bank_16k &= _prgBankMask16K;
addr = (bank_16k << 14) | ofs; addr = (bank_16k << 14) | ofs;
return Rom[addr]; return Rom[addr];
} }
@ -63,58 +66,51 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
if (o == true && S == false) if (o == true && S == false)
{ {
prg_banks_16k[0] = (byte)(p); _prgBanks16K[0] = (byte)(p);
prg_banks_16k[1] = (byte)(p); _prgBanks16K[1] = (byte)(p);
} }
if (o == true && S == true) if (o == true && S == true)
{ {
prg_banks_16k[0] = (byte)((p & ~1)); _prgBanks16K[0] = (byte)((p & ~1));
prg_banks_16k[1] = (byte)((p & ~1) + 1); _prgBanks16K[1] = (byte)((p & ~1) + 1);
} }
if (o == false && S == false && L == false) if (o == false && S == false && L == false)
{ {
prg_banks_16k[0] = (byte)p; _prgBanks16K[0] = (byte)p;
prg_banks_16k[1] = (byte)(p & 0x38); _prgBanks16K[1] = (byte)(p & 0x38);
} }
if (o == false && S == true && L == false) if (o == false && S == true && L == false)
{ {
prg_banks_16k[0] = (byte)(p & 0x3E); _prgBanks16K[0] = (byte)(p & 0x3E);
prg_banks_16k[1] = (byte)(p & 0x38); _prgBanks16K[1] = (byte)(p & 0x38);
} }
if (o == false && S == false && L == true) if (o == false && S == false && L == true)
{ {
prg_banks_16k[0] = (byte)p; _prgBanks16K[0] = (byte)p;
prg_banks_16k[1] = (byte)(p | 0x07); _prgBanks16K[1] = (byte)(p | 0x07);
} }
if (o == false && S == true && L == true) if (o == false && S == true && L == true)
{ {
prg_banks_16k[0] = (byte)(p & 0x3E); _prgBanks16K[0] = (byte)(p & 0x3E);
prg_banks_16k[1] = (byte)(p | 0x07); _prgBanks16K[1] = (byte)(p | 0x07);
} }
prg_banks_16k[0] = (byte)(prg_banks_16k[0]&prg_bank_mask_16k); _prgBanks16K[0] = (byte)(_prgBanks16K[0]&_prgBankMask16K);
prg_banks_16k[1] = (byte)(prg_banks_16k[1]&prg_bank_mask_16k); _prgBanks16K[1] = (byte)(_prgBanks16K[1]&_prgBankMask16K);
if (M_horz) SetMirrorType(EMirrorType.Horizontal); if (M_horz) SetMirrorType(EMirrorType.Horizontal);
else SetMirrorType(EMirrorType.Vertical); else SetMirrorType(EMirrorType.Vertical);
} }
public override void WritePpu(int addr, byte value) public override void WritePpu(int addr, byte value)
{ {
if (addr < 0x2000) if (addr < 0x2000)
{ {
if (vram_protected) if (_vramProtected)
return; return;
else base.WritePpu(addr, value); else base.WritePpu(addr, value);
} }
else base.WritePpu(addr, value); else base.WritePpu(addr, value);
} }
public override void SyncState(Serializer ser)
{
base.SyncState(ser);
ser.Sync(nameof(prg), ref prg);
}
} }
} }

View File

@ -9,13 +9,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
private byte[] preg = new byte[2]; private byte[] preg = new byte[2];
private byte[] creg = new byte[8]; private byte[] creg = new byte[8];
private int prg_bank_mask_8k, chr_bank_mask_1k; private int _prgBankMask8K, _chrBankMask1K;
private int IRQLatch, IRQClock, IRQCount; private int _irqLatch, _irqClock, _irqCount;
private bool IRQa; private bool _irqA;
public override bool Configure(NES.EDetectionOrigin origin) public override bool Configure(NES.EDetectionOrigin origin)
{ {
//analyze board type
switch (Cart.board_type) switch (Cart.board_type)
{ {
case "MAPPER252": case "MAPPER252":
@ -23,12 +22,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
default: default:
return false; return false;
} }
AssertPrg(256); AssertPrg(256);
AssertChr(128); AssertChr(128);
AssertVram(2); AssertVram(2);
AssertWram(8); AssertWram(8);
prg_bank_mask_8k = Cart.prg_size / 8 - 1; _prgBankMask8K = Cart.prg_size / 8 - 1;
chr_bank_mask_1k = Cart.chr_size - 1; _chrBankMask1K = Cart.chr_size - 1;
SetMirrorType(EMirrorType.Vertical); SetMirrorType(EMirrorType.Vertical);
return true; return true;
} }
@ -38,27 +38,30 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
base.SyncState(ser); base.SyncState(ser);
ser.Sync(nameof(preg), ref preg, false); ser.Sync(nameof(preg), ref preg, false);
ser.Sync(nameof(creg), ref creg, false); ser.Sync(nameof(creg), ref creg, false);
ser.Sync(nameof(_irqLatch), ref _irqLatch);
ser.Sync(nameof(_irqClock), ref _irqClock);
ser.Sync(nameof(_irqCount), ref _irqCount);
ser.Sync(nameof(_irqA), ref _irqA);
} }
public override void ClockCpu() public override void ClockCpu()
{ {
if (IRQa) if (_irqA)
{ {
IRQClock += 3; _irqClock += 3;
if (IRQClock >= 341) if (_irqClock >= 341)
{ {
IRQClock -= 341; _irqClock -= 341;
IRQCount++; _irqCount++;
if (IRQCount==0x100) if (_irqCount==0x100)
{ {
IrqSignal=true; IrqSignal=true;
IRQCount = IRQLatch; _irqCount = _irqLatch;
} }
} }
} }
} }
public override void WritePrg(int addr, byte value) public override void WritePrg(int addr, byte value)
{ {
WriteReg((addr + 0x8000), value); WriteReg((addr + 0x8000), value);
@ -90,9 +93,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
preg[1] = value; preg[1] = value;
break; break;
case 0xF000: IrqSignal = false; IRQLatch &= 0xF0; IRQLatch |= value & 0xF; break; case 0xF000: IrqSignal = false; _irqLatch &= 0xF0; _irqLatch |= value & 0xF; break;
case 0xF004: IrqSignal = false; IRQLatch &= 0x0F; IRQLatch |= value << 4; break; case 0xF004: IrqSignal = false; _irqLatch &= 0x0F; _irqLatch |= value << 4; break;
case 0xF008: IrqSignal = false; IRQClock = 0; IRQCount = IRQLatch; IRQa = value.Bit(1); break; case 0xF008: IrqSignal = false; _irqClock = 0; _irqCount = _irqLatch; _irqA = value.Bit(1); break;
} }
} }
@ -104,19 +107,19 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
if (addr < 0x2000) if (addr < 0x2000)
{ {
bank = preg[0] & prg_bank_mask_8k; bank = preg[0] & _prgBankMask8K;
} }
else if (addr < 0x4000) else if (addr < 0x4000)
{ {
bank = preg[1] & prg_bank_mask_8k; bank = preg[1] & _prgBankMask8K;
} }
else if (addr < 0x6000) else if (addr < 0x6000)
{ {
bank = prg_bank_mask_8k - 1; bank = _prgBankMask8K - 1;
} }
else else
{ {
bank = prg_bank_mask_8k; bank = _prgBankMask8K;
} }
@ -137,7 +140,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
} }
else else
{ {
bank = (creg[x] & chr_bank_mask_1k) << 10; bank = (creg[x] & _chrBankMask1K) << 10;
return Vrom[bank + (addr & 0x3FF)]; return Vrom[bank + (addr & 0x3FF)];
} }

View File

@ -5,14 +5,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
{ {
public class Mapper253 : NesBoardBase public class Mapper253 : NesBoardBase
{ {
private byte[] prg = new byte[2]; private byte[] _prg = new byte[2];
private byte[] chrlo = new byte[8]; private byte[] chrlo = new byte[8];
private byte[] chrhi = new byte[8]; private byte[] chrhi = new byte[8];
private bool vlock; private bool _vLock;
private int IRQLatch, IRQClock, IRQCount; private int _irqLatch, _irqClock, _irqCount;
private bool IRQa; private bool _irqA;
private int prg_bank_mask_8k, chr_bank_mask_1k; private int _prgBankMask8K, _chrBankMask1k;
public override bool Configure(NES.EDetectionOrigin origin) public override bool Configure(NES.EDetectionOrigin origin)
{ {
@ -25,8 +25,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
return false; return false;
} }
prg_bank_mask_8k = Cart.prg_size / 8 - 1; _prgBankMask8K = Cart.prg_size / 8 - 1;
chr_bank_mask_1k = Cart.chr_size - 1; _chrBankMask1k = Cart.chr_size - 1;
return true; return true;
} }
@ -34,24 +34,24 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
public override void SyncState(Serializer ser) public override void SyncState(Serializer ser)
{ {
base.SyncState(ser); base.SyncState(ser);
ser.Sync("preg", ref prg, false); ser.Sync("preg", ref _prg, false);
ser.Sync(nameof(chrlo), ref chrlo, false); ser.Sync(nameof(chrlo), ref chrlo, false);
ser.Sync(nameof(chrhi), ref chrhi, false); ser.Sync(nameof(chrhi), ref chrhi, false);
} }
public override void ClockCpu() public override void ClockCpu()
{ {
if (IRQa) if (_irqA)
{ {
IRQClock += 3; _irqClock += 3;
if (IRQClock >= 341) if (_irqClock >= 341)
{ {
IRQClock -= 341; _irqClock -= 341;
IRQCount++; _irqCount++;
if (IRQCount == 0x100) if (_irqCount == 0x100)
{ {
IrqSignal = true; IrqSignal = true;
IRQCount = IRQLatch; _irqCount = _irqLatch;
} }
} }
} }
@ -69,9 +69,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
if (ind == 0) if (ind == 0)
{ {
if (clo == 0xc8) if (clo == 0xc8)
vlock = false; _vLock = false;
else if (clo == 0x88) else if (clo == 0x88)
vlock = true; _vLock = true;
} }
if (sar > 0) if (sar > 0)
chrhi[ind] = (byte)(value >> 4); chrhi[ind] = (byte)(value >> 4);
@ -80,13 +80,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
{ {
switch (addr) switch (addr)
{ {
case 0x8010: prg[0] = value; break; case 0x8010: _prg[0] = value; break;
case 0xA010: prg[1] = value; break; case 0xA010: _prg[1] = value; break;
case 0x9400: SetMirroring(value); break; case 0x9400: SetMirroring(value); break;
case 0xF000: IrqSignal = false; IRQLatch &= 0xF0; IRQLatch |= value & 0xF; break; case 0xF000: IrqSignal = false; _irqLatch &= 0xF0; _irqLatch |= value & 0xF; break;
case 0xF004: IrqSignal = false; IRQLatch &= 0x0F; IRQLatch |= value << 4; break; case 0xF004: IrqSignal = false; _irqLatch &= 0x0F; _irqLatch |= value << 4; break;
case 0xF008: IrqSignal = false; IRQClock = 0; IRQCount = IRQLatch; IRQa = value.Bit(1); break; case 0xF008: IrqSignal = false; _irqClock = 0; _irqCount = _irqLatch; _irqA = value.Bit(1); break;
} }
} }
} }
@ -108,19 +108,19 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
if (addr < 0x2000) if (addr < 0x2000)
{ {
bank = prg[0] & prg_bank_mask_8k; bank = _prg[0] & _prgBankMask8K;
} }
else if (addr < 0x4000) else if (addr < 0x4000)
{ {
bank = prg[1] & prg_bank_mask_8k; bank = _prg[1] & _prgBankMask8K;
} }
else if (addr < 0x6000) else if (addr < 0x6000)
{ {
bank = prg_bank_mask_8k - 1; bank = _prgBankMask8K - 1;
} }
else else
{ {
bank = prg_bank_mask_8k; bank = _prgBankMask8K;
} }
@ -134,9 +134,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
{ {
int x = (addr >> 10) & 7; int x = (addr >> 10) & 7;
var chr = chrlo[x] | (chrhi[x] << 8); var chr = chrlo[x] | (chrhi[x] << 8);
int bank = (chr & chr_bank_mask_1k) << 10; int bank = (chr & _chrBankMask1k) << 10;
if ((chrlo[x] == 4 || chrlo[x] == 5) && !vlock) if ((chrlo[x] == 4 || chrlo[x] == 5) && !_vLock)
{ {
bank = chr & 1; bank = chr & 1;
return Vram[(bank << 10) + (addr & 0x3FF)]; return Vram[(bank << 10) + (addr & 0x3FF)];
@ -159,9 +159,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
{ {
int x = (addr >> 10) & 7; int x = (addr >> 10) & 7;
var chr = chrlo[x] | (chrhi[x] << 8); var chr = chrlo[x] | (chrhi[x] << 8);
int bank = (chr & chr_bank_mask_1k) << 10; int bank = (chr & _chrBankMask1k) << 10;
if ((chrlo[x] == 4 || chrlo[x] == 5) && !vlock) if ((chrlo[x] == 4 || chrlo[x] == 5) && !_vLock)
{ {
bank = chr & 1; bank = chr & 1;
Vram[(bank << 10) + (addr & 0x3FF)]=value; Vram[(bank << 10) + (addr & 0x3FF)]=value;

View File

@ -1,30 +1,23 @@
//see http://nesdev.parodius.com/bbs/viewtopic.php?t=5426&sid=e7472c15a758ebf05c588c8330c2187f using BizHawk.Common;
//and http://nesdev.parodius.com/bbs/viewtopic.php?t=311
//for some info on NAMCOT 108
//but mostly http://wiki.nesdev.com/w/index.php/INES_Mapper_206
// see http://nesdev.parodius.com/bbs/viewtopic.php?t=5426&sid=e7472c15a758ebf05c588c8330c2187f
// and http://nesdev.parodius.com/bbs/viewtopic.php?t=311
// for some info on NAMCOT 108
// but mostly http://wiki.nesdev.com/w/index.php/INES_Mapper_206
//TODO - prg is 4 bits, chr is 6 bits //TODO - prg is 4 bits, chr is 6 bits
using BizHawk.Common;
namespace BizHawk.Emulation.Cores.Nintendo.NES namespace BizHawk.Emulation.Cores.Nintendo.NES
{ {
//also, Namcot109, Namcot118, Namcot119 chips are this exact same thing // also, Namcot109, Namcot118, Namcot119 chips are this exact same thing
public class Namcot108Chip public class Namcot108Chip
{ {
//state private int reg_addr;
int reg_addr; private byte[] regs = new byte[8];
byte[] regs = new byte[8];
//volatile state private byte[] _chrRegs1K = new byte[8];
byte[] chr_regs_1k = new byte[8]; private byte[] _prgRegs8K = new byte[4];
byte[] prg_regs_8k = new byte[4];
NesBoardBase board;
public Namcot108Chip(NesBoardBase board) public Namcot108Chip(NesBoardBase board)
{ {
this.board = board;
Sync(); Sync();
} }
@ -32,6 +25,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
{ {
ser.Sync(nameof(reg_addr), ref reg_addr); ser.Sync(nameof(reg_addr), ref reg_addr);
ser.Sync(nameof(regs), ref regs, false); ser.Sync(nameof(regs), ref regs, false);
ser.Sync(nameof(_chrRegs1K), ref _chrRegs1K, false);
ser.Sync(nameof(_prgRegs8K), ref _prgRegs8K, false);
Sync(); Sync();
} }
@ -52,37 +47,37 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
void Sync() void Sync()
{ {
prg_regs_8k[0] = regs[6]; _prgRegs8K[0] = regs[6];
prg_regs_8k[1] = regs[7]; _prgRegs8K[1] = regs[7];
prg_regs_8k[2] = 0xFE; _prgRegs8K[2] = 0xFE;
prg_regs_8k[3] = 0xFF; _prgRegs8K[3] = 0xFF;
byte r0_0 = (byte)(regs[0] & ~1); byte r0_0 = (byte)(regs[0] & ~1);
byte r0_1 = (byte)(regs[0] | 1); byte r0_1 = (byte)(regs[0] | 1);
byte r1_0 = (byte)(regs[1] & ~1); byte r1_0 = (byte)(regs[1] & ~1);
byte r1_1 = (byte)(regs[1] | 1); byte r1_1 = (byte)(regs[1] | 1);
chr_regs_1k[0] = r0_0; _chrRegs1K[0] = r0_0;
chr_regs_1k[1] = r0_1; _chrRegs1K[1] = r0_1;
chr_regs_1k[2] = r1_0; _chrRegs1K[2] = r1_0;
chr_regs_1k[3] = r1_1; _chrRegs1K[3] = r1_1;
chr_regs_1k[4] = regs[2]; _chrRegs1K[4] = regs[2];
chr_regs_1k[5] = regs[3]; _chrRegs1K[5] = regs[3];
chr_regs_1k[6] = regs[4]; _chrRegs1K[6] = regs[4];
chr_regs_1k[7] = regs[5]; _chrRegs1K[7] = regs[5];
} }
public int Get_PRGBank_8K(int addr) public int Get_PRGBank_8K(int addr)
{ {
int bank_8k = addr >> 13; int bank_8k = addr >> 13;
bank_8k = prg_regs_8k[bank_8k]; bank_8k = _prgRegs8K[bank_8k];
return bank_8k; return bank_8k;
} }
public int Get_CHRBank_1K(int addr) public int Get_CHRBank_1K(int addr)
{ {
int bank_1k = addr >> 10; int bank_1k = addr >> 10;
bank_1k = chr_regs_1k[bank_1k]; bank_1k = _chrRegs1K[bank_1k];
return bank_1k; return bank_1k;
} }
} }

View File

@ -5,7 +5,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
public sealed class UNIF_BMC_FK23C : MMC3Board_Base public sealed class UNIF_BMC_FK23C : MMC3Board_Base
{ {
private byte[] exRegs = new byte[8]; private byte[] exRegs = new byte[8];
private int[] chr_regs_1k = new int[8]; private int[] _chrRegs1K = new int[8];
public int[] prg_regs_8k = new int[4]; public int[] prg_regs_8k = new int[4];
[MapperProp] [MapperProp]
@ -56,14 +56,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
byte r1_0 = (byte)(mmc3.regs[1] & ~1); byte r1_0 = (byte)(mmc3.regs[1] & ~1);
byte r1_1 = (byte)(mmc3.regs[1] | 1); byte r1_1 = (byte)(mmc3.regs[1] | 1);
chr_regs_1k[0] = r0_0; _chrRegs1K[0] = r0_0;
chr_regs_1k[1] = r0_1; _chrRegs1K[1] = r0_1;
chr_regs_1k[2] = r1_0; _chrRegs1K[2] = r1_0;
chr_regs_1k[3] = r1_1; _chrRegs1K[3] = r1_1;
chr_regs_1k[4] = mmc3.regs[2]; _chrRegs1K[4] = mmc3.regs[2];
chr_regs_1k[5] = mmc3.regs[3]; _chrRegs1K[5] = mmc3.regs[3];
chr_regs_1k[6] = mmc3.regs[4]; _chrRegs1K[6] = mmc3.regs[4];
chr_regs_1k[7] = mmc3.regs[5]; _chrRegs1K[7] = mmc3.regs[5];
UpdateChr_2(); UpdateChr_2();
UpdatePrg_2(); UpdatePrg_2();
@ -75,6 +75,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
{ {
base.SyncState(ser); base.SyncState(ser);
ser.Sync(nameof(exRegs), ref exRegs, false); ser.Sync(nameof(exRegs), ref exRegs, false);
ser.Sync(nameof(_chrRegs1K), ref _chrRegs1K, false);
ser.Sync(nameof(prg_regs_8k), ref prg_regs_8k, false); ser.Sync(nameof(prg_regs_8k), ref prg_regs_8k, false);
ser.Sync(nameof(prg_mask), ref prg_mask_8k); ser.Sync(nameof(prg_mask), ref prg_mask_8k);
ser.Sync(nameof(chr_mask), ref chr_mask_1k); ser.Sync(nameof(chr_mask), ref chr_mask_1k);
@ -88,7 +89,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
{ {
int bank = mmc3.chr_regs_1k[i]; int bank = mmc3.chr_regs_1k[i];
if (((exRegs[0] & 0x40) == 0) && (((exRegs[3] & 0x2) == 0) || (i != 1 && i != 3))) if (((exRegs[0] & 0x40) == 0) && (((exRegs[3] & 0x2) == 0) || (i != 1 && i != 3)))
chr_regs_1k[i] = ((exRegs[2] & 0x7F) << 3 | bank ); _chrRegs1K[i] = ((exRegs[2] & 0x7F) << 3 | bank );
} }
} }
@ -97,22 +98,22 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
if ((exRegs[0] & 0x40) > 0) if ((exRegs[0] & 0x40) > 0)
{ {
int bank = (exRegs[2] | unromChr); int bank = (exRegs[2] | unromChr);
chr_regs_1k[0] = bank; _chrRegs1K[0] = bank;
chr_regs_1k[1] = bank;//(bank + 1); _chrRegs1K[1] = bank;//(bank + 1);
chr_regs_1k[2] = bank;//(bank + 2); _chrRegs1K[2] = bank;//(bank + 2);
chr_regs_1k[3] = bank;//(bank + 3); _chrRegs1K[3] = bank;//(bank + 3);
chr_regs_1k[4] = bank;//(bank + 4); _chrRegs1K[4] = bank;//(bank + 4);
chr_regs_1k[5] = bank;//(bank + 5); _chrRegs1K[5] = bank;//(bank + 5);
chr_regs_1k[6] = bank;//(bank + 6); _chrRegs1K[6] = bank;//(bank + 6);
chr_regs_1k[7] = bank;//(bank + 7); _chrRegs1K[7] = bank;//(bank + 7);
} }
else else
{ {
if ((exRegs[3] & 0x2) > 0) if ((exRegs[3] & 0x2) > 0)
{ {
int bank = (exRegs[2] & 0x7F) << 3; int bank = (exRegs[2] & 0x7F) << 3;
chr_regs_1k[1] = (bank | exRegs[6]); _chrRegs1K[1] = (bank | exRegs[6]);
chr_regs_1k[3] = (bank | exRegs[7]); _chrRegs1K[3] = (bank | exRegs[7]);
} }
UpdateChr(); UpdateChr();
} }
@ -238,7 +239,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
if (addr < 0x2000) if (addr < 0x2000)
{ {
int bank_1k = addr >> 10; int bank_1k = addr >> 10;
bank_1k = chr_regs_1k[bank_1k]; bank_1k = _chrRegs1K[bank_1k];
if ((exRegs[0] & 0x40) > 0) if ((exRegs[0] & 0x40) > 0)
addr = (bank_1k << 13) | (addr & 0x1FFF); addr = (bank_1k << 13) | (addr & 0x1FFF);

View File

@ -410,6 +410,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=Mupen/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Mupen/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=mutexing/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=mutexing/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=muxed/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=muxed/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Namcot/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Nametable/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Nametable/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Nametables/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Nametables/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=neshawk/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=neshawk/@EntryIndexedValue">True</s:Boolean>