136 lines
2.9 KiB
C++
136 lines
2.9 KiB
C++
//////////////////////////////////////////////////////////////////////////
|
||
// Mapper168 Subor (PPUExtLatch) //
|
||
//////////////////////////////////////////////////////////////////////////
|
||
|
||
void Mapper168::Reset()
|
||
{
|
||
reg5000 = 0;
|
||
reg5200 = 0;
|
||
reg5300 = 0;
|
||
PPU_SW = 0;
|
||
NT_data = 0;
|
||
nes->ppu->SetExtLatchMode( TRUE );
|
||
SetPROM_16K_Bank(4,0);
|
||
SetPROM_16K_Bank(6,0);
|
||
|
||
Rom_Type = 0;
|
||
DWORD crc = nes->rom->GetPROM_CRC();
|
||
if( crc == 0x0A9808AE ) //[Subor] Karaoke (C)
|
||
{
|
||
Rom_Type = 1;
|
||
SetPROM_32K_Bank( 0 );
|
||
nes->SetVideoMode( 2 );
|
||
}
|
||
if( crc == 0x12D61CE8 ) //[Subor] Subor V11.0 (C)
|
||
{
|
||
Rom_Type = 2;
|
||
}
|
||
}
|
||
|
||
BYTE Mapper168::ReadLow( WORD addr )
|
||
{
|
||
if(addr==0x5300) return 0x8F; //返回0x8F,跳过真人语音发声有关的程序段
|
||
return Mapper::ReadLow( addr );
|
||
}
|
||
|
||
void Mapper168::WriteLow(WORD addr, BYTE data)
|
||
{
|
||
if(addr==0x5000){
|
||
reg5000 = data;
|
||
SetBank_CPU();
|
||
}else if(addr==0x5200){
|
||
reg5200 = data & 0x7;
|
||
SetBank_CPU();
|
||
}else if(addr==0x5300){
|
||
reg5300 = data;
|
||
}else if(addr>=0x6000){
|
||
CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data;
|
||
}
|
||
}
|
||
|
||
void Mapper168::Write(WORD addr, BYTE data)
|
||
{
|
||
if(Rom_Type==1){ //[Subor] Karaoke (C)
|
||
SetPROM_32K_Bank( data&0x1F );
|
||
if(data&0x40) SetVRAM_Mirror( VRAM_HMIRROR );
|
||
else SetVRAM_Mirror( VRAM_VMIRROR );
|
||
if(data&0xC0) PPU_SW = 1;
|
||
else PPU_SW = 0;
|
||
}
|
||
}
|
||
|
||
void Mapper168::SetBank_CPU()
|
||
{
|
||
if(reg5200<4) SetPROM_16K_Bank(4,reg5000);
|
||
else SetPROM_32K_Bank(reg5000);
|
||
switch( reg5200 ) {
|
||
case 0:
|
||
SetVRAM_Mirror( VRAM_VMIRROR );
|
||
PPU_SW = 0;
|
||
break;
|
||
case 2:
|
||
SetVRAM_Mirror( VRAM_VMIRROR );
|
||
PPU_SW = 1;
|
||
break;
|
||
case 1:
|
||
case 3:
|
||
SetVRAM_Mirror( VRAM_HMIRROR );
|
||
PPU_SW = 0;
|
||
break;
|
||
case 5:
|
||
if(reg5000==4 && Rom_Type==2){ //Special for [Subor] Subor V11.0 (C) - Tank (坦克大战)
|
||
nes->ppu->SetExtLatchMode( FALSE );
|
||
SetVRAM_Mirror( VRAM_HMIRROR );
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
void Mapper168::PPU_Latch( WORD addr )
|
||
{
|
||
if((addr&0xF000)==0x2000){
|
||
NT_data=(addr>>8)&0x03;
|
||
}
|
||
}
|
||
|
||
void Mapper168::PPU_ExtLatch( WORD ntbladr, BYTE& chr_l, BYTE& chr_h, BYTE& attr )
|
||
{
|
||
INT loopy_v = nes->ppu->GetPPUADDR();
|
||
INT loopy_y = nes->ppu->GetTILEY();
|
||
INT tileofs = (PPUREG[0]&PPU_BGTBL_BIT)<<8;
|
||
INT attradr = 0x23C0+(loopy_v&0x0C00)+((loopy_v&0x0380)>>4);
|
||
INT attrsft = (ntbladr&0x0040)>>4;
|
||
LPBYTE pNTBL = PPU_MEM_BANK[ntbladr>>10];
|
||
INT ntbl_x = ntbladr&0x001F;
|
||
INT tileadr, ntb;
|
||
|
||
ntb = (ntbladr>>10)&3;
|
||
|
||
if(ntb==2)
|
||
tileofs |= 0x1000;
|
||
else if(ntb && PPU_SW)
|
||
tileofs |= 0x1000;
|
||
else
|
||
tileofs |= 0x0000;
|
||
|
||
attradr &= 0x3FF;
|
||
attr = ((pNTBL[attradr+(ntbl_x>>2)]>>((ntbl_x&2)+attrsft))&3)<<2;
|
||
tileadr = tileofs+pNTBL[ntbladr&0x03FF]*0x10+loopy_y;
|
||
|
||
chr_l = PPU_MEM_BANK[tileadr>>10][ tileadr&0x03FF ];
|
||
chr_h = PPU_MEM_BANK[tileadr>>10][(tileadr&0x03FF)+8];
|
||
}
|
||
|
||
void Mapper168::SaveState( LPBYTE p )
|
||
{
|
||
p[0] = reg5000;
|
||
p[1] = reg5200;
|
||
}
|
||
|
||
void Mapper168::LoadState( LPBYTE p )
|
||
{
|
||
|
||
reg5000 = p[0];
|
||
reg5200 = p[1];
|
||
}
|