125
« on: 2011-08-03 09:11:52 »
I found some code from two different emulators that describes how the bank switcher works for Mapper 163. What I was doing was just copying the bank switch code from the original rom, but I 'd like to have an idea of how it works. Here is two code snippets from two different emulators.
I think that $5000 is a security check, and 5001-5003 switch the rom, but are the arguments?
there is also a scan-line interrupt at line 127... I think.
You want to help decipher?
//////////////////////////////////////////////////////////////////////////
// Mapper163 NanJing Games (NES Chinese RPR game) //
//////////////////////////////////////////////////////////////////////////
void Mapper163::Reset()
{
reg[1] = 0xFF;
strobe = 1;
security = trigger = reg[0] = 0x00;
SetPROM_32K_Bank(15);
SetCRAM_8K_Bank(0);
}
BYTE Mapper163::ReadLow( WORD addr )
{
if((addr>=0x5000 && addr<0x6000))
{
switch (addr & 0x7700)
{
case 0x5100:
return security;
break;
case 0x5500:
if(trigger)
return security;
else
return 0;
break;
}
return 4;
}
else if( addr>=0x6000 ) {
return CPU_MEM_BANK[addr>>13][addr&0x1FFF];
}
return 0;
}
void Mapper163::WriteLow(WORD addr, BYTE data)
{
if((addr>=0x4020 && addr<0x6000))
{
if(addr==0x5101){
if(strobe && !data){
trigger ^= 1;
}
strobe = data;
}else if(addr==0x5100 && data==6){
SetPROM_32K_Bank(3);
}
else{
switch (addr & 0x7300)
{
case 0x5000:
reg[1]=data;
SetPROM_32K_Bank( (reg[1] & 0xF) | (reg[0] << 4) );
if(!(reg[1]&0x80)&&(nes->ppu->GetScanlineNo()<128))
SetCRAM_8K_Bank(0);
break;
case 0x5200:
reg[0]=data;
SetPROM_32K_Bank( (reg[1] & 0xF) | (reg[0] << 4) );
break;
case 0x5300:
security=data;
break;
}
}
}
else if( addr>=0x6000 ) {
CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data;
}
}
void Mapper163::HSync(int scanline)
{
if( (reg[1]&0x80) && nes->ppu->IsDispON() ) {
if(scanline==127){
SetCRAM_4K_Bank(0, 1);
SetCRAM_4K_Bank(4, 1);
}
if(scanline==239){
SetCRAM_4K_Bank(0, 0);
SetCRAM_4K_Bank(4, 0);
}
}
}
void Mapper163::SaveState( LPBYTE p )
{
p[0] = reg[0];
p[1] = reg[1];
}
void Mapper163::LoadState( LPBYTE p )
{
reg[0] = p[0];
reg[1] = p[1];
}
/*************************************************************
Bootleg Board by Nanjing
Games: A lot of pirate originals
iNES: mapper 163
In MESS: Unsupported.
*************************************************************/
static void nanjing_irq( device_t *device, int scanline, int vblank, int blanked )
{
nes_state *state = device->machine().driver_data<nes_state>();
if (BIT(state->m_mmc_reg[0], 7))
{
if (scanline == 127)
{
chr4_0(device->machine(), 1, CHRRAM);
chr4_4(device->machine(), 1, CHRRAM);
}
if (scanline == 239)
{
chr4_0(device->machine(), 0, CHRRAM);
chr4_4(device->machine(), 0, CHRRAM);
}
}
}
static WRITE8_HANDLER( nanjing_l_w )
{
nes_state *state = space->machine().driver_data<nes_state>();
LOG_MMC(("nanjing_l_w, offset: %04x, data: %02x\n", offset, data));
offset += 0x100;
if (offset < 0x1000)
return;
if (offset == 0x1100) // 0x5100
{
if (data == 6)
prg32(space->machine(), 3);
return;
}
if (offset == 0x1101) // 0x5101
{
UINT8 temp = state->m_mmc_count;
state->m_mmc_count = data;
if (temp & !data)
state->m_mmc_latch2 ^= 0xff;
}
switch (offset & 0x300)
{
case 0x000:
case 0x200:
state->m_mmc_reg[BIT(offset, 9)] = data;
if (!BIT(state->m_mmc_reg[0], 7) && ppu2c0x_get_current_scanline(state->m_ppu) <= 127)
chr8(space->machine(), 0, CHRRAM);
break;
case 0x300:
state->m_mmc_latch1 = data;
break;
}
prg32(space->machine(), (state->m_mmc_reg[0] & 0x0f) | ((state->m_mmc_reg[1] & 0x0f) << 4));
}
static READ8_HANDLER( nanjing_l_r )
{
nes_state *state = space->machine().driver_data<nes_state>();
UINT8 value = 0;
LOG_MMC(("nanjing_l_r, offset: %04x\n", offset));
offset += 0x100;
if (offset < 0x1000)
return 0;
switch (offset & 0x700)
{
case 0x100:
value = state->m_mmc_latch1;
break;
case 0x500:
value = state->m_mmc_latch2 & state->m_mmc_latch1;
break;
case 0x000:
case 0x200:
case 0x300:
case 0x400:
case 0x600:
case 0x700:
value = 4;
break;
}
return value;
}