2013-11-04 00:36:15 +00:00
using BizHawk.Common ;
2014-07-03 17:23:03 +00:00
using BizHawk.Common.NumberExtensions ;
2013-11-04 00:36:15 +00:00
2013-11-14 13:15:41 +00:00
namespace BizHawk.Emulation.Cores.Nintendo.NES
2011-04-18 23:55:47 +00:00
{
2011-06-13 08:38:10 +00:00
//AKA half of mapper 034 (the other half is BxROM which is entirely different..)
2013-08-25 01:08:17 +00:00
public sealed class AVE_NINA_001 : NES . NESBoardBase
2011-06-13 08:38:10 +00:00
{
//configuration
int prg_bank_mask_32k , chr_bank_mask_4k ;
//state
IntBuffer chr_banks_4k = new IntBuffer ( 2 ) ;
int prg_bank_32k ;
public override void Dispose ( )
{
base . Dispose ( ) ;
chr_banks_4k . Dispose ( ) ;
}
public override void SyncState ( Serializer ser )
{
base . SyncState ( ser ) ;
ser . Sync ( "chr_banks_4k" , ref chr_banks_4k ) ;
ser . Sync ( "prg_bank_32k" , ref prg_bank_32k ) ;
}
public override bool Configure ( NES . EDetectionOrigin origin )
{
2011-04-18 23:55:47 +00:00
switch ( Cart . board_type )
{
2014-01-23 23:32:53 +00:00
case "AVE-NINA-02" : // untested
2011-06-13 08:38:10 +00:00
case "AVE-NINA-01" : //Impossible Mission 2 (U)
AssertPrg ( 64 ) ; AssertChr ( 64 ) ; AssertWram ( 8 ) ; AssertVram ( 0 ) ;
2011-04-18 23:55:47 +00:00
break ;
2011-06-13 08:38:10 +00:00
2011-04-18 23:55:47 +00:00
default :
return false ;
}
2011-06-13 08:38:10 +00:00
prg_bank_mask_32k = Cart . prg_size / 32 - 1 ;
chr_bank_mask_4k = Cart . chr_size / 4 - 1 ;
SetMirrorType ( Cart . pad_h , Cart . pad_v ) ;
return true ;
}
public override byte ReadPPU ( int addr )
{
if ( addr < 0x2000 )
{
int bank_4k = addr > > 12 ;
int ofs = addr & ( ( 1 < < 12 ) - 1 ) ;
bank_4k = chr_banks_4k [ bank_4k ] ;
addr = ( bank_4k < < 12 ) | ofs ;
return VROM [ addr ] ;
}
else return base . ReadPPU ( addr ) ;
}
public override byte ReadPRG ( int addr )
{
addr | = ( prg_bank_32k < < 15 ) ;
2014-01-12 16:19:14 +00:00
return ROM [ addr ] ;
2011-06-13 08:38:10 +00:00
}
public override void WriteWRAM ( int addr , byte value )
{
switch ( addr )
{
case 0x1FFD : //$7FFD: Select 32k PRG @ $8000
prg_bank_32k = value ;
prg_bank_32k & = prg_bank_mask_32k ;
break ;
case 0x1FFE :
chr_banks_4k [ 0 ] = value ;
chr_banks_4k [ 0 ] & = chr_bank_mask_4k ;
break ;
case 0x1FFF :
chr_banks_4k [ 1 ] = value ;
chr_banks_4k [ 1 ] & = chr_bank_mask_4k ;
break ;
default :
//apparently these regs are patched in over the WRAM..
2014-01-12 16:19:14 +00:00
base . WriteWRAM ( addr , value ) ;
2011-06-13 08:38:10 +00:00
break ;
}
}
}
2014-01-12 16:19:14 +00:00
// according to the latest on nesdev:
// mapper 079: [.... PCCC] @ 4100
// mapper 113: [MCPP PCCC] @ 4100 (no games for this are in bootgod)
2011-06-13 08:38:10 +00:00
class AVE_NINA_006 : NES . NESBoardBase
{
//configuration
int prg_bank_mask_32k , chr_bank_mask_8k ;
2014-01-12 16:19:14 +00:00
bool mirror_control_enabled ;
2011-06-13 08:38:10 +00:00
//state
int chr_bank_8k , prg_bank_32k ;
2011-04-18 23:55:47 +00:00
public override void SyncState ( Serializer ser )
2011-06-13 08:38:10 +00:00
{
2011-04-18 23:55:47 +00:00
base . SyncState ( ser ) ;
2011-06-13 08:38:10 +00:00
ser . Sync ( "chr_bank_8k" , ref chr_bank_8k ) ;
ser . Sync ( "prg_bank_32k" , ref prg_bank_32k ) ;
}
public override bool Configure ( NES . EDetectionOrigin origin )
{
//configure
switch ( Cart . board_type )
{
2012-03-22 06:20:10 +00:00
case "MAPPER079" :
2014-01-12 16:19:14 +00:00
AssertPrg ( 32 , 64 ) ; AssertChr ( 32 , 64 ) ;
2012-03-22 06:20:10 +00:00
break ;
2014-01-23 23:08:56 +00:00
case "TXC-74*138/175" : // untested
break ;
2012-03-22 06:20:10 +00:00
case "MAPPER113" :
2014-01-12 16:19:14 +00:00
mirror_control_enabled = true ;
2012-03-22 06:20:10 +00:00
break ;
2011-06-13 08:38:10 +00:00
case "AVE-NINA-06" : //Blackjack (U)
case "AVE-NINA-03" : //F-15 City War (U)
case "AVE-MB-91" : //Deathbots (U)
2014-01-15 23:27:02 +00:00
if ( Cart . chips . Count = = 0 ) // some boards had no mapper chips on them
return false ;
2011-06-13 08:38:10 +00:00
AssertPrg ( 32 , 64 ) ; AssertChr ( 32 , 64 ) ; AssertWram ( 0 ) ; AssertVram ( 0 ) ;
break ;
default :
return false ;
}
prg_bank_mask_32k = Cart . prg_size / 32 - 1 ;
chr_bank_mask_8k = Cart . chr_size / 8 - 1 ;
SetMirrorType ( Cart . pad_h , Cart . pad_v ) ;
prg_bank_32k = 0 ;
return true ;
}
//FCEUX responds to this for PRG writes as well.. ?
public override void WriteEXP ( int addr , byte value )
{
addr & = 0x4100 ;
switch ( addr )
{
case 0x0100 : //$4100: [.CPP PCCC]
chr_bank_8k = ( value & 7 ) | ( ( value > > 3 ) & 0x8 ) ;
2011-09-25 00:21:19 +00:00
chr_bank_8k & = chr_bank_mask_8k ;
prg_bank_32k = ( ( value > > 3 ) & 7 ) ;
2011-06-13 08:38:10 +00:00
prg_bank_32k & = prg_bank_mask_32k ;
2014-01-12 16:19:14 +00:00
if ( mirror_control_enabled )
SetMirrorType ( value . Bit ( 7 ) ? EMirrorType . Vertical : EMirrorType . Horizontal ) ;
2011-06-13 08:38:10 +00:00
//NES.LogLine("chr={0:X2}, prg={1:X2}, with val={2:X2}", chr_reg, prg_reg, value);
break ;
}
}
public override byte ReadPRG ( int addr )
{
addr | = ( prg_bank_32k < < 15 ) ;
2015-08-16 12:31:18 +00:00
if ( ROM . Length < 0x8000 ) // GoodNES labels a version of Othello (HES) with only 16kb prg as the good dump. We will consider GoodNES wrong and label this as a bad dump, but this hack allows it to run just fine
{
addr & = 0x3FFF ;
}
2011-06-13 08:38:10 +00:00
return ROM [ addr ] ;
}
public override byte ReadPPU ( int addr )
{
if ( addr < 0x2000 )
{
addr | = ( chr_bank_8k < < 13 ) ;
return VROM [ addr ] ;
}
2014-01-12 16:19:14 +00:00
else
return base . ReadPPU ( addr ) ;
2011-06-13 08:38:10 +00:00
}
}
2011-04-18 23:55:47 +00:00
}