core: Update to latest upstream release

This commit is contained in:
Rupert Carmichael 2024-03-29 00:23:52 -04:00
parent 2cef539e0d
commit efe3a052c7
18 changed files with 500 additions and 102 deletions

View File

@ -1064,7 +1064,7 @@
<device type="zapper" /> <device type="zapper" />
</peripherals> </peripherals>
<cartridge system="Famicom" dump="unknown" crc="0AFB395E" sha1="CFFAC7D2ECB18A28C36E0E90A6682DFE5BA6E3D1"> <cartridge system="Famicom" dump="unknown" crc="0AFB395E" sha1="CFFAC7D2ECB18A28C36E0E90A6682DFE5BA6E3D1">
<board mapper="5"> <board type="HVC-ELROM" mapper="5">
<prg size="128k" /> <prg size="128k" />
<chr size="128k" /> <chr size="128k" />
</board> </board>
@ -2879,7 +2879,7 @@
</game> </game>
<game> <game>
<cartridge system="Famicom" dump="unknown" crc="1CED086F" sha1="46C0B521B3C595409C05972388909CCB0D5F6369"> <cartridge system="Famicom" dump="unknown" crc="1CED086F" sha1="46C0B521B3C595409C05972388909CCB0D5F6369">
<board mapper="5"> <board type="HVC-ETROM" mapper="5">
<prg size="256k" /> <prg size="256k" />
<chr size="128k" /> <chr size="128k" />
<wram size="8k" /> <wram size="8k" />
@ -3128,6 +3128,17 @@
</board> </board>
</cartridge> </cartridge>
</game> </game>
<game>
<peripherals>
<device type="zapper" />
</peripherals>
<cartridge system="NES-NTSC" dump="ok" crc="1F14123C" sha1="9B1B8354B7449FDDA4176C93BCE7660D47F66019">
<board mapper="4">
<prg size="32k" />
<chr size="16k" />
</board>
</cartridge>
</game>
<game> <game>
<cartridge system="Famicom" dump="ok" crc="1F2D9DB7" sha1="544203A8304A7922A46579512665C743527CA1E6"> <cartridge system="Famicom" dump="ok" crc="1F2D9DB7" sha1="544203A8304A7922A46579512665C743527CA1E6">
<board type="HVC-NROM-256" mapper="0"> <board type="HVC-NROM-256" mapper="0">
@ -10280,7 +10291,7 @@
</game> </game>
<game> <game>
<cartridge system="Famicom" dump="unknown" crc="6396B988" sha1="B326D1984D5D369BC168028AD7672D2EFC2ECDDB"> <cartridge system="Famicom" dump="unknown" crc="6396B988" sha1="B326D1984D5D369BC168028AD7672D2EFC2ECDDB">
<board mapper="5"> <board type="HVC-ETROM" mapper="5">
<prg size="256k" /> <prg size="256k" />
<chr size="128k" /> <chr size="128k" />
<wram size="8k" /> <wram size="8k" />
@ -11493,7 +11504,7 @@
</game> </game>
<game> <game>
<cartridge system="Famicom" dump="unknown" crc="6F4E4312" sha1="99CF6CA63B173A2B86125F16BBE11885EF1AC377"> <cartridge system="Famicom" dump="unknown" crc="6F4E4312" sha1="99CF6CA63B173A2B86125F16BBE11885EF1AC377">
<board mapper="5"> <board type="HVC-EWROM" mapper="5">
<prg size="512k" /> <prg size="512k" />
<chr size="256k" /> <chr size="256k" />
<wram size="32k" battery="1" /> <wram size="32k" battery="1" />
@ -19131,7 +19142,7 @@
</game> </game>
<game> <game>
<cartridge system="Famicom" dump="unknown" crc="B4735FAC" sha1="4AC3E9136706AB009EE2F68C7D009422D73EE8E8"> <cartridge system="Famicom" dump="unknown" crc="B4735FAC" sha1="4AC3E9136706AB009EE2F68C7D009422D73EE8E8">
<board mapper="5"> <board type="HVC-ELROM" mapper="5">
<prg size="512k" /> <prg size="512k" />
<chr size="512k" /> <chr size="512k" />
</board> </board>
@ -19825,7 +19836,7 @@
</game> </game>
<game> <game>
<cartridge system="Famicom" dump="unknown" crc="BB7F829A" sha1="BC7393653D04F3E3D35E3D0623ACA4A2C27E0AA1"> <cartridge system="Famicom" dump="unknown" crc="BB7F829A" sha1="BC7393653D04F3E3D35E3D0623ACA4A2C27E0AA1">
<board mapper="5"> <board type= "HVC-ELROM" mapper="5">
<prg size="128k" /> <prg size="128k" />
<chr size="128k" /> <chr size="128k" />
</board> </board>
@ -19952,7 +19963,7 @@
</game> </game>
<game> <game>
<cartridge system="Famicom" dump="unknown" crc="BC80FB52" sha1="74DBA27392CA4451875AD0267E5466F92D835A62"> <cartridge system="Famicom" dump="unknown" crc="BC80FB52" sha1="74DBA27392CA4451875AD0267E5466F92D835A62">
<board mapper="5"> <board type="HVC-EKROM" mapper="5">
<prg size="256k" /> <prg size="256k" />
<chr size="256k" /> <chr size="256k" />
<wram size="8k" battery="1" /> <wram size="8k" battery="1" />
@ -25490,7 +25501,7 @@
</game> </game>
<game> <game>
<cartridge system="Famicom" dump="unknown" crc="EEE9A682" sha1="46C443D0EB27AF7A566E744F096F981034A06E59"> <cartridge system="Famicom" dump="unknown" crc="EEE9A682" sha1="46C443D0EB27AF7A566E744F096F981034A06E59">
<board mapper="5"> <board type="HVC-ETROM" mapper="5">
<prg size="256k" /> <prg size="256k" />
<chr size="128k" /> <chr size="128k" />
<wram size="8k" /> <wram size="8k" />
@ -25978,7 +25989,7 @@
</game> </game>
<game> <game>
<cartridge system="Famicom" dump="unknown" crc="F540677B" sha1="44A5BC2B8156D50518EEBEEFA522A7642E0476DC"> <cartridge system="Famicom" dump="unknown" crc="F540677B" sha1="44A5BC2B8156D50518EEBEEFA522A7642E0476DC">
<board mapper="5"> <board type="HVC-EWROM" mapper="5">
<prg size="512k" /> <prg size="512k" />
<chr size="256k" /> <chr size="256k" />
<wram size="32k" battery="1" /> <wram size="32k" battery="1" />
@ -27057,7 +27068,7 @@
</game> </game>
<game> <game>
<cartridge system="Famicom" dump="unknown" crc="FE3488D1" sha1="800AEFE756E85A0A78CCB4DAE68EBBA5DF24BF41"> <cartridge system="Famicom" dump="unknown" crc="FE3488D1" sha1="800AEFE756E85A0A78CCB4DAE68EBBA5DF24BF41">
<board mapper="5"> <board type="HVC-ETROM" mapper="5">
<prg size="512k" /> <prg size="512k" />
<chr size="128k" /> <chr size="128k" />
<wram size="8k" /> <wram size="8k" />

View File

@ -89,6 +89,7 @@ SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardBandaiLz93d50ex.cpp
SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardBandaiOekaKids.cpp SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardBandaiOekaKids.cpp
SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardBenshengBs5.cpp SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardBenshengBs5.cpp
SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardBmc110in1.cpp SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardBmc110in1.cpp
SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardBmc120in1.cpp
SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardBmc1200in1.cpp SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardBmc1200in1.cpp
SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardBmc150in1.cpp SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardBmc150in1.cpp
SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardBmc15in1.cpp SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardBmc15in1.cpp
@ -252,6 +253,7 @@ SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardUnl158b.cpp
SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardUnlA9746.cpp SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardUnlA9746.cpp
SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardUnlCc21.cpp SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardUnlCc21.cpp
SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardUnlEdu2000.cpp SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardUnlEdu2000.cpp
SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardUnlFam250Schi24.cpp
SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardUnlKingOfFighters96.cpp SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardUnlKingOfFighters96.cpp
SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardUnlKingOfFighters97.cpp SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardUnlKingOfFighters97.cpp
SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardUnlMortalKombat2.cpp SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardUnlMortalKombat2.cpp

View File

@ -22,7 +22,7 @@
#include "nstdatabase.hpp" #include "nstdatabase.hpp"
#define NST_VERSION "1.52.0" #define NST_VERSION "1.52.1"
#define MIN(a,b) ((a)<(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b))
#define MAX(a,b) ((a)>(b)?(a):(b)) #define MAX(a,b) ((a)>(b)?(a):(b))

File diff suppressed because one or more lines are too long

View File

@ -297,8 +297,8 @@ namespace Nes
if (!rate) if (!rate)
return RESULT_ERR_INVALID_PARAM; return RESULT_ERR_INVALID_PARAM;
if (rate < 44100 || rate > 96000) /*if (rate < 44100 || rate > 96000)
return RESULT_ERR_UNSUPPORTED; return RESULT_ERR_UNSUPPORTED;*/
settings.rate = rate; settings.rate = rate;
UpdateSettings(); UpdateSettings();
@ -2284,20 +2284,37 @@ namespace Nes
{ {
NST_VERIFY( !dma.buffered && (!readAddress || !cpu.IsWriteCycle(clock)) ); NST_VERIFY( !dma.buffered && (!readAddress || !cpu.IsWriteCycle(clock)) );
if (!readAddress) /* DMC DMA adds:
* case 1: 4 cycles normally
* case 2: 3 if it lands on a CPU write
* case 3: 2 if it lands on the $4014 write or during OAM DMA
* case 4: 1 if on the next-to-next-to-last DMA cycle
* case 5: 3 if on the last DMA cycle
* https://forums.nesdev.org/viewtopic.php?f=3&t=6100
* https://www.nesdev.org/wiki/DMA
*/
uint cyclesToSteal = cpu.IsWriteCycle(clock) ? 3 : 4;
if (cpu.GetOamDMA())
{ {
cpu.StealCycles( cpu.GetClock(cpu.IsWriteCycle(clock) ? 2 : 3) ); if (cpu.GetOamDMACycle() == 255)
{
cyclesToSteal = 3;
}
else if (cpu.GetOamDMACycle() == 254)
{
cyclesToSteal = 1;
}
else
{
cyclesToSteal = 2;
}
} }
else if (cpu.GetCycles() != clock)
{ if (readAddress && cpu.GetCycles() == clock)
cpu.StealCycles( cpu.GetClock(3) );
}
else
{ {
NST_DEBUG_MSG("DMA/Read conflict!"); NST_DEBUG_MSG("DMA/Read conflict!");
cpu.StealCycles( cpu.GetClock(1) );
/* According to dmc_dma_during_read4/dma_2007_read, DMC DMA during read causes /* According to dmc_dma_during_read4/dma_2007_read, DMC DMA during read causes
* 2-3 extra $2007 reads before the real read. The nesdev wiki states that this * 2-3 extra $2007 reads before the real read. The nesdev wiki states that this
* also happens when polling $2002 for vblank. * also happens when polling $2002 for vblank.
@ -2308,13 +2325,12 @@ namespace Nes
cpu.Peek( readAddress ); cpu.Peek( readAddress );
} }
cpu.StealCycles( cpu.GetClock(1) );
cpu.Peek( readAddress ); cpu.Peek( readAddress );
cpu.StealCycles( cpu.GetClock(1) );
} }
cpu.StealCycles( cpu.GetClock() * cyclesToSteal);
dma.buffer = cpu.Peek( dma.address ); dma.buffer = cpu.Peek( dma.address );
cpu.StealCycles( cpu.GetClock() );
dma.address = 0x8000 | ((dma.address + 1U) & 0x7FFF); dma.address = 0x8000 | ((dma.address + 1U) & 0x7FFF);
dma.buffered = true; dma.buffered = true;

View File

@ -490,6 +490,9 @@ namespace Nes
bool cpuOverclocking; bool cpuOverclocking;
uint extraCycles; uint extraCycles;
bool dmaOam;
uint dmaOamCycle;
static dword logged; static dword logged;
static void (Cpu::*const opcodes[0x100])(); static void (Cpu::*const opcodes[0x100])();
static const byte writeClocks[0x100]; static const byte writeClocks[0x100];
@ -513,6 +516,30 @@ namespace Nes
return cycles.count; return cycles.count;
} }
void SetOamDMA(bool dma)
{
if (dma && !dmaOam && IsOddCycle())
{
StealCycles( GetClock() );
}
dmaOam = dma;
}
bool GetOamDMA()
{
return dmaOam;
}
uint GetOamDMACycle()
{
return dmaOamCycle;
}
void SetOamDMACycle(uint count)
{
dmaOamCycle = count;
}
void DoIRQ(IrqLine line=IRQ_EXT) void DoIRQ(IrqLine line=IRQ_EXT)
{ {
DoIRQ( line, cycles.count ); DoIRQ( line, cycles.count );

View File

@ -1109,9 +1109,6 @@ namespace Nes
NES_POKE_D(Ppu,4014) NES_POKE_D(Ppu,4014)
{ {
if (cpu.IsOddCycle())
cpu.StealCycles( cpu.GetClock() );
Update( cycles.one ); Update( cycles.one );
cpu.StealCycles( cpu.GetClock() ); cpu.StealCycles( cpu.GetClock() );
@ -1121,19 +1118,31 @@ namespace Nes
if ((regs.oam == 0x00 && data < 0x2000) && (!(regs.ctrl[1] & Regs::CTRL1_BG_SP_ENABLED) || cpu.GetCycles() <= GetHVIntClock() - cpu.GetClock() * 512)) if ((regs.oam == 0x00 && data < 0x2000) && (!(regs.ctrl[1] & Regs::CTRL1_BG_SP_ENABLED) || cpu.GetCycles() <= GetHVIntClock() - cpu.GetClock() * 512))
{ {
cpu.StealCycles( cpu.GetClock() * 512 );
const byte* const NST_RESTRICT cpuRam = cpu.GetRam() + (data & (Cpu::RAM_SIZE-1)); const byte* const NST_RESTRICT cpuRam = cpu.GetRam() + (data & (Cpu::RAM_SIZE-1));
byte* const NST_RESTRICT oamRam = oam.ram; byte* const NST_RESTRICT oamRam = oam.ram;
for (uint i=0x00; i < 0x100; i += 0x4) cpu.SetOamDMA(true);
for (uint i=0x00; i < 0x100; i++)
{ {
oamRam[i+0x0] = cpuRam[i+0x0]; cpu.SetOamDMACycle(i);
oamRam[i+0x1] = cpuRam[i+0x1];
oamRam[i+0x2] = cpuRam[i+0x2] & 0xE3U; cpu.StealCycles( cpu.GetClock() );
oamRam[i+0x3] = cpuRam[i+0x3]; cpu.Update();
oamRam[i] = cpuRam[i];
if ((i & 0x03) == 0x02)
{
oamRam[i] &= 0xE3U;
}
cpu.StealCycles( cpu.GetClock() );
cpu.Update();
} }
cpu.SetOamDMACycle(0);
cpu.SetOamDMA(false);
io.latch = oamRam[0xFF]; io.latch = oamRam[0xFF];
UpdateDecay(0xFF); UpdateDecay(0xFF);
} }

View File

@ -561,7 +561,6 @@ namespace Nes
{ {
overclocked = overclock2x; overclocked = overclock2x;
} }
}; };
} }
} }

View File

@ -101,6 +101,7 @@
#include "NstBoardUnlA9746.hpp" #include "NstBoardUnlA9746.hpp"
#include "NstBoardUnlCc21.hpp" #include "NstBoardUnlCc21.hpp"
#include "NstBoardUnlEdu2000.hpp" #include "NstBoardUnlEdu2000.hpp"
#include "NstBoardUnlFam250Schi24.hpp"
#include "NstBoardUnlKingOfFighters96.hpp" #include "NstBoardUnlKingOfFighters96.hpp"
#include "NstBoardUnlKingOfFighters97.hpp" #include "NstBoardUnlKingOfFighters97.hpp"
#include "NstBoardUnlMmc3BigPrgRom.hpp" #include "NstBoardUnlMmc3BigPrgRom.hpp"
@ -128,6 +129,7 @@
#include "NstBoardBtlTobidaseDaisakusen.hpp" #include "NstBoardBtlTobidaseDaisakusen.hpp"
#include "NstBoardBmc110in1.hpp" #include "NstBoardBmc110in1.hpp"
#include "NstBoardBmc1200in1.hpp" #include "NstBoardBmc1200in1.hpp"
#include "NstBoardBmc120in1.hpp"
#include "NstBoardBmc150in1.hpp" #include "NstBoardBmc150in1.hpp"
#include "NstBoardBmc15in1.hpp" #include "NstBoardBmc15in1.hpp"
#include "NstBoardBmc20in1.hpp" #include "NstBoardBmc20in1.hpp"
@ -1575,65 +1577,8 @@ namespace Nes
case 5: case 5:
if name = "ExROM";
( id = Type::STD_EXROM_5;
(prg == SIZE_128K || prg == SIZE_256K || prg == SIZE_512K) &&
(chr == SIZE_128K || chr == SIZE_256K || chr == SIZE_512K) &&
(wram <= SIZE_32K)
)
{
if (wram > SIZE_16K)
{
name = "EWROM";
id = Type::STD_EWROM;
}
else if (wram > SIZE_8K)
{
name = "ETROM";
id = Type::STD_ETROM;
}
else if (wram || useWramAuto)
{
wramAuto = useWramAuto;
name = "EKROM";
id = Type::STD_EKROM;
}
else
{
name = "ELROM";
id = Type::STD_ELROM;
}
}
else
{
name = "ExROM (non-standard)";
if (wram > SIZE_40K)
{
id = Type::STD_EXROM_5;
}
else if (wram > SIZE_32K)
{
id = Type::STD_EXROM_4;
}
else if (wram > SIZE_16K)
{
id = Type::STD_EXROM_3;
}
else if (wram > SIZE_8K)
{
id = Type::STD_EXROM_2;
}
else if (wram || useWramAuto)
{
wramAuto = useWramAuto;
id = Type::STD_EXROM_1;
}
else
{
id = Type::STD_EXROM_0;
}
}
break; break;
case 6: case 6:
@ -2397,6 +2342,12 @@ namespace Nes
id = Type::TAITO_X1005; id = Type::TAITO_X1005;
break; break;
case 81:
name = "NTDEC N715021";
id = Type::NTDEC_SUPERGUN;
break;
case 82: case 82:
name = "TAITO X1-017"; name = "TAITO X1-017";
@ -3253,8 +3204,15 @@ namespace Nes
case 227: case 227:
name = "BMC 1200-IN-1"; if (submapper == 1)
id = Type::BMC_1200IN1; {
name = "BMC 120-IN-1";
id = Type::BMC_120IN1;
}
else {
name = "BMC 1200-IN-1";
id = Type::BMC_1200IN1;
}
break; break;
case 228: case 228:
@ -3523,6 +3481,18 @@ namespace Nes
id = Type::BMC_SUPER_40IN1; id = Type::BMC_SUPER_40IN1;
break; break;
case 354:
name = "UNL-FAM250-SCHI24";
id = Type::UNL_FAM250SCHI24;
if (submapper == 1)
{
chips.Add(L"SCHI-24");
}
break;
case 400: case 400:
name = "UNL-RET-X7-GBL"; name = "UNL-RET-X7-GBL";
@ -3686,6 +3656,7 @@ namespace Nes
case Type::BMC_DRAGONBOLLPARTY : return new Cony::Standard(c); case Type::BMC_DRAGONBOLLPARTY : return new Cony::Standard(c);
case Type::BMC_110IN1 : return new Bmc::B110in1(c); case Type::BMC_110IN1 : return new Bmc::B110in1(c);
case Type::BMC_1200IN1 : return new Bmc::B1200in1(c); case Type::BMC_1200IN1 : return new Bmc::B1200in1(c);
case Type::BMC_120IN1 : return new Bmc::B120in1(c);
case Type::BMC_150IN1 : return new Bmc::B150in1(c); case Type::BMC_150IN1 : return new Bmc::B150in1(c);
case Type::BMC_15IN1 : return new Bmc::B15in1(c); case Type::BMC_15IN1 : return new Bmc::B15in1(c);
case Type::BMC_20IN1 : return new Bmc::B20in1(c); case Type::BMC_20IN1 : return new Bmc::B20in1(c);
@ -3865,6 +3836,7 @@ namespace Nes
case Type::NTDEC_ASDER_0 : case Type::NTDEC_ASDER_0 :
case Type::NTDEC_ASDER_1 : return new Ntdec::Asder(c); case Type::NTDEC_ASDER_1 : return new Ntdec::Asder(c);
case Type::NTDEC_FIGHTINGHERO : return new Ntdec::FightingHero(c); case Type::NTDEC_FIGHTINGHERO : return new Ntdec::FightingHero(c);
case Type::NTDEC_SUPERGUN : return new Ntdec::SuperGun(c);
case Type::OPENCORP_DAOU306 : return new OpenCorp::Daou306(c); case Type::OPENCORP_DAOU306 : return new OpenCorp::Daou306(c);
case Type::REXSOFT_SL1632 : return new RexSoft::Sl1632(c); case Type::REXSOFT_SL1632 : return new RexSoft::Sl1632(c);
case Type::REXSOFT_DBZ5 : return new RexSoft::Dbz5(c); case Type::REXSOFT_DBZ5 : return new RexSoft::Dbz5(c);
@ -3926,6 +3898,7 @@ namespace Nes
case Type::UNL_A9746 : return new Unlicensed::A9746(c); case Type::UNL_A9746 : return new Unlicensed::A9746(c);
case Type::UNL_CC21 : return new Unlicensed::Cc21(c); case Type::UNL_CC21 : return new Unlicensed::Cc21(c);
case Type::UNL_EDU2000 : return new Unlicensed::Edu2000(c); case Type::UNL_EDU2000 : return new Unlicensed::Edu2000(c);
case Type::UNL_FAM250SCHI24 : return new Unlicensed::Fam250Schi24(c);
case Type::UNL_FS304 : return new Waixing::Fs304(c); case Type::UNL_FS304 : return new Waixing::Fs304(c);
case Type::UNL_KINGOFFIGHTERS96 : return new Unlicensed::KingOfFighters96(c); case Type::UNL_KINGOFFIGHTERS96 : return new Unlicensed::KingOfFighters96(c);
case Type::UNL_KINGOFFIGHTERS97 : return new Unlicensed::KingOfFighters97(c); case Type::UNL_KINGOFFIGHTERS97 : return new Unlicensed::KingOfFighters97(c);

View File

@ -264,6 +264,7 @@ namespace Nes
BMC_150IN1 = MakeId< 202, 128, 64, 0, 0, CRM_0, NMT_V, 0 >::ID, BMC_150IN1 = MakeId< 202, 128, 64, 0, 0, CRM_0, NMT_V, 0 >::ID,
BMC_15IN1 = MakeId< 205, 512, 512, 0, 0, CRM_0, NMT_X, 0 >::ID, BMC_15IN1 = MakeId< 205, 512, 512, 0, 0, CRM_0, NMT_X, 0 >::ID,
BMC_1200IN1 = MakeId< 227, 512, 0, 0, 0, CRM_8, NMT_V, 0 >::ID, BMC_1200IN1 = MakeId< 227, 512, 0, 0, 0, CRM_8, NMT_V, 0 >::ID,
BMC_120IN1 = MakeId< 227, 512, 0, 0, 0, CRM_8, NMT_V, 1 >::ID,
BMC_20IN1 = MakeId< 231, 512, 0, 0, 0, CRM_8, NMT_V, 0 >::ID, BMC_20IN1 = MakeId< 231, 512, 0, 0, 0, CRM_8, NMT_V, 0 >::ID,
BMC_21IN1 = MakeId< 201, 128, 32, 0, 0, CRM_0, NMT_V, 0 >::ID, BMC_21IN1 = MakeId< 201, 128, 32, 0, 0, CRM_0, NMT_V, 0 >::ID,
BMC_22GAMES = MakeId< 230, 1024, 0, 0, 0, CRM_8, NMT_V, 0 >::ID, BMC_22GAMES = MakeId< 230, 1024, 0, 0, 0, CRM_8, NMT_V, 0 >::ID,
@ -434,7 +435,7 @@ namespace Nes
KAY_PANDAPRINCE = MakeId< 121, 256, 256, 0, 0, CRM_0, NMT_V, 0 >::ID, KAY_PANDAPRINCE = MakeId< 121, 256, 256, 0, 0, CRM_0, NMT_V, 0 >::ID,
// Konami // Konami
KONAMI_VRC1 = MakeId< 75, 128, 128, 0, 0, CRM_0, NMT_V, 0 >::ID, KONAMI_VRC1 = MakeId< 75, 128, 128, 0, 0, CRM_0, NMT_V, 0 >::ID,
KONAMI_VRC2 = MakeId< 22, 128, 256, 0, 0, CRM_0, NMT_V, 0 >::ID, KONAMI_VRC2 = MakeId< 22, 256, 256, 0, 0, CRM_0, NMT_V, 0 >::ID,
KONAMI_VRC3 = MakeId< 73, 128, 0, 8, 0, CRM_8, NMT_X, 0 >::ID, KONAMI_VRC3 = MakeId< 73, 128, 0, 8, 0, CRM_8, NMT_X, 0 >::ID,
KONAMI_VRC4_0 = MakeId< 21, 256, 256, 0, 0, CRM_0, NMT_V, 0 >::ID, KONAMI_VRC4_0 = MakeId< 21, 256, 256, 0, 0, CRM_0, NMT_V, 0 >::ID,
KONAMI_VRC4_1 = MakeId< 21, 256, 256, 2, 0, CRM_0, NMT_V, 0 >::ID, KONAMI_VRC4_1 = MakeId< 21, 256, 256, 2, 0, CRM_0, NMT_V, 0 >::ID,
@ -467,6 +468,7 @@ namespace Nes
NTDEC_ASDER_0 = MakeId< 112, 256, 512, 0, 0, CRM_0, NMT_X, 0 >::ID, NTDEC_ASDER_0 = MakeId< 112, 256, 512, 0, 0, CRM_0, NMT_X, 0 >::ID,
NTDEC_ASDER_1 = MakeId< 112, 256, 512, 8, 0, CRM_0, NMT_X, 0 >::ID, NTDEC_ASDER_1 = MakeId< 112, 256, 512, 8, 0, CRM_0, NMT_X, 0 >::ID,
NTDEC_FIGHTINGHERO = MakeId< 193, 128, 256, 0, 0, CRM_0, NMT_X, 0 >::ID, NTDEC_FIGHTINGHERO = MakeId< 193, 128, 256, 0, 0, CRM_0, NMT_X, 0 >::ID,
NTDEC_SUPERGUN = MakeId< 81, 64, 32, 0, 0, CRM_0, NMT_X, 0 >::ID,
// Nanjing // Nanjing
NANJING_STD = MakeId< 163, 2048, 0, 8, 0, CRM_8, NMT_X, 0 >::ID, NANJING_STD = MakeId< 163, 2048, 0, 8, 0, CRM_8, NMT_X, 0 >::ID,
// Nihon Bussan // Nihon Bussan
@ -544,6 +546,7 @@ namespace Nes
UNL_A9746 = MakeId< 219, 128, 256, 0, 0, CRM_0, NMT_X, 0 >::ID, UNL_A9746 = MakeId< 219, 128, 256, 0, 0, CRM_0, NMT_X, 0 >::ID,
UNL_CC21 = MakeId< 27, 32, 8, 0, 0, CRM_0, NMT_Z, 0 >::ID, UNL_CC21 = MakeId< 27, 32, 8, 0, 0, CRM_0, NMT_Z, 0 >::ID,
UNL_EDU2000 = MakeId< 329, 1024, 0, 0, 32, CRM_8, NMT_Z, 0 >::ID, UNL_EDU2000 = MakeId< 329, 1024, 0, 0, 32, CRM_8, NMT_Z, 0 >::ID,
UNL_FAM250SCHI24 = MakeId< 354, 4096, 0, 0, 0, CRM_8, NMT_V, 0 >::ID,
UNL_FS304 = MakeId< 162, 2048, 0, 8, 0, CRM_8, NMT_X, 0 >::ID, UNL_FS304 = MakeId< 162, 2048, 0, 8, 0, CRM_8, NMT_X, 0 >::ID,
UNL_KINGOFFIGHTERS96 = MakeId< 187, 512, 512, 0, 0, CRM_0, NMT_X, 0 >::ID, UNL_KINGOFFIGHTERS96 = MakeId< 187, 512, 512, 0, 0, CRM_0, NMT_X, 0 >::ID,
UNL_KINGOFFIGHTERS97 = MakeId< 263, 256, 256, 0, 0, CRM_0, NMT_X, 0 >::ID, UNL_KINGOFFIGHTERS97 = MakeId< 263, 256, 256, 0, 0, CRM_0, NMT_X, 0 >::ID,

View File

@ -0,0 +1,80 @@
////////////////////////////////////////////////////////////////////////////////////////
//
// Nestopia - NES/Famicom emulator written in C++
//
// Copyright (C) 2003-2008 Martin Freij
// Copyright (C) 2023 Rupert Carmichael
//
// This file is part of Nestopia.
//
// Nestopia is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// Nestopia is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Nestopia; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////////////
#include "NstBoard.hpp"
#include "NstBoardBmc120in1.hpp"
namespace Nes
{
namespace Core
{
namespace Boards
{
namespace Bmc
{
#ifdef NST_MSVC_OPTIMIZE
#pragma optimize("s", on)
#endif
void B120in1::SubReset(bool)
{
Map( 0x8000U, 0xFFFFU, &B120in1::Poke_8000 );
NES_DO_POKE(8000,0x8000,0x00);
}
#ifdef NST_MSVC_OPTIMIZE
#pragma optimize("", on)
#endif
NES_POKE_A(B120in1,8000)
{
const uint bank = (address >> 4 & 0x10) | (address >> 3 & 0x0F);
if (address & 0x1)
{
prg.SwapBank<SIZE_32K,0x0000>( bank );
}
else
{
const uint offset = (bank << 1) | (address >> 2 & 0x1);
prg.SwapBanks<SIZE_16K,0x0000>( offset, offset );
}
if (!(address & 0x80))
{
prg.SwapBank<SIZE_16K,0x4000>( ((address & 0x200) ? 0x7 : 0x0) | (bank << 1 & 0x38) );
chr.Source().SetSecurity(true, true);
}
else
{
chr.Source().SetSecurity(true, false);
}
ppu.SetMirroring( (address & 0x2) ? Ppu::NMT_H : Ppu::NMT_V );
}
}
}
}
}

View File

@ -0,0 +1,59 @@
////////////////////////////////////////////////////////////////////////////////////////
//
// Nestopia - NES/Famicom emulator written in C++
//
// Copyright (C) 2003-2008 Martin Freij
// Copyright (C) 2023 Rupert Carmichael
//
// This file is part of Nestopia.
//
// Nestopia is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// Nestopia is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Nestopia; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////////////
#ifndef NST_BOARD_BMC_120IN1_H
#define NST_BOARD_BMC_120IN1_H
#ifdef NST_PRAGMA_ONCE
#pragma once
#endif
namespace Nes
{
namespace Core
{
namespace Boards
{
namespace Bmc
{
class B120in1 : public Board
{
public:
explicit B120in1(const Context& c)
: Board(c) {}
private:
void SubReset(bool);
NES_DECL_POKE( 8000 );
};
}
}
}
}
#endif

View File

@ -176,6 +176,21 @@ namespace Nes
case 0x3: prg.SwapBank<SIZE_8K,0x0000>( data ); break; case 0x3: prg.SwapBank<SIZE_8K,0x0000>( data ); break;
} }
} }
void SuperGun::SubReset(const bool hard)
{
Map( 0x8000U, 0xFFFFU, &SuperGun::Poke_8000 );
if (hard)
prg.SwapBank<SIZE_16K,0x0000>(0);
}
NES_POKE_AD(SuperGun,8000)
{
ppu.Update();
prg.SwapBank<SIZE_16K,0x0000>((address >> 2) & 0xFF);
chr.SwapBank<SIZE_8K,0x0000>(address & 0xFF);
}
} }
} }
} }

View File

@ -77,6 +77,20 @@ namespace Nes
NES_DECL_POKE( 6000 ); NES_DECL_POKE( 6000 );
}; };
class SuperGun : public Board
{
public:
explicit SuperGun(const Context& c)
: Board(c) {}
private:
void SubReset(bool);
NES_DECL_POKE( 8000 );
};
} }
} }
} }

View File

@ -50,7 +50,8 @@ namespace Nes
chr.SwapBank<SIZE_1K>( 0x1800, (chrHigh[6] << 8) | chrLow[6] ); chr.SwapBank<SIZE_1K>( 0x1800, (chrHigh[6] << 8) | chrLow[6] );
chr.SwapBank<SIZE_1K>( 0x1C00, (chrHigh[7] << 8) | chrLow[7] ); chr.SwapBank<SIZE_1K>( 0x1C00, (chrHigh[7] << 8) | chrLow[7] );
if (mirrorUsed) { if (mirrorUsed)
{
ppu.SetMirroring( mirror ^ 0x1 ? Ppu::NMT_V : Ppu::NMT_H ); ppu.SetMirroring( mirror ^ 0x1 ? Ppu::NMT_V : Ppu::NMT_H );
} }
else else
@ -66,6 +67,9 @@ namespace Nes
chrLow[i] = chrHigh[i] = 0; chrLow[i] = chrHigh[i] = 0;
} }
mirror = 0;
mirrorUsed = 0;
Map( 0xC000U, 0xC00FU, &Daou306::Poke_C000 ); Map( 0xC000U, 0xC00FU, &Daou306::Poke_C000 );
Map( 0xC010U, PRG_SWAP_16K_0 ); Map( 0xC010U, PRG_SWAP_16K_0 );
Map( 0xC014U, &Daou306::Poke_C014 ); Map( 0xC014U, &Daou306::Poke_C014 );

View File

@ -52,9 +52,9 @@ namespace Nes
NES_POKE_AD(Policeman,8400) NES_POKE_AD(Policeman,8400)
{ {
ppu.Update(); ppu.Update();
data = GetBusData(address,data); //data = GetBusData(address,data); // Unnecessary
prg.SwapBank<SIZE_32K,0x0000>( data >> 4 ); prg.SwapBank<SIZE_32K,0x0000>( data >> 4 );
chr.SwapBank<SIZE_8K,0x0000>( data ); chr.SwapBank<SIZE_8K,0x0000>( data & 0x0F );
} }
} }
} }

View File

@ -0,0 +1,121 @@
////////////////////////////////////////////////////////////////////////////////////////
//
// Nestopia - NES/Famicom emulator written in C++
//
// Copyright (C) 2003-2008 Martin Freij
// Copyright (C) 2020-2024 Rupert Carmichael
//
// This file is part of Nestopia.
//
// Nestopia is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// Nestopia is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Nestopia; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////////////
// Reference: https://github.com/TASEmulators/fceux/blob/master/src/boards/354.cpp
#include "NstBoard.hpp"
#include "NstBoardUnlFam250Schi24.hpp"
namespace Nes
{
namespace Core
{
namespace Boards
{
namespace Unlicensed
{
#ifdef NST_MSVC_OPTIMIZE
#pragma optimize("s", on)
#endif
void Fam250Schi24::SubReset(bool)
{
bankreg = 0;
Map( 0x6000U, 0x7FFFU, &Fam250Schi24::Peek_6000 );
Map( submapper == 1 ? 0xE000U : 0xF000U, 0xFFFFU, &Fam250Schi24::Poke_F000 );
prg.SwapBank<SIZE_32K,0x0000>(0);
}
void Fam250Schi24::SubLoad(State::Loader& state,const dword baseChunk)
{
NST_VERIFY( (baseChunk == AsciiId<'F','S','C'>::V) );
if (baseChunk == AsciiId<'F','S','C'>::V)
{
while (const dword chunk = state.Begin())
{
if (chunk == AsciiId<'R','E','G'>::V)
bankreg = state.Read8();
state.End();
}
}
}
void Fam250Schi24::SubSave(State::Saver& state) const
{
state.Begin( AsciiId<'F','S','C'>::V ).Begin( AsciiId<'R','E','G'>::V ).Write8( bankreg ).End().End();
}
#ifdef NST_MSVC_OPTIMIZE
#pragma optimize("", on)
#endif
NES_PEEK_A(Fam250Schi24,6000)
{
return *(prg.Source().Mem(bankreg * SIZE_8K) + (address & 0x1FFF));
}
NES_POKE_AD(Fam250Schi24,F000)
{
const uint bank = data & 0x3F | address << 2 & 0x40 | address >> 5 & 0x80;
ppu.SetMirroring( (data & 0x40) ? Ppu::NMT_H : Ppu::NMT_V );
chr.Source().WriteEnable( !(address & 0x08) );
switch (address & 0x07)
{
case 0: case 4:
prg.SwapBank<SIZE_32K,0x0000>(bank >> 1);
break;
case 1:
prg.SwapBank<SIZE_16K,0x0000>(bank);
prg.SwapBank<SIZE_16K,0x4000>(bank | 0x07);
break;
case 2: case 6:
prg.SwapBank<SIZE_8K,0x0000>(bank << 1 | data >> 7);
prg.SwapBank<SIZE_8K,0x2000>(bank << 1 | data >> 7);
prg.SwapBank<SIZE_8K,0x4000>(bank << 1 | data >> 7);
prg.SwapBank<SIZE_8K,0x6000>(bank << 1 | data >> 7);
break;
case 3: case 7:
prg.SwapBank<SIZE_16K,0x0000>(bank);
prg.SwapBank<SIZE_16K,0x4000>(bank);
break;
case 5:
bankreg = bank << 1 | data >> 7;
prg.SwapBank<SIZE_32K,0x0000>(bank >> 1 | 0x03);
break;
}
}
}
}
}
}

View File

@ -0,0 +1,65 @@
////////////////////////////////////////////////////////////////////////////////////////
//
// Nestopia - NES/Famicom emulator written in C++
//
// Copyright (C) 2003-2008 Martin Freij
// Copyright (C) 2020-2024 Rupert Carmichael
//
// This file is part of Nestopia.
//
// Nestopia is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// Nestopia is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Nestopia; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////////////
#ifndef NST_BOARD_UNL_FAM250SCHI24_H
#define NST_BOARD_UNL_FAM250SCHI24_H
#ifdef NST_PRAGMA_ONCE
#pragma once
#endif
namespace Nes
{
namespace Core
{
namespace Boards
{
namespace Unlicensed
{
class Fam250Schi24 : public Board
{
public:
explicit Fam250Schi24(const Context& c)
: Board(c) { submapper = c.chips.Has(L"SCHI-24") ? 1 : 0; }
private:
void SubReset(bool);
void SubLoad(State::Loader&,dword);
void SubSave(State::Saver&) const;
NES_DECL_PEEK( 6000 );
NES_DECL_POKE( F000 );
uint bankreg;
uint submapper;
};
}
}
}
}
#endif