2025-06-27 00:32:57 +08:00
# ifndef _MAPPER001_H_
# define _MAPPER001_H_
# include "nes_mapper.h"
Mapper1Res * MAP1 ;
void Map1_set_ROM_banks ( void ) ;
void Mapper001_Reset ( )
{
uint32 size_in_K ;
MAP1 - > Map1_Cnt = 0 ;
MAP1 - > Map1_Latch = 0x00 ;
MAP1 - > Map1_Regs [ 0 ] = 0x0c ;
MAP1 - > Map1_Regs [ 1 ] = 0x00 ;
MAP1 - > Map1_Regs [ 2 ] = 0x00 ;
MAP1 - > Map1_Regs [ 3 ] = 0x00 ;
2025-07-05 19:47:28 +08:00
size_in_K = ( RomHeader - > num_16k_rom_banks < < 1 ) * 8 ; //16kB ROM<4F> <4D> <EFBFBD> <EFBFBD> Ŀ
2025-06-27 00:32:57 +08:00
if ( size_in_K = = 1024 )
{
MAP1 - > Map1_Size = Map1_1024K ;
}
else if ( size_in_K = = 512 )
{
MAP1 - > Map1_Size = Map1_512K ;
}
else
{
MAP1 - > Map1_Size = Map1_SMALL ;
}
2025-07-05 19:47:28 +08:00
MAP1 - > Map1_256K_base = 0 ; // use first 256Kʹ <4B> õ<EFBFBD> һ <EFBFBD> <D2BB> 256 k
2025-06-27 00:32:57 +08:00
MAP1 - > Map1_swap = 0 ;
if ( MAP1 - > Map1_Size = = Map1_SMALL )
{
2025-07-05 19:47:28 +08:00
// set two high pages to last two banks<6B> <73> <EFBFBD> <EFBFBD> <EFBFBD> ߵ <EFBFBD> ҳ<EFBFBD> <D2B3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> <CEAA> <EFBFBD> <EFBFBD>
2025-06-27 00:32:57 +08:00
MAP1 - > Map1_HI1 = ( RomHeader - > num_16k_rom_banks < < 1 ) - 2 ;
MAP1 - > Map1_HI2 = ( RomHeader - > num_16k_rom_banks < < 1 ) - 1 ;
}
else
{
// set two high pages to last two banks of current 256K region
MAP1 - > Map1_HI1 = ( 256 / 8 ) - 2 ;
MAP1 - > Map1_HI2 = ( 256 / 8 ) - 1 ;
}
// set CPU bank pointers
MAP1 - > Map1_bank1 = 0 ;
MAP1 - > Map1_bank2 = 1 ;
MAP1 - > Map1_bank3 = MAP1 - > Map1_HI1 ;
MAP1 - > Map1_bank4 = MAP1 - > Map1_HI2 ;
/* Set ROM Banks */
Map1_set_ROM_banks ( ) ; //************************************************************
}
void Map1_set_ROM_banks ( void )
{
// ROMBANK0 = ROMPAGE( ( (MAP1->Map1_256K_base << 5) + (MAP1->Map1_bank1 & ((256/8)-1)) ) % ( Neshd->byRomSize << 1 ) );
// ROMBANK1 = ROMPAGE( ( (MAP1->Map1_256K_base << 5) + (MAP1->Map1_bank2 & ((256/8)-1)) ) % ( Neshd->byRomSize << 1 ) );
// ROMBANK2 = ROMPAGE( ( (MAP1->Map1_256K_base << 5) + (MAP1->Map1_bank3 & ((256/8)-1)) ) % ( Neshd->byRomSize << 1 ) );
// ROMBANK3 = ROMPAGE( ( (MAP1->Map1_256K_base << 5) + (MAP1->Map1_bank4 & ((256/8)-1)) ) % ( Neshd->byRomSize << 1 ) );
//******************************************************************************************************
// set_CPU_banks((MMC1_256K_base << 5) + (MMC1_bank1 & ((256/8)-1)),
// (MMC1_256K_base << 5) + (MMC1_bank2 & ((256/8)-1)),
// (MMC1_256K_base << 5) + (MMC1_bank3 & ((256/8)-1)),
// (MMC1_256K_base << 5) + (MMC1_bank4 & ((256/8)-1)));
set_cpu_bank0 ( ( ( MAP1 - > Map1_256K_base < < 5 ) + ( MAP1 - > Map1_bank1 & ( ( 256 / 8 ) - 1 ) ) ) ) ;
set_cpu_bank1 ( ( ( MAP1 - > Map1_256K_base < < 5 ) + ( MAP1 - > Map1_bank2 & ( ( 256 / 8 ) - 1 ) ) ) ) ;
set_cpu_bank2 ( ( ( MAP1 - > Map1_256K_base < < 5 ) + ( MAP1 - > Map1_bank3 & ( ( 256 / 8 ) - 1 ) ) ) ) ;
set_cpu_bank3 ( ( ( MAP1 - > Map1_256K_base < < 5 ) + ( MAP1 - > Map1_bank4 & ( ( 256 / 8 ) - 1 ) ) ) ) ;
}
void Mapper001_Write ( uint8 byData , uint16 wAddr ) //VROM_1K_SIZE
{
uint32 dwRegNum ;
// if write is to a different reg, reset
if ( ( wAddr & 0x6000 ) ! = ( MAP1 - > Map1_Last_Write_Addr & 0x6000 ) )
{
MAP1 - > Map1_Cnt = 0 ;
MAP1 - > Map1_Latch = 0x00 ;
}
MAP1 - > Map1_Last_Write_Addr = wAddr ;
// if bit 7 set, reset and return
if ( byData & 0x80 )
{
MAP1 - > Map1_Cnt = 0 ;
MAP1 - > Map1_Latch = 0x00 ;
return ;
}
if ( byData & 0x01 ) MAP1 - > Map1_Latch | = ( 1 < < MAP1 - > Map1_Cnt ) ;
MAP1 - > Map1_Cnt + + ;
if ( MAP1 - > Map1_Cnt < 5 ) return ;
dwRegNum = ( wAddr & 0x7FFF ) > > 13 ;
MAP1 - > Map1_Regs [ dwRegNum ] = MAP1 - > Map1_Latch ;
MAP1 - > Map1_Cnt = 0 ;
MAP1 - > Map1_Latch = 0x00 ;
switch ( dwRegNum )
{
case 0 :
{
// set mirroring
if ( MAP1 - > Map1_Regs [ 0 ] & 0x02 )
{
if ( MAP1 - > Map1_Regs [ 0 ] & 0x01 )
{
2025-07-05 19:47:28 +08:00
PPU_set_mirroring ( 0 , 0 , 1 , 1 ) ; //ˮƽ <CBAE> <C6BD> <EFBFBD> <EFBFBD> InfoNES_Mirroring( 0 ); //0011
2025-06-27 00:32:57 +08:00
}
else
{
2025-07-05 19:47:28 +08:00
PPU_set_mirroring ( 0 , 1 , 0 , 1 ) ; //<2F> <> ֱ<EFBFBD> <D6B1> <EFBFBD> <EFBFBD> InfoNES_Mirroring( 1 ); //0101
2025-06-27 00:32:57 +08:00
}
}
else
{
// one-screen mirroring
if ( MAP1 - > Map1_Regs [ 0 ] & 0x01 )
{
PPU_set_mirroring ( 1 , 1 , 1 , 1 ) ; //InfoNES_Mirroring( 2 ); //1111
}
else
{
PPU_set_mirroring ( 0 , 0 , 0 , 0 ) ; //InfoNES_Mirroring( 3 ); //0000
}
}
}
break ;
case 1 :
{
uint8 byBankNum = MAP1 - > Map1_Regs [ 1 ] ;
if ( MAP1 - > Map1_Size = = Map1_1024K )
{
if ( MAP1 - > Map1_Regs [ 0 ] & 0x10 )
{
if ( MAP1 - > Map1_swap )
{
MAP1 - > Map1_256K_base = ( MAP1 - > Map1_Regs [ 1 ] & 0x10 ) > > 4 ;
if ( MAP1 - > Map1_Regs [ 0 ] & 0x08 )
{
MAP1 - > Map1_256K_base | = ( ( MAP1 - > Map1_Regs [ 2 ] & 0x10 ) > > 3 ) ;
}
Map1_set_ROM_banks ( ) ; //**********************************
MAP1 - > Map1_swap = 0 ;
}
else
{
MAP1 - > Map1_swap = 1 ;
}
}
else
{
// use 1st or 4th 256K banks
MAP1 - > Map1_256K_base = ( MAP1 - > Map1_Regs [ 1 ] & 0x10 ) ? 3 : 0 ;
Map1_set_ROM_banks ( ) ;
}
}
else if ( ( MAP1 - > Map1_Size = = Map1_512K ) & & ( ! RomHeader - > num_8k_vrom_banks ) )
{
MAP1 - > Map1_256K_base = ( MAP1 - > Map1_Regs [ 1 ] & 0x10 ) > > 4 ;
Map1_set_ROM_banks ( ) ;
}
else if ( RomHeader - > num_8k_vrom_banks )
{
// set VROM bank at $0000
if ( MAP1 - > Map1_Regs [ 0 ] & 0x10 )
{
// swap 4K
byBankNum < < = 2 ;
// PPUBANK[ 0 ] = VROMPAGE( (byBankNum+0) % (Neshd->byVRomSize << 3) );
// PPUBANK[ 1 ] = VROMPAGE( (byBankNum+1) % (Neshd->byVRomSize << 3) );
// PPUBANK[ 2 ] = VROMPAGE( (byBankNum+2) % (Neshd->byVRomSize << 3) );
// PPUBANK[ 3 ] = VROMPAGE( (byBankNum+3) % (Neshd->byVRomSize << 3) );
// InfoNES_SetupChr();
//*********************************************************************************
set_PPU_bank0 ( byBankNum + 0 ) ;
set_PPU_bank1 ( byBankNum + 1 ) ;
set_PPU_bank2 ( byBankNum + 2 ) ;
set_PPU_bank3 ( byBankNum + 3 ) ;
}
else
{
// swap 8K
byBankNum < < = 2 ;
// PPUBANK[ 0 ] = VROMPAGE( (byBankNum+0) % (Neshd->byVRomSize << 3) );
// PPUBANK[ 1 ] = VROMPAGE( (byBankNum+1) % (Neshd->byVRomSize << 3) );
// PPUBANK[ 2 ] = VROMPAGE( (byBankNum+2) % (Neshd->byVRomSize << 3) );
// PPUBANK[ 3 ] = VROMPAGE( (byBankNum+3) % (Neshd->byVRomSize << 3) );
// PPUBANK[ 4 ] = VROMPAGE( (byBankNum+4) % (Neshd->byVRomSize << 3) );
// PPUBANK[ 5 ] = VROMPAGE( (byBankNum+5) % (Neshd->byVRomSize << 3) );
// PPUBANK[ 6 ] = VROMPAGE( (byBankNum+6) % (Neshd->byVRomSize << 3) );
// PPUBANK[ 7 ] = VROMPAGE( (byBankNum+7) % (Neshd->byVRomSize << 3) );
// InfoNES_SetupChr();
//******************************************************************************************
// swap 8K
set_PPU_banks ( byBankNum + 0 , byBankNum + 1 , byBankNum + 2 , byBankNum + 3 ,
byBankNum + 4 , byBankNum + 5 , byBankNum + 6 , byBankNum + 7 ) ;
}
}
}
break ;
case 2 :
{
uint8 byBankNum = MAP1 - > Map1_Regs [ 2 ] ;
if ( ( MAP1 - > Map1_Size = = Map1_1024K ) & & ( MAP1 - > Map1_Regs [ 0 ] & 0x08 ) )
{
if ( MAP1 - > Map1_swap )
{
MAP1 - > Map1_256K_base = ( MAP1 - > Map1_Regs [ 1 ] & 0x10 ) > > 4 ;
MAP1 - > Map1_256K_base | = ( ( MAP1 - > Map1_Regs [ 2 ] & 0x10 ) > > 3 ) ;
Map1_set_ROM_banks ( ) ;
MAP1 - > Map1_swap = 0 ;
}
else
{
MAP1 - > Map1_swap = 1 ;
}
}
if ( ! RomHeader - > num_8k_vrom_banks )
{
if ( MAP1 - > Map1_Regs [ 0 ] & 0x10 )
{
byBankNum < < = 2 ;
// PPUBANK[ 4 ] = CRAMPAGE( byBankNum+0 );
// PPUBANK[ 5 ] = CRAMPAGE( byBankNum+1 );
// PPUBANK[ 6 ] = CRAMPAGE( byBankNum+2 );
// PPUBANK[ 7 ] = CRAMPAGE( byBankNum+3 );
// InfoNES_SetupChr();
//************************************************************
set_VRAM_bank ( 4 , byBankNum + 0 ) ;
set_VRAM_bank ( 5 , byBankNum + 1 ) ;
set_VRAM_bank ( 6 , byBankNum + 2 ) ;
set_VRAM_bank ( 7 , byBankNum + 3 ) ;
break ;
}
}
// set 4K VROM bank at $1000
if ( MAP1 - > Map1_Regs [ 0 ] & 0x10 )
{
// swap 4K
byBankNum < < = 2 ;
// PPUBANK[ 4 ] = VROMPAGE( (byBankNum+0) % (Neshd->byVRomSize << 3) );
// PPUBANK[ 5 ] = VROMPAGE( (byBankNum+1) % (Neshd->byVRomSize << 3) );
// PPUBANK[ 6 ] = VROMPAGE( (byBankNum+2) % (Neshd->byVRomSize << 3) );
// PPUBANK[ 7 ] = VROMPAGE( (byBankNum+3) % (Neshd->byVRomSize << 3) );
// InfoNES_SetupChr();
//**************************************************************************************
// swap 4K
set_PPU_bank4 ( byBankNum + 0 ) ;
set_PPU_bank5 ( byBankNum + 1 ) ;
set_PPU_bank6 ( byBankNum + 2 ) ;
set_PPU_bank7 ( byBankNum + 3 ) ;
}
}
break ;
case 3 :
{
uint8 byBankNum = MAP1 - > Map1_Regs [ 3 ] ;
// set ROM bank
if ( MAP1 - > Map1_Regs [ 0 ] & 0x08 )
{
// 16K of ROM
byBankNum < < = 1 ;
if ( MAP1 - > Map1_Regs [ 0 ] & 0x04 )
{
// 16K of ROM at $8000
MAP1 - > Map1_bank1 = byBankNum ;
MAP1 - > Map1_bank2 = byBankNum + 1 ;
MAP1 - > Map1_bank3 = MAP1 - > Map1_HI1 ;
MAP1 - > Map1_bank4 = MAP1 - > Map1_HI2 ;
}
else
{
// 16K of ROM at $C000
if ( MAP1 - > Map1_Size = = Map1_SMALL )
{
MAP1 - > Map1_bank1 = 0 ;
MAP1 - > Map1_bank2 = 1 ;
MAP1 - > Map1_bank3 = byBankNum ;
MAP1 - > Map1_bank4 = byBankNum + 1 ;
}
}
}
else
{
// 32K of ROM at $8000
byBankNum < < = 1 ;
MAP1 - > Map1_bank1 = byBankNum ;
MAP1 - > Map1_bank2 = byBankNum + 1 ;
if ( MAP1 - > Map1_Size = = Map1_SMALL )
{
MAP1 - > Map1_bank3 = byBankNum + 2 ;
MAP1 - > Map1_bank4 = byBankNum + 3 ;
}
}
Map1_set_ROM_banks ( ) ; //*********************************************
}
break ;
}
}
void Mapper001_Init ( )
{
NES_Mapper - > Reset = Mapper001_Reset ;
NES_Mapper - > Write = Mapper001_Write ;
}
# endif