[NES] work on some mappers, make a mapper compatibility list
This commit is contained in:
parent
38a11e91fb
commit
db2ba34c01
|
@ -64,12 +64,12 @@
|
|||
<Compile Include="Consoles\Nintendo\NES\Boards\AxROM.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\BxROM.cs" />
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\Camerica.cs" />
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\CNROM.cs" />
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\CPROM.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\CxROM.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\ExROM.cs" />
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\GxROM.cs">
|
||||
<SubType>Code</SubType>
|
||||
|
@ -80,6 +80,7 @@
|
|||
<Compile Include="Consoles\Nintendo\NES\Boards\Irem_G101.cs" />
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\Irem_H3001.cs" />
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\Jaleco-JF_11_14.cs" />
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\Mapper069.cs" />
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\Mapper107.cs" />
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\Mapper242.cs" />
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\MMC3_family\DRROM.cs" />
|
||||
|
@ -230,6 +231,7 @@
|
|||
<Compile Include="Sound\Utilities\Waves.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Consoles\Nintendo\Docs\compatibility.txt" />
|
||||
<Content Include="Consoles\Nintendo\Docs\notes_for_disch.txt" />
|
||||
<Content Include="Consoles\Nintendo\Docs\test_status.txt" />
|
||||
<Content Include="Consoles\PC Engine\Compat.txt" />
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
mappers:
|
||||
key:
|
||||
|
||||
Complete - what it sounds like
|
||||
Good - thought to be complete
|
||||
Decent - mostly compatible, but many significant edge cases not tested
|
||||
Minimal - Important games are playable, but emulation is known not to be complete
|
||||
~NEEDED~ - Needed for neshawk 1.0
|
||||
Needed - Someone should do this
|
||||
Nothing - Not implemented
|
||||
Junk - Who cares about this. Not enough games, or unlicensed junk or no interesting games
|
||||
|
||||
Mapper compatibility does not warrant game compatibility, which may be contingent on other aspects of emulation.
|
||||
It is just a rough guide for future work.
|
||||
Open bus and bus conflict emulation is not considered complete or thorough in any event.
|
||||
|
||||
000 NROM Complete
|
||||
001 SxROM=MMC1 Decent
|
||||
002 UxROM Good
|
||||
003 CNROM Good
|
||||
004 MMC3 Decent
|
||||
005 ExRom=MMC5 Minimal
|
||||
007 AxROM Good
|
||||
009 PxROM=MMC2 ~NEEDED~
|
||||
010 MMC4 Needed (easy once 009 is done)
|
||||
011 Misc Complete
|
||||
013 CPROM Complete
|
||||
015 Multicart Junk
|
||||
016 Bandai Nothing (+159)
|
||||
018 Jaleco* Nothing
|
||||
019 Namcot106 Needed (+210)
|
||||
021 VRC4 Needed
|
||||
022 VRC2 Nothing
|
||||
023 VRC*? Nothing
|
||||
024 VRC6 Needed
|
||||
025 VRC4? Nothing
|
||||
026 VRC6? Nothing
|
||||
032 Irem_G101 Complete
|
||||
033 Taito Complete
|
||||
034 Misc Complete
|
||||
044 Multicart Junk
|
||||
045 Multicart Junk
|
||||
046 Multicart Junk
|
||||
047 MMC3Multi Needed (1st party)
|
||||
048 MMC3Variant Needed (similar to mmc3, should inherit)
|
||||
049 Multicart Junk
|
||||
050 Pirate Junk
|
||||
052 Multicart Junk
|
||||
057 Multicart Junk
|
||||
058 Multicart Junk
|
||||
060 Multicart Junk
|
||||
061 Multicart Junk
|
||||
062 Multicart Junk
|
||||
064 Tengen Needed
|
||||
065 Misc (J) Nothing
|
||||
066 GxROM Complete
|
||||
067 Misc (J) Nothing
|
||||
068 Sunsoft4 Complete
|
||||
069 FME7 Minimal
|
||||
070 Misc Nothing
|
||||
071 Camerica Complete
|
||||
072 Misc (J) Nothing
|
||||
073 VRC3 Nothing
|
||||
074 Pirate (CN) Junk
|
||||
075 VRC1 Nothing
|
||||
076 Misc (J) Nothing
|
||||
077 Misc (J) Nothing
|
||||
078 Misc Nothing
|
||||
079 NINA-06 Complete
|
||||
080 Misc (J) Nothing
|
||||
082 Misc (J) Nothing
|
||||
085 VRC7 Needed (lagrange point)
|
||||
086 Misc (J) Nothing
|
||||
087 Misc (J) Nothing (easy)
|
||||
088 Misc (J) Nothing
|
||||
089 Misc (J) Nothing (easy)
|
||||
090 Garbage Junk (+209)
|
||||
091 Pirate Junk
|
||||
092 Misc (J) Nothing (similar to 072)
|
||||
093 Misc (J) Nothing (easy)
|
||||
094 Misc (J) Nothing (easy)
|
||||
095 MMC3Variant Complete
|
||||
096 Misc (J) Nothing
|
||||
097 Misc (J) Nothing (easy)
|
||||
105 NES-EVENT ~NEEDED~
|
||||
107 Misc Nothing (easy)
|
||||
112 Misc (CN) Nothing
|
||||
113 =USELESS= Junk
|
||||
115 MMC3Variant Nothing
|
||||
118 TLSROM Complete
|
||||
119 TQROM Complete
|
||||
140 Misc (J) Complete
|
||||
152 Misc (J) Nothing
|
||||
154 Misc (J) Nothing
|
||||
159 Bandai {{See 016}}
|
||||
164 Pirate Junk
|
||||
165 Pirate Junk
|
||||
180 Misc (J) Nothing
|
||||
182 MMC3Variant Nothing
|
||||
184 Sunsoft-1 Complete
|
||||
185 Misc (J) Nothing
|
||||
189 MMC3Variant Nothing
|
||||
191 Pirate Junk
|
||||
192 Pirate Junk
|
||||
193 Unlicensed Junk
|
||||
194 Pirate Junk
|
||||
200 Multicart Junk
|
||||
201 Multicart Junk
|
||||
203 Multicart Junk
|
||||
205 Multicart Junk
|
||||
207 Misc (J) Nothing
|
||||
209 Garbage {{See 090}}
|
||||
210 Namcot106 {{See 019}}
|
||||
225 Multicart Junk
|
||||
226 Multicart Junk
|
||||
227 Multicart Junk
|
||||
228 Unlicensed Nothing
|
||||
230 Multicart Junk
|
||||
231 Multicart Junk
|
||||
232 Camerica Complete
|
||||
233 Multicart Junk
|
||||
234 Misc Nothing
|
||||
240 Misc (CN) Nothing
|
||||
242 Misc (CN) Complete
|
||||
243 Misc Nothing
|
||||
245 Pirate Junk
|
||||
246 Misc (CN) Nothing
|
|
@ -304,7 +304,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
if (dict.ContainsKey("PAD_H"))
|
||||
cart.pad_h = byte.Parse(dict["PAD_H"]);
|
||||
if (dict.ContainsKey("PAD_V"))
|
||||
cart.pad_h = byte.Parse(dict["PAD_V"]);
|
||||
cart.pad_v = byte.Parse(dict["PAD_V"]);
|
||||
if (dict.ContainsKey("bad"))
|
||||
cart.bad = true;
|
||||
|
||||
|
|
|
@ -4,63 +4,171 @@ using System.Diagnostics;
|
|||
|
||||
namespace BizHawk.Emulation.Consoles.Nintendo
|
||||
{
|
||||
/*
|
||||
|
||||
*/
|
||||
//AKA half of mapper 034 (the other half is BxROM which is entirely different..)
|
||||
class AVE_NINA_001 : NES.NESBoardBase
|
||||
{
|
||||
//configuration
|
||||
int prg_bank_mask_32k, chr_bank_mask_4k;
|
||||
|
||||
class AVI_NINA_001 : NES.NESBoardBase
|
||||
{
|
||||
public override bool Configure(NES.EDetectionOrigin origin)
|
||||
{
|
||||
//configure
|
||||
//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)
|
||||
{
|
||||
switch (Cart.board_type)
|
||||
{
|
||||
case "AVI_NINA_001":
|
||||
case "AVE-NINA-01": //Impossible Mission 2 (U)
|
||||
AssertPrg(64); AssertChr(64); AssertWram(8); AssertVram(0);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
SetMirrorType(Cart.pad_h, Cart.pad_v);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override byte ReadPPU(int addr)
|
||||
{
|
||||
return base.ReadPPU(addr);
|
||||
}
|
||||
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);
|
||||
return ROM[addr];
|
||||
}
|
||||
|
||||
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..
|
||||
base.WriteWRAM(addr,value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//AKA mapper 079
|
||||
//historically, mapper 113 is confused with this, but I can't find any need for mapper 113. bootgod's db has nothing for mapper 113
|
||||
class AVE_NINA_006 : NES.NESBoardBase
|
||||
{
|
||||
//configuration
|
||||
int prg_bank_mask_32k, chr_bank_mask_8k;
|
||||
bool mirror_control_enabled;
|
||||
|
||||
//state
|
||||
int chr_bank_8k, prg_bank_32k;
|
||||
|
||||
public override void SyncState(Serializer ser)
|
||||
{
|
||||
{
|
||||
base.SyncState(ser);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
class AVI_Misc : NES.NESBoardBase
|
||||
{
|
||||
public override bool Configure(NES.EDetectionOrigin origin)
|
||||
{
|
||||
//configure
|
||||
switch (Cart.board_type)
|
||||
{
|
||||
case "AVI_Misc":
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
SetMirrorType(Cart.pad_h, Cart.pad_v);
|
||||
return true;
|
||||
}
|
||||
ser.Sync("chr_bank_8k", ref chr_bank_8k);
|
||||
ser.Sync("prg_bank_32k", ref prg_bank_32k);
|
||||
}
|
||||
|
||||
public override byte ReadPPU(int addr)
|
||||
{
|
||||
return base.ReadPPU(addr);
|
||||
}
|
||||
public override bool Configure(NES.EDetectionOrigin origin)
|
||||
{
|
||||
//configure
|
||||
switch (Cart.board_type)
|
||||
{
|
||||
case "AVE-NINA-06": //Blackjack (U)
|
||||
case "AVE-NINA-03": //F-15 City War (U)
|
||||
case "AVE-MB-91": //Deathbots (U)
|
||||
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);
|
||||
chr_bank_8k = ((value >> 3) & 7);
|
||||
prg_bank_32k &= prg_bank_mask_32k;
|
||||
prg_bank_32k &= chr_bank_mask_8k;
|
||||
if (mirror_control_enabled)
|
||||
SetMirrorType(value.Bit(7) ? EMirrorType.Vertical : EMirrorType.Horizontal);
|
||||
//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);
|
||||
return ROM[addr];
|
||||
}
|
||||
|
||||
public override byte ReadPPU(int addr)
|
||||
{
|
||||
if (addr < 0x2000)
|
||||
{
|
||||
addr |= (chr_bank_8k << 13);
|
||||
return VROM[addr];
|
||||
}
|
||||
else return base.ReadPPU(addr);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override void SyncState(Serializer ser)
|
||||
{
|
||||
base.SyncState(ser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Nintendo
|
||||
{
|
||||
//AKA half of mapper 034 (the other half is AVE_NINA_001 which is entirely different..)
|
||||
class BxROM : NES.NESBoardBase
|
||||
{
|
||||
//configuration
|
||||
int prg_bank_mask_32k;
|
||||
|
||||
//state
|
||||
int prg_bank_32k;
|
||||
|
||||
public override void SyncState(Serializer ser)
|
||||
{
|
||||
base.SyncState(ser);
|
||||
ser.Sync("prg_bank_32k", ref prg_bank_32k);
|
||||
}
|
||||
|
||||
public override bool Configure(NES.EDetectionOrigin origin)
|
||||
{
|
||||
switch (Cart.board_type)
|
||||
{
|
||||
case "IREM-BNROM": //Mashou (J).nes
|
||||
case "NES-BNROM": //Deadly Towers (U)
|
||||
AssertPrg(128); AssertChr(0); AssertWram(0); AssertVram(8);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
prg_bank_mask_32k = Cart.prg_size / 32 - 1;
|
||||
|
||||
SetMirrorType(Cart.pad_h, Cart.pad_v);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override byte ReadPRG(int addr)
|
||||
{
|
||||
addr |= (prg_bank_32k << 15);
|
||||
return ROM[addr];
|
||||
}
|
||||
|
||||
public override void WritePRG(int addr, byte value)
|
||||
{
|
||||
value = HandleNormalPRGConflict(addr, value);
|
||||
prg_bank_32k = value & prg_bank_mask_32k;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
//Bump 'n' Jump
|
||||
//Cybernoid
|
||||
|
||||
public class CxROM : NES.NESBoardBase
|
||||
public class CNROM : NES.NESBoardBase
|
||||
{
|
||||
//configuration
|
||||
int prg_mask,chr_mask;
|
||||
|
@ -28,7 +28,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
{
|
||||
case "NES-CNROM": //adventure island
|
||||
case "HVC-CNROM":
|
||||
AssertPrg(16, 32); AssertChr(16,32);
|
||||
AssertPrg(16, 32); AssertChr(8,16,32);
|
||||
break;
|
||||
|
||||
default:
|
|
@ -0,0 +1,170 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Nintendo
|
||||
{
|
||||
//AKA mapper 071
|
||||
//TODO - apparently this mapper contains good nes timing test cases
|
||||
class Camerica_Mapper071 : NES.NESBoardBase
|
||||
{
|
||||
//configuration
|
||||
int prg_bank_mask_16k;
|
||||
bool mirror_control_enabled;
|
||||
|
||||
//state
|
||||
IntBuffer prg_banks_16k = new IntBuffer(2);
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
prg_banks_16k.Dispose();
|
||||
}
|
||||
|
||||
public override void SyncState(Serializer ser)
|
||||
{
|
||||
base.SyncState(ser);
|
||||
ser.Sync("prg_banks_16k", ref prg_banks_16k);
|
||||
}
|
||||
|
||||
public override bool Configure(NES.EDetectionOrigin origin)
|
||||
{
|
||||
//configure
|
||||
switch (Cart.board_type)
|
||||
{
|
||||
case "CAMERICA-ALGQ": //Linus Spacehead's Cosmic Crusade (U)
|
||||
AssertPrg(128,256); AssertChr(0); AssertWram(0); AssertVram(8);
|
||||
break;
|
||||
case "CAMERICA-BF9093": //Big Nose Freaks Out (U)
|
||||
AssertPrg(64,128,256); AssertChr(0); AssertWram(0); AssertVram(8);
|
||||
break;
|
||||
case "CAMERICA-BF9097": //Fire Hawk
|
||||
AssertPrg(128); AssertChr(0); AssertWram(0); AssertVram(8);
|
||||
mirror_control_enabled = true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
prg_bank_mask_16k = Cart.prg_size / 16 - 1;
|
||||
|
||||
prg_banks_16k[0] = 0x00;
|
||||
prg_banks_16k[1] = 0xFF & prg_bank_mask_16k;
|
||||
|
||||
SetMirrorType(Cart.pad_h, Cart.pad_v);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void WritePRG(int addr, byte value)
|
||||
{
|
||||
addr &= 0x7000;
|
||||
switch (addr)
|
||||
{
|
||||
//$8000-9FFF: [...M ....] Mirroring (for Fire Hawk only!)
|
||||
case 0x0000:
|
||||
case 0x1000:
|
||||
if(mirror_control_enabled)
|
||||
SetMirrorType(value.Bit(4) ? EMirrorType.OneScreenB : EMirrorType.OneScreenA);
|
||||
break;
|
||||
|
||||
//$C000-FFFF: PRG Select (16k @ $8000)
|
||||
case 0x4000: case 0x5000:
|
||||
case 0x6000: case 0x7000:
|
||||
prg_banks_16k[0] = value & prg_bank_mask_16k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override byte ReadPRG(int addr)
|
||||
{
|
||||
int bank_16k = addr >> 14;
|
||||
int ofs = addr & ((1 << 14) - 1);
|
||||
bank_16k = prg_banks_16k[bank_16k];
|
||||
addr = (bank_16k << 14) | ofs;
|
||||
return ROM[addr];
|
||||
}
|
||||
}
|
||||
|
||||
//AKA mapper 232
|
||||
class Camerica_Mapper232 : NES.NESBoardBase
|
||||
{
|
||||
//configuration
|
||||
int prg_bank_mask_16k;
|
||||
|
||||
//state
|
||||
IntBuffer prg_banks_16k = new IntBuffer(2);
|
||||
int prg_block, prg_page;
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
prg_banks_16k.Dispose();
|
||||
}
|
||||
|
||||
public override void SyncState(Serializer ser)
|
||||
{
|
||||
base.SyncState(ser);
|
||||
ser.Sync("prg_banks_16k", ref prg_banks_16k);
|
||||
ser.Sync("prg_block", ref prg_block);
|
||||
ser.Sync("prg_page", ref prg_page);
|
||||
}
|
||||
|
||||
public override bool Configure(NES.EDetectionOrigin origin)
|
||||
{
|
||||
//configure
|
||||
switch (Cart.board_type)
|
||||
{
|
||||
case "CAMERICA-ALGQ": //Quattro Adventure (U)
|
||||
case "CAMERICA-9096": //Quattro Arcade (U)
|
||||
AssertPrg(256); AssertChr(0); AssertWram(0); AssertVram(8);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
prg_bank_mask_16k = Cart.prg_size / 16 - 1;
|
||||
|
||||
SetMirrorType(Cart.pad_h, Cart.pad_v);
|
||||
SyncPRG();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void WritePRG(int addr, byte value)
|
||||
{
|
||||
addr &= 0x4000;
|
||||
switch (addr)
|
||||
{
|
||||
case 0x0000:
|
||||
prg_block = (value>>3)&3;
|
||||
SyncPRG();
|
||||
break;
|
||||
case 0x4000:
|
||||
prg_page = value & 3;
|
||||
SyncPRG();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SyncPRG()
|
||||
{
|
||||
prg_banks_16k[0] = (prg_block << 2) | prg_page;
|
||||
prg_banks_16k[1] = (prg_block << 2) | 3;
|
||||
prg_banks_16k[0] &= prg_bank_mask_16k;
|
||||
prg_banks_16k[1] &= prg_bank_mask_16k;
|
||||
}
|
||||
|
||||
public override byte ReadPRG(int addr)
|
||||
{
|
||||
int bank_16k = addr >> 14;
|
||||
int ofs = addr & ((1 << 14) - 1);
|
||||
bank_16k = prg_banks_16k[bank_16k];
|
||||
addr = (bank_16k<<14) | ofs;
|
||||
return ROM[addr];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -4,7 +4,7 @@ using System.Diagnostics;
|
|||
|
||||
namespace BizHawk.Emulation.Consoles.Nintendo
|
||||
{
|
||||
//mapper 11
|
||||
//mapper 011
|
||||
|
||||
//Crystal Mines
|
||||
//Metal Fighter
|
||||
|
@ -22,6 +22,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
{
|
||||
switch (Cart.board_type)
|
||||
{
|
||||
case "Discrete_74x377-FLEX":
|
||||
break;
|
||||
case "COLORDREAMS-74*377":
|
||||
AssertPrg(32,64,128); AssertChr(16,32,64,128); AssertVram(0); AssertWram(0);
|
||||
break;
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
* Life Span: October 1986 - April 1987
|
||||
PCB Class: Jaleco-JF-11
|
||||
Jaleco-JF-14
|
||||
iNES Mapper #140
|
||||
iNES Mapper 140
|
||||
|
||||
JF-11
|
||||
PRG-ROM: 128kb
|
||||
|
|
|
@ -0,0 +1,269 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Nintendo
|
||||
{
|
||||
//Mapper 069 is FME7
|
||||
//or, Sunsoft-5, which is FME7 with additional sound hardware
|
||||
|
||||
class Sunsoft_5 : Sunsoft_FME7
|
||||
{
|
||||
public override bool Configure(NES.EDetectionOrigin origin)
|
||||
{
|
||||
//configure
|
||||
switch (Cart.board_type)
|
||||
{
|
||||
case "SUNSOFT-5A": //Batman (J)
|
||||
AssertPrg(128); AssertChr(128); AssertWram(0); AssertVram(0); AssertBattery(false);
|
||||
break;
|
||||
case "SUNSOFT-5B": //Gimmick! (J)
|
||||
AssertPrg(256); AssertChr(128); AssertWram(0); AssertVram(0); AssertBattery(false);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
BaseConfigure();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void WritePRG(int addr, byte value)
|
||||
{
|
||||
//TODO - sound
|
||||
base.WritePRG(addr, value);
|
||||
}
|
||||
}
|
||||
|
||||
class Sunsoft_FME7 : NES.NESBoardBase
|
||||
{
|
||||
//configuration
|
||||
int prg_bank_mask_8k, chr_bank_mask_1k, wram_bank_mask_8k;
|
||||
|
||||
//state
|
||||
int addr_reg;
|
||||
ByteBuffer regs = new ByteBuffer(12);
|
||||
ByteBuffer prg_banks_8k = new ByteBuffer(4);
|
||||
int wram_bank;
|
||||
bool wram_ram_selected, wram_ram_enabled;
|
||||
ushort irq_counter;
|
||||
bool irq_countdown, irq_enabled, irq_asserted;
|
||||
int clock_counter;
|
||||
|
||||
|
||||
public override void SyncState(Serializer ser)
|
||||
{
|
||||
base.SyncState(ser);
|
||||
ser.Sync("addr_reg", ref addr_reg);
|
||||
ser.Sync("regs", ref regs);
|
||||
ser.Sync("prg_banks_8k", ref prg_banks_8k);
|
||||
ser.Sync("wram_bank", ref wram_bank);
|
||||
ser.Sync("wram_ram_selected", ref wram_ram_selected);
|
||||
ser.Sync("wram_ram_enabled", ref wram_ram_enabled);
|
||||
ser.Sync("irq_counter", ref irq_counter);
|
||||
ser.Sync("irq_countdown", ref irq_countdown);
|
||||
ser.Sync("irq_enabled", ref irq_enabled);
|
||||
ser.Sync("irq_asserted", ref irq_asserted);
|
||||
ser.Sync("clock_counter", ref clock_counter);
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
regs.Dispose();
|
||||
prg_banks_8k.Dispose();
|
||||
}
|
||||
|
||||
public override bool Configure(NES.EDetectionOrigin origin)
|
||||
{
|
||||
//configure
|
||||
switch (Cart.board_type)
|
||||
{
|
||||
case "MAPPER069-FLEX":
|
||||
break;
|
||||
case "SUNSOFT-FME-7": //Barcode World (J)
|
||||
AssertPrg(128,256); AssertChr(256); AssertWram(0,8); AssertVram(0);
|
||||
break;
|
||||
case "NES-BTR": //Batman - Return of the Joker (U)
|
||||
AssertPrg(128); AssertChr(256); AssertWram(8); AssertVram(0); AssertBattery(false);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
BaseConfigure();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void BaseConfigure()
|
||||
{
|
||||
prg_bank_mask_8k = (Cart.prg_size / 8) - 1;
|
||||
wram_bank_mask_8k = (Cart.wram_size / 8) - 1;
|
||||
chr_bank_mask_1k = Cart.chr_size - 1;
|
||||
prg_banks_8k[3] = 0xFF;
|
||||
SetMirrorType(EMirrorType.Vertical);
|
||||
}
|
||||
|
||||
void SyncPRG()
|
||||
{
|
||||
wram_ram_enabled = (regs[8] & 0x80) != 0;
|
||||
wram_ram_selected = (regs[8]&0x40)!=0;
|
||||
wram_bank = (byte)(regs[8] & 0x7F);
|
||||
for(int i=0;i<3;i++)
|
||||
{
|
||||
prg_banks_8k[i] = regs[8 + i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
public override void WritePRG(int addr, byte value)
|
||||
{
|
||||
addr &= 0xE000;
|
||||
switch (addr)
|
||||
{
|
||||
case 0x0000: //$8000: [.... AAAA] Address for use with $A000
|
||||
addr_reg = value & 0xF;
|
||||
break;
|
||||
case 0x2000: //$A000: [DDDD DDDD] Data port
|
||||
switch(addr_reg)
|
||||
{
|
||||
case 0: case 1: case 2: case 3:
|
||||
case 4: case 5: case 6: case 7:
|
||||
regs[addr_reg] = value;
|
||||
//NES.LogLine("cr set to {0},{1},{2},{3},{4},{5},{6},{7}", regs[0], regs[1], regs[2], regs[3], regs[4], regs[5], regs[6], regs[7]);
|
||||
break;
|
||||
case 8: case 9: case 0xA: case 0xB:
|
||||
regs[addr_reg] = value;
|
||||
//NES.LogLine("pr/wr set to {0},{1},{2},{3},~0xFF~", regs[8], regs[9], regs[10], regs[11]);
|
||||
SyncPRG();
|
||||
break;
|
||||
case 0xC:
|
||||
switch (value & 3)
|
||||
{
|
||||
case 0: SetMirrorType(EMirrorType.Vertical); break;
|
||||
case 1: SetMirrorType(EMirrorType.Horizontal); break;
|
||||
case 2: SetMirrorType(EMirrorType.OneScreenA); break;
|
||||
case 3: SetMirrorType(EMirrorType.OneScreenB); break;
|
||||
}
|
||||
break;
|
||||
case 0xD:
|
||||
irq_countdown = value.Bit(7);
|
||||
irq_enabled = value.Bit(0);
|
||||
//if (value != 0) NES.LogLine("irq set to {0},{1} with value {2:x2}", irq_countdown, irq_enabled, value);
|
||||
if (!irq_enabled) irq_asserted = false;
|
||||
SyncIrq();
|
||||
break;
|
||||
case 0xE:
|
||||
irq_counter &= 0xFF00;
|
||||
irq_counter |= value;
|
||||
//NES.LogLine("irq_counter set to {0:x4}", irq_counter);
|
||||
break;
|
||||
case 0xF:
|
||||
irq_counter &= 0x00FF;
|
||||
irq_counter |= (ushort)(value << 8);
|
||||
//NES.LogLine("irq_counter set to {0:x4}", irq_counter);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SyncIrq()
|
||||
{
|
||||
NES.irq_cart = irq_asserted;
|
||||
}
|
||||
|
||||
void ClockCPU()
|
||||
{
|
||||
if (!irq_countdown) return;
|
||||
irq_counter--;
|
||||
if (irq_counter == 0xFFFF)
|
||||
{
|
||||
irq_asserted = true;
|
||||
SyncIrq();
|
||||
}
|
||||
}
|
||||
|
||||
public override void ClockPPU()
|
||||
{
|
||||
clock_counter++;
|
||||
if (clock_counter == 3)
|
||||
{
|
||||
ClockCPU();
|
||||
clock_counter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override byte ReadPRG(int addr)
|
||||
{
|
||||
int bank_8k = addr >> 13;
|
||||
int ofs = addr & ((1<<13)-1);
|
||||
bank_8k = prg_banks_8k[bank_8k];
|
||||
bank_8k &= prg_bank_mask_8k;
|
||||
addr = (bank_8k << 13) | ofs;
|
||||
return ROM[addr];
|
||||
}
|
||||
|
||||
int CalcWRAMAddress(int addr, int bank_mask_8k)
|
||||
{
|
||||
int ofs = addr & ((1 << 13) - 1);
|
||||
int bank_8k = wram_bank;
|
||||
bank_8k &= bank_mask_8k;
|
||||
addr = (bank_8k << 13) | ofs;
|
||||
return addr;
|
||||
}
|
||||
|
||||
int CalcPPUAddress(int addr)
|
||||
{
|
||||
int bank_1k = addr >> 10;
|
||||
int ofs = addr & ((1 << 10) - 1);
|
||||
bank_1k = regs[bank_1k];
|
||||
bank_1k &= chr_bank_mask_1k;
|
||||
return (bank_1k<<10) | ofs;
|
||||
}
|
||||
|
||||
public override byte ReadPPU(int addr)
|
||||
{
|
||||
if (addr < 0x2000)
|
||||
return VROM[CalcPPUAddress(addr)];
|
||||
else return base.ReadPPU(addr);
|
||||
}
|
||||
|
||||
public override void WritePPU(int addr, byte value)
|
||||
{
|
||||
if (addr < 0x2000)
|
||||
{ }
|
||||
else base.WritePPU(addr, value);
|
||||
}
|
||||
|
||||
public override byte ReadWRAM(int addr)
|
||||
{
|
||||
if (!wram_ram_selected)
|
||||
{
|
||||
addr = CalcWRAMAddress(addr, prg_bank_mask_8k);
|
||||
return ROM[addr];
|
||||
}
|
||||
else if (!wram_ram_enabled)
|
||||
return 0xFF; //empty bus
|
||||
else
|
||||
{
|
||||
addr = CalcWRAMAddress(addr, wram_bank_mask_8k);
|
||||
return WRAM[addr];
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteWRAM(int addr, byte value)
|
||||
{
|
||||
if (!wram_ram_selected) return;
|
||||
else if (!wram_ram_enabled)
|
||||
return; //empty bus
|
||||
else
|
||||
{
|
||||
addr = CalcWRAMAddress(addr, wram_bank_mask_8k);
|
||||
WRAM[addr] = value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
|
||||
/*
|
||||
PCB Class: Unknown
|
||||
iNES Mapper #242
|
||||
iNES Mapper 242
|
||||
PRG-ROM: 32KB
|
||||
PRG-RAM: None
|
||||
CHR-ROM: 16KB
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
/*
|
||||
* Life Span: April 1986 - July 1986
|
||||
PCB Class: SUNSOFT-1
|
||||
iNES Mapper #184
|
||||
iNES Mapper 184
|
||||
PRG-ROM: 32KB
|
||||
PRG-RAM: None
|
||||
CHR-ROM: 16KB
|
||||
|
|
|
@ -16,8 +16,9 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
static readonly bool USE_DATABASE = true;
|
||||
|
||||
//Game issues:
|
||||
//Dragon warrior 3/4 certainly need some additional work done to the mapper wiring to get to the super big PRG (probably SXROM too)
|
||||
//Tecmo superbowl - wobbly "NFL" logo at the end of a game (even skipped game) [zeromus cant test this; how do you skip game?]
|
||||
//Bigfoot (U) seems not to work
|
||||
//Bill and ted's excellent video game adventure (U) doesnt work until more detailed emulation exists (check 001.txt)
|
||||
|
||||
//---
|
||||
//Game issues for tester to check off.
|
||||
|
@ -381,6 +382,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
Console.WriteLine("headerless rom hash: {0}", hash_sha1);
|
||||
Console.WriteLine("headerless rom hash: {0}", hash_md5);
|
||||
|
||||
Type boardType = null;
|
||||
CartInfo choice = null;
|
||||
if(USE_DATABASE)
|
||||
choice = IdentifyFromBootGodDB(hash_sha1);
|
||||
|
@ -403,8 +405,28 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
string iNES_board = iNESBoardDetector.Detect(choice);
|
||||
if (iNES_board == null)
|
||||
throw new Exception("couldnt identify NES rom");
|
||||
Console.WriteLine("Chose board from iNES heuristics: " + iNES_board);
|
||||
choice.board_type = iNES_board;
|
||||
|
||||
//try spinning up a board with 8K wram and with 0K wram to see if one answers
|
||||
try
|
||||
{
|
||||
boardType = FindBoard(choice, origin);
|
||||
}
|
||||
catch { }
|
||||
if (boardType == null)
|
||||
{
|
||||
if (choice.wram_size == 8) choice.wram_size = 0;
|
||||
else if (choice.wram_size == 0) choice.wram_size = 8;
|
||||
try
|
||||
{
|
||||
boardType = FindBoard(choice, origin);
|
||||
}
|
||||
catch { }
|
||||
if (boardType != null)
|
||||
Console.WriteLine("Ambiguous iNES wram size resolved as {0}k", choice.wram_size);
|
||||
}
|
||||
|
||||
Console.WriteLine("Chose board from iNES heuristics: " + iNES_board);
|
||||
choice.game.name = game.Name;
|
||||
origin = EDetectionOrigin.INES;
|
||||
}
|
||||
|
@ -425,7 +447,6 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
game_name = choice.game.name;
|
||||
|
||||
//find a INESBoard to handle this
|
||||
Type boardType = null;
|
||||
boardType = FindBoard(choice, origin);
|
||||
if (boardType == null)
|
||||
throw new Exception("No class implements the necessary board type: " + choice.board_type);
|
||||
|
|
|
@ -91,13 +91,20 @@ static string ClassifyTable = @"
|
|||
4 512 128 8 0 NES-TKROM; Pool of radiance (J)
|
||||
7 128 0 8 0 NES-ANROM; marble madness
|
||||
7 256 0 8 8 NES-AOROM; battletoads
|
||||
11 -1 -1 -1 -1 Discrete_74x377-FLEX; Bible Adventures (U) ?
|
||||
13 32 0 8 16 NES-CPROM; videomation
|
||||
65 -1 -1 -1 -1 IREM-H3001-FLEX; //Ai Sensei No Oshiete - Watashi No Hoshi (J).nes
|
||||
66 64 16 8 0 NES-MHROM; super mario bros / duck hunt
|
||||
66 128 32 8 0 NES-GNROM; gumshoe
|
||||
68 128 256 8 0 SUNSOFT-4; After Burner 2 (J)
|
||||
69 -1 -1 -1 -1 MAPPER069-FLEX; Gimmick! (J)
|
||||
71 -1 -1 -1 -1 CAMERICA-BF9093; Micro Machines (U)
|
||||
79 -1 -1 -1 -1 AVE-NINA-06; Blackjack (U)
|
||||
113 -1 -1 -1 -1 AVE-NINA-06; ???
|
||||
232 -1 -1 -1 -1 CAMERICA-ALGQ; Quattro Adventure
|
||||
";
|
||||
}
|
||||
//;232 -1 -1 -1 -1 Camerica_BF9096-FLEX; Quattro Adventure
|
||||
|
||||
unsafe struct iNES_HEADER
|
||||
{
|
||||
|
|
|
@ -2284,6 +2284,7 @@ sha1:192C543866F1037276D2778046ABEDCA84868E26 Bio Senshi Dan - Increaser To No
|
|||
sha1:E80FF0B707B0D675FDBEF474E3FDB1A83E2B7C44 Mississippi Satsujin Jiken (J) NES board=JALECO-JF-11;PRG=128;CHR=32;PAD_H=1
|
||||
sha1:8A5FD1061ADACDEABF422A2D2E555FF70749AE7C Mississippi Satsujin Jiken (Alt) (J) NES board=GXROM_HACKY;PRG=128;CHR=32;PAD_H=1
|
||||
sha1:8C7D33753649A2BAF2EAAF8D5FFC2AE8E9316A13 Akira (J) NES board=TAITO-TC0190FMC;PRG=128;CHR=256;WRAM=0
|
||||
sha1:0AE47BD83202A5A2235B0BC16278F56D66038AB5 Deathbots (U) NES board=AVE-NINA-06;PRG=64;CHR=64;PAD_H=1;PAD_V=0
|
||||
|
||||
;these roms are in goodNES but theyre junk
|
||||
sha1:4D6117577CE301BB987C5C32FEEF7B132A21B046 Afro Man (Mega Man 3 Hack) (UNL) NES board=TXROM-HOMEBREW;PRG=256;CHR=128;WRAM=8
|
||||
|
|
Loading…
Reference in New Issue