319 lines
13 KiB
C++
319 lines
13 KiB
C++
//////////////////////////////////////////////////////////////////////////
|
||
// Mapper045 1000000-in-1 //
|
||
//////////////////////////////////////////////////////////////////////////
|
||
void Mapper045::Reset()
|
||
{
|
||
patch = 0;
|
||
for( INT i = 0; i < 8; i++ ) {
|
||
reg[i] = 0;
|
||
}
|
||
|
||
prg0 = 0;
|
||
prg1 = 1;
|
||
prg2 = PROM_8K_SIZE-2;
|
||
prg3 = PROM_8K_SIZE-1;
|
||
|
||
DWORD crc = nes->rom->GetPROM_CRC();
|
||
if( crc == 0x58bcacf6 // Kunio 8-in-1 (Pirate Cart)
|
||
|| crc == 0x9103cfd6 // HIK 7-in-1 (Pirate Cart)
|
||
|| crc == 0xc082e6d3 ) { // Super 8-in-1 (Pirate Cart)
|
||
patch = 1;
|
||
prg2 = 62;
|
||
prg3 = 63;
|
||
}
|
||
if( crc == 0xe0dd259d ) { // Super 3-in-1 (Pirate Cart)
|
||
patch = 2;
|
||
}
|
||
SetPROM_32K_Bank( prg0, prg1, prg2, prg3 );
|
||
p[0] = prg0;
|
||
p[1] = prg1;
|
||
p[2] = prg2;
|
||
p[3] = prg3;
|
||
|
||
SetVROM_8K_Bank( 0 );
|
||
|
||
// chr0 = c[0] = 0;
|
||
// chr1 = c[1] = 0
|
||
// chr2 = c[2] = 0;
|
||
// chr3 = c[3] = 0;
|
||
// chr4 = c[4] = 0;
|
||
// chr5 = c[5] = 0;
|
||
// chr6 = c[6] = 0;
|
||
// chr7 = c[7] = 0;
|
||
|
||
chr0 = c[0] = 0;
|
||
chr1 = c[1] = 1;
|
||
chr2 = c[2] = 2;
|
||
chr3 = c[3] = 3;
|
||
chr4 = c[4] = 4;
|
||
chr5 = c[5] = 5;
|
||
chr6 = c[6] = 6;
|
||
chr7 = c[7] = 7;
|
||
|
||
irq_enable = 0;
|
||
irq_counter = 0;
|
||
irq_latch = 0;
|
||
irq_latched = 0;
|
||
irq_reset = 0;
|
||
}
|
||
|
||
void Mapper045::WriteLow( WORD addr, BYTE data )
|
||
{
|
||
// if( addr == 0x6000 ) {
|
||
// if( addr == 0x6000 && !(reg[3]&0x40) ) {
|
||
if( !(reg[3]&0x40) ) {
|
||
reg[reg[5]] = data;
|
||
reg[5] = (reg[5]+1) & 0x03;
|
||
|
||
SetBank_CPU_4( prg0 );
|
||
SetBank_CPU_5( prg1 );
|
||
SetBank_CPU_6( prg2 );
|
||
SetBank_CPU_7( prg3 );
|
||
SetBank_PPU();
|
||
}
|
||
}
|
||
|
||
void Mapper045::Write( WORD addr, BYTE data )
|
||
{
|
||
switch( addr & 0xE001 ) {
|
||
case 0x8000:
|
||
if( (data&0x40)!=(reg[6]&0x40) ) {
|
||
BYTE swp;
|
||
swp = prg0; prg0 = prg2; prg2 = swp;
|
||
swp = p[0]; p[0] = p[2]; p[2] = swp;
|
||
SetBank_CPU_4( p[0] );
|
||
SetBank_CPU_5( p[1] );
|
||
}
|
||
if( VROM_1K_SIZE ) {
|
||
if( (data&0x80)!=(reg[6]&0x80) ) {
|
||
INT swp;
|
||
swp = chr4; chr4 = chr0; chr0 = swp;
|
||
swp = chr5; chr5 = chr1; chr1 = swp;
|
||
swp = chr6; chr6 = chr2; chr2 = swp;
|
||
swp = chr7; chr7 = chr3; chr3 = swp;
|
||
swp = c[4]; c[4] = c[0]; c[0] = swp;
|
||
swp = c[5]; c[5] = c[1]; c[1] = swp;
|
||
swp = c[6]; c[6] = c[2]; c[2] = swp;
|
||
swp = c[7]; c[7] = c[3]; c[3] = swp;
|
||
SetVROM_8K_Bank( c[0],c[1],c[2],c[3],c[4],c[5],c[6],c[7] );
|
||
}
|
||
}
|
||
reg[6] = data;
|
||
break;
|
||
case 0x8001:
|
||
switch( reg[6] & 0x07 ) {
|
||
case 0x00:
|
||
chr0 = (data & 0xFE)+0;
|
||
chr1 = (data & 0xFE)+1;
|
||
SetBank_PPU();
|
||
break;
|
||
case 0x01:
|
||
chr2 = (data & 0xFE)+0;
|
||
chr3 = (data & 0xFE)+1;
|
||
SetBank_PPU();
|
||
break;
|
||
case 0x02:
|
||
chr4 = data;
|
||
SetBank_PPU();
|
||
break;
|
||
case 0x03:
|
||
chr5 = data;
|
||
SetBank_PPU();
|
||
break;
|
||
case 0x04:
|
||
chr6 = data;
|
||
SetBank_PPU();
|
||
break;
|
||
case 0x05:
|
||
chr7 = data;
|
||
SetBank_PPU();
|
||
break;
|
||
case 0x06:
|
||
if( reg[6] & 0x40 ) {
|
||
prg2 = data & 0x3F;
|
||
SetBank_CPU_6( data );
|
||
} else {
|
||
prg0 = data & 0x3F;
|
||
SetBank_CPU_4( data );
|
||
}
|
||
break;
|
||
case 0x07:
|
||
prg1 = data & 0x3F;
|
||
SetBank_CPU_5( data );
|
||
break;
|
||
}
|
||
break;
|
||
case 0xA000:
|
||
if( data & 0x01 ) SetVRAM_Mirror( VRAM_HMIRROR );
|
||
else SetVRAM_Mirror( VRAM_VMIRROR );
|
||
break;
|
||
case 0xC000:
|
||
if( patch == 2 ) {
|
||
if( data == 0x29 || data == 0x70 )
|
||
data = 0x07;
|
||
}
|
||
irq_latch = data;
|
||
irq_latched = 1;
|
||
if( irq_reset ) {
|
||
irq_counter = data;
|
||
irq_latched = 0;
|
||
}
|
||
// irq_counter = data;
|
||
break;
|
||
case 0xC001:
|
||
// irq_latch = data;
|
||
irq_counter = irq_latch;
|
||
break;
|
||
case 0xE000:
|
||
irq_enable = 0;
|
||
irq_reset = 1;
|
||
nes->cpu->ClrIRQ( IRQ_MAPPER );
|
||
break;
|
||
case 0xE001:
|
||
irq_enable = 1;
|
||
if( irq_latched ) {
|
||
irq_counter = irq_latch;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
void Mapper045::HSync( INT scanline )
|
||
{
|
||
irq_reset = 0;
|
||
if( (scanline >= 0 && scanline <= 239) && nes->ppu->IsDispON() ) {
|
||
if( irq_counter ) {
|
||
irq_counter--;
|
||
if( irq_counter == 0 ) {
|
||
if( irq_enable ) {
|
||
nes->cpu->SetIRQ( IRQ_MAPPER );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void Mapper045::SetBank_CPU_4( INT data )
|
||
{
|
||
data &= (reg[3] & 0x3F) ^ 0xFF;
|
||
data &= 0x3F;
|
||
data |= reg[1];
|
||
SetPROM_8K_Bank( 4, data );
|
||
p[0] = data;
|
||
}
|
||
|
||
void Mapper045::SetBank_CPU_5( INT data )
|
||
{
|
||
data &= (reg[3] & 0x3F) ^ 0xFF;
|
||
data &= 0x3F;
|
||
data |= reg[1];
|
||
SetPROM_8K_Bank( 5, data );
|
||
p[1] = data;
|
||
}
|
||
|
||
void Mapper045::SetBank_CPU_6( INT data )
|
||
{
|
||
data &= (reg[3] & 0x3F) ^ 0xFF;
|
||
data &= 0x3F;
|
||
data |= reg[1];
|
||
SetPROM_8K_Bank( 6, data );
|
||
p[2] = data;
|
||
}
|
||
|
||
void Mapper045::SetBank_CPU_7( INT data )
|
||
{
|
||
data &= (reg[3] & 0x3F) ^ 0xFF;
|
||
data &= 0x3F;
|
||
data |= reg[1];
|
||
SetPROM_8K_Bank( 7, data );
|
||
p[3] = data;
|
||
}
|
||
|
||
void Mapper045::SetBank_PPU()
|
||
{
|
||
BYTE table[16] = {
|
||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||
0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF
|
||
};
|
||
|
||
c[0] = chr0;
|
||
c[1] = chr1;
|
||
c[2] = chr2;
|
||
c[3] = chr3;
|
||
c[4] = chr4;
|
||
c[5] = chr5;
|
||
c[6] = chr6;
|
||
c[7] = chr7;
|
||
|
||
for( INT i = 0; i < 8; i++ ) {
|
||
c[i] &= table[reg[2] & 0x0F];
|
||
c[i] |= reg[0] & ((patch!=1)?0xFF:0xC0);
|
||
c[i] += (reg[2] & ((patch!=1)?0x10:0x30))<<4;
|
||
}
|
||
|
||
if( reg[6] & 0x80 ) {
|
||
SetVROM_8K_Bank( c[4], c[5], c[6], c[7], c[0], c[1], c[2], c[3] );
|
||
} else {
|
||
SetVROM_8K_Bank( c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7] );
|
||
}
|
||
}
|
||
|
||
void Mapper045::SaveState( LPBYTE ps )
|
||
{
|
||
INT i;
|
||
for( i = 0; i < 8; i++ ) {
|
||
ps[i] = reg[i];
|
||
}
|
||
for( i = 0; i < 4; i++ ) {
|
||
ps[i+8] = p[i];
|
||
}
|
||
for( i = 0; i < 8; i++ ) {
|
||
*(INT*)&ps[i*4+64] = c[i];
|
||
}
|
||
ps[20] = prg0;
|
||
ps[21] = prg1;
|
||
ps[22] = prg2;
|
||
ps[23] = prg3;
|
||
ps[24] = chr0;
|
||
ps[25] = chr1;
|
||
ps[26] = chr2;
|
||
ps[27] = chr3;
|
||
ps[28] = chr4;
|
||
ps[29] = chr5;
|
||
ps[30] = chr6;
|
||
ps[31] = chr7;
|
||
ps[32] = irq_enable;
|
||
ps[33] = irq_counter;
|
||
ps[34] = irq_latch;
|
||
}
|
||
|
||
void Mapper045::LoadState( LPBYTE ps )
|
||
{
|
||
INT i;
|
||
for( i = 0; i < 8; i++ ) {
|
||
reg[i] = ps[i];
|
||
}
|
||
for( i = 0; i < 4; i++ ) {
|
||
p[i] = ps[i+8];
|
||
}
|
||
for( i = 0; i < 8; i++ ) {
|
||
c[i] = *(INT*)&ps[i*4+64];
|
||
}
|
||
prg0 = ps[20];
|
||
prg1 = ps[21];
|
||
prg2 = ps[22];
|
||
prg3 = ps[23];
|
||
chr0 = ps[24];
|
||
chr1 = ps[25];
|
||
chr2 = ps[26];
|
||
chr3 = ps[27];
|
||
chr4 = ps[28];
|
||
chr5 = ps[29];
|
||
chr6 = ps[30];
|
||
chr7 = ps[31];
|
||
irq_enable = ps[32];
|
||
irq_counter = ps[33];
|
||
irq_latch = ps[34];
|
||
}
|
||
|