ulfalizer wrote:
This is probably among the fastest "simple" thing you could do. Not sure how much of a hotstop this is anyway though.
The only problem with this method (also, why I personally stopped using it), is the constant calls to your bank switching function every time one of the components of a mapper's address decoder changes. For example, MMC3's prg mode:
Code:
private void Poke8000(uint address, byte data)
{
this.chrMode = (data & 0x80U) << 5; // $0000/$1000
this.prgMode = (data & 0x40U) << 8; // $0000/$4000
this.address = (data & 0x07U);
}
protected override uint DecodePrg(uint address)
{
address ^= prgMode & ~(address << 1); // Swap banks $8000 and $C000 if PRG Mode is '1', otherwise don't.
switch (address & 0xE000U)
{
default:
case 0x8000U: return (address & 0x1FFFU) | prgPage[0U];
case 0xA000U: return (address & 0x1FFFU) | prgPage[1U];
case 0xC000U: return (address & 0x1FFFU) | prgPage[2U];
case 0xE000U: return (address & 0x1FFFU) | prgPage[3U];
}
}
With the old method you'd have to do something like:
Code:
private void Poke8000(uint address, byte data)
{
this.chrMode = (data & 0x80U) << 5; // $0000/$1000
this.prgMode = (data & 0x40U) << 8; // $0000/$4000
this.address = (data & 0x07U) << 0;
UpdatePrgBanks();
UpdateChrBanks();
}
private void UpdatePrgBanks()
{
if (prgMode == 0U)
{
SwitchPrg( PRG.Size8KB, PRG.Bank8000, prgReg[0U] );
SwitchPrg( PRG.Size8KB, PRG.BankA000, prgReg[1U] );
SwitchPrg( PRG.Size8KB, PRG.BankC000, prgReg[2U] );
SwitchPrg( PRG.Size8KB, PRG.BankE000, prgReg[3U] );
}
else
{
SwitchPrg( PRG.Size8KB, PRG.Bank8000, prgReg[2U] );
SwitchPrg( PRG.Size8KB, PRG.BankA000, prgReg[1U] );
SwitchPrg( PRG.Size8KB, PRG.BankC000, prgReg[0U] );
SwitchPrg( PRG.Size8KB, PRG.BankE000, prgReg[3U] );
}
}
And you'd also have to call UpdatePrgBanks or individually update each bank when the banks change. It was too much hassle for me, so I switched to defining PRG/CHR banks once
You should also consider what might happen if some future mapper decides to use 4kB PRG pages, to support that new mapper, you'd have to go back and change your code, and depending on your implementation, change all of your previous mapper code. But everyone has their own way of doing things, and I much prefer raw decoding.