From 49e50e6bc5ea6fa5b74331c15e9662439c2d2c41 Mon Sep 17 00:00:00 2001 From: Rupert Carmichael <5050061-carmiker@users.noreply.gitlab.com> Date: Wed, 20 Nov 2024 21:53:38 -0500 Subject: [PATCH] core: Apply latest upstream changes This adds support for the NES 2.0 Default Expansion Device field, and better support for MMC3 and VRC2/4 hacks --- source/core/NstCartridge.hpp | 1 + source/core/NstCartridgeInes.cpp | 145 ++++++++++++++++++++++++++++ source/core/api/NstApiCartridge.cpp | 1 + source/core/api/NstApiCartridge.hpp | 5 + source/core/board/NstBoard.cpp | 2 +- source/core/board/NstBoard.hpp | 4 +- 6 files changed, 155 insertions(+), 3 deletions(-) diff --git a/source/core/NstCartridge.hpp b/source/core/NstCartridge.hpp index 60577af..4143689 100644 --- a/source/core/NstCartridge.hpp +++ b/source/core/NstCartridge.hpp @@ -83,6 +83,7 @@ namespace Nes bool battery; bool wramAuto; Ram trainer; + uchar inputDevice; }; class VsSystem; diff --git a/source/core/NstCartridgeInes.cpp b/source/core/NstCartridgeInes.cpp index b07ff0d..2239eb2 100644 --- a/source/core/NstCartridgeInes.cpp +++ b/source/core/NstCartridgeInes.cpp @@ -513,6 +513,150 @@ namespace Nes break; } + switch (setup.inputType) + { + // Currently unsupported by the NES 2.0 spec or for other reasons: + // POWERGLOVE, MOUSE, SUBORKEYBOARD, HORITRACK, CRAZYCLIMBER + case 0x01: // Standard Controllers + { + profile.game.controllers[0] = Api::Input::PAD1; + profile.game.controllers[1] = Api::Input::PAD2; + break; + } + case 0x02: // NES Four Score/Satellite + { + profile.game.controllers[0] = Api::Input::PAD1; + profile.game.controllers[1] = Api::Input::PAD2; + profile.game.controllers[2] = Api::Input::PAD3; + profile.game.controllers[3] = Api::Input::PAD4; + break; + } + case 0x08: // Zapper + { + profile.game.controllers[1] = Api::Input::ZAPPER; + break; + } + case 0x0A: // Bandai Hyper Shot + { + profile.game.adapter = Api::Input::ADAPTER_FAMICOM; + profile.game.controllers[4] = Api::Input::BANDAIHYPERSHOT; + break; + } + case 0x0B: case 0x0C: // Power Pad (Side A, Side B) + { + profile.game.controllers[1] = Api::Input::POWERPAD; + break; + } + case 0x0D: case 0x0E: // Family Trainer (Side A, Side B) + { + profile.game.adapter = Api::Input::ADAPTER_FAMICOM; + profile.game.controllers[4] = Api::Input::FAMILYTRAINER; + break; + } + case 0x0F: // Arkanoid Paddle (NES) + { + profile.game.controllers[1] = Api::Input::PADDLE; + break; + } + case 0x10: // Arkanoid Paddle (Famicom) + { + profile.game.adapter = Api::Input::ADAPTER_FAMICOM; + profile.game.controllers[4] = Api::Input::PADDLE; + break; + } + case 0x12: // Konami Hypershot + { + profile.game.adapter = Api::Input::ADAPTER_FAMICOM; + profile.game.controllers[0] = Api::Input::UNCONNECTED; + profile.game.controllers[1] = Api::Input::UNCONNECTED; + profile.game.controllers[4] = Api::Input::KONAMIHYPERSHOT; + break; + } + case 0x13: // Coconuts Pachinko Controller + { + profile.game.adapter = Api::Input::ADAPTER_FAMICOM; + profile.game.controllers[4] = Api::Input::PACHINKO; + break; + } + case 0x14: // Exciting Boxing + { + profile.game.adapter = Api::Input::ADAPTER_FAMICOM; + profile.game.controllers[4] = Api::Input::EXCITINGBOXING; + break; + } + case 0x15: // Jissen Mahjong Controller + { + profile.game.adapter = Api::Input::ADAPTER_FAMICOM; + profile.game.controllers[0] = Api::Input::UNCONNECTED; + profile.game.controllers[1] = Api::Input::UNCONNECTED; + profile.game.controllers[4] = Api::Input::MAHJONG; + break; + } + case 0x16: // Party Tap + { + profile.game.adapter = Api::Input::ADAPTER_FAMICOM; + profile.game.controllers[1] = Api::Input::UNCONNECTED; + profile.game.controllers[4] = Api::Input::PARTYTAP; + break; + } + case 0x17: // Oeka Kids Tablet + { + profile.game.adapter = Api::Input::ADAPTER_FAMICOM; + profile.game.controllers[0] = Api::Input::UNCONNECTED; + profile.game.controllers[1] = Api::Input::UNCONNECTED; + profile.game.controllers[4] = Api::Input::OEKAKIDSTABLET; + break; + } + case 0x18: // Sunsoft Barcode Battler + { + profile.game.adapter = Api::Input::ADAPTER_FAMICOM; + profile.game.controllers[4] = Api::Input::BARCODEWORLD; + break; + } + case 0x1A: // Pokkun Moguraa (Whack-a-Mole Mat and Mallet) + { + profile.game.adapter = Api::Input::ADAPTER_FAMICOM; + profile.game.controllers[1] = Api::Input::UNCONNECTED; + profile.game.controllers[4] = Api::Input::POKKUNMOGURAA; + break; + } + case 0x1B: // Top Rider + { + profile.game.adapter = Api::Input::ADAPTER_FAMICOM; + profile.game.controllers[0] = Api::Input::UNCONNECTED; + profile.game.controllers[1] = Api::Input::UNCONNECTED; + profile.game.controllers[4] = Api::Input::TOPRIDER; + break; + } + case 0x1E: // Doremikko Keyboard + { + profile.game.adapter = Api::Input::ADAPTER_FAMICOM; + profile.game.controllers[4] = Api::Input::DOREMIKKOKEYBOARD; + break; + } + case 0x1F: // R.O.B. Gyro Set + { + profile.game.controllers[1] = Api::Input::ROB; + break; + } + case 0x21: // Turbo File + { + profile.game.adapter = Api::Input::ADAPTER_FAMICOM; + profile.game.controllers[4] = Api::Input::TURBOFILE; + break; + } + case 0x23: // Family BASIC Keyboard + { + profile.game.adapter = Api::Input::ADAPTER_FAMICOM; + profile.game.controllers[4] = Api::Input::FAMILYKEYBOARD; + break; + } + default: + { + break; + } + } + return trainerSetup; } @@ -752,6 +896,7 @@ namespace Nes setup.prgNvRam = ((header[10]) >> 4) - 1U < 14 ? 64UL << (header[10] >> 4) : 0; setup.chrRam = ((header[11]) & 0xFU) - 1U < 14 ? 64UL << (header[11] & 0xFU) : 0; setup.chrNvRam = ((header[11]) >> 4) - 1U < 14 ? 64UL << (header[11] >> 4) : 0; + setup.inputType = header[15]; } else { diff --git a/source/core/api/NstApiCartridge.cpp b/source/core/api/NstApiCartridge.cpp index c9a018d..ea9720e 100644 --- a/source/core/api/NstApiCartridge.cpp +++ b/source/core/api/NstApiCartridge.cpp @@ -347,6 +347,7 @@ namespace Nes security = 0; version = 0; trainer = false; + inputType = 0; } Result Cartridge::NesHeader::Import(const void* const data,const ulong length) throw() diff --git a/source/core/api/NstApiCartridge.hpp b/source/core/api/NstApiCartridge.hpp index 9ae71f5..5baca6b 100644 --- a/source/core/api/NstApiCartridge.hpp +++ b/source/core/api/NstApiCartridge.hpp @@ -1309,6 +1309,11 @@ namespace Nes * Trainer. */ bool trainer; + + /** + * Input Device Type. + */ + uchar inputType; }; /** diff --git a/source/core/board/NstBoard.cpp b/source/core/board/NstBoard.cpp index 2ee25e9..301631c 100644 --- a/source/core/board/NstBoard.cpp +++ b/source/core/board/NstBoard.cpp @@ -1833,7 +1833,7 @@ namespace Nes case 23: - if (submapper == 1) // VRC4f - Unknown, but plausibly World Hero? + if (submapper == 1 || chr < SIZE_128K) // VRC4f - Axelay, plausibly World Hero? { Chips::Type& chip = chips.Add(L"Konami VRC IV"); chip.Pin(3) = L"PRG A1"; diff --git a/source/core/board/NstBoard.hpp b/source/core/board/NstBoard.hpp index 755b558..07000b5 100644 --- a/source/core/board/NstBoard.hpp +++ b/source/core/board/NstBoard.hpp @@ -566,8 +566,8 @@ namespace Nes UNL_UXROM_M5 = MakeId< 180, 4096, 8, 8, 0, CRM_0, NMT_X, 0 >::ID, UNL_TRXROM = MakeId< 4, 512, 256, 8, 0, CRM_0, NMT_4, 0 >::ID, UNL_XZY = MakeId< 176, 1024, 256, 8, 0, CRM_0, NMT_X, 0 >::ID, - UNL_MMC3BIGCHRRAM = MakeId< 4, 512, 0, 0, 0, CRM_32, NMT_X, 0 >::ID, - UNL_MMC3BIGPRGROM = MakeId< 4, 1024, 0, 8, 0, CRM_8, NMT_X, 0 >::ID, + UNL_MMC3BIGCHRRAM = MakeId< 4, 512, 0, 8, 0, CRM_32, NMT_X, 0 >::ID, + UNL_MMC3BIGPRGROM = MakeId< 4, 1024, 0, 8, 0, CRM_32, NMT_X, 0 >::ID, // Waixing WAIXING_PS2_0 = MakeId< 15, 1024, 0, 0, 0, CRM_8, NMT_V, 0 >::ID, WAIXING_PS2_1 = MakeId< 15, 1024, 0, 8, 0, CRM_8, NMT_V, 0 >::ID,