286 lines
5.8 KiB
C++
286 lines
5.8 KiB
C++
|
|
/////////////////////////////////////////////////////////////////////
|
|
// Mapper 45
|
|
void NES_mapper45::Reset()
|
|
{
|
|
patch = 0;
|
|
|
|
prg0 = 0;
|
|
prg1 = 1;
|
|
prg2 = num_8k_ROM_banks-2;
|
|
prg3 = num_8k_ROM_banks-1;
|
|
|
|
if(parent_NES->crc32() == 0x58bcacf6 || // Kunio 8-in-1 (Pirate Cart)
|
|
parent_NES->crc32() == 0x9103cfd6 || // HIK 7-in-1 (Pirate Cart)
|
|
parent_NES->crc32() == 0xc082e6d3) // Super 8-in-1 (Pirate Cart)
|
|
{
|
|
patch = 1;
|
|
prg2 = 62;
|
|
prg3 = 63;
|
|
}
|
|
|
|
set_CPU_banks(prg0,prg1,prg2,prg3);
|
|
p[0] = prg0;
|
|
p[1] = prg1;
|
|
p[2] = prg2;
|
|
p[3] = prg3;
|
|
|
|
// set PPU bank pointers
|
|
set_PPU_banks(0,1,2,3,4,5,6,7);
|
|
chr0 = 0; chr1 = 1; chr2 = 2; chr3 = 3;
|
|
chr4 = 4; chr5 = 5; chr6 = 6; chr7 = 7;
|
|
c[0] = chr0; c[1] = chr1; c[2] = chr2; c[3] = chr3;
|
|
c[4] = chr4; c[5] = chr5; c[6] = chr6; c[7] = chr7;
|
|
|
|
irq_enabled = 0;
|
|
irq_counter = 0;
|
|
irq_latch = 0;
|
|
|
|
regs[0] = regs[1] = regs[2] = regs[3] = 0;
|
|
regs[4] = regs[5] = regs[6] = 0;
|
|
}
|
|
|
|
void NES_mapper45::MemoryWriteSaveRAM(uint32 addr, uint8 data)
|
|
{
|
|
if(addr == 0x6000)
|
|
{
|
|
regs[regs[5]] = data;
|
|
regs[5]= (regs[5]+1) & 0x03;
|
|
MAP45_set_CPU_bank4(prg0);
|
|
MAP45_set_CPU_bank5(prg1);
|
|
MAP45_set_CPU_bank6(prg2);
|
|
MAP45_set_CPU_bank7(prg3);
|
|
MAP45_set_PPU_banks();
|
|
}
|
|
}
|
|
|
|
void NES_mapper45::MemoryWrite(uint32 addr, uint8 data)
|
|
{
|
|
switch(addr & 0xE001)
|
|
{
|
|
case 0x8000:
|
|
{
|
|
uint32 swap;
|
|
if((data & 0x40) != (regs[6] & 0x40))
|
|
{
|
|
swap = prg0; prg0 = prg2; prg2 = swap;
|
|
swap = p[0]; p[0] = p[2]; p[2] = swap;
|
|
set_CPU_bank4(p[0]);
|
|
set_CPU_bank6(p[2]);
|
|
}
|
|
if(num_8k_ROM_banks)
|
|
{
|
|
if((data & 0x80) != (regs[6] & 0x80))
|
|
{
|
|
swap = chr4; chr4 = chr0; chr0 = swap;
|
|
swap = chr5; chr5 = chr1; chr1 = swap;
|
|
swap = chr6; chr6 = chr2; chr2 = swap;
|
|
swap = chr7; chr7 = chr3; chr3 = swap;
|
|
swap = c[4]; c[4] = c[0]; c[0] = swap;
|
|
swap = c[5]; c[5] = c[1]; c[1] = swap;
|
|
swap = c[6]; c[6] = c[2]; c[2] = swap;
|
|
swap = c[7]; c[7] = c[3]; c[3] = swap;
|
|
set_PPU_banks(c[0],c[1],c[2],c[3],c[4],c[5],c[6],c[7]);
|
|
}
|
|
}
|
|
regs[6] = data;
|
|
}
|
|
break;
|
|
|
|
case 0x8001:
|
|
{
|
|
switch(regs[6] & 0x07)
|
|
{
|
|
case 0x00:
|
|
{
|
|
chr0 = (data & 0xFE)+0;
|
|
chr1 = (data & 0xFE)+1;
|
|
MAP45_set_PPU_banks();
|
|
}
|
|
break;
|
|
|
|
case 0x01:
|
|
{
|
|
chr2 = (data & 0xFE)+0;
|
|
chr3 = (data & 0xFE)+1;
|
|
MAP45_set_PPU_banks();
|
|
}
|
|
break;
|
|
|
|
case 0x02:
|
|
{
|
|
chr4 = data;
|
|
MAP45_set_PPU_banks();
|
|
}
|
|
break;
|
|
|
|
case 0x03:
|
|
{
|
|
chr5 = data;
|
|
MAP45_set_PPU_banks();
|
|
}
|
|
break;
|
|
|
|
case 0x04:
|
|
{
|
|
chr6 = data;
|
|
MAP45_set_PPU_banks();
|
|
}
|
|
break;
|
|
|
|
case 0x05:
|
|
{
|
|
chr7 = data;
|
|
MAP45_set_PPU_banks();
|
|
}
|
|
break;
|
|
|
|
case 0x06:
|
|
{
|
|
if(regs[6] & 0x40)
|
|
{
|
|
prg2 = data & 0x3F;
|
|
MAP45_set_CPU_bank6(data);
|
|
}
|
|
else
|
|
{
|
|
prg0 = data & 0x3F;
|
|
MAP45_set_CPU_bank4(data);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 0x07:
|
|
{
|
|
prg1 = data & 0x3F;
|
|
MAP45_set_CPU_bank5(data);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 0xA000:
|
|
{
|
|
if(data & 0x01)
|
|
{
|
|
set_mirroring(NES_PPU::MIRROR_HORIZ);
|
|
}
|
|
else
|
|
{
|
|
set_mirroring(NES_PPU::MIRROR_VERT);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 0xC000:
|
|
{
|
|
irq_counter = data;
|
|
}
|
|
break;
|
|
|
|
case 0xC001:
|
|
{
|
|
irq_latch = data;
|
|
}
|
|
break;
|
|
|
|
case 0xE000:
|
|
{
|
|
irq_enabled = 0;
|
|
}
|
|
break;
|
|
|
|
case 0xE001:
|
|
{
|
|
irq_enabled = 1;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void NES_mapper45::HSync(uint32 scanline)
|
|
{
|
|
if(irq_enabled)
|
|
{
|
|
if((scanline >= 0) && (scanline <= 239))
|
|
{
|
|
if(parent_NES->ppu->spr_enabled() || parent_NES->ppu->bg_enabled())
|
|
{
|
|
if(!(irq_counter--))
|
|
{
|
|
irq_counter = irq_latch;
|
|
parent_NES->cpu->DoIRQ();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void NES_mapper45::MAP45_set_CPU_bank4(uint8 data)
|
|
{
|
|
data &= (regs[3] & 0x3F) ^ 0xFF;
|
|
data &= 0x3F;
|
|
data |= regs[1];
|
|
set_CPU_bank4(data);
|
|
p[0] = data;
|
|
}
|
|
|
|
void NES_mapper45::MAP45_set_CPU_bank5(uint8 data)
|
|
{
|
|
data &= (regs[3] & 0x3F) ^ 0xFF;
|
|
data &= 0x3F;
|
|
data |= regs[1];
|
|
set_CPU_bank5(data);
|
|
p[1] = data;
|
|
}
|
|
void NES_mapper45::MAP45_set_CPU_bank6(uint8 data)
|
|
{
|
|
data &= (regs[3] & 0x3F) ^ 0xFF;
|
|
data &= 0x3F;
|
|
data |= regs[1];
|
|
set_CPU_bank6(data);
|
|
p[2] = data;
|
|
}
|
|
void NES_mapper45::MAP45_set_CPU_bank7(uint8 data)
|
|
{
|
|
data &= (regs[3] & 0x3F) ^ 0xFF;
|
|
data &= 0x3F;
|
|
data |= regs[1];
|
|
set_CPU_bank7(data);
|
|
p[3] = data;
|
|
}
|
|
|
|
void NES_mapper45::MAP45_set_PPU_banks()
|
|
{
|
|
uint8 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(uint8 i = 0; i < 8; i++)
|
|
{
|
|
c[i] &= table[regs[2] & 0x0F];
|
|
c[i] |= regs[0] & ((patch == 0) ? 0xff : 0xC0);
|
|
c[i] += (uint32)(regs[2] & ((patch == 0) ? 0x10 : 0x30)) << 4;
|
|
}
|
|
if(regs[6] & 0x80)
|
|
{
|
|
set_PPU_banks(c[4],c[5],c[6],c[7],c[0],c[1],c[2],c[3]);
|
|
}
|
|
else
|
|
{
|
|
set_PPU_banks(c[0],c[1],c[2],c[3],c[4],c[5],c[6],c[7]);
|
|
}
|
|
}
|
|
/////////////////////////////////////////////////////////////////////
|
|
|