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

309 lines
5.7 KiB
C++

//////////////////////////////////////////////////////////////////////////
// Mapper187 Street Fighter Zero 2 97 //
//////////////////////////////////////////////////////////////////////////
void Mapper187::Reset()
{
INT i;
for( i = 0; i < 8; i++ ) {
chr[i] = 0x00;
bank[i] = 0x00;
}
prg[0] = PROM_8K_SIZE-4;
prg[1] = PROM_8K_SIZE-3;
prg[2] = PROM_8K_SIZE-2;
prg[3] = PROM_8K_SIZE-1;
SetBank_CPU();
ext_mode = 0;
chr_mode = 0;
ext_enable = 0;
irq_enable = 0;
irq_counter = 0;
irq_latch = 0;
last_write = 0;
nes->SetRenderMethod( NES::POST_ALL_RENDER );
}
BYTE Mapper187::ReadLow( WORD addr )
{
switch( last_write&0x03 ) {
case 0:
return 0x83;
case 1:
return 0x83;
case 2:
return 0x42;
case 3:
return 0x00;
}
return 0;
}
void Mapper187::WriteLow( WORD addr, BYTE data )
{
last_write = data;
if( (addr == 0x5000)||(addr == 0x6000) ) {
ext_mode = data;
/* if( data & 0x80 ) {
if( data & 0x20 ) {
prg[0] = ((data&0x1E)<<1)+0;
prg[1] = ((data&0x1E)<<1)+1;
prg[2] = ((data&0x1E)<<1)+2;
prg[3] = ((data&0x1E)<<1)+3;
} else {
prg[2] = ((data&0x1F)<<1)+0;
prg[3] = ((data&0x1F)<<1)+1;
}
} else {
prg[0] = bank[6];
prg[1] = bank[7];
prg[2] = PROM_8K_SIZE-2;
prg[3] = PROM_8K_SIZE-1;
}
SetBank_CPU();
*/
if(data & 0x80) {
uint8 bank = data & 0x1F;
if (data & 0x20) {
if (data & 0x40)
SetPROM_32K_Bank(bank>>2);
else
SetPROM_32K_Bank(bank>>1);
} else {
SetPROM_16K_Bank(4, bank);
SetPROM_16K_Bank(6, bank);
}
} else SetPROM_32K_Bank(bank[6],bank[7],PROM_8K_SIZE-2,PROM_8K_SIZE-1);
}
}
void Mapper187::Write( WORD addr, BYTE data )
{
last_write = data;
switch( addr ) {
case 0x8003:
ext_enable = 0xFF;
// if( (data&0x80) != (chr_mode&0x80) ) {
// for( INT i = 0; i < 4; i++ ) {
// INT temp = chr[i];
// chr[i] = chr[i+4];
// chr[i+4] = temp;
// }
// SetBank_PPU();
// }
chr_mode = data;
if( (data&0xF0) == 0 ) {
prg[2] = PROM_8K_SIZE-2;
SetBank_CPU();
}
break;
case 0x8000:
ext_enable = 0;
// if( (data&0x80) != (chr_mode&0x80) ) {
// for( INT i = 0; i < 4; i++ ) {
// INT temp = chr[i];
// chr[i] = chr[i+4];
// chr[i+4] = temp;
// }
// SetBank_PPU();
// }
chr_mode = data;
break;
case 0x8001:
if( !ext_enable ) {
switch( chr_mode & 7 ) {
case 0:
data &= 0xFE;
chr[4] = (INT)data+0x100;
chr[5] = (INT)data+0x100+1;
// chr[0+((chr_mode&0x80)?4:0)] = data;
// chr[1+((chr_mode&0x80)?4:0)] = data+1;
SetBank_PPU();
break;
case 1:
data &= 0xFE;
chr[6] = (INT)data+0x100;
chr[7] = (INT)data+0x100+1;
// chr[2+((chr_mode&0x80)?4:0)] = data;
// chr[3+((chr_mode&0x80)?4:0)] = data+1;
SetBank_PPU();
break;
case 2:
chr[0] = data;
// chr[0+((chr_mode&0x80)?0:4)] = data;
SetBank_PPU();
break;
case 3:
chr[1] = data;
// chr[1+((chr_mode&0x80)?0:4)] = data;
SetBank_PPU();
break;
case 4:
chr[2] = data;
// chr[2+((chr_mode&0x80)?0:4)] = data;
SetBank_PPU();
break;
case 5:
chr[3] = data;
// chr[3+((chr_mode&0x80)?0:4)] = data;
SetBank_PPU();
break;
case 6:
if( (ext_mode&0xA0)!=0xA0 ) {
prg[0] = data;
SetBank_CPU();
}
break;
case 7:
if( (ext_mode&0xA0)!=0xA0 ) {
prg[1] = data;
SetBank_CPU();
}
break;
default:
break;
}
} else {
switch( chr_mode ) {
case 0x2A:
prg[1] = 0x0F;
break;
case 0x28:
prg[2] = 0x17;
break;
case 0x26:
break;
default:
break;
}
SetBank_CPU();
}
bank[chr_mode&7] = data;
break;
case 0xA000:
if( data & 0x01 ) {
SetVRAM_Mirror( VRAM_HMIRROR );
} else {
SetVRAM_Mirror( VRAM_VMIRROR );
}
break;
case 0xA001:
break;
case 0xC000:
irq_counter = data;
irq_occur = 0;
nes->cpu->ClrIRQ( IRQ_MAPPER );
break;
case 0xC001:
irq_latch = data;
irq_occur = 0;
nes->cpu->ClrIRQ( IRQ_MAPPER );
break;
case 0xE000:
case 0xE002:
irq_enable = 0;
irq_occur = 0;
nes->cpu->ClrIRQ( IRQ_MAPPER );
break;
case 0xE001:
case 0xE003:
irq_enable = 1;
irq_occur = 0;
nes->cpu->ClrIRQ( IRQ_MAPPER );
break;
}
}
void Mapper187::Clock( INT cycles )
{
// if( irq_occur ) {
// nes->cpu->IRQ_NotPending();
// }
}
void Mapper187::HSync( INT scanline )
{
if( (scanline >= 0 && scanline <= 239) ) {
if( nes->ppu->IsDispON() ) {
if( irq_enable ) {
if( !irq_counter ) {
irq_counter--;
irq_enable = 0;
irq_occur = 0xFF;
nes->cpu->SetIRQ( IRQ_MAPPER );
} else {
irq_counter--;
}
}
}
}
}
void Mapper187::SetBank_CPU()
{
SetPROM_32K_Bank( prg[0], prg[1], prg[2], prg[3] );
}
void Mapper187::SetBank_PPU()
{
SetVROM_8K_Bank( chr[0], chr[1], chr[2], chr[3],
chr[4], chr[5], chr[6], chr[7] );
}
void Mapper187::SaveState( LPBYTE p )
{
INT i;
for( i = 0; i < 4; i++ ) {
p[i] = prg[i];
}
for( i = 0; i < 8; i++ ) {
p[4+i] = bank[i];
}
for( i = 0; i < 8; i++ ) {
*((INT*)&p[12+i*sizeof(INT)]) = chr[i];
}
p[44] = ext_mode;
p[45] = chr_mode;
p[46] = ext_enable;
p[47] = irq_enable;
p[48] = irq_counter;
p[49] = irq_latch;
p[50] = irq_occur;
p[51] = last_write;
}
void Mapper187::LoadState( LPBYTE p )
{
INT i;
for( i = 0; i < 4; i++ ) {
prg[i] = p[i];
}
for( i = 0; i < 8; i++ ) {
bank[i] = p[4+i];
}
for( i = 0; i < 8; i++ ) {
chr[i] = *((INT*)&p[12+i*sizeof(INT)]);
}
ext_mode = p[44];
chr_mode = p[45];
ext_enable = p[46];
irq_enable = p[47];
irq_counter = p[48];
irq_latch = p[49];
irq_occur = p[50];
last_write = p[51];
}