Wow, nice info I got from you guys. Now I pass all MMC3 tests except the 4-scanline_timing and 6-MMC3-alt.
The bad news are that those games I mentioned earlier and (possibly more) wont even start, crashing into bad opcodes. So I wonder if there's any gotchas about PRG mapping. Here's how i'm doing it:
On writes to $8000, I sync PRG and CHR banks according to the mode in bits 6 and 7, on writes to $8001 y update the register indicated by previous value written to $8000 & 7, then re-sync PRG and CHR:
Code:
....
switch (addr & 0xE001){
case 0x8000:
CHRMode = val & 0x80;
PRGMode = val & 0x40;
regAddr = val & 0x7;
prgProtect = val & 0x20;
syncPRG();
syncCHR();
return;
case 0x8001:
swapRegs[regAddr] = val;
syncPRG();
syncCHR();
return;
...
And here is my banks sync code:
Code:
void MMC3::syncPRG(){
if (PRGMode){
cData.prgPtr[2] = prg[prgSize8K - 2];
cData.prgPtr[3] = prg[swapRegs[7]];
cData.prgPtr[4] = prg[swapRegs[6]];
cData.prgPtr[5] = prg[prgSize8K - 1];
} else {
cData.prgPtr[2] = prg[swapRegs[6]];
cData.prgPtr[3] = prg[swapRegs[7]];
cData.prgPtr[4] = prg[prgSize8K - 2];
cData.prgPtr[5] = prg[prgSize8K - 1];
}
}
void MMC3::syncCHR(){
if (CHRMode)
{
cData.chrPtr[0] = chr[swapRegs[2]];
cData.chrPtr[1] = chr[swapRegs[3]];
cData.chrPtr[2] = chr[swapRegs[4]];
cData.chrPtr[3] = chr[swapRegs[5]];
cData.chrPtr[4] = chr[swapRegs[0] & 0xFE];
cData.chrPtr[5] = chr[swapRegs[0] | 1];
cData.chrPtr[6] = chr[swapRegs[1] & 0xFE];
cData.chrPtr[7] = chr[swapRegs[1] | 1];
for (int i=0; i < 4; i++)
ppu.changeCache1KBank(i, swapRegs[i+2]);
ppu.changeCache2KBank(2, swapRegs[0]);
ppu.changeCache2KBank(3, swapRegs[1]);
}
else
{
cData.chrPtr[0] = chr[swapRegs[0] & 0xFE];
cData.chrPtr[1] = chr[swapRegs[0] | 1];
cData.chrPtr[2] = chr[swapRegs[1] & 0xFE];
cData.chrPtr[3] = chr[swapRegs[1] | 1];
cData.chrPtr[4] = chr[swapRegs[2]];
cData.chrPtr[5] = chr[swapRegs[3]];
cData.chrPtr[6] = chr[swapRegs[4]];
cData.chrPtr[7] = chr[swapRegs[5]];
for (int i=4; i < 8; i++)
ppu.changeCache1KBank(i, swapRegs[i-2]);
ppu.changeCache2KBank(0, swapRegs[0]);
ppu.changeCache2KBank(1, swapRegs[1]);
}
}
Thanks a lot for your help. Hope I don't waste your time by missing obvious things... :S