Update ImGui
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
#include <Core.hpp>
|
||||
#include <ParallelRDPWrapper.hpp>
|
||||
#include <Window.hpp>
|
||||
#include <algorithm>
|
||||
#include <Scheduler.hpp>
|
||||
|
||||
namespace n64 {
|
||||
@@ -18,18 +17,17 @@ void Core::Stop() {
|
||||
romLoaded = false;
|
||||
}
|
||||
|
||||
CartInfo Core::LoadROM(const std::string& rom_) {
|
||||
void Core::LoadROM(const std::string& rom_) {
|
||||
rom = rom_;
|
||||
cpu->Reset();
|
||||
cpu->mem.Reset();
|
||||
pause = false;
|
||||
romLoaded = true;
|
||||
|
||||
CartInfo cartInfo = cpu->mem.LoadROM(rom);
|
||||
isPAL = cartInfo.isPAL;
|
||||
cpu->mem.mmio.si.pif.ExecutePIF(cpu->mem, cpu->regs, cartInfo);
|
||||
|
||||
return cartInfo;
|
||||
cpu->mem.LoadROM(rom);
|
||||
GameDB::match(cpu->mem);
|
||||
isPAL = cpu->mem.IsROMPAL();
|
||||
cpu->mem.mmio.si.pif.ExecutePIF(cpu->mem, cpu->regs);
|
||||
}
|
||||
|
||||
void Core::Run(Window& window, float volumeL, float volumeR) {
|
||||
|
||||
@@ -19,7 +19,7 @@ struct Core {
|
||||
~Core() { Stop(); }
|
||||
Core();
|
||||
void Stop();
|
||||
CartInfo LoadROM(const std::string&);
|
||||
void LoadROM(const std::string&);
|
||||
void Run(Window&, float volumeL, float volumeR);
|
||||
void TogglePause() { pause = !pause; }
|
||||
VI& GetVI() { return cpu->mem.mmio.vi; }
|
||||
|
||||
36
src/backend/GameDB.cpp
Normal file
36
src/backend/GameDB.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <GameDB.hpp>
|
||||
#include <Mem.hpp>
|
||||
|
||||
namespace n64 {
|
||||
void GameDB::match(Mem& mem) {
|
||||
ROM& rom = mem.rom;
|
||||
for (const auto & i : gamedb) {
|
||||
bool matches_code = i.code == rom.code;
|
||||
bool matches_region = false;
|
||||
|
||||
for (int j = 0; j < i.regions.size() && !matches_region; j++) {
|
||||
if (i.regions[j] == rom.header.countryCode[0]) {
|
||||
matches_region = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (matches_code) {
|
||||
if (matches_region) {
|
||||
mem.saveType = i.saveType;
|
||||
mem.rom.gameNameDB = i.name;
|
||||
Util::debug("Loaded {}\n", i.name);
|
||||
return;
|
||||
} else {
|
||||
Util::warn("Matched code for %s, but not region! Game supposedly exists in regions [{}] but this image has region {}\n",
|
||||
i.name, i.regions, rom.header.countryCode[0]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Util::debug("Did not match any Game DB entries. Code: {} Region: {}\n", mem.rom.code, mem.rom.header.countryCode[0]);
|
||||
|
||||
mem.rom.gameNameDB = "";
|
||||
mem.saveType = SAVE_NONE;
|
||||
}
|
||||
}
|
||||
210
src/backend/GameDB.hpp
Normal file
210
src/backend/GameDB.hpp
Normal file
@@ -0,0 +1,210 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
namespace n64 {
|
||||
enum SaveType {
|
||||
SAVE_NONE,
|
||||
SAVE_EEPROM_4k,
|
||||
SAVE_EEPROM_16k,
|
||||
SAVE_FLASH_1m,
|
||||
SAVE_SRAM_256k
|
||||
};
|
||||
|
||||
struct Mem;
|
||||
struct GameDBEntry {
|
||||
std::string code;
|
||||
std::string regions;
|
||||
SaveType saveType;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
namespace GameDB {
|
||||
void match(Mem &mem);
|
||||
}
|
||||
|
||||
static const GameDBEntry gamedb[] = {
|
||||
{"NNM", "E", SAVE_NONE, "Namco Museum 64"},
|
||||
{"NDM", "E", SAVE_NONE, "Doom 64"},
|
||||
{"NGN", "E", SAVE_EEPROM_4k, "GoldenEye 007"},
|
||||
// Copied from CEN64 with small edits: https://github.com/n64dev/cen64/blob/master/device/cart_db.c
|
||||
{"CFZ", "EJ", SAVE_SRAM_256k, "F-Zero X (NTSC)"},
|
||||
{"CLB", "EJ", SAVE_EEPROM_4k, "Mario Party (NTSC)"},
|
||||
{"CP2", "J", SAVE_FLASH_1m, "Pokémon Stadium 2 (Japan)"},
|
||||
{"CPS", "J", SAVE_SRAM_256k, "Pokémon Stadium (Japan)"},
|
||||
{"CZL", "EJ", SAVE_SRAM_256k, "Legend of Zelda: Ocarina of Time (NTSC)"},
|
||||
{"N3D", "J", SAVE_EEPROM_16k, "Doraemon 3: Nobita no Machi SOS!"},
|
||||
{"N3H", "J", SAVE_SRAM_256k, "Ganbare! Nippon! Olympics 2000"},
|
||||
{"NA2", "J", SAVE_SRAM_256k, "Virtual Pro Wrestling 2"},
|
||||
{"NAB", "JP", SAVE_EEPROM_4k, "Air Boarder 64"},
|
||||
{"NAD", "E", SAVE_EEPROM_4k, "Worms Armageddon (USA)"},
|
||||
{"NAF", "J", SAVE_FLASH_1m, "Doubutsu no Mori"},
|
||||
{"NAG", "EJP", SAVE_EEPROM_4k, "AeroGauge"},
|
||||
{"NAL", "EJPU", SAVE_SRAM_256k, "Super Smash Bros"},
|
||||
{"NB5", "J", SAVE_SRAM_256k, "Biohazard 2"},
|
||||
{"NB6", "J", SAVE_EEPROM_4k, "Super B-Daman: Battle Phoenix 64"},
|
||||
{"NB7", "EJPU", SAVE_EEPROM_16k, "Banjo-Tooie"},
|
||||
{"NBC", "EJP", SAVE_EEPROM_4k, "Blast Corps"},
|
||||
{"NBD", "EJP", SAVE_EEPROM_4k, "Bomberman Hero"},
|
||||
{"NBH", "EP", SAVE_EEPROM_4k, "Body Harvest"},
|
||||
{"NBK", "EJP", SAVE_EEPROM_4k, "Banjo-Kazooie"},
|
||||
{"NBM", "EJP", SAVE_EEPROM_4k, "Bomberman 64"},
|
||||
{"NBN", "J", SAVE_EEPROM_4k, "Bakuretsu Muteki Bangaioh"},
|
||||
{"NBV", "EJ", SAVE_EEPROM_4k, "Bomberman 64: The Second Attack!"},
|
||||
{"NCC", "DEP", SAVE_FLASH_1m, "Command & Conquer"},
|
||||
{"NCG", "J", SAVE_EEPROM_4k, "Choro Q 64 2: Hacha-Mecha Grand Prix Race"},
|
||||
{"NCH", "EP", SAVE_EEPROM_4k, "Chopper Attack"},
|
||||
{"NCK", "E", SAVE_FLASH_1m, "NBA Courtside 2"},
|
||||
{"NCR", "EJP", SAVE_EEPROM_4k, "Penny Racers"},
|
||||
{"NCT", "EJP", SAVE_EEPROM_4k, "Chameleon Twist"},
|
||||
{"NCU", "EP", SAVE_EEPROM_4k, "Cruis'n USA"},
|
||||
{"NCW", "EP", SAVE_EEPROM_16k, "Cruis'n World"},
|
||||
{"NCX", "J", SAVE_EEPROM_4k, "Custom Robo"},
|
||||
{"NCZ", "J", SAVE_EEPROM_16k, "Custom Robo V2"},
|
||||
{"ND2", "J", SAVE_EEPROM_16k, "Doraemon 2: Nobita to Hikari no Shinden"},
|
||||
{"ND3", "J", SAVE_EEPROM_16k, "Akumajou Dracula Mokushiroku"},
|
||||
{"ND4", "J", SAVE_EEPROM_16k, "Akumajou Dracula Mokushiroku Gaiden: Legend of Cornell"},
|
||||
{"ND6", "J", SAVE_EEPROM_16k, "Densha de Go! 64"},
|
||||
{"NDA", "J", SAVE_FLASH_1m, "Derby Stallion 64"},
|
||||
{"NDK", "J", SAVE_EEPROM_4k, "Space Dynamites"},
|
||||
{"NDO", "EJP", SAVE_EEPROM_16k, "Donkey Kong 64"},
|
||||
{"NDP", "E", SAVE_FLASH_1m, "Dinosaur Planet"},
|
||||
{"NDR", "J", SAVE_EEPROM_4k, "Doraemon: Nobita to 3tsu no Seireiseki"},
|
||||
{"NDU", "EP", SAVE_EEPROM_4k, "Duck Dodgers"},
|
||||
{"NDY", "EJP", SAVE_EEPROM_4k, "Diddy Kong Racing"},
|
||||
{"NEA", "EP", SAVE_EEPROM_4k, "PGA European Tour"},
|
||||
{"NEP", "EJP", SAVE_EEPROM_16k, "Star Wars Episode I: Racer"},
|
||||
{"NER", "E", SAVE_EEPROM_4k, "AeroFighters Assault (USA)"},
|
||||
{"NEV", "J", SAVE_EEPROM_16k, "Neon Genesis Evangelion"},
|
||||
{"NF2", "P", SAVE_EEPROM_4k, "F-1 World Grand Prix II"},
|
||||
{"NFG", "E", SAVE_EEPROM_4k, "Fighter Destiny 2"},
|
||||
{"NFH", "EP", SAVE_EEPROM_4k, "Bass Hunter 64"},
|
||||
{"NFU", "EP", SAVE_EEPROM_16k, "Conker's Bad Fur Day"},
|
||||
{"NFW", "DEFJP", SAVE_EEPROM_4k, "F-1 World Grand Prix"},
|
||||
{"NFX", "EJPU", SAVE_EEPROM_4k, "Star Fox 64"},
|
||||
{"NFY", "J", SAVE_EEPROM_4k, "Kakutou Denshou: F-Cup Maniax"},
|
||||
{"NFZ", "P", SAVE_SRAM_256k, "F-Zero X (PAL)"},
|
||||
{"NG6", "J", SAVE_SRAM_256k, "Ganbare Goemon: Dero Dero Douchuu Obake Tenkomori"},
|
||||
{"NGC", "EP", SAVE_EEPROM_16k, "GT 64: Championship Edition"},
|
||||
{"NGE", "EJP", SAVE_EEPROM_4k, "GoldenEye 007"},
|
||||
{"NGL", "J", SAVE_EEPROM_4k, "Getter Love!!"},
|
||||
{"NGP", "J", SAVE_SRAM_256k, "Goemon: Mononoke Sugoroku"},
|
||||
{"NGT", "J", SAVE_EEPROM_16k, "City-Tour GP: Zen-Nihon GT Senshuken"},
|
||||
{"NGU", "J", SAVE_EEPROM_4k, "Tsumi to Batsu: Hoshi no Keishousha"},
|
||||
{"NGV", "EP", SAVE_EEPROM_4k, "Glover"},
|
||||
{"NHA", "J", SAVE_EEPROM_4k, "Bomber Man 64 (Japan)"},
|
||||
{"NHF", "J", SAVE_EEPROM_4k, "64 Hanafuda: Tenshi no Yakusoku"},
|
||||
{"NHP", "J", SAVE_EEPROM_4k, "Heiwa Pachinko World 64"},
|
||||
{"NHY", "J", SAVE_SRAM_256k, "Hybrid Heaven (Japan)"},
|
||||
{"NIB", "J", SAVE_SRAM_256k, "Itoi Shigesato no Bass Tsuri No. 1 Kettei Ban!"},
|
||||
{"NIC", "E", SAVE_EEPROM_4k, "Indy Racing 2000"},
|
||||
{"NIJ", "EP", SAVE_EEPROM_4k, "Indiana Jones and the Infernal Machine"},
|
||||
{"NIM", "J", SAVE_EEPROM_16k, "Ide Yosuke no Mahjong Juku"},
|
||||
{"NIR", "J", SAVE_EEPROM_4k, "Utchan Nanchan no Hono no Challenger: Denryuu Ira Ira Bou"},
|
||||
{"NJ5", "J", SAVE_SRAM_256k, "Jikkyou Powerful Pro Yakyuu 5"},
|
||||
{"NJD", "E", SAVE_FLASH_1m, "Jet Force Gemini (Kiosk Demo)"},
|
||||
{"NJF", "EJP", SAVE_FLASH_1m, "Jet Force Gemini"},
|
||||
{"NJG", "J", SAVE_SRAM_256k, "Jinsei Game 64"},
|
||||
{"NJM", "EP", SAVE_EEPROM_4k, "Earthworm Jim 3D"},
|
||||
{"NK2", "EJP", SAVE_EEPROM_4k, "Snowboard Kids 2"},
|
||||
{"NK4", "EJP", SAVE_EEPROM_16k, "Kirby 64: The Crystal Shards"},
|
||||
{"NKA", "DEFJP", SAVE_EEPROM_4k, "Fighters Destiny"},
|
||||
{"NKG", "EP", SAVE_SRAM_256k, "MLB featuring Ken Griffey Jr."},
|
||||
{"NKI", "EP", SAVE_EEPROM_4k, "Killer Instinct Gold"},
|
||||
{"NKJ", "E", SAVE_FLASH_1m, "Ken Griffey Jr.'s Slugfest"},
|
||||
{"NKT", "EJP", SAVE_EEPROM_4k, "Mario Kart 64"},
|
||||
{"NLB", "P", SAVE_EEPROM_4k, "Mario Party (PAL)"},
|
||||
{"NLL", "J", SAVE_EEPROM_4k, "Last Legion UX"},
|
||||
{"NLR", "EJP", SAVE_EEPROM_4k, "Lode Runner 3D"},
|
||||
{"NM6", "E", SAVE_FLASH_1m, "Mega Man 64"},
|
||||
{"NM8", "EJP", SAVE_EEPROM_16k, "Mario Tennis"},
|
||||
{"NMF", "EJP", SAVE_SRAM_256k, "Mario Golf"},
|
||||
{"NMG", "DEP", SAVE_EEPROM_4k, "Monaco Grand Prix"},
|
||||
{"NMI", "DEFIPS", SAVE_EEPROM_4k, "Mission: Impossible"},
|
||||
{"NML", "EJP", SAVE_EEPROM_4k, "Mickey's Speedway USA"},
|
||||
{"NMO", "E", SAVE_EEPROM_4k, "Monopoly"},
|
||||
{"NMQ", "EJP", SAVE_FLASH_1m, "Paper Mario"},
|
||||
{"NMR", "EJP", SAVE_EEPROM_4k, "Multi Racing Championship"},
|
||||
{"NMS", "J", SAVE_EEPROM_4k, "Morita Shougi 64"},
|
||||
{"NMU", "E", SAVE_EEPROM_4k, "Big Mountain 2000"},
|
||||
{"NMV", "EJP", SAVE_EEPROM_16k, "Mario Party 3"},
|
||||
{"NMW", "EJP", SAVE_EEPROM_4k, "Mario Party 2"},
|
||||
{"NMX", "EJP", SAVE_EEPROM_16k, "Excitebike 64"},
|
||||
{"NN6", "E", SAVE_EEPROM_4k, "Dr. Mario 64"},
|
||||
{"NNA", "EP", SAVE_EEPROM_4k, "Star Wars Episode I: Battle for Naboo"},
|
||||
{"NNB", "EP", SAVE_EEPROM_16k, "Kobe Bryant in NBA Courtside"},
|
||||
{"NOB", "EJ", SAVE_SRAM_256k, "Ogre Battle 64: Person of Lordly Caliber"},
|
||||
{"NOS", "J", SAVE_EEPROM_4k, "64 Oozumou"},
|
||||
{"NP2", "J", SAVE_EEPROM_4k, "Chou Kuukan Nighter Pro Yakyuu King 2"},
|
||||
{"NP3", "DEFIJPS", SAVE_FLASH_1m, "Pokémon Stadium 2"},
|
||||
{"NP6", "J", SAVE_SRAM_256k, "Jikkyou Powerful Pro Yakyuu 6"},
|
||||
{"NPA", "J", SAVE_SRAM_256k, "Jikkyou Powerful Pro Yakyuu 2000"},
|
||||
{"NPD", "EJP", SAVE_EEPROM_16k, "Perfect Dark"},
|
||||
{"NPE", "J", SAVE_SRAM_256k, "Jikkyou Powerful Pro Yakyuu Basic Ban 2001"},
|
||||
{"NPF", "DEFIJPSU", SAVE_FLASH_1m, "Pokémon Snap"},
|
||||
{"NPG", "EJ", SAVE_EEPROM_4k, "Hey You, Pikachu!"},
|
||||
{"NPH", "E", SAVE_FLASH_1m, "Pokémon Snap Station (Kiosk Demo)"},
|
||||
{"NPM", "P", SAVE_SRAM_256k, "Premier Manager 64"},
|
||||
{"NPN", "DEFP", SAVE_FLASH_1m, "Pokémon Puzzle League"},
|
||||
{"NPO", "DEFIPS", SAVE_FLASH_1m, "Pokémon Stadium (USA, PAL)"},
|
||||
{"NPP", "J", SAVE_EEPROM_16k, "Parlor! Pro 64: Pachinko Jikki Simulation Game"},
|
||||
{"NPS", "J", SAVE_SRAM_256k, "Jikkyou J.League 1999: Perfect Striker 2"},
|
||||
{"NPT", "J", SAVE_EEPROM_4k, "Puyo Puyon Party"},
|
||||
{"NPW", "EJP", SAVE_EEPROM_4k, "Pilotwings 64"},
|
||||
{"NPY", "J", SAVE_EEPROM_4k, "Puyo Puyo Sun 64"},
|
||||
{"NR7", "J", SAVE_EEPROM_16k, "Robot Poncots 64: 7tsu no Umi no Caramel"},
|
||||
{"NRA", "J", SAVE_EEPROM_4k, "Rally '99"},
|
||||
{"NRC", "EJP", SAVE_EEPROM_4k, "Top Gear Overdrive"},
|
||||
{"NRE", "EP", SAVE_SRAM_256k, "Resident Evil 2"},
|
||||
{"NRH", "J", SAVE_FLASH_1m, "Rockman Dash"},
|
||||
{"NRI", "EP", SAVE_SRAM_256k, "The New Tetris"},
|
||||
{"NRS", "EJP", SAVE_EEPROM_4k, "Star Wars: Rogue Squadron"},
|
||||
{"NRZ", "EP", SAVE_EEPROM_16k, "Ridge Racer 64"},
|
||||
{"NS4", "J", SAVE_SRAM_256k, "Super Robot Taisen 64"},
|
||||
{"NS6", "EJ", SAVE_EEPROM_4k, "Star Soldier: Vanishing Earth"},
|
||||
{"NSA", "JP", SAVE_EEPROM_4k, "AeroFighters Assault (PAL, Japan)"},
|
||||
{"NSC", "EP", SAVE_EEPROM_4k, "Starshot: Space Circus Fever"},
|
||||
{"NSI", "J", SAVE_SRAM_256k, "Fushigi no Dungeon: Fuurai no Shiren 2"},
|
||||
{"NSM", "EJP", SAVE_EEPROM_4k, "Super Mario 64"},
|
||||
{"NSN", "J", SAVE_EEPROM_4k, "Snow Speeder"},
|
||||
{"NSQ", "EP", SAVE_FLASH_1m, "StarCraft 64"},
|
||||
{"NSS", "J", SAVE_EEPROM_4k, "Super Robot Spirits"},
|
||||
{"NSU", "EP", SAVE_EEPROM_4k, "Rocket: Robot on Wheels"},
|
||||
{"NSV", "EP", SAVE_EEPROM_4k, "SpaceStation Silicon Valley"},
|
||||
{"NSW", "EJP", SAVE_EEPROM_4k, "Star Wars: Shadows of the Empire"},
|
||||
{"NT3", "J", SAVE_SRAM_256k, "Toukon Road 2"},
|
||||
{"NT6", "J", SAVE_EEPROM_4k, "Tetris 64"},
|
||||
{"NT9", "EP", SAVE_FLASH_1m, "Tigger's Honey Hunt"},
|
||||
{"NTB", "J", SAVE_EEPROM_4k, "Transformers: Beast Wars Metals 64"},
|
||||
{"NTC", "J", SAVE_EEPROM_4k, "64 Trump Collection"},
|
||||
{"NTE", "AP", SAVE_SRAM_256k, "1080 Snowboarding"},
|
||||
{"NTJ", "EP", SAVE_EEPROM_4k, "Tom and Jerry in Fists of Furry"},
|
||||
{"NTM", "EJP", SAVE_EEPROM_4k, "Mischief Makers"},
|
||||
{"NTN", "EP", SAVE_EEPROM_4k, "All-Star Tennis 99"},
|
||||
{"NTP", "EP", SAVE_EEPROM_4k, "Tetrisphere"},
|
||||
{"NTR", "JP", SAVE_EEPROM_4k, "Top Gear Rally (PAL, Japan)"},
|
||||
{"NTW", "J", SAVE_EEPROM_4k, "64 de Hakken!! Tamagotchi"},
|
||||
{"NTX", "EP", SAVE_EEPROM_4k, "Taz Express"},
|
||||
{"NUB", "J", SAVE_EEPROM_16k, "PD Ultraman Battle Collection 64"},
|
||||
{"NUM", "J", SAVE_SRAM_256k, "Nushi Zuri 64: Shiokaze ni Notte"},
|
||||
{"NUT", "J", SAVE_SRAM_256k, "Nushi Zuri 64"},
|
||||
{"NVB", "J", SAVE_SRAM_256k, "Bass Rush: ECOGEAR PowerWorm Championship"},
|
||||
{"NVL", "EP", SAVE_EEPROM_4k, "V-Rally 99 (USA, PAL)"},
|
||||
{"NVP", "J", SAVE_SRAM_256k, "Virtual Pro Wrestling 64"},
|
||||
{"NVY", "J", SAVE_EEPROM_4k, "V-Rally 99 (Japan)"},
|
||||
{"NW2", "EP", SAVE_SRAM_256k, "WCW/nWo Revenge"},
|
||||
{"NW4", "EP", SAVE_FLASH_1m, "WWF No Mercy"},
|
||||
{"NWC", "J", SAVE_EEPROM_4k, "Wild Choppers"},
|
||||
{"NWL", "EP", SAVE_SRAM_256k, "Waialae Country Club: True Golf Classics"},
|
||||
{"NWQ", "E", SAVE_EEPROM_4k, "Rally Challenge 2000"},
|
||||
{"NWR", "EJP", SAVE_EEPROM_4k, "Wave Race 64"},
|
||||
{"NWT", "J", SAVE_EEPROM_4k, "Wetrix (Japan)"},
|
||||
{"NWU", "P", SAVE_EEPROM_4k, "Worms Armageddon (PAL)"},
|
||||
{"NWX", "EJP", SAVE_SRAM_256k, "WWF WrestleMania 2000"},
|
||||
{"NXO", "E", SAVE_EEPROM_4k, "Cruis'n Exotica"},
|
||||
{"NYK", "J", SAVE_EEPROM_4k, "Yakouchuu II: Satsujin Kouro"},
|
||||
{"NYS", "EJP", SAVE_EEPROM_16k, "Yoshi's Story"},
|
||||
{"NYW", "EJ", SAVE_SRAM_256k, "Harvest Moon 64"},
|
||||
{"NZL", "P", SAVE_SRAM_256k, "Legend of Zelda: Ocarina of Time (PAL)"},
|
||||
{"NZS", "EJP", SAVE_FLASH_1m, "Legend of Zelda: Majora's Mask"},
|
||||
};
|
||||
}
|
||||
@@ -3,66 +3,25 @@
|
||||
#include <MemoryHelpers.hpp>
|
||||
|
||||
namespace Util {
|
||||
enum RomTypes {
|
||||
Z64 = 0x80371240,
|
||||
N64 = 0x40123780,
|
||||
V64 = 0x37804012
|
||||
};
|
||||
|
||||
inline void GetRomCRC(size_t size, u8 *rom, u32 &crc) {
|
||||
RomTypes endianness;
|
||||
memcpy(&endianness, rom, 4);
|
||||
endianness = static_cast<RomTypes>(be32toh(endianness));
|
||||
#define Z64 0x80371240
|
||||
#define N64 0x40123780
|
||||
#define V64 0x37804012
|
||||
|
||||
template <bool toBE = false>
|
||||
inline void SwapN64Rom(size_t size, u8 *rom, u32 endianness) {
|
||||
switch (endianness) {
|
||||
case RomTypes::V64: {
|
||||
case V64:
|
||||
SwapBuffer16(size, rom);
|
||||
crc = crc32(0, rom, size);
|
||||
}
|
||||
if constexpr(!toBE)
|
||||
SwapBuffer32(size, rom);
|
||||
break;
|
||||
case RomTypes::N64: {
|
||||
SwapBuffer32(size, rom);
|
||||
crc = crc32(0, rom, size);
|
||||
}
|
||||
case N64:
|
||||
if constexpr(toBE)
|
||||
SwapBuffer32(size, rom);
|
||||
break;
|
||||
case RomTypes::Z64:
|
||||
crc = crc32(0, rom, size);
|
||||
break;
|
||||
default:
|
||||
panic("Unrecognized rom format! Make sure this is a valid Nintendo 64 ROM dump!\n");
|
||||
}
|
||||
}
|
||||
|
||||
inline void SwapN64Rom(size_t size, u8 *rom, u32 &crc, u32 &cicChecksum) {
|
||||
RomTypes endianness;
|
||||
memcpy(&endianness, rom, 4);
|
||||
endianness = static_cast<RomTypes>(be32toh(endianness));
|
||||
|
||||
switch (endianness) {
|
||||
case RomTypes::V64: {
|
||||
u8 *temp = (u8 *) calloc(size, 1);
|
||||
memcpy(temp, rom, size);
|
||||
SwapBuffer16(size, temp);
|
||||
crc = crc32(0, temp, size);
|
||||
cicChecksum = crc32(0, &temp[0x40], 0x9c0);
|
||||
free(temp);
|
||||
SwapBuffer32(size, rom);
|
||||
SwapBuffer16(size, rom);
|
||||
}
|
||||
break;
|
||||
case RomTypes::N64: {
|
||||
u8 *temp = (u8 *) calloc(size, 1);
|
||||
memcpy(temp, rom, size);
|
||||
SwapBuffer32(size, temp);
|
||||
crc = crc32(0, temp, size);
|
||||
cicChecksum = crc32(0, &temp[0x40], 0x9c0);
|
||||
free(temp);
|
||||
}
|
||||
break;
|
||||
case RomTypes::Z64:
|
||||
crc = crc32(0, rom, size);
|
||||
cicChecksum = crc32(0, &rom[0x40], 0x9c0);
|
||||
SwapBuffer32(size, rom);
|
||||
case Z64:
|
||||
if constexpr(!toBE)
|
||||
SwapBuffer32(size, rom);
|
||||
break;
|
||||
default:
|
||||
panic("Unrecognized rom format! Make sure this is a valid Nintendo 64 ROM dump!\n");
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace n64 {
|
||||
Mem::Mem() {
|
||||
cart = (u8*)calloc(CART_SIZE, 1);
|
||||
rom.cart = (u8*)calloc(CART_SIZE, 1);
|
||||
sram = (u8*)calloc(SRAM_SIZE, 1);
|
||||
Reset();
|
||||
}
|
||||
@@ -24,12 +24,27 @@ void Mem::Reset() {
|
||||
writePages[i] = pointer;
|
||||
}
|
||||
|
||||
memset(cart, 0, CART_SIZE);
|
||||
memset(rom.cart, 0, CART_SIZE);
|
||||
memset(sram, 0, SRAM_SIZE);
|
||||
mmio.Reset();
|
||||
}
|
||||
|
||||
CartInfo Mem::LoadROM(const std::string& filename) {
|
||||
inline void SetROMCIC(u32 checksum, ROM& rom) {
|
||||
switch (checksum) {
|
||||
case 0xEC8B1325: rom.cicType = CIC_NUS_7102; break; // 7102
|
||||
case 0x1DEB51A9: rom.cicType = CIC_NUS_6101; break; // 6101
|
||||
case 0xC08E5BD6: rom.cicType = CIC_NUS_6102_7101; break;
|
||||
case 0x03B8376A: rom.cicType = CIC_NUS_6103_7103; break;
|
||||
case 0xCF7F41DC: rom.cicType = CIC_NUS_6105_7105; break;
|
||||
case 0xD1059C6A: rom.cicType = CIC_NUS_6106_7106; break;
|
||||
default:
|
||||
Util::warn("Could not determine CIC TYPE! Checksum: 0x{:08X} is unknown!\n", checksum);
|
||||
rom.cicType = UNKNOWN_CIC_TYPE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Mem::LoadROM(const std::string& filename) {
|
||||
std::ifstream file(filename, std::ios::binary);
|
||||
file.unsetf(std::ios::skipws);
|
||||
|
||||
@@ -39,24 +54,46 @@ CartInfo Mem::LoadROM(const std::string& filename) {
|
||||
|
||||
file.seekg(0, std::ios::end);
|
||||
size_t size = file.tellg();
|
||||
size_t sizeAdjusted = Util::NextPow2(size);
|
||||
romMask = sizeAdjusted - 1;
|
||||
file.seekg(0, std::ios::beg);
|
||||
|
||||
file.read(reinterpret_cast<char*>(cart), size);
|
||||
|
||||
size_t sizeAdjusted = Util::NextPow2(size);
|
||||
rom.mask = sizeAdjusted - 1;
|
||||
u8* buf = (u8*)malloc(sizeAdjusted);
|
||||
file.read(reinterpret_cast<char*>(buf), size);
|
||||
file.close();
|
||||
|
||||
CartInfo result{};
|
||||
u32 endianness = be32toh(*reinterpret_cast<u32*>(buf));
|
||||
Util::SwapN64Rom<true>(sizeAdjusted, buf, endianness);
|
||||
|
||||
u32 cicChecksum;
|
||||
Util::SwapN64Rom(sizeAdjusted, cart, result.crc, cicChecksum);
|
||||
memcpy(mmio.rsp.dmem, cart, 0x1000);
|
||||
memcpy(rom.cart, buf, sizeAdjusted);
|
||||
rom.size = sizeAdjusted;
|
||||
memcpy(&rom.header, buf, sizeof(ROMHeader));
|
||||
memcpy(rom.gameNameCart, rom.header.imageName, sizeof(rom.header.imageName));
|
||||
|
||||
SetCICType(result.cicType, cicChecksum);
|
||||
result.isPAL = IsROMPAL();
|
||||
rom.header.clockRate = be32toh(rom.header.clockRate);
|
||||
rom.header.programCounter = be32toh(rom.header.programCounter);
|
||||
rom.header.release = be32toh(rom.header.release);
|
||||
rom.header.crc1 = be32toh(rom.header.crc1);
|
||||
rom.header.crc2 = be32toh(rom.header.crc2);
|
||||
rom.header.unknown = be64toh(rom.header.unknown);
|
||||
rom.header.unknown2 = be32toh(rom.header.unknown2);
|
||||
rom.header.manufacturerId = be32toh(rom.header.manufacturerId);
|
||||
rom.header.cartridgeId = be16toh(rom.header.cartridgeId);
|
||||
|
||||
return result;
|
||||
rom.code[0] = rom.header.manufacturerId & 0xFF;
|
||||
rom.code[1] = (rom.header.cartridgeId >> 8) & 0xFF;
|
||||
rom.code[2] = rom.header.cartridgeId & 0xFF;
|
||||
rom.code[3] = '\0';
|
||||
|
||||
for (int i = sizeof(rom.header.imageName) - 1; rom.gameNameCart[i] == ' '; i--) {
|
||||
rom.gameNameCart[i] = '\0';
|
||||
}
|
||||
|
||||
u32 checksum = Util::crc32(0, &rom.cart[0x40], 0x9c0);
|
||||
SetROMCIC(checksum, rom);
|
||||
endianness = be32toh(*reinterpret_cast<u32*>(rom.cart));
|
||||
Util::SwapN64Rom(sizeAdjusted, rom.cart, endianness);
|
||||
rom.pal = IsROMPAL();
|
||||
}
|
||||
|
||||
u8 Mem::Read8(n64::Registers ®s, u32 paddr) {
|
||||
@@ -88,7 +125,7 @@ u8 Mem::Read8(n64::Registers ®s, u32 paddr) {
|
||||
}
|
||||
case CART_REGION:
|
||||
paddr = (paddr + 2) & ~2;
|
||||
return cart[BYTE_ADDRESS(paddr) & romMask];
|
||||
return rom.cart[BYTE_ADDRESS(paddr) & rom.mask];
|
||||
case 0x1FC00000 ... 0x1FC007BF:
|
||||
return si.pif.pifBootrom[BYTE_ADDRESS(paddr) - 0x1FC00000];
|
||||
case PIF_RAM_REGION:
|
||||
@@ -128,7 +165,7 @@ u16 Mem::Read16(n64::Registers ®s, u32 paddr) {
|
||||
return mmio.Read(paddr);
|
||||
case 0x10000000 ... 0x1FBFFFFF:
|
||||
paddr = (paddr + 2) & ~3;
|
||||
return Util::ReadAccess<u16>(cart, HALF_ADDRESS(paddr) & romMask);
|
||||
return Util::ReadAccess<u16>(rom.cart, HALF_ADDRESS(paddr) & rom.mask);
|
||||
case 0x1FC00000 ... 0x1FC007BF:
|
||||
return Util::ReadAccess<u16>(si.pif.pifBootrom, HALF_ADDRESS(paddr) - 0x1FC00000);
|
||||
case PIF_RAM_REGION:
|
||||
@@ -165,7 +202,7 @@ u32 Mem::Read32(n64::Registers ®s, u32 paddr) {
|
||||
case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF:
|
||||
return mmio.Read(paddr);
|
||||
case 0x10000000 ... 0x1FBFFFFF:
|
||||
return Util::ReadAccess<u32>(cart, paddr & romMask);
|
||||
return Util::ReadAccess<u32>(rom.cart, paddr & rom.mask);
|
||||
case 0x1FC00000 ... 0x1FC007BF:
|
||||
return Util::ReadAccess<u32>(si.pif.pifBootrom, paddr - 0x1FC00000);
|
||||
case PIF_RAM_REGION:
|
||||
@@ -201,7 +238,7 @@ u64 Mem::Read64(n64::Registers ®s, u32 paddr) {
|
||||
case 0x04500000 ... 0x048FFFFF:
|
||||
return mmio.Read(paddr);
|
||||
case 0x10000000 ... 0x1FBFFFFF:
|
||||
return Util::ReadAccess<u64>(cart, paddr & romMask);
|
||||
return Util::ReadAccess<u64>(rom.cart, paddr & rom.mask);
|
||||
case 0x1FC00000 ... 0x1FC007BF:
|
||||
return Util::ReadAccess<u64>(si.pif.pifBootrom, paddr - 0x1FC00000);
|
||||
case PIF_RAM_REGION:
|
||||
@@ -274,7 +311,10 @@ void Mem::Write8(Registers& regs, u32 paddr, u32 val) {
|
||||
case 0x00800000 ... 0x03FFFFFF:
|
||||
case 0x04200000 ... 0x042FFFFF:
|
||||
case 0x08000000 ... 0x0FFFFFFF:
|
||||
Util::debug("SRAM 8 bit write {:02X}\n", val);
|
||||
break;
|
||||
case 0x04900000 ... 0x07FFFFFF:
|
||||
case 0x1FC00000 ... 0x1FC007BF:
|
||||
case 0x1FC00800 ... 0x7FFFFFFF:
|
||||
case 0x80000000 ... 0xFFFFFFFF:
|
||||
break;
|
||||
@@ -323,6 +363,7 @@ void Mem::Write16(Registers& regs, u32 paddr, u32 val) {
|
||||
case 0x04200000 ... 0x042FFFFF:
|
||||
case 0x08000000 ... 0x0FFFFFFF:
|
||||
case 0x04900000 ... 0x07FFFFFF:
|
||||
case 0x1FC00000 ... 0x1FC007BF:
|
||||
case 0x1FC00800 ... 0x7FFFFFFF:
|
||||
case 0x80000000 ... 0xFFFFFFFF:
|
||||
break;
|
||||
@@ -373,7 +414,8 @@ void Mem::Write32(Registers& regs, u32 paddr, u32 val) {
|
||||
break;
|
||||
case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF:
|
||||
case 0x08000000 ... 0x0FFFFFFF: case 0x04900000 ... 0x07FFFFFF:
|
||||
case 0x1FC00800 ... 0x7FFFFFFF: case 0x80000000 ... 0xFFFFFFFF: break;
|
||||
case 0x1FC00000 ... 0x1FC007BF: case 0x1FC00800 ... 0x7FFFFFFF:
|
||||
case 0x80000000 ... 0xFFFFFFFF: break;
|
||||
default: Util::panic("Unimplemented 32-bit write at address {:08X} with value {:0X} (PC = {:016X})\n", paddr, val, (u64)regs.pc);
|
||||
}
|
||||
}
|
||||
@@ -414,6 +456,7 @@ void Mem::Write64(Registers& regs, u32 paddr, u64 val) {
|
||||
case 0x04200000 ... 0x042FFFFF:
|
||||
case 0x08000000 ... 0x0FFFFFFF:
|
||||
case 0x04900000 ... 0x07FFFFFF:
|
||||
case 0x1FC00000 ... 0x1FC007BF:
|
||||
case 0x1FC00800 ... 0x7FFFFFFF:
|
||||
case 0x80000000 ... 0xFFFFFFFF:
|
||||
break;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <log.hpp>
|
||||
#include <Registers.hpp>
|
||||
#include <algorithm>
|
||||
#include <GameDB.hpp>
|
||||
|
||||
namespace n64 {
|
||||
struct CartInfo {
|
||||
@@ -17,13 +18,41 @@ struct CartInfo {
|
||||
|
||||
struct JIT;
|
||||
|
||||
struct ROMHeader {
|
||||
u8 initialValues[4];
|
||||
u32 clockRate;
|
||||
u32 programCounter;
|
||||
u32 release;
|
||||
u32 crc1;
|
||||
u32 crc2;
|
||||
u64 unknown;
|
||||
char imageName[20];
|
||||
u32 unknown2;
|
||||
u32 manufacturerId;
|
||||
u16 cartridgeId;
|
||||
char countryCode[2];
|
||||
u8 bootCode[4032];
|
||||
};
|
||||
|
||||
struct ROM {
|
||||
u8* cart;
|
||||
size_t size;
|
||||
size_t mask;
|
||||
ROMHeader header;
|
||||
CICType cicType;
|
||||
char gameNameCart[20];
|
||||
std::string gameNameDB;
|
||||
char code[4];
|
||||
bool pal;
|
||||
};
|
||||
|
||||
struct Mem {
|
||||
~Mem() {
|
||||
free(sram);
|
||||
}
|
||||
Mem();
|
||||
void Reset();
|
||||
CartInfo LoadROM(const std::string&);
|
||||
void LoadROM(const std::string&);
|
||||
[[nodiscard]] auto GetRDRAM() const -> u8* {
|
||||
return mmio.rdp.rdram;
|
||||
}
|
||||
@@ -73,47 +102,21 @@ struct Mem {
|
||||
fclose(fp);
|
||||
}
|
||||
uintptr_t writePages[PAGE_COUNT], readPages[PAGE_COUNT];
|
||||
ROM rom;
|
||||
SaveType saveType;
|
||||
private:
|
||||
friend struct SI;
|
||||
friend struct PI;
|
||||
friend struct AI;
|
||||
friend struct RSP;
|
||||
friend struct Core;
|
||||
u8* sram, *cart;
|
||||
u8* sram;
|
||||
u8 isviewer[ISVIEWER_SIZE]{};
|
||||
size_t romMask = 0;
|
||||
|
||||
static void SetCICType(u32& cicType, u32 checksum) {
|
||||
switch(checksum) {
|
||||
case 0xEC8B1325: // 7102
|
||||
cicType = CIC_NUS_7102;
|
||||
break;
|
||||
case 0x1DEB51A9: // 6101
|
||||
cicType = CIC_NUS_6101;
|
||||
break;
|
||||
case 0xC08E5BD6:
|
||||
cicType = CIC_NUS_6102_7101;
|
||||
break;
|
||||
case 0x03B8376A:
|
||||
cicType = CIC_NUS_6103_7103;
|
||||
break;
|
||||
case 0xCF7F41DC:
|
||||
cicType = CIC_NUS_6105_7105;
|
||||
break;
|
||||
case 0xD1059C6A:
|
||||
cicType = CIC_NUS_6106_7106;
|
||||
break;
|
||||
default:
|
||||
Util::warn("Could not determine CIC TYPE! Checksum: {:08X} is unknown!\n", checksum);
|
||||
cicType = UNKNOWN_CIC_TYPE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsROMPAL() {
|
||||
static const char pal_codes[] = {'D', 'F', 'I', 'P', 'S', 'U', 'X', 'Y'};
|
||||
return std::any_of(std::begin(pal_codes), std::end(pal_codes), [this](char a) {
|
||||
return cart[0x3e] == a;
|
||||
return rom.cart[0x3e] == a;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -52,7 +52,7 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
|
||||
}
|
||||
rdLen = len;
|
||||
for(int i = 0; i < len; i++) {
|
||||
mem.cart[BYTE_ADDRESS(cart_addr + i) & mem.romMask] = mem.mmio.rdp.rdram[BYTE_ADDRESS(dram_addr + i) & RDRAM_DSIZE];
|
||||
mem.rom.cart[BYTE_ADDRESS(cart_addr + i) & mem.rom.mask] = mem.mmio.rdp.rdram[BYTE_ADDRESS(dram_addr + i) & RDRAM_DSIZE];
|
||||
}
|
||||
dramAddr = dram_addr + len;
|
||||
cartAddr = cart_addr + len;
|
||||
@@ -68,7 +68,7 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
|
||||
}
|
||||
wrLen = len;
|
||||
for(int i = 0; i < len; i++) {
|
||||
mem.mmio.rdp.rdram[BYTE_ADDRESS(dram_addr + i) & RDRAM_DSIZE] = mem.cart[BYTE_ADDRESS(cart_addr + i) & mem.romMask];
|
||||
mem.mmio.rdp.rdram[BYTE_ADDRESS(dram_addr + i) & RDRAM_DSIZE] = mem.rom.cart[BYTE_ADDRESS(cart_addr + i) & mem.rom.mask];
|
||||
}
|
||||
dramAddr = dram_addr + len;
|
||||
cartAddr = cart_addr + len;
|
||||
|
||||
@@ -55,7 +55,22 @@ void PIF::ProcessPIFCommands(Mem& mem) {
|
||||
res[2] = controller.joy_x;
|
||||
res[3] = controller.joy_y;
|
||||
break;
|
||||
case 2: case 3: res[0] = 0; break;
|
||||
case 2:
|
||||
Util::print("MEMPAK READ\n");
|
||||
res[0] = 0;
|
||||
break;
|
||||
case 3:
|
||||
Util::print("MEMPAK WRITE\n");
|
||||
res[0] = 0;
|
||||
break;
|
||||
case 4:
|
||||
Util::print("EEPROM READ\n");
|
||||
res[0] = 0;
|
||||
break;
|
||||
case 5:
|
||||
Util::print("EEPROM WRITE\n");
|
||||
res[0] = 0;
|
||||
break;
|
||||
default: Util::panic("Unimplemented PIF command {}", cmd[2]);
|
||||
}
|
||||
|
||||
@@ -163,9 +178,7 @@ void PIF::UpdateController() {
|
||||
}
|
||||
}
|
||||
|
||||
void PIF::DoPIFHLE(Mem& mem, Registers& regs, CartInfo cartInfo) {
|
||||
u32 cicType = cartInfo.cicType;
|
||||
bool pal = cartInfo.isPAL;
|
||||
void PIF::DoPIFHLE(Mem& mem, Registers& regs, bool pal, CICType cicType) {
|
||||
mem.Write32(regs, PIF_RAM_REGION_START + 0x24, cicSeeds[cicType]);
|
||||
|
||||
switch(cicType) {
|
||||
@@ -426,12 +439,13 @@ void PIF::DoPIFHLE(Mem& mem, Registers& regs, CartInfo cartInfo) {
|
||||
regs.gpr[22] = (cicSeeds[cicType] >> 8) & 0xFF;
|
||||
regs.cop0.Reset();
|
||||
mem.Write32(regs, 0x04300004, 0x01010101);
|
||||
memcpy(mem.mmio.rsp.dmem, mem.rom.cart, 0x1000);
|
||||
regs.SetPC32(0xA4000040);
|
||||
}
|
||||
|
||||
void PIF::ExecutePIF(Mem& mem, Registers& regs, CartInfo cartInfo) {
|
||||
u32 cicType = cartInfo.cicType;
|
||||
bool pal = cartInfo.isPAL;
|
||||
void PIF::ExecutePIF(Mem& mem, Registers& regs) {
|
||||
CICType cicType = mem.rom.cicType;
|
||||
bool pal = mem.rom.pal;
|
||||
mem.Write32(regs, PIF_RAM_REGION_START + 0x24, cicSeeds[cicType]);
|
||||
switch(cicType) {
|
||||
case UNKNOWN_CIC_TYPE:
|
||||
@@ -447,6 +461,6 @@ void PIF::ExecutePIF(Mem& mem, Registers& regs, CartInfo cartInfo) {
|
||||
break;
|
||||
}
|
||||
|
||||
DoPIFHLE(mem, regs, cartInfo);
|
||||
DoPIFHLE(mem, regs, pal, cicType);
|
||||
}
|
||||
}
|
||||
@@ -44,10 +44,10 @@ constexpr u32 cicSeeds[] = {
|
||||
0x0,
|
||||
0x00043F3F, // CIC_NUS_6101
|
||||
0x00043F3F, // CIC_NUS_7102
|
||||
0x00003F3F, // CIC_NUS_6102_7101
|
||||
0x0000783F, // CIC_NUS_6103_7103
|
||||
0x0000913F, // CIC_NUS_6105_7105
|
||||
0x0000853F, // CIC_NUS_6106_7106
|
||||
0x00043F3F, // CIC_NUS_6102_7101
|
||||
0x00047878, // CIC_NUS_6103_7103
|
||||
0x00049191, // CIC_NUS_6105_7105
|
||||
0x00048585, // CIC_NUS_6106_7106
|
||||
};
|
||||
|
||||
enum CICType {
|
||||
@@ -64,12 +64,23 @@ struct CartInfo;
|
||||
|
||||
struct PIF {
|
||||
void ProcessPIFCommands(Mem&);
|
||||
void ExecutePIF(Mem& mem, Registers& regs, CartInfo cartInfo);
|
||||
void DoPIFHLE(Mem& mem, Registers& regs, CartInfo cartInfo);
|
||||
void ExecutePIF(Mem& mem, Registers& regs);
|
||||
void DoPIFHLE(Mem& mem, Registers& regs, bool pal, CICType cicType);
|
||||
void UpdateController();
|
||||
bool gamepadConnected = false;
|
||||
SDL_GameController* gamepad;
|
||||
Controller controller;
|
||||
u8 pifBootrom[PIF_BOOTROM_SIZE]{}, pifRam[PIF_RAM_SIZE];
|
||||
u8 Read(u32 addr) {
|
||||
addr &= 0x7FF;
|
||||
if(addr < 0x7c0) return pifBootrom[addr];
|
||||
return pifRam[addr];
|
||||
}
|
||||
|
||||
void Write(u32 addr, u8 val) {
|
||||
addr &= 0x7FF;
|
||||
if(addr < 0x7c0) return;
|
||||
pifRam[addr] = val;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -44,7 +44,6 @@ void DMA(Mem& mem, Registers& regs) {
|
||||
for(int i = 0; i < 64; i++) {
|
||||
si.pif.pifRam[i] = mem.mmio.rdp.rdram[BYTE_ADDRESS(si.dramAddr + i)];
|
||||
}
|
||||
Util::debug("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})\n", si.pifAddr, si.dramAddr);
|
||||
si.pif.ProcessPIFCommands(mem);
|
||||
}
|
||||
InterruptRaise(mem.mmio.mi, regs, Interrupt::SI);
|
||||
@@ -66,7 +65,7 @@ void SI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
|
||||
pifAddr = val & 0x1FFFFFFF;
|
||||
status.dmaBusy = true;
|
||||
toDram = false;
|
||||
scheduler.enqueueRelative({SI_DMA_DELAY, DMA});
|
||||
scheduler.enqueueRelative({4065*3, DMA});
|
||||
Util::debug("SI DMA from RDRAM to PIF RAM ({:08X} to {:08X})\n", dramAddr, pifAddr);
|
||||
} break;
|
||||
case 0x04800018:
|
||||
|
||||
@@ -151,22 +151,8 @@ ImDrawData* Window::Present(n64::Core& core) {
|
||||
|
||||
void Window::LoadROM(n64::Core& core, const std::string &path) {
|
||||
if(!path.empty()) {
|
||||
n64::CartInfo cartInfo = core.LoadROM(path);
|
||||
std::ifstream gameDbFile("resources/db.json");
|
||||
json gameDb = json::parse(gameDbFile);
|
||||
gameName = "";
|
||||
|
||||
for(const auto& item : gameDb["items"]) {
|
||||
auto crc = item["crc"];
|
||||
if(!crc.empty()) {
|
||||
if(crc.get<std::string>() == fmt::format("{:08X}", cartInfo.crc)) {
|
||||
auto name = item["name"];
|
||||
if(!name.empty()) {
|
||||
gameName = name.get<std::string>();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
core.LoadROM(path);
|
||||
gameName = core.cpu->mem.rom.gameNameDB;
|
||||
|
||||
if(gameName.empty()) {
|
||||
gameName = fs::path(path).stem().string();
|
||||
@@ -177,7 +163,6 @@ void Window::LoadROM(n64::Core& core, const std::string &path) {
|
||||
shadowWindowTitle = windowTitle;
|
||||
|
||||
SDL_SetWindowTitle(window, windowTitle.c_str());
|
||||
gameDbFile.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user