673 lines
15 KiB
C++
673 lines
15 KiB
C++
//////////////////////////////////////////////////////////////////////////
|
||
// Mapper005 Nintendo MMC5 //
|
||
//////////////////////////////////////////////////////////////////////////
|
||
#define MMC5_IRQ_METAL (1<<0)
|
||
|
||
void Mapper005::Reset()
|
||
{
|
||
INT i;
|
||
|
||
prg_size = 3;
|
||
chr_size = 3;
|
||
|
||
sram_we_a = 0x00;
|
||
sram_we_b = 0x00;
|
||
|
||
graphic_mode = 0;
|
||
nametable_mode = 0;
|
||
|
||
for( i = 0; i < 4; i++ ) {
|
||
nametable_type[i] = 0;
|
||
}
|
||
|
||
fill_chr = fill_pal = 0;
|
||
split_control = split_scroll = split_page = 0;
|
||
|
||
irq_enable = 0;
|
||
irq_status = 0;
|
||
irq_scanline = 0;
|
||
irq_line = 0;
|
||
irq_clear = 0;
|
||
|
||
irq_type = 0;
|
||
|
||
mult_a = mult_b = 0;
|
||
|
||
chr_type = 0;
|
||
chr_mode = 0;
|
||
for( i = 0; i < 8; i++ ) {
|
||
chr_page[0][i] = i;
|
||
chr_page[1][i] = 4+(i&0x03);
|
||
}
|
||
|
||
SetPROM_32K_Bank( PROM_8K_SIZE-1, PROM_8K_SIZE-1, PROM_8K_SIZE-1, PROM_8K_SIZE-1 );
|
||
SetVROM_8K_Bank( 0 );
|
||
|
||
for( i = 0; i < 8; i++ ) {
|
||
BG_MEM_BANK[i] = VROM+0x0400*i;
|
||
BG_MEM_PAGE[i] = i;
|
||
}
|
||
|
||
// SRAM<41>Ý’è
|
||
SetBank_SRAM( 3, 0 );
|
||
|
||
sram_size = 0;
|
||
nes->SetSAVERAM_SIZE( 16*1024 );
|
||
|
||
DWORD crc = nes->rom->GetPROM_CRC();
|
||
|
||
if( crc == 0x2b548d75 // Bandit Kings of Ancient China(U)
|
||
|| crc == 0xf4cd4998 // Dai Koukai Jidai(J)
|
||
|| crc == 0x8fa95456 // Ishin no Arashi(J)
|
||
|| crc == 0x98c8e090 // Nobunaga no Yabou - Sengoku Gunyuu Den(J)
|
||
|| crc == 0x8e9a5e2f // L'Empereur(Alt)(U)
|
||
|| crc == 0x57e3218b // L'Empereur(U)
|
||
|| crc == 0x2f50bd38 // L'Empereur(J)
|
||
|| crc == 0xb56958d1 // Nobunaga's Ambition 2(U)
|
||
|| crc == 0xe6c28c5f // Suikoden - Tenmei no Chikai(J)
|
||
|| crc == 0xcd35e2e9 ) { // Uncharted Waters(U)
|
||
sram_size = 1;
|
||
nes->SetSAVERAM_SIZE( 32*1024 );
|
||
} else
|
||
if( crc == 0xf4120e58 // Aoki Ookami to Shiroki Mejika - Genchou Hishi(J)
|
||
|| crc == 0x286613d8 // Nobunaga no Yabou - Bushou Fuuun Roku(J)
|
||
|| crc == 0x11eaad26 // Romance of the Three Kingdoms 2(U)
|
||
|| crc == 0x95ba5733 ) { // Sangokushi 2(J)
|
||
sram_size = 2;
|
||
nes->SetSAVERAM_SIZE( 64*1024 );
|
||
}
|
||
|
||
if( crc == 0x95ca9ec7 ) { // Castlevania 3 - Dracula's Curse(U)
|
||
nes->SetRenderMethod( NES::TILE_RENDER );
|
||
}
|
||
|
||
if( crc == 0xcd9acf43 ) { // Metal Slader Glory(J)
|
||
irq_type = MMC5_IRQ_METAL;
|
||
}
|
||
|
||
if( crc == 0xe91548d8 ) { // Shin 4 Nin Uchi Mahjong - Yakuman Tengoku(J)
|
||
chr_type = 1;
|
||
}
|
||
|
||
nes->ppu->SetExtLatchMode( TRUE );
|
||
nes->apu->SelectExSound( 8 );
|
||
}
|
||
|
||
BYTE Mapper005::ReadLow( WORD addr )
|
||
{
|
||
BYTE data = (BYTE)(addr>>8);
|
||
|
||
switch( addr ) {
|
||
case 0x5015:
|
||
data = nes->apu->ExRead( addr );
|
||
break;
|
||
|
||
case 0x5204:
|
||
data = irq_status;
|
||
// irq_status = 0;
|
||
irq_status &= ~0x80;
|
||
|
||
nes->cpu->ClrIRQ( IRQ_MAPPER );
|
||
break;
|
||
case 0x5205:
|
||
data = mult_a*mult_b;
|
||
break;
|
||
case 0x5206:
|
||
data = (BYTE)(((WORD)mult_a*(WORD)mult_b)>>8);
|
||
break;
|
||
}
|
||
|
||
if( addr >= 0x5C00 && addr <= 0x5FFF ) {
|
||
if( graphic_mode >= 2 ) { // ExRAM mode
|
||
data = VRAM[0x0800+(addr&0x3FF)];
|
||
}
|
||
} else if( addr >= 0x6000 && addr <= 0x7FFF ) {
|
||
data = Mapper::ReadLow( addr );
|
||
}
|
||
|
||
return data;
|
||
}
|
||
|
||
void Mapper005::WriteLow( WORD addr, BYTE data )
|
||
{
|
||
INT i;
|
||
|
||
#if 0
|
||
if( addr >= 0x5000 && addr <=0x5100 ) {
|
||
DEBUGOUT( "$%04X=%02X C:%10d\n", addr, data, nes->cpu->GetTotalCycles() );
|
||
}
|
||
#endif
|
||
|
||
switch( addr ) {
|
||
case 0x5100:
|
||
prg_size = data & 0x03;
|
||
break;
|
||
case 0x5101:
|
||
chr_size = data & 0x03;
|
||
break;
|
||
|
||
case 0x5102:
|
||
sram_we_a = data & 0x03;
|
||
break;
|
||
case 0x5103:
|
||
sram_we_b = data & 0x03;
|
||
break;
|
||
|
||
case 0x5104:
|
||
graphic_mode = data & 0x03;
|
||
break;
|
||
case 0x5105:
|
||
nametable_mode = data;
|
||
for( i = 0; i < 4; i++ ) {
|
||
nametable_type[i] = data&0x03;
|
||
SetVRAM_1K_Bank( 8+i, nametable_type[i] );
|
||
data >>= 2;
|
||
}
|
||
break;
|
||
|
||
case 0x5106:
|
||
fill_chr = data;
|
||
break;
|
||
case 0x5107:
|
||
fill_pal = data & 0x03;
|
||
break;
|
||
|
||
case 0x5113:
|
||
SetBank_SRAM( 3, data&0x07 );
|
||
break;
|
||
|
||
case 0x5114:
|
||
case 0x5115:
|
||
case 0x5116:
|
||
case 0x5117:
|
||
SetBank_CPU( addr, data );
|
||
break;
|
||
|
||
case 0x5120:
|
||
case 0x5121:
|
||
case 0x5122:
|
||
case 0x5123:
|
||
case 0x5124:
|
||
case 0x5125:
|
||
case 0x5126:
|
||
case 0x5127:
|
||
chr_mode = 0;
|
||
chr_page[0][addr&0x07] = data;
|
||
SetBank_PPU();
|
||
break;
|
||
|
||
case 0x5128:
|
||
case 0x5129:
|
||
case 0x512A:
|
||
case 0x512B:
|
||
chr_mode = 1;
|
||
chr_page[1][(addr&0x03)+0] = data;
|
||
chr_page[1][(addr&0x03)+4] = data;
|
||
SetBank_PPU();
|
||
break;
|
||
|
||
case 0x5200:
|
||
split_control = data;
|
||
break;
|
||
case 0x5201:
|
||
split_scroll = data;
|
||
break;
|
||
case 0x5202:
|
||
split_page = data&0x3F;
|
||
break;
|
||
|
||
case 0x5203:
|
||
irq_line = data;
|
||
|
||
nes->cpu->ClrIRQ( IRQ_MAPPER );
|
||
break;
|
||
case 0x5204:
|
||
irq_enable = data;
|
||
|
||
nes->cpu->ClrIRQ( IRQ_MAPPER );
|
||
break;
|
||
|
||
case 0x5205:
|
||
mult_a = data;
|
||
break;
|
||
case 0x5206:
|
||
mult_b = data;
|
||
break;
|
||
|
||
default:
|
||
if( addr >= 0x5000 && addr <= 0x5015 ) {
|
||
nes->apu->ExWrite( addr, data );
|
||
} else if( addr >= 0x5C00 && addr <= 0x5FFF ) {
|
||
if( graphic_mode == 2 ) { // ExRAM
|
||
VRAM[0x0800+(addr&0x3FF)] = data;
|
||
} else if( graphic_mode != 3 ) { // Split,ExGraphic
|
||
if( irq_status&0x40 ) {
|
||
VRAM[0x0800+(addr&0x3FF)] = data;
|
||
} else {
|
||
VRAM[0x0800+(addr&0x3FF)] = 0;
|
||
}
|
||
}
|
||
} else if( addr >= 0x6000 && addr <= 0x7FFF ) {
|
||
if( sram_we_a == 0x02 && sram_we_b == 0x01 ) {
|
||
if( CPU_MEM_TYPE[3] == BANKTYPE_RAM ) {
|
||
CPU_MEM_BANK[3][addr&0x1FFF] = data;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
void Mapper005::Write( WORD addr, BYTE data )
|
||
{
|
||
if( sram_we_a == 0x02 && sram_we_b == 0x01 ) {
|
||
if( addr >= 0x8000 && addr < 0xE000 ) {
|
||
if( CPU_MEM_TYPE[addr>>13] == BANKTYPE_RAM ) {
|
||
CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void Mapper005::SetBank_CPU( WORD addr, BYTE data )
|
||
{
|
||
if( data & 0x80 ) {
|
||
// PROM Bank
|
||
switch( addr & 7 ) {
|
||
case 4:
|
||
if( prg_size == 3 ) {
|
||
SetPROM_8K_Bank( 4, data&0x7F );
|
||
}
|
||
break;
|
||
case 5:
|
||
if( prg_size == 1 || prg_size == 2 ) {
|
||
SetPROM_16K_Bank( 4, (data&0x7F)>>1 );
|
||
} else if( prg_size == 3 ) {
|
||
SetPROM_8K_Bank( 5, (data&0x7F) );
|
||
}
|
||
break;
|
||
case 6:
|
||
if( prg_size == 2 || prg_size == 3 ) {
|
||
SetPROM_8K_Bank( 6, (data&0x7F) );
|
||
}
|
||
break;
|
||
case 7:
|
||
if( prg_size == 0 ) {
|
||
SetPROM_32K_Bank( (data&0x7F)>>2 );
|
||
} else if( prg_size == 1 ) {
|
||
SetPROM_16K_Bank( 6, (data&0x7F)>>1 );
|
||
} else if( prg_size == 2 || prg_size == 3 ) {
|
||
SetPROM_8K_Bank( 7, (data&0x7F) );
|
||
}
|
||
break;
|
||
}
|
||
} else {
|
||
// WRAM Bank
|
||
switch( addr & 7 ) {
|
||
case 4:
|
||
if( prg_size == 3 ) {
|
||
SetBank_SRAM( 4, data&0x07 );
|
||
}
|
||
break;
|
||
case 5:
|
||
if( prg_size == 1 || prg_size == 2 ) {
|
||
SetBank_SRAM( 4, (data&0x06)+0 );
|
||
SetBank_SRAM( 5, (data&0x06)+1 );
|
||
} else if( prg_size == 3 ) {
|
||
SetBank_SRAM( 5, data&0x07 );
|
||
}
|
||
break;
|
||
case 6:
|
||
if( prg_size == 2 || prg_size == 3 ) {
|
||
SetBank_SRAM( 6, data&0x07 );
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
void Mapper005::SetBank_SRAM( BYTE page, BYTE data )
|
||
{
|
||
if( sram_size == 0 ) data = (data > 3) ? 8 : 0;
|
||
if( sram_size == 1 ) data = (data > 3) ? 1 : 0;
|
||
if( sram_size == 2 ) data = (data > 3) ? 8 : data;
|
||
if( sram_size == 3 ) data = (data > 3) ? 4 : data;
|
||
|
||
if( data != 8 ) {
|
||
SetPROM_Bank( page, &WRAM[0x2000*data], BANKTYPE_RAM );
|
||
CPU_MEM_PAGE[page] = data;
|
||
} else {
|
||
CPU_MEM_TYPE[page] = BANKTYPE_ROM;
|
||
}
|
||
}
|
||
|
||
void Mapper005::SetBank_PPU()
|
||
{
|
||
INT i;
|
||
|
||
if( chr_mode == 0 ) {
|
||
// PPU SP Bank
|
||
switch( chr_size ) {
|
||
case 0:
|
||
SetVROM_8K_Bank( chr_page[0][7] );
|
||
break;
|
||
case 1:
|
||
SetVROM_4K_Bank( 0, chr_page[0][3] );
|
||
SetVROM_4K_Bank( 4, chr_page[0][7] );
|
||
break;
|
||
case 2:
|
||
SetVROM_2K_Bank( 0, chr_page[0][1] );
|
||
SetVROM_2K_Bank( 2, chr_page[0][3] );
|
||
SetVROM_2K_Bank( 4, chr_page[0][5] );
|
||
SetVROM_2K_Bank( 6, chr_page[0][7] );
|
||
break;
|
||
case 3:
|
||
SetVROM_8K_Bank( chr_page[0][0],
|
||
chr_page[0][1],
|
||
chr_page[0][2],
|
||
chr_page[0][3],
|
||
chr_page[0][4],
|
||
chr_page[0][5],
|
||
chr_page[0][6],
|
||
chr_page[0][7] );
|
||
break;
|
||
}
|
||
} else if( chr_mode == 1 ) {
|
||
// PPU BG Bank
|
||
switch( chr_size ) {
|
||
case 0:
|
||
for( i = 0; i < 8; i++ ) {
|
||
BG_MEM_BANK[i] = VROM+0x2000*(chr_page[1][7]%VROM_8K_SIZE)+0x0400*i;
|
||
BG_MEM_PAGE[i] = (chr_page[1][7]%VROM_8K_SIZE)*8+i;
|
||
}
|
||
break;
|
||
case 1:
|
||
for( i = 0; i < 4; i++ ) {
|
||
BG_MEM_BANK[i+0] = VROM+0x1000*(chr_page[1][3]%VROM_4K_SIZE)+0x0400*i;
|
||
BG_MEM_BANK[i+4] = VROM+0x1000*(chr_page[1][7]%VROM_4K_SIZE)+0x0400*i;
|
||
BG_MEM_PAGE[i+0] = (chr_page[1][3]%VROM_4K_SIZE)*4+i;
|
||
BG_MEM_PAGE[i+4] = (chr_page[1][7]%VROM_4K_SIZE)*4+i;
|
||
}
|
||
break;
|
||
case 2:
|
||
for( i = 0; i < 2; i++ ) {
|
||
BG_MEM_BANK[i+0] = VROM+0x0800*(chr_page[1][1]%VROM_2K_SIZE)+0x0400*i;
|
||
BG_MEM_BANK[i+2] = VROM+0x0800*(chr_page[1][3]%VROM_2K_SIZE)+0x0400*i;
|
||
BG_MEM_BANK[i+4] = VROM+0x0800*(chr_page[1][5]%VROM_2K_SIZE)+0x0400*i;
|
||
BG_MEM_BANK[i+6] = VROM+0x0800*(chr_page[1][7]%VROM_2K_SIZE)+0x0400*i;
|
||
BG_MEM_PAGE[i+0] = (chr_page[1][1]%VROM_2K_SIZE)*2+i;
|
||
BG_MEM_PAGE[i+2] = (chr_page[1][3]%VROM_2K_SIZE)*2+i;
|
||
BG_MEM_PAGE[i+4] = (chr_page[1][5]%VROM_2K_SIZE)*2+i;
|
||
BG_MEM_PAGE[i+6] = (chr_page[1][7]%VROM_2K_SIZE)*2+i;
|
||
}
|
||
break;
|
||
case 3:
|
||
for( i = 0; i < 8; i++ ) {
|
||
BG_MEM_BANK[i] = VROM+0x0400*(chr_page[1][i]%VROM_1K_SIZE);
|
||
BG_MEM_PAGE[i] = (chr_page[1][i]%VROM_1K_SIZE)+i;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
void Mapper005::HSync( INT scanline )
|
||
{
|
||
if( irq_type & MMC5_IRQ_METAL ) {
|
||
if( irq_scanline == irq_line ) {
|
||
irq_status |= 0x80;
|
||
}
|
||
}
|
||
|
||
// if( nes->ppu->IsDispON() && scanline < 239 ) {
|
||
if( nes->ppu->IsDispON() && scanline < 240 ) {
|
||
irq_scanline++;
|
||
irq_status |= 0x40;
|
||
irq_clear = 0;
|
||
} else if( irq_type & MMC5_IRQ_METAL ) {
|
||
irq_scanline = 0;
|
||
irq_status &= ~0x80;
|
||
irq_status &= ~0x40;
|
||
}
|
||
|
||
if( !(irq_type & MMC5_IRQ_METAL) ) {
|
||
if( irq_scanline == irq_line ) {
|
||
irq_status |= 0x80;
|
||
}
|
||
|
||
if( ++irq_clear > 2 ) {
|
||
irq_scanline = 0;
|
||
irq_status &= ~0x80;
|
||
irq_status &= ~0x40;
|
||
|
||
nes->cpu->ClrIRQ( IRQ_MAPPER );
|
||
}
|
||
}
|
||
|
||
if( (irq_enable & 0x80) && (irq_status & 0x80) && (irq_status & 0x40) ) {
|
||
nes->cpu->SetIRQ( IRQ_MAPPER );
|
||
/// nes->cpu->IRQ_NotPending();
|
||
#if 0
|
||
{
|
||
LPBYTE lpScn = nes->ppu->GetScreenPtr();
|
||
|
||
lpScn = lpScn+(256+16)*scanline;
|
||
|
||
for( INT i = 0; i < 256+16; i++ ) {
|
||
lpScn[i] = 22;
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
|
||
// For Split mode!
|
||
if( scanline == 0 ) {
|
||
split_yofs = split_scroll&0x07;
|
||
split_addr = ((split_scroll&0xF8)<<2);
|
||
} else if( nes->ppu->IsDispON() ) {
|
||
if( split_yofs == 7 ) {
|
||
split_yofs = 0;
|
||
if( (split_addr & 0x03E0) == 0x03A0 ) {
|
||
split_addr &= 0x001F;
|
||
} else {
|
||
if( (split_addr & 0x03E0) == 0x03E0 ) {
|
||
split_addr &= 0x001F;
|
||
} else {
|
||
split_addr += 0x0020;
|
||
}
|
||
}
|
||
} else {
|
||
split_yofs++;
|
||
}
|
||
}
|
||
}
|
||
|
||
void Mapper005::PPU_ExtLatchX( INT x )
|
||
{
|
||
split_x = x;
|
||
}
|
||
|
||
void Mapper005::PPU_ExtLatch( WORD addr, BYTE& chr_l, BYTE& chr_h, BYTE& attr )
|
||
{
|
||
WORD ntbladr, attradr, tileadr, tileofs;
|
||
WORD tile_yofs;
|
||
DWORD tilebank;
|
||
BOOL bSplit;
|
||
|
||
tile_yofs = nes->ppu->GetTILEY();
|
||
|
||
bSplit = FALSE;
|
||
if( split_control & 0x80 ) {
|
||
if( !(split_control&0x40) ) {
|
||
// Left side
|
||
if( (split_control&0x1F) > split_x ) {
|
||
bSplit = TRUE;
|
||
}
|
||
} else {
|
||
// Right side
|
||
if( (split_control&0x1F) <= split_x ) {
|
||
bSplit = TRUE;
|
||
}
|
||
}
|
||
}
|
||
|
||
if( !bSplit ) {
|
||
if( nametable_type[(addr&0x0C00)>>10] == 3 ) {
|
||
// Fill mode
|
||
if( graphic_mode == 1 ) {
|
||
// ExGraphic mode
|
||
ntbladr = 0x2000+(addr&0x0FFF);
|
||
// Get Nametable
|
||
tileadr = fill_chr*0x10+tile_yofs;
|
||
// Get TileBank
|
||
tilebank = 0x1000*((VRAM[0x0800+(ntbladr&0x03FF)]&0x3F)%VROM_4K_SIZE);
|
||
// Attribute
|
||
attr = (fill_pal<<2)&0x0C;
|
||
// Get Pattern
|
||
chr_l = VROM[tilebank+tileadr ];
|
||
chr_h = VROM[tilebank+tileadr+8];
|
||
} else {
|
||
// Normal
|
||
tileofs = (PPUREG[0]&PPU_BGTBL_BIT)?0x1000:0x0000;
|
||
tileadr = tileofs+fill_chr*0x10+tile_yofs;
|
||
attr = (fill_pal<<2)&0x0C;
|
||
// Get Pattern
|
||
if( chr_type ) {
|
||
chr_l = PPU_MEM_BANK[tileadr>>10][ tileadr&0x03FF ];
|
||
chr_h = PPU_MEM_BANK[tileadr>>10][(tileadr&0x03FF)+8];
|
||
} else {
|
||
chr_l = BG_MEM_BANK[tileadr>>10][ tileadr&0x03FF ];
|
||
chr_h = BG_MEM_BANK[tileadr>>10][(tileadr&0x03FF)+8];
|
||
}
|
||
}
|
||
} else if( graphic_mode == 1 ) {
|
||
// ExGraphic mode
|
||
ntbladr = 0x2000+(addr&0x0FFF);
|
||
// Get Nametable
|
||
tileadr = (WORD)PPU_MEM_BANK[ntbladr>>10][ntbladr&0x03FF]*0x10+tile_yofs;
|
||
// Get TileBank
|
||
tilebank = 0x1000*((VRAM[0x0800+(ntbladr&0x03FF)]&0x3F)%VROM_4K_SIZE);
|
||
// Get Attribute
|
||
attr = (VRAM[0x0800+(ntbladr&0x03FF)]&0xC0)>>4;
|
||
// Get Pattern
|
||
chr_l = VROM[tilebank+tileadr ];
|
||
chr_h = VROM[tilebank+tileadr+8];
|
||
} else {
|
||
// Normal or ExVRAM
|
||
tileofs = (PPUREG[0]&PPU_BGTBL_BIT)?0x1000:0x0000;
|
||
ntbladr = 0x2000+(addr&0x0FFF);
|
||
attradr = 0x23C0+(addr&0x0C00)+((addr&0x0380)>>4)+((addr&0x001C)>>2);
|
||
// Get Nametable
|
||
tileadr = tileofs+PPU_MEM_BANK[ntbladr>>10][ntbladr&0x03FF]*0x10+tile_yofs;
|
||
// Get Attribute
|
||
attr = PPU_MEM_BANK[attradr>>10][attradr&0x03FF];
|
||
if( ntbladr & 0x0002 ) attr >>= 2;
|
||
if( ntbladr & 0x0040 ) attr >>= 4;
|
||
attr = (attr&0x03)<<2;
|
||
// Get Pattern
|
||
if( chr_type ) {
|
||
chr_l = PPU_MEM_BANK[tileadr>>10][ tileadr&0x03FF ];
|
||
chr_h = PPU_MEM_BANK[tileadr>>10][(tileadr&0x03FF)+8];
|
||
} else {
|
||
chr_l = BG_MEM_BANK[tileadr>>10][ tileadr&0x03FF ];
|
||
chr_h = BG_MEM_BANK[tileadr>>10][(tileadr&0x03FF)+8];
|
||
}
|
||
}
|
||
} else {
|
||
ntbladr = ((split_addr&0x03E0)|(split_x&0x1F))&0x03FF;
|
||
// Get Split TileBank
|
||
tilebank = 0x1000*((INT)split_page%VROM_4K_SIZE);
|
||
tileadr = (WORD)VRAM[0x0800+ntbladr]*0x10+split_yofs;
|
||
// Get Attribute
|
||
attradr = 0x03C0+((ntbladr&0x0380)>>4)+((ntbladr&0x001C)>>2);
|
||
attr = VRAM[0x0800+attradr];
|
||
if( ntbladr & 0x0002 ) attr >>= 2;
|
||
if( ntbladr & 0x0040 ) attr >>= 4;
|
||
attr = (attr&0x03)<<2;
|
||
// Get Pattern
|
||
chr_l = VROM[tilebank+tileadr ];
|
||
chr_h = VROM[tilebank+tileadr+8];
|
||
}
|
||
}
|
||
|
||
void Mapper005::SaveState( LPBYTE p )
|
||
{
|
||
p[ 0] = prg_size;
|
||
p[ 1] = chr_size;
|
||
p[ 2] = sram_we_a;
|
||
p[ 3] = sram_we_b;
|
||
p[ 4] = graphic_mode;
|
||
p[ 5] = nametable_mode;
|
||
p[ 6] = nametable_type[0];
|
||
p[ 7] = nametable_type[1];
|
||
p[ 8] = nametable_type[2];
|
||
p[ 9] = nametable_type[3];
|
||
p[10] = sram_page;
|
||
p[11] = fill_chr;
|
||
p[12] = fill_pal;
|
||
p[13] = split_control;
|
||
p[14] = split_scroll;
|
||
p[15] = split_page;
|
||
p[16] = chr_mode;
|
||
p[17] = irq_status;
|
||
p[18] = irq_enable;
|
||
p[19] = irq_line;
|
||
p[20] = irq_scanline;
|
||
p[21] = irq_clear;
|
||
p[22] = mult_a;
|
||
p[23] = mult_b;
|
||
|
||
INT i, j;
|
||
for( j = 0; j < 2; j++ ) {
|
||
for( i = 0; i < 8; i++ ) {
|
||
p[24+j*8+i] = chr_page[j][i];
|
||
}
|
||
}
|
||
for( i = 0; i < 8; i++ ) {
|
||
p[40+i] = BG_MEM_PAGE[i];
|
||
}
|
||
}
|
||
|
||
void Mapper005::LoadState( LPBYTE p )
|
||
{
|
||
prg_size = p[ 0];
|
||
chr_size = p[ 1];
|
||
sram_we_a = p[ 2];
|
||
sram_we_b = p[ 3];
|
||
graphic_mode = p[ 4];
|
||
nametable_mode = p[ 5];
|
||
nametable_type[0] = p[ 6];
|
||
nametable_type[1] = p[ 7];
|
||
nametable_type[2] = p[ 8];
|
||
nametable_type[3] = p[ 9];
|
||
sram_page = p[10];
|
||
fill_chr = p[11];
|
||
fill_pal = p[12];
|
||
split_control = p[13];
|
||
split_scroll = p[14];
|
||
split_page = p[15];
|
||
chr_mode = p[16];
|
||
irq_status = p[17];
|
||
irq_enable = p[18];
|
||
irq_line = p[19];
|
||
irq_scanline = p[20];
|
||
irq_clear = p[21];
|
||
mult_a = p[22];
|
||
mult_b = p[23];
|
||
|
||
INT i, j;
|
||
|
||
for( j = 0; j < 2; j++ ) {
|
||
for( i = 0; i < 8; i++ ) {
|
||
chr_page[j][i] = p[24+j*8+i];
|
||
}
|
||
}
|
||
// BGƒoƒ“ƒN‚Ì<E2809A>Ä<EFBFBD>Ý’è<E28099>ˆ—<CB86>
|
||
for( i = 0; i < 8; i++ ) {
|
||
BG_MEM_PAGE[i] = p[40+i]%VROM_1K_SIZE;
|
||
}
|
||
for( i = 0; i < 8; i++ ) {
|
||
BG_MEM_BANK[i] = VROM+0x0400*BG_MEM_PAGE[i];
|
||
}
|
||
}
|