AxibugEmuOnline/References/VirtuaNESex_src_191105/NES/Mapper/Mapper168.cpp
2024-08-05 17:58:53 +08:00

136 lines
2.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//////////////////////////////////////////////////////////////////////////
// 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];
}