169 lines
3.6 KiB
C++
169 lines
3.6 KiB
C++
////////////////////////////////////////////////////////////////////////////
|
|
// BoardSA9602B Mei Shao Nv Meng Gong Chang (Princess Maker)(Sachen)(Unl)[!] //
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
void BoardSA9602B::Reset()
|
|
{
|
|
CRAM_sav = 3 ;
|
|
memcpy(&CRAM[CRAM_sav*0x2000], &WRAM[0], 0x2000);
|
|
reg[0] = 0;
|
|
reg[1] = 0;
|
|
IRQCount = IRQLatch = IRQa = MMC3cmd = 0;
|
|
DRegBuf[0] = 0;
|
|
DRegBuf[1] = 2;
|
|
DRegBuf[2] = 4;
|
|
DRegBuf[3] = 5;
|
|
DRegBuf[4] = 6;
|
|
DRegBuf[5] = 7;
|
|
DRegBuf[6] = 0;
|
|
DRegBuf[7] = 1;
|
|
A000B = 0;
|
|
UpdatePrg(0);
|
|
UpdateChr(0);
|
|
}
|
|
|
|
void BoardSA9602B::Write( WORD addr, BYTE data )
|
|
{
|
|
switch (addr & 0xE001) {
|
|
case 0x8000:
|
|
reg[0] = data;
|
|
if ((data & 0x40) != (MMC3cmd & 0x40))
|
|
UpdatePrg(data);
|
|
if ((data & 0x80) != (MMC3cmd & 0x80))
|
|
UpdateChr(data);
|
|
MMC3cmd = data;
|
|
break;
|
|
case 0x8001:
|
|
{
|
|
if ((reg[0] & 7) < 6) {
|
|
reg[1] = data >> 6;
|
|
UpdatePrg(MMC3cmd);
|
|
}
|
|
int cbase = (MMC3cmd & 0x80) << 5;
|
|
DRegBuf[MMC3cmd & 0x7] = data;
|
|
switch (MMC3cmd & 0x07) {
|
|
case 0:
|
|
UpdateChr((cbase ^ 0x000), data & (~1));
|
|
UpdateChr((cbase ^ 0x400), data | 1);
|
|
break;
|
|
case 1:
|
|
UpdateChr((cbase ^ 0x800), data & (~1));
|
|
UpdateChr((cbase ^ 0xC00), data | 1);
|
|
break;
|
|
case 2:
|
|
UpdateChr(cbase ^ 0x1000, data);
|
|
break;
|
|
case 3:
|
|
UpdateChr(cbase ^ 0x1400, data);
|
|
break;
|
|
case 4:
|
|
UpdateChr(cbase ^ 0x1800, data);
|
|
break;
|
|
case 5:
|
|
UpdateChr(cbase ^ 0x1C00, data);
|
|
break;
|
|
case 6:
|
|
if (MMC3cmd & 0x40)
|
|
UpdatePrg(0xC000, data);
|
|
else
|
|
UpdatePrg(0x8000, data);
|
|
break;
|
|
case 7:
|
|
UpdatePrg(0xA000, data);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0xA000:
|
|
A000B = data;
|
|
if (!nes->rom->Is4SCREEN()) {
|
|
if (A000B & 0x01) SetVRAM_Mirror(VRAM_HMIRROR);
|
|
else SetVRAM_Mirror(VRAM_VMIRROR);
|
|
}
|
|
break;
|
|
case 0xC000: IRQReload = 0;IRQCount = data; break;
|
|
case 0xC001: IRQReload = 0;IRQLatch = data; break;
|
|
case 0xE000: IRQReload = 0;IRQa = 0;nes->cpu->ClrIRQ(IRQ_MAPPER); break;
|
|
case 0xE001: IRQReload = 0;IRQa = 1; break;
|
|
}
|
|
}
|
|
|
|
void BoardSA9602B::UpdatePrg(WORD addr, BYTE data)
|
|
{
|
|
SetPROM_8K_Bank(addr>>13, (data&0x3F)|(reg[1]<<6));
|
|
if (MMC3cmd & 0x40)
|
|
SetPROM_8K_Bank(4, 0x3E);
|
|
else
|
|
SetPROM_8K_Bank(6, 0x3E);
|
|
SetPROM_8K_Bank(7, 0x3F);
|
|
}
|
|
|
|
void BoardSA9602B::UpdateChr(WORD addr, BYTE data)
|
|
{
|
|
SetCRAM_1K_Bank(addr >> 10, data);
|
|
}
|
|
|
|
void BoardSA9602B::UpdatePrg(BYTE data)
|
|
{
|
|
if (data & 0x40) {
|
|
UpdatePrg(0xC000, DRegBuf[6]);
|
|
UpdatePrg(0x8000, ~1);
|
|
}
|
|
else {
|
|
UpdatePrg(0x8000, DRegBuf[6]);
|
|
UpdatePrg(0xC000, ~1);
|
|
}
|
|
UpdatePrg(0xA000, DRegBuf[7]);
|
|
UpdatePrg(0xE000, ~0);
|
|
}
|
|
|
|
void BoardSA9602B::UpdateChr(BYTE data)
|
|
{
|
|
BYTE cbase = (data & 0x80) << 5;
|
|
UpdateChr((cbase ^ 0x000), DRegBuf[0] & (~1));
|
|
UpdateChr((cbase ^ 0x400), DRegBuf[0] | 1);
|
|
UpdateChr((cbase ^ 0x800), DRegBuf[1] & (~1));
|
|
UpdateChr((cbase ^ 0xC00), DRegBuf[1] | 1);
|
|
UpdateChr(cbase ^ 0x1000, DRegBuf[2]);
|
|
UpdateChr(cbase ^ 0x1400, DRegBuf[3]);
|
|
UpdateChr(cbase ^ 0x1800, DRegBuf[4]);
|
|
UpdateChr(cbase ^ 0x1c00, DRegBuf[5]);
|
|
if (!nes->rom->Is4SCREEN()) {
|
|
if (A000B & 0x01) SetVRAM_Mirror(VRAM_HMIRROR);
|
|
else SetVRAM_Mirror(VRAM_VMIRROR);
|
|
}
|
|
}
|
|
|
|
void BoardSA9602B::HSync(INT scanline)
|
|
{
|
|
if ((scanline >= 0 && scanline <= 239)) {
|
|
if (nes->ppu->IsDispON())
|
|
{
|
|
if (IRQa && !IRQReload) {
|
|
if (scanline == 0) {
|
|
if (IRQCount) {
|
|
IRQCount -= 1;
|
|
}
|
|
}
|
|
if (!(IRQCount)){
|
|
IRQReload = 0xFF;
|
|
IRQCount = IRQLatch;
|
|
nes->cpu->SetIRQ(IRQ_MAPPER);
|
|
}
|
|
IRQCount--;
|
|
}
|
|
}
|
|
}
|
|
memcpy(&WRAM[0], &CRAM[CRAM_sav*0x2000], 0x2000);
|
|
}
|
|
|
|
void BoardSA9602B::SaveState( LPBYTE p )
|
|
{
|
|
//
|
|
}
|
|
|
|
void BoardSA9602B::LoadState( LPBYTE p )
|
|
{
|
|
//
|
|
}
|