mirror of https://github.com/bsnes-emu/bsnes.git
126 lines
2.6 KiB
C++
126 lines
2.6 KiB
C++
struct MMC1 : Chip {
|
|
MMC1(Board& board) : Chip(board) {
|
|
revision = Revision::MMC1B2;
|
|
}
|
|
|
|
auto main() -> void {
|
|
if(writedelay) writedelay--;
|
|
tick();
|
|
}
|
|
|
|
auto addrPRG(uint addr) -> uint {
|
|
bool region = addr & 0x4000;
|
|
uint bank = (prgBank & ~1) + region;
|
|
|
|
if(prgSize) {
|
|
bank = (region == 0 ? 0x0 : 0xf);
|
|
if(region != prgMode) bank = prgBank;
|
|
}
|
|
|
|
return (bank << 14) | (addr & 0x3fff);
|
|
}
|
|
|
|
auto addrCHR(uint addr) -> uint {
|
|
bool region = addr & 0x1000;
|
|
uint bank = chrBank[region];
|
|
if(chrMode == 0) bank = (chrBank[0] & ~1) | region;
|
|
return (bank << 12) | (addr & 0x0fff);
|
|
}
|
|
|
|
auto addrCIRAM(uint addr) -> uint {
|
|
switch(mirror) {
|
|
case 0: return 0x0000 | (addr & 0x03ff);
|
|
case 1: return 0x0400 | (addr & 0x03ff);
|
|
case 2: return ((addr & 0x0400) >> 0) | (addr & 0x03ff);
|
|
case 3: return ((addr & 0x0800) >> 1) | (addr & 0x03ff);
|
|
}
|
|
}
|
|
|
|
auto writeIO(uint addr, uint8 data) -> void {
|
|
if(writedelay) return;
|
|
writedelay = 2;
|
|
|
|
if(data & 0x80) {
|
|
shiftaddr = 0;
|
|
prgSize = 1;
|
|
prgMode = 1;
|
|
} else {
|
|
shiftdata = ((data & 1) << 4) | (shiftdata >> 1);
|
|
if(++shiftaddr == 5) {
|
|
shiftaddr = 0;
|
|
switch((addr >> 13) & 3) {
|
|
case 0:
|
|
chrMode = (shiftdata & 0x10);
|
|
prgSize = (shiftdata & 0x08);
|
|
prgMode = (shiftdata & 0x04);
|
|
mirror = (shiftdata & 0x03);
|
|
break;
|
|
|
|
case 1:
|
|
chrBank[0] = (shiftdata & 0x1f);
|
|
break;
|
|
|
|
case 2:
|
|
chrBank[1] = (shiftdata & 0x1f);
|
|
break;
|
|
|
|
case 3:
|
|
ramDisable = (shiftdata & 0x10);
|
|
prgBank = (shiftdata & 0x0f);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
auto power() -> void {
|
|
writedelay = 0;
|
|
shiftaddr = 0;
|
|
shiftdata = 0;
|
|
|
|
chrMode = 0;
|
|
prgSize = 1;
|
|
prgMode = 1;
|
|
mirror = 0;
|
|
chrBank[0] = 0;
|
|
chrBank[1] = 1;
|
|
ramDisable = 0;
|
|
prgBank = 0;
|
|
}
|
|
|
|
auto serialize(serializer& s) -> void {
|
|
s.integer(writedelay);
|
|
s.integer(shiftaddr);
|
|
s.integer(shiftdata);
|
|
|
|
s.integer(chrMode);
|
|
s.integer(prgSize);
|
|
s.integer(prgMode);
|
|
s.integer(mirror);
|
|
s.array(chrBank);
|
|
s.integer(ramDisable);
|
|
s.integer(prgBank);
|
|
}
|
|
|
|
enum class Revision : uint {
|
|
MMC1,
|
|
MMC1A,
|
|
MMC1B1,
|
|
MMC1B2,
|
|
MMC1B3,
|
|
MMC1C,
|
|
} revision;
|
|
|
|
uint writedelay;
|
|
uint shiftaddr;
|
|
uint shiftdata;
|
|
|
|
bool chrMode;
|
|
bool prgSize; //0 = 32K, 1 = 16K
|
|
bool prgMode;
|
|
uint2 mirror; //0 = first, 1 = second, 2 = vertical, 3 = horizontal
|
|
uint5 chrBank[2];
|
|
bool ramDisable;
|
|
uint4 prgBank;
|
|
};
|