Merge melonDS master, do massive cleanup/splitup of code
also, get rid of the GBA SRAM hack where it was inserted in ROMs (gross), instead figure out the size and give melonDS a blank save of the correct size GBA SRAM is also now in SaveRAM also add in more memory domains (SRAM/ROM/DSi BIOS)
This commit is contained in:
parent
2fc9f719e5
commit
f7786e81b9
Binary file not shown.
|
@ -6,16 +6,6 @@
|
|||
namespace Config
|
||||
{
|
||||
|
||||
#ifdef JIT_ENABLED
|
||||
bool JIT_Enable = false;
|
||||
int JIT_MaxBlockSize = 32;
|
||||
bool JIT_BranchOptimisations = true;
|
||||
bool JIT_LiteralOptimisations = true;
|
||||
bool JIT_FastMemory = true;
|
||||
#endif
|
||||
|
||||
bool ExternalBIOSEnable;
|
||||
|
||||
std::string BIOS9Path = "bios9.rom";
|
||||
std::string BIOS7Path = "bios7.rom";
|
||||
std::string FirmwarePath = "firmware.bin";
|
||||
|
@ -39,20 +29,4 @@ bool DSiSDReadOnly = true;
|
|||
bool DSiSDFolderSync = false;
|
||||
std::string DSiSDFolderPath = "";
|
||||
|
||||
bool FirmwareOverrideSettings;
|
||||
std::string FirmwareUsername;
|
||||
int FirmwareLanguage;
|
||||
int FirmwareBirthdayMonth;
|
||||
int FirmwareBirthdayDay;
|
||||
int FirmwareFavouriteColour;
|
||||
std::string FirmwareMessage;
|
||||
std::string FirmwareMAC;
|
||||
bool RandomizeMAC;
|
||||
|
||||
int AudioBitrate;
|
||||
|
||||
bool FixedBootTime = true;
|
||||
bool UseRealTime = false;
|
||||
int TimeAtBoot = 0;
|
||||
|
||||
}
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Config
|
||||
{
|
||||
|
||||
#ifdef JIT_ENABLED
|
||||
extern bool JIT_Enable;
|
||||
extern int JIT_MaxBlockSize;
|
||||
extern bool JIT_BranchOptimisations;
|
||||
extern bool JIT_LiteralOptimisations;
|
||||
extern bool JIT_FastMemory;
|
||||
#endif
|
||||
|
||||
extern bool ExternalBIOSEnable;
|
||||
|
||||
extern std::string BIOS9Path;
|
||||
extern std::string BIOS7Path;
|
||||
extern std::string FirmwarePath;
|
||||
|
||||
extern std::string DSiBIOS9Path;
|
||||
extern std::string DSiBIOS7Path;
|
||||
extern std::string DSiFirmwarePath;
|
||||
extern std::string DSiNANDPath;
|
||||
|
||||
extern bool DLDIEnable;
|
||||
extern std::string DLDISDPath;
|
||||
extern int DLDISize;
|
||||
extern bool DLDIReadOnly;
|
||||
extern bool DLDIFolderSync;
|
||||
extern std::string DLDIFolderPath;
|
||||
|
||||
extern bool DSiSDEnable;
|
||||
extern std::string DSiSDPath;
|
||||
extern int DSiSDSize;
|
||||
extern bool DSiSDReadOnly;
|
||||
extern bool DSiSDFolderSync;
|
||||
extern std::string DSiSDFolderPath;
|
||||
|
||||
extern bool FirmwareOverrideSettings;
|
||||
extern std::string FirmwareUsername;
|
||||
extern int FirmwareLanguage;
|
||||
extern int FirmwareBirthdayMonth;
|
||||
extern int FirmwareBirthdayDay;
|
||||
extern int FirmwareFavouriteColour;
|
||||
extern std::string FirmwareMessage;
|
||||
extern std::string FirmwareMAC;
|
||||
extern bool RandomizeMAC;
|
||||
|
||||
extern int AudioBitrate;
|
||||
|
||||
extern bool FixedBootTime;
|
||||
extern bool UseRealTime;
|
||||
extern int TimeAtBoot;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,267 @@
|
|||
#include "NDS.h"
|
||||
#include "NDSCart.h"
|
||||
#include "GBACart.h"
|
||||
#include "DSi.h"
|
||||
#include "ARM.h"
|
||||
|
||||
#include "dthumb.h"
|
||||
|
||||
#include <waterboxcore.h>
|
||||
|
||||
void (*InputCallback)() = nullptr;
|
||||
|
||||
ECL_EXPORT void SetInputCallback(void (*callback)())
|
||||
{
|
||||
InputCallback = callback;
|
||||
}
|
||||
|
||||
void (*ReadCallback)(u32) = nullptr;
|
||||
void (*WriteCallback)(u32) = nullptr;
|
||||
void (*ExecuteCallback)(u32) = nullptr;
|
||||
|
||||
ECL_EXPORT void SetMemoryCallback(u32 which, void (*callback)(u32 addr))
|
||||
{
|
||||
switch (which)
|
||||
{
|
||||
case 0: ReadCallback = callback; break;
|
||||
case 1: WriteCallback = callback; break;
|
||||
case 2: ExecuteCallback = callback; break;
|
||||
}
|
||||
}
|
||||
|
||||
TraceMask_t TraceMask = TRACE_NONE;
|
||||
static void (*TraceCallback)(TraceMask_t, u32, u32*, char*, u32) = nullptr;
|
||||
|
||||
ECL_EXPORT void SetTraceCallback(void (*callback)(TraceMask_t mask, u32 opcode, u32* regs, char* disasm, u32 cyclesOff), TraceMask_t mask)
|
||||
{
|
||||
TraceCallback = callback;
|
||||
TraceMask = callback ? mask : TRACE_NONE;
|
||||
}
|
||||
|
||||
void TraceTrampoline(TraceMask_t type, u32* regs, u32 opcode)
|
||||
{
|
||||
static char disasm[DTHUMB_STRING_LENGTH];
|
||||
|
||||
memset(disasm, 0, sizeof(disasm));
|
||||
switch (type)
|
||||
{
|
||||
case TRACE_ARM7_THUMB: Disassemble_thumb(opcode, disasm, ARMv4T); break;
|
||||
case TRACE_ARM7_ARM: Disassemble_arm(opcode, disasm, ARMv4T); break;
|
||||
case TRACE_ARM9_THUMB: Disassemble_thumb(opcode, disasm, ARMv5TE); break;
|
||||
case TRACE_ARM9_ARM: Disassemble_arm(opcode, disasm, ARMv5TE); break;
|
||||
default: __builtin_unreachable();
|
||||
}
|
||||
|
||||
TraceCallback(type, opcode, regs, disasm, NDS::GetSysClockCycles(2));
|
||||
}
|
||||
|
||||
namespace NDS
|
||||
{
|
||||
extern ARMv5* ARM9;
|
||||
extern ARMv4* ARM7;
|
||||
}
|
||||
|
||||
ECL_EXPORT void GetRegs(u32* regs)
|
||||
{
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
*regs++ = NDS::ARM9->R[i];
|
||||
}
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
*regs++ = NDS::ARM7->R[i];
|
||||
}
|
||||
}
|
||||
|
||||
ECL_EXPORT void SetReg(s32 ncpu, s32 index, s32 val)
|
||||
{
|
||||
if (ncpu)
|
||||
{
|
||||
NDS::ARM7->R[index] = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
NDS::ARM9->R[index] = val;
|
||||
}
|
||||
}
|
||||
|
||||
/* excerpted from gbatek
|
||||
|
||||
NDS9 Memory Map
|
||||
|
||||
00000000h Instruction TCM (32KB) (not moveable) (mirror-able to 1000000h)
|
||||
0xxxx000h Data TCM (16KB) (moveable)
|
||||
02000000h Main Memory (4MB)
|
||||
03000000h Shared WRAM (0KB, 16KB, or 32KB can be allocated to ARM9)
|
||||
04000000h ARM9-I/O Ports
|
||||
05000000h Standard Palettes (2KB) (Engine A BG/OBJ, Engine B BG/OBJ)
|
||||
06000000h VRAM - Engine A, BG VRAM (max 512KB)
|
||||
06200000h VRAM - Engine B, BG VRAM (max 128KB)
|
||||
06400000h VRAM - Engine A, OBJ VRAM (max 256KB)
|
||||
06600000h VRAM - Engine B, OBJ VRAM (max 128KB)
|
||||
06800000h VRAM - "LCDC"-allocated (max 656KB)
|
||||
07000000h OAM (2KB) (Engine A, Engine B)
|
||||
08000000h GBA Slot ROM (max 32MB)
|
||||
0A000000h GBA Slot RAM (max 64KB)
|
||||
FFFF0000h ARM9-BIOS (32KB) (only 3K used)
|
||||
|
||||
NDS7 Memory Map
|
||||
|
||||
00000000h ARM7-BIOS (16KB)
|
||||
02000000h Main Memory (4MB)
|
||||
03000000h Shared WRAM (0KB, 16KB, or 32KB can be allocated to ARM7)
|
||||
03800000h ARM7-WRAM (64KB)
|
||||
04000000h ARM7-I/O Ports
|
||||
04800000h Wireless Communications Wait State 0 (8KB RAM at 4804000h)
|
||||
04808000h Wireless Communications Wait State 1 (I/O Ports at 4808000h)
|
||||
06000000h VRAM allocated as Work RAM to ARM7 (max 256K)
|
||||
08000000h GBA Slot ROM (max 32MB)
|
||||
0A000000h GBA Slot RAM (max 64KB)
|
||||
|
||||
Further Memory (not mapped to ARM9/ARM7 bus)
|
||||
|
||||
3D Engine Polygon RAM (52KBx2)
|
||||
3D Engine Vertex RAM (72KBx2)
|
||||
Firmware (256KB) (built-in serial flash memory)
|
||||
GBA-BIOS (16KB) (not used in NDS mode)
|
||||
NDS Slot ROM (serial 8bit-bus, max 4GB with default protocol)
|
||||
NDS Slot FLASH/EEPROM/FRAM (serial 1bit-bus)
|
||||
|
||||
*/
|
||||
|
||||
template<bool arm9>
|
||||
static bool SafeToPeek(u32 addr)
|
||||
{
|
||||
if (arm9)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
case 0x04000130:
|
||||
case 0x04000131:
|
||||
case 0x04000600:
|
||||
case 0x04000601:
|
||||
case 0x04000602:
|
||||
case 0x04000603:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else // arm7
|
||||
{
|
||||
if (addr >= 0x04800000 && addr <= 0x04810000)
|
||||
{
|
||||
if (addr & 1) addr--;
|
||||
addr &= 0x7FFE;
|
||||
if (addr == 0x044 || addr == 0x060)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ARM9Access(u8* buffer, s64 address, s64 count, bool write)
|
||||
{
|
||||
if (write)
|
||||
{
|
||||
void (*Write)(u32, u8) = NDS::ConsoleType == 1 ? DSi::ARM9Write8 : NDS::ARM9Write8;
|
||||
while (count--)
|
||||
{
|
||||
if (address < NDS::ARM9->ITCMSize)
|
||||
{
|
||||
NDS::ARM9->ITCM[address++ & (ITCMPhysicalSize - 1)] = *buffer++;
|
||||
}
|
||||
else if ((address & NDS::ARM9->DTCMMask) == NDS::ARM9->DTCMBase)
|
||||
{
|
||||
NDS::ARM9->DTCM[address++ & (DTCMPhysicalSize - 1)] = *buffer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Write(address++, *buffer++);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
u8 (*Read)(u32) = NDS::ConsoleType == 1 ? DSi::ARM9Read8 : NDS::ARM9Read8;
|
||||
while (count--)
|
||||
{
|
||||
if (address < NDS::ARM9->ITCMSize)
|
||||
{
|
||||
*buffer++ = NDS::ARM9->ITCM[address & (ITCMPhysicalSize - 1)];
|
||||
}
|
||||
else if ((address & NDS::ARM9->DTCMMask) == NDS::ARM9->DTCMBase)
|
||||
{
|
||||
*buffer++ = NDS::ARM9->DTCM[address & (DTCMPhysicalSize - 1)];
|
||||
}
|
||||
else
|
||||
{
|
||||
*buffer++ = SafeToPeek<true>(address) ? Read(address) : 0;
|
||||
}
|
||||
|
||||
address++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ARM7Access(u8* buffer, s64 address, s64 count, bool write)
|
||||
{
|
||||
if (write)
|
||||
{
|
||||
void (*Write)(u32, u8) = NDS::ConsoleType == 1 ? DSi::ARM7Write8 : NDS::ARM7Write8;
|
||||
while (count--)
|
||||
Write(address++, *buffer++);
|
||||
}
|
||||
else
|
||||
{
|
||||
u8 (*Read)(u32) = NDS::ConsoleType == 1 ? DSi::ARM7Read8 : NDS::ARM7Read8;
|
||||
while (count--)
|
||||
*buffer++ = SafeToPeek<true>(address) ? Read(address) : 0, address++;
|
||||
}
|
||||
}
|
||||
|
||||
ECL_EXPORT void GetMemoryAreas(MemoryArea *m)
|
||||
{
|
||||
int i = 0;
|
||||
#define ADD_MEMORY_DOMAIN(name, data, size, flags) do \
|
||||
{ \
|
||||
m[i].Data = (void*)data; \
|
||||
m[i].Name = name; \
|
||||
m[i].Size = size; \
|
||||
m[i].Flags = flags; \
|
||||
i++; \
|
||||
} while (0)
|
||||
|
||||
ADD_MEMORY_DOMAIN("Main RAM", NDS::MainRAM, NDS::ConsoleType == 1 ? NDS::MainRAMMaxSize : NDS::MainRAMMaxSize / 4, MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_PRIMARY);
|
||||
ADD_MEMORY_DOMAIN("Shared WRAM", NDS::SharedWRAM, NDS::SharedWRAMSize, MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_WRITABLE);
|
||||
ADD_MEMORY_DOMAIN("ARM7 WRAM", NDS::ARM7WRAM, NDS::ARM7WRAMSize, MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_WRITABLE);
|
||||
|
||||
if (NDSCart::Cart)
|
||||
{
|
||||
ADD_MEMORY_DOMAIN("SRAM", NDSCart::GetSaveMemory(), NDSCart::GetSaveMemoryLength(), MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_WRITABLE);
|
||||
ADD_MEMORY_DOMAIN("ROM", NDSCart::Cart->GetROM(), NDSCart::Cart->GetROMLength(), MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_WRITABLE);
|
||||
}
|
||||
|
||||
if (GBACart::Cart)
|
||||
{
|
||||
ADD_MEMORY_DOMAIN("GBA SRAM", GBACart::GetSaveMemory(), GBACart::GetSaveMemoryLength(), MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_WRITABLE);
|
||||
ADD_MEMORY_DOMAIN("GBA ROM", GBACart::Cart->GetROM(), GBACart::Cart->GetROMLength(), MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_WRITABLE);
|
||||
}
|
||||
|
||||
ADD_MEMORY_DOMAIN("Instruction TCM", NDS::ARM9->ITCM, ITCMPhysicalSize, MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_WRITABLE);
|
||||
ADD_MEMORY_DOMAIN("Data TCM", NDS::ARM9->DTCM, DTCMPhysicalSize, MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_WRITABLE);
|
||||
|
||||
ADD_MEMORY_DOMAIN("ARM9 BIOS", NDS::ARM9BIOS, sizeof(NDS::ARM9BIOS), MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_WRITABLE);
|
||||
ADD_MEMORY_DOMAIN("ARM7 BIOS", NDS::ARM7BIOS, sizeof(NDS::ARM7BIOS), MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_WRITABLE);
|
||||
|
||||
if (NDS::ConsoleType == 1)
|
||||
{
|
||||
ADD_MEMORY_DOMAIN("ARM9i BIOS", DSi::ARM9iBIOS, sizeof(DSi::ARM9iBIOS), MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_WRITABLE);
|
||||
ADD_MEMORY_DOMAIN("ARM7i BIOS", DSi::ARM7iBIOS, sizeof(DSi::ARM7iBIOS), MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_WRITABLE);
|
||||
}
|
||||
|
||||
ADD_MEMORY_DOMAIN("ARM9 System Bus", ARM9Access, 1ull << 32, MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_FUNCTIONHOOK);
|
||||
ADD_MEMORY_DOMAIN("ARM7 System Bus", ARM7Access, 1ull << 32, MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_FUNCTIONHOOK);
|
||||
|
||||
// fixme: include more shit
|
||||
}
|
|
@ -0,0 +1,214 @@
|
|||
#include "NDS.h"
|
||||
#include "DSi_NAND.h"
|
||||
#include "DSi_TMD.h"
|
||||
#include "CRC32.h"
|
||||
|
||||
#include "BizFileManager.h"
|
||||
|
||||
namespace FileManager
|
||||
{
|
||||
|
||||
constexpr u32 DSIWARE_CATEGORY = 0x00030004;
|
||||
|
||||
static std::optional<std::pair<std::unique_ptr<u8[]>, size_t>> GetFileData(std::string path)
|
||||
{
|
||||
auto file = Platform::OpenFile(path, Platform::FileMode::Read);
|
||||
if (!file)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
size_t size = Platform::FileLength(file);
|
||||
auto data = std::make_unique<u8[]>(size);
|
||||
|
||||
Platform::FileRewind(file);
|
||||
Platform::FileRead(data.get(), size, 1, file);
|
||||
Platform::CloseFile(file);
|
||||
|
||||
return std::make_pair(std::move(data), size);
|
||||
}
|
||||
|
||||
const char* InitNAND(bool clearNand, bool dsiWare)
|
||||
{
|
||||
auto dsiBios7Path = Platform::GetConfigString(Platform::ConfigEntry::DSi_BIOS7Path);
|
||||
auto bios7i = Platform::OpenFile(dsiBios7Path, Platform::FileMode::Read);
|
||||
if (!bios7i)
|
||||
{
|
||||
return "Failed to obtain BIOS7i!";
|
||||
}
|
||||
|
||||
u8 es_keyY[16]{};
|
||||
Platform::FileSeek(bios7i, 0x8308, Platform::FileSeekOrigin::Start);
|
||||
Platform::FileRead(es_keyY, 16, 1, bios7i);
|
||||
Platform::CloseFile(bios7i);
|
||||
|
||||
if (!DSi_NAND::Init(es_keyY))
|
||||
{
|
||||
return "Failed to init DSi NAND!";
|
||||
}
|
||||
|
||||
if (clearNand)
|
||||
{
|
||||
std::vector<u32> titlelist;
|
||||
DSi_NAND::ListTitles(DSIWARE_CATEGORY, titlelist);
|
||||
|
||||
for (auto& title : titlelist)
|
||||
{
|
||||
DSi_NAND::DeleteTitle(DSIWARE_CATEGORY, title);
|
||||
}
|
||||
}
|
||||
|
||||
if (dsiWare)
|
||||
{
|
||||
auto rom = GetFileData("dsiware.rom");
|
||||
if (!rom)
|
||||
{
|
||||
return "Failed to obtain DSiWare ROM!";
|
||||
}
|
||||
|
||||
auto tmdData = GetFileData("tmd.rom");
|
||||
if (!tmdData)
|
||||
{
|
||||
return "Failed to obtain TMD!";
|
||||
}
|
||||
|
||||
if (tmdData->second != sizeof(DSi_TMD::TitleMetadata))
|
||||
{
|
||||
return "TMD is not the correct size!";
|
||||
}
|
||||
|
||||
DSi_TMD::TitleMetadata tmd;
|
||||
memcpy(&tmd, tmdData->first.get(), sizeof(DSi_TMD::TitleMetadata));
|
||||
if (!DSi_NAND::ImportTitle(rom->first.get(), rom->second, tmd, false))
|
||||
{
|
||||
DSi_NAND::DeInit();
|
||||
return "Loading DSiWare failed!";
|
||||
}
|
||||
}
|
||||
|
||||
DSi_NAND::DeInit();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
enum class GBASaveType
|
||||
{
|
||||
NONE,
|
||||
SRAM,
|
||||
EEPROM512,
|
||||
EEPROM,
|
||||
FLASH512,
|
||||
FLASH1M,
|
||||
};
|
||||
|
||||
#include "GBASaveOverrides.h"
|
||||
|
||||
static GBASaveType FindGbaSaveType(const u8* gbaRomData, size_t gbaRomSize)
|
||||
{
|
||||
u32 crc = CRC32(gbaRomData, gbaRomSize);
|
||||
if (auto saveOverride = GbaCrcSaveTypeOverrides.find(crc); saveOverride != GbaCrcSaveTypeOverrides.end())
|
||||
{
|
||||
return saveOverride->second;
|
||||
}
|
||||
|
||||
if (gbaRomSize >= 0xB0)
|
||||
{
|
||||
char gameId[4];
|
||||
std::memcpy(gameId, &gbaRomData[0xAC], 4);
|
||||
if (auto saveOverride = GbaGameIdSaveTypeOverrides.find(std::string(gameId, 4)); saveOverride != GbaGameIdSaveTypeOverrides.end())
|
||||
{
|
||||
return saveOverride->second;
|
||||
}
|
||||
}
|
||||
|
||||
if (memmem(gbaRomData, gbaRomSize, "EEPROM_V", strlen("EEPROM_V")))
|
||||
{
|
||||
return GBASaveType::EEPROM512;
|
||||
}
|
||||
|
||||
if (memmem(gbaRomData, gbaRomSize, "SRAM_V", strlen("SRAM_V")))
|
||||
{
|
||||
return GBASaveType::SRAM;
|
||||
}
|
||||
|
||||
if (memmem(gbaRomData, gbaRomSize, "FLASH_V", strlen("FLASH_V"))
|
||||
|| memmem(gbaRomData, gbaRomSize, "FLASH512_V", strlen("FLASH512_V")))
|
||||
{
|
||||
return GBASaveType::FLASH512;
|
||||
}
|
||||
|
||||
if (memmem(gbaRomData, gbaRomSize, "FLASH1M_V", strlen("FLASH1M_V")))
|
||||
{
|
||||
return GBASaveType::FLASH1M;
|
||||
}
|
||||
|
||||
return GBASaveType::NONE;
|
||||
}
|
||||
|
||||
static std::pair<std::unique_ptr<u8[]>, size_t> CreateBlankGbaSram(const u8* gbaRomData, size_t gbaRomSize)
|
||||
{
|
||||
auto saveType = FindGbaSaveType(gbaRomData, gbaRomSize);
|
||||
|
||||
if (saveType == GBASaveType::NONE)
|
||||
{
|
||||
return std::make_pair(nullptr, 0);
|
||||
}
|
||||
|
||||
size_t size;
|
||||
switch (saveType)
|
||||
{
|
||||
case GBASaveType::SRAM:
|
||||
size = 0x8000;
|
||||
break;
|
||||
case GBASaveType::EEPROM512:
|
||||
size = 0x200;
|
||||
break;
|
||||
case GBASaveType::EEPROM:
|
||||
size = 0x2000;
|
||||
break;
|
||||
case GBASaveType::FLASH512:
|
||||
size = 0x10000;
|
||||
break;
|
||||
case GBASaveType::FLASH1M:
|
||||
size = 0x20000;
|
||||
break;
|
||||
default:
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
auto data = std::make_unique<u8[]>(size);
|
||||
memset(data.get(), 0xFF, size);
|
||||
return std::make_pair(std::move(data), size);
|
||||
}
|
||||
|
||||
const char* InitCarts(bool gba)
|
||||
{
|
||||
auto ndsRom = GetFileData("nds.rom");
|
||||
if (!ndsRom)
|
||||
{
|
||||
return "Failed to obtain NDS ROM!";
|
||||
}
|
||||
|
||||
if (!NDS::LoadCart(ndsRom->first.get(), ndsRom->second, nullptr, 0))
|
||||
{
|
||||
return "Failed to load NDS ROM!";
|
||||
}
|
||||
|
||||
if (gba)
|
||||
{
|
||||
auto gbaRom = GetFileData("gba.rom");
|
||||
if (!gbaRom)
|
||||
{
|
||||
return "Failed to obtain GBA ROM!";
|
||||
}
|
||||
|
||||
auto gbaSram = CreateBlankGbaSram(gbaRom->first.get(), gbaRom->second);
|
||||
if (!NDS::LoadGBACart(gbaRom->first.get(), gbaRom->second, gbaSram.first.get(), gbaSram.second))
|
||||
{
|
||||
return "Failed to load GBA ROM!";
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef BIZFILEMANAGER_H
|
||||
#define BIZFILEMANAGER_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
namespace FileManager
|
||||
{
|
||||
|
||||
const char* InitNAND(bool clearNand, bool dsiWare);
|
||||
const char* InitCarts(bool gba);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -2,412 +2,80 @@
|
|||
#include "GPU.h"
|
||||
#include "SPU.h"
|
||||
#include "RTC.h"
|
||||
#include "ARM.h"
|
||||
#include "NDSCart.h"
|
||||
#include "GBACart.h"
|
||||
#include "DSi.h"
|
||||
#include "DSi_NAND.h"
|
||||
#include "Platform.h"
|
||||
#include "BizConfig.h"
|
||||
#include "types.h"
|
||||
#include "frontend/mic_blow.h"
|
||||
|
||||
#include "emulibc.h"
|
||||
#include "waterboxcore.h"
|
||||
#include "BizPlatform/BizConfig.h"
|
||||
#include "BizPlatform/BizFile.h"
|
||||
#include "BizPlatform/BizLog.h"
|
||||
#include "BizFileManager.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <time.h>
|
||||
#include <emulibc.h>
|
||||
#include <waterboxcore.h>
|
||||
|
||||
#include <sstream>
|
||||
static bool SkipFW;
|
||||
static time_t CurTime;
|
||||
|
||||
constexpr u32 DSIWARE_CATEGORY = 0x00030004;
|
||||
|
||||
static GPU::RenderSettings biz_render_settings { false, 1, false };
|
||||
static bool biz_skip_fw;
|
||||
static time_t biz_time;
|
||||
|
||||
static time_t BizRtcCallback()
|
||||
struct InitConfig
|
||||
{
|
||||
return biz_time;
|
||||
}
|
||||
bool SkipFW;
|
||||
bool HasGBACart;
|
||||
bool DSi;
|
||||
bool ClearNAND;
|
||||
bool LoadDSiWare;
|
||||
int ThreeDeeRenderer;
|
||||
GPU::RenderSettings RenderSettings;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
ECL_EXPORT const char* Init(InitConfig* initConfig,
|
||||
Platform::ConfigCallbackInterface* configCallbackInterface,
|
||||
Platform::FileCallbackInterface* fileCallbackInterface,
|
||||
Platform::LogCallback_t logCallback)
|
||||
{
|
||||
NONE = 0x00,
|
||||
USE_REAL_BIOS = 0x01,
|
||||
SKIP_FIRMWARE = 0x02,
|
||||
GBA_CART_PRESENT = 0x04,
|
||||
CLEAR_NAND = 0x08,
|
||||
FIRMWARE_OVERRIDE = 0x10,
|
||||
IS_DSI = 0x20,
|
||||
LOAD_DSIWARE = 0x40,
|
||||
THREADED_RENDERING = 0x80,
|
||||
} LoadFlags;
|
||||
Platform::SetConfigCallbacks(*configCallbackInterface);
|
||||
Platform::SetFileCallbacks(*fileCallbackInterface);
|
||||
Platform::SetLogCallback(logCallback);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8* DsRomData;
|
||||
u32 DsRomLen;
|
||||
u8* GbaRomData;
|
||||
u32 GbaRomLen;
|
||||
u8* GbaRamData;
|
||||
u32 GbaRamLen;
|
||||
char* NandData;
|
||||
u32 NandLen;
|
||||
u8* TmdData;
|
||||
s32 AudioBitrate;
|
||||
} LoadData;
|
||||
SkipFW = initConfig->SkipFW;
|
||||
NDS::SetConsoleType(initConfig->DSi);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char* FirmwareUsername; // max 10 length (then terminator)
|
||||
s32 FirmwareUsernameLength;
|
||||
s32 FirmwareLanguage;
|
||||
s32 FirmwareBirthdayMonth;
|
||||
s32 FirmwareBirthdayDay;
|
||||
s32 FirmwareFavouriteColour;
|
||||
char* FirmwareMessage; // max 26 length (then terminator)
|
||||
s32 FirmwareMessageLength;
|
||||
} FirmwareSettings;
|
||||
CurTime = 0;
|
||||
RTC::RtcCallback = []() { return CurTime; };
|
||||
|
||||
extern std::stringstream* NANDFilePtr;
|
||||
|
||||
ECL_EXPORT bool Init(LoadFlags loadFlags, LoadData* loadData, FirmwareSettings* fwSettings)
|
||||
{
|
||||
Config::ExternalBIOSEnable = !!(loadFlags & USE_REAL_BIOS);
|
||||
Config::AudioBitrate = loadData->AudioBitrate;
|
||||
Config::FirmwareOverrideSettings = !!(loadFlags & FIRMWARE_OVERRIDE);
|
||||
biz_skip_fw = !!(loadFlags & SKIP_FIRMWARE);
|
||||
bool isDsi = !!(loadFlags & IS_DSI);
|
||||
|
||||
NDS::SetConsoleType(isDsi);
|
||||
biz_time = 0;
|
||||
RTC::RtcCallback = BizRtcCallback;
|
||||
|
||||
if (Config::FirmwareOverrideSettings)
|
||||
if (initConfig->DSi)
|
||||
{
|
||||
std::string fwUsername(fwSettings->FirmwareUsername, fwSettings->FirmwareUsernameLength);
|
||||
fwUsername += '\0';
|
||||
Config::FirmwareUsername = fwUsername;
|
||||
Config::FirmwareLanguage = fwSettings->FirmwareLanguage;
|
||||
Config::FirmwareBirthdayMonth = fwSettings->FirmwareBirthdayMonth;
|
||||
Config::FirmwareBirthdayDay = fwSettings->FirmwareBirthdayDay;
|
||||
Config::FirmwareFavouriteColour = fwSettings->FirmwareFavouriteColour;
|
||||
std::string fwMessage(fwSettings->FirmwareMessage, fwSettings->FirmwareMessageLength);
|
||||
fwMessage += '\0';
|
||||
Config::FirmwareMessage = fwMessage;
|
||||
Config::FirmwareMAC = "00:09:BF:0E:49:16"; // TODO: Make configurable
|
||||
if (const char* error = FileManager::InitNAND(initConfig->ClearNAND, initConfig->LoadDSiWare))
|
||||
{
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
NANDFilePtr = isDsi ? new std::stringstream(std::string(loadData->NandData, loadData->NandLen), std::ios_base::in | std::ios_base::out | std::ios_base::binary) : nullptr;
|
||||
|
||||
if (isDsi)
|
||||
if (!NDS::Init())
|
||||
{
|
||||
FILE* bios7i = Platform::OpenLocalFile(Config::DSiBIOS7Path, "rb");
|
||||
if (!bios7i)
|
||||
return false;
|
||||
|
||||
u8 es_keyY[16];
|
||||
fseek(bios7i, 0x8308, SEEK_SET);
|
||||
fread(es_keyY, 16, 1, bios7i);
|
||||
fclose(bios7i);
|
||||
|
||||
if (!DSi_NAND::Init(es_keyY))
|
||||
return false;
|
||||
|
||||
if (loadFlags & CLEAR_NAND)
|
||||
{
|
||||
std::vector<u32> titlelist;
|
||||
DSi_NAND::ListTitles(DSIWARE_CATEGORY, titlelist);
|
||||
|
||||
for (auto& title : titlelist)
|
||||
{
|
||||
DSi_NAND::DeleteTitle(DSIWARE_CATEGORY, title);
|
||||
}
|
||||
}
|
||||
|
||||
if (loadFlags & LOAD_DSIWARE)
|
||||
{
|
||||
if (!DSi_NAND::ImportTitle("dsiware.rom", loadData->TmdData, false))
|
||||
{
|
||||
DSi_NAND::DeInit();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
DSi_NAND::DeInit();
|
||||
return "Failed to init core!";
|
||||
}
|
||||
|
||||
if (!NDS::Init()) return false;
|
||||
GPU::InitRenderer(false);
|
||||
biz_render_settings.Soft_Threaded = !!(loadFlags & THREADED_RENDERING);
|
||||
GPU::SetRenderSettings(false, biz_render_settings);
|
||||
GPU::InitRenderer(initConfig->ThreeDeeRenderer);
|
||||
GPU::SetRenderSettings(initConfig->ThreeDeeRenderer, initConfig->RenderSettings);
|
||||
|
||||
NDS::LoadBIOS();
|
||||
if (!isDsi || !(loadFlags & LOAD_DSIWARE))
|
||||
|
||||
if (!initConfig->LoadDSiWare)
|
||||
{
|
||||
if (!NDS::LoadCart(loadData->DsRomData, loadData->DsRomLen, nullptr, 0))
|
||||
return false;
|
||||
if (const char* error = FileManager::InitCarts(initConfig->HasGBACart))
|
||||
{
|
||||
return error;
|
||||
}
|
||||
}
|
||||
if (!isDsi && (loadFlags & GBA_CART_PRESENT))
|
||||
|
||||
if (SkipFW || NDS::NeedsDirectBoot())
|
||||
{
|
||||
if (!NDS::LoadGBACart(loadData->GbaRomData, loadData->GbaRomLen, loadData->GbaRamData, loadData->GbaRamLen))
|
||||
return false;
|
||||
NDS::SetupDirectBoot("nds.rom");
|
||||
}
|
||||
if (biz_skip_fw) NDS::SetupDirectBoot("");
|
||||
|
||||
NDS::Start();
|
||||
Config::FirmwareOverrideSettings = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace NDSCart { extern CartCommon* Cart; }
|
||||
extern bool NdsSaveRamIsDirty;
|
||||
|
||||
ECL_EXPORT void PutSaveRam(u8* data, u32 len)
|
||||
{
|
||||
NDS::LoadSave(data, len);
|
||||
NdsSaveRamIsDirty = false;
|
||||
}
|
||||
|
||||
ECL_EXPORT void GetSaveRam(u8* data)
|
||||
{
|
||||
if (NDSCart::Cart)
|
||||
{
|
||||
NDSCart::Cart->GetSaveData(data);
|
||||
NdsSaveRamIsDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
ECL_EXPORT u32 GetSaveRamLength()
|
||||
{
|
||||
return NDSCart::Cart ? NDSCart::Cart->GetSaveLen() : 0;
|
||||
}
|
||||
|
||||
ECL_EXPORT bool SaveRamIsDirty()
|
||||
{
|
||||
return NdsSaveRamIsDirty;
|
||||
}
|
||||
|
||||
ECL_EXPORT void ImportDSiWareSavs(u32 titleId)
|
||||
{
|
||||
if (DSi_NAND::Init(&DSi::ARM7iBIOS[0x8308]))
|
||||
{
|
||||
DSi_NAND::ImportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_PublicSav, "public.sav");
|
||||
DSi_NAND::ImportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_PrivateSav, "private.sav");
|
||||
DSi_NAND::ImportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_BannerSav, "banner.sav");
|
||||
DSi_NAND::DeInit();
|
||||
}
|
||||
}
|
||||
|
||||
ECL_EXPORT void ExportDSiWareSavs(u32 titleId)
|
||||
{
|
||||
if (DSi_NAND::Init(&DSi::ARM7iBIOS[0x8308]))
|
||||
{
|
||||
DSi_NAND::ExportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_PublicSav, "public.sav");
|
||||
DSi_NAND::ExportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_PrivateSav, "private.sav");
|
||||
DSi_NAND::ExportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_BannerSav, "banner.sav");
|
||||
DSi_NAND::DeInit();
|
||||
}
|
||||
}
|
||||
|
||||
ECL_EXPORT void DSiWareSavsLength(u32 titleId, u32* publicSavSize, u32* privateSavSize, u32* bannerSavSize)
|
||||
{
|
||||
*publicSavSize = *privateSavSize = *bannerSavSize = 0;
|
||||
if (DSi_NAND::Init(&DSi::ARM7iBIOS[0x8308]))
|
||||
{
|
||||
u32 version;
|
||||
NDSHeader header{};
|
||||
|
||||
DSi_NAND::GetTitleInfo(DSIWARE_CATEGORY, titleId, version, &header, nullptr);
|
||||
*publicSavSize = header.DSiPublicSavSize;
|
||||
*privateSavSize = header.DSiPrivateSavSize;
|
||||
*bannerSavSize = (header.AppFlags & 0x04) ? 0x4000 : 0;
|
||||
DSi_NAND::DeInit();
|
||||
}
|
||||
}
|
||||
|
||||
/* excerpted from gbatek
|
||||
|
||||
NDS9 Memory Map
|
||||
|
||||
00000000h Instruction TCM (32KB) (not moveable) (mirror-able to 1000000h)
|
||||
0xxxx000h Data TCM (16KB) (moveable)
|
||||
02000000h Main Memory (4MB)
|
||||
03000000h Shared WRAM (0KB, 16KB, or 32KB can be allocated to ARM9)
|
||||
04000000h ARM9-I/O Ports
|
||||
05000000h Standard Palettes (2KB) (Engine A BG/OBJ, Engine B BG/OBJ)
|
||||
06000000h VRAM - Engine A, BG VRAM (max 512KB)
|
||||
06200000h VRAM - Engine B, BG VRAM (max 128KB)
|
||||
06400000h VRAM - Engine A, OBJ VRAM (max 256KB)
|
||||
06600000h VRAM - Engine B, OBJ VRAM (max 128KB)
|
||||
06800000h VRAM - "LCDC"-allocated (max 656KB)
|
||||
07000000h OAM (2KB) (Engine A, Engine B)
|
||||
08000000h GBA Slot ROM (max 32MB)
|
||||
0A000000h GBA Slot RAM (max 64KB)
|
||||
FFFF0000h ARM9-BIOS (32KB) (only 3K used)
|
||||
|
||||
NDS7 Memory Map
|
||||
|
||||
00000000h ARM7-BIOS (16KB)
|
||||
02000000h Main Memory (4MB)
|
||||
03000000h Shared WRAM (0KB, 16KB, or 32KB can be allocated to ARM7)
|
||||
03800000h ARM7-WRAM (64KB)
|
||||
04000000h ARM7-I/O Ports
|
||||
04800000h Wireless Communications Wait State 0 (8KB RAM at 4804000h)
|
||||
04808000h Wireless Communications Wait State 1 (I/O Ports at 4808000h)
|
||||
06000000h VRAM allocated as Work RAM to ARM7 (max 256K)
|
||||
08000000h GBA Slot ROM (max 32MB)
|
||||
0A000000h GBA Slot RAM (max 64KB)
|
||||
|
||||
Further Memory (not mapped to ARM9/ARM7 bus)
|
||||
|
||||
3D Engine Polygon RAM (52KBx2)
|
||||
3D Engine Vertex RAM (72KBx2)
|
||||
Firmware (256KB) (built-in serial flash memory)
|
||||
GBA-BIOS (16KB) (not used in NDS mode)
|
||||
NDS Slot ROM (serial 8bit-bus, max 4GB with default protocol)
|
||||
NDS Slot FLASH/EEPROM/FRAM (serial 1bit-bus)
|
||||
|
||||
*/
|
||||
|
||||
template<bool arm9>
|
||||
static bool SafeToPeek(u32 addr)
|
||||
{
|
||||
if (arm9)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
case 0x04000130:
|
||||
case 0x04000131:
|
||||
case 0x04000600:
|
||||
case 0x04000601:
|
||||
case 0x04000602:
|
||||
case 0x04000603:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else // arm7
|
||||
{
|
||||
if (addr >= 0x04800000 && addr <= 0x04810000)
|
||||
{
|
||||
if (addr & 1) addr--;
|
||||
addr &= 0x7FFE;
|
||||
if (addr == 0x044 || addr == 0x060)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ARM9Access(u8* buffer, s64 address, s64 count, bool write)
|
||||
{
|
||||
if (write)
|
||||
{
|
||||
void (*Write)(u32, u8) = NDS::ConsoleType == 1 ? DSi::ARM9Write8 : NDS::ARM9Write8;
|
||||
while (count--)
|
||||
{
|
||||
if (address < NDS::ARM9->ITCMSize)
|
||||
{
|
||||
NDS::ARM9->ITCM[address++ & (ITCMPhysicalSize - 1)] = *buffer++;
|
||||
}
|
||||
else if ((address & NDS::ARM9->DTCMMask) == NDS::ARM9->DTCMBase)
|
||||
{
|
||||
NDS::ARM9->DTCM[address++ & (DTCMPhysicalSize - 1)] = *buffer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Write(address++, *buffer++);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
u8 (*Read)(u32) = NDS::ConsoleType == 1 ? DSi::ARM9Read8 : NDS::ARM9Read8;
|
||||
while (count--)
|
||||
{
|
||||
if (address < NDS::ARM9->ITCMSize)
|
||||
{
|
||||
*buffer++ = NDS::ARM9->ITCM[address & (ITCMPhysicalSize - 1)];
|
||||
}
|
||||
else if ((address & NDS::ARM9->DTCMMask) == NDS::ARM9->DTCMBase)
|
||||
{
|
||||
*buffer++ = NDS::ARM9->DTCM[address & (DTCMPhysicalSize - 1)];
|
||||
}
|
||||
else
|
||||
{
|
||||
*buffer++ = SafeToPeek<true>(address) ? Read(address) : 0;
|
||||
}
|
||||
|
||||
address++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ARM7Access(u8* buffer, s64 address, s64 count, bool write)
|
||||
{
|
||||
if (write)
|
||||
{
|
||||
void (*Write)(u32, u8) = NDS::ConsoleType == 1 ? DSi::ARM7Write8 : NDS::ARM7Write8;
|
||||
while (count--)
|
||||
Write(address++, *buffer++);
|
||||
}
|
||||
else
|
||||
{
|
||||
u8 (*Read)(u32) = NDS::ConsoleType == 1 ? DSi::ARM7Read8 : NDS::ARM7Read8;
|
||||
while (count--)
|
||||
*buffer++ = SafeToPeek<true>(address) ? Read(address) : 0, address++;
|
||||
}
|
||||
}
|
||||
|
||||
ECL_EXPORT void GetMemoryAreas(MemoryArea *m)
|
||||
{
|
||||
m[0].Data = NDS::MainRAM;
|
||||
m[0].Name = "Main RAM";
|
||||
m[0].Size = NDS::MainRAMMaxSize;
|
||||
m[0].Flags = MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_PRIMARY;
|
||||
|
||||
m[1].Data = NDS::SharedWRAM;
|
||||
m[1].Name = "Shared WRAM";
|
||||
m[1].Size = NDS::SharedWRAMSize;
|
||||
m[1].Flags = MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_WRITABLE;
|
||||
|
||||
m[2].Data = NDS::ARM7WRAM;
|
||||
m[2].Name = "ARM7 WRAM";
|
||||
m[2].Size = NDS::ARM7WRAMSize;
|
||||
m[2].Flags = MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_WRITABLE;
|
||||
|
||||
m[3].Data = NDS::ARM9->ITCM;
|
||||
m[3].Name = "Instruction TCM";
|
||||
m[3].Size = ITCMPhysicalSize;
|
||||
m[3].Flags = MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_WRITABLE;
|
||||
|
||||
m[4].Data = NDS::ARM9->DTCM;
|
||||
m[4].Name = "Data TCM";
|
||||
m[4].Size = DTCMPhysicalSize;
|
||||
m[4].Flags = MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_WRITABLE;
|
||||
|
||||
m[5].Data = NDS::ARM9BIOS;
|
||||
m[5].Name = "ARM9 BIOS";
|
||||
m[5].Size = sizeof NDS::ARM9BIOS;
|
||||
m[5].Flags = MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_WRITABLE;
|
||||
|
||||
m[6].Data = NDS::ARM7BIOS;
|
||||
m[6].Name = "ARM7 BIOS";
|
||||
m[6].Size = sizeof NDS::ARM7BIOS;
|
||||
m[6].Flags = MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_WRITABLE;
|
||||
|
||||
m[7].Data = (void*)ARM9Access;
|
||||
m[7].Name = "ARM9 System Bus";
|
||||
m[7].Size = 1ull << 32;
|
||||
m[7].Flags = MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_FUNCTIONHOOK;
|
||||
|
||||
m[8].Data = (void*)ARM7Access;
|
||||
m[8].Name = "ARM7 System Bus";
|
||||
m[8].Size = 1ull << 32;
|
||||
m[8].Flags = MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_FUNCTIONHOOK;
|
||||
|
||||
// fixme: include more shit
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct MyFrameInfo : public FrameInfo
|
||||
|
@ -432,11 +100,11 @@ static int sampPos = 0;
|
|||
|
||||
static void MicFeedNoise(s8 vol)
|
||||
{
|
||||
int sampLen = sizeof mic_blow / sizeof mic_blow[0];
|
||||
int sampLen = sizeof(mic_blow) / sizeof (*mic_blow);
|
||||
|
||||
for (int i = 0; i < 735; i++)
|
||||
{
|
||||
biz_mic_input[i] = std::round(mic_blow[sampPos++] * (vol / 100.0));
|
||||
biz_mic_input[i] = round(mic_blow[sampPos++] * (vol / 100.0));
|
||||
if (sampPos >= sampLen) sampPos = 0;
|
||||
}
|
||||
}
|
||||
|
@ -450,7 +118,11 @@ ECL_EXPORT void FrameAdvance(MyFrameInfo* f)
|
|||
if (f->Keys & 0x8000)
|
||||
{
|
||||
NDS::LoadBIOS();
|
||||
if (biz_skip_fw) NDS::SetupDirectBoot("");
|
||||
if (SkipFW || NDS::NeedsDirectBoot())
|
||||
{
|
||||
NDS::SetupDirectBoot("nds.rom");
|
||||
}
|
||||
|
||||
NDS::Start();
|
||||
}
|
||||
|
||||
|
@ -466,12 +138,15 @@ ECL_EXPORT void FrameAdvance(MyFrameInfo* f)
|
|||
}
|
||||
|
||||
if (f->Keys & 0x2000)
|
||||
{
|
||||
NDS::SetLidClosed(false);
|
||||
}
|
||||
else if (f->Keys & 0x4000)
|
||||
{
|
||||
NDS::SetLidClosed(true);
|
||||
}
|
||||
|
||||
MicFeedNoise(f->MicVolume);
|
||||
|
||||
NDS::MicInputFrame(biz_mic_input, 735);
|
||||
|
||||
int sensor = GBACart::SetInput(0, 1);
|
||||
|
@ -479,161 +154,53 @@ ECL_EXPORT void FrameAdvance(MyFrameInfo* f)
|
|||
{
|
||||
if (sensor > f->GBALightSensor)
|
||||
{
|
||||
while (GBACart::SetInput(0, 1) != f->GBALightSensor) {}
|
||||
while (GBACart::SetInput(0, 1) != f->GBALightSensor);
|
||||
}
|
||||
else if (sensor < f->GBALightSensor)
|
||||
{
|
||||
while (GBACart::SetInput(1, 1) != f->GBALightSensor) {}
|
||||
while (GBACart::SetInput(1, 1) != f->GBALightSensor);
|
||||
}
|
||||
}
|
||||
|
||||
biz_time = f->Time;
|
||||
CurTime = f->Time;
|
||||
|
||||
NDS::RunFrame();
|
||||
dynamic_cast<GPU3D::SoftRenderer*>(GPU3D::CurrentRenderer.get())->StopRenderThread();
|
||||
|
||||
if (auto softRenderer = dynamic_cast<GPU3D::SoftRenderer*>(GPU3D::CurrentRenderer.get()))
|
||||
{
|
||||
softRenderer->StopRenderThread();
|
||||
}
|
||||
|
||||
const u32 SingleScreenSize = 256 * 192;
|
||||
memcpy(f->VideoBuffer, GPU::Framebuffer[GPU::FrontBuffer][0], SingleScreenSize * sizeof (u32));
|
||||
memcpy(f->VideoBuffer + SingleScreenSize, GPU::Framebuffer[GPU::FrontBuffer][1], SingleScreenSize * sizeof (u32));
|
||||
|
||||
f->Width = 256;
|
||||
f->Height = 384;
|
||||
|
||||
f->Samples = SPU::ReadOutput(f->SoundBuffer);
|
||||
if (f->Samples < 737) // hack
|
||||
if (f->Samples == 0) // hack
|
||||
{
|
||||
memset(f->SoundBuffer + (f->Samples * 2), 0, ((737 * 2) - (f->Samples * 2)) * sizeof (u16));
|
||||
memset(f->SoundBuffer, 0, 737 * 2 * sizeof (u16));
|
||||
f->Samples = 737;
|
||||
}
|
||||
|
||||
f->Cycles = NDS::GetSysClockCycles(2);
|
||||
f->Lagged = NDS::LagFrameFlag;
|
||||
|
||||
// if we want to consider other lag sources, use that lag flag if we haven't unlagged already
|
||||
if (f->ConsiderAltLag && NDS::LagFrameFlag)
|
||||
{
|
||||
f->Lagged = NDS::AltLagFrameFlag;
|
||||
}
|
||||
else
|
||||
{
|
||||
f->Lagged = NDS::LagFrameFlag;
|
||||
}
|
||||
|
||||
RunningFrame = false;
|
||||
}
|
||||
|
||||
void (*InputCallback)() = nullptr;
|
||||
|
||||
ECL_EXPORT void SetInputCallback(void (*callback)())
|
||||
{
|
||||
InputCallback = callback;
|
||||
}
|
||||
|
||||
ECL_EXPORT void GetRegs(u32* regs)
|
||||
{
|
||||
NDS::GetRegs(regs);
|
||||
}
|
||||
|
||||
ECL_EXPORT void SetReg(s32 ncpu, s32 index, s32 val)
|
||||
{
|
||||
NDS::SetReg(ncpu, index, val);
|
||||
}
|
||||
|
||||
ECL_EXPORT u32 GetCallbackCycleOffset()
|
||||
{
|
||||
return RunningFrame ? NDS::GetSysClockCycles(2) : 0;
|
||||
}
|
||||
|
||||
void (*ReadCallback)(u32) = nullptr;
|
||||
void (*WriteCallback)(u32) = nullptr;
|
||||
void (*ExecuteCallback)(u32) = nullptr;
|
||||
|
||||
ECL_EXPORT void SetMemoryCallback(u32 which, void (*callback)(u32 addr))
|
||||
{
|
||||
switch (which)
|
||||
{
|
||||
case 0: ReadCallback = callback; break;
|
||||
case 1: WriteCallback = callback; break;
|
||||
case 2: ExecuteCallback = callback; break;
|
||||
}
|
||||
}
|
||||
|
||||
TraceMask_t TraceMask = TRACE_NONE;
|
||||
static void (*TraceCallback)(TraceMask_t, u32, u32*, char*, u32) = nullptr;
|
||||
#define TRACE_STRING_LENGTH 80
|
||||
typedef enum {
|
||||
ARMv4T, //ARM v4, THUMB v1
|
||||
ARMv5TE, //ARM v5, THUMB v2
|
||||
ARMv6, //ARM v6, THUMB v3
|
||||
} ARMARCH; //only 32-bit legacy architectures with THUMB support
|
||||
extern "C" u32 Disassemble_thumb(u32 code, char str[TRACE_STRING_LENGTH], ARMARCH tv);
|
||||
extern "C" void Disassemble_arm(u32 code, char str[TRACE_STRING_LENGTH], ARMARCH av);
|
||||
|
||||
void TraceTrampoline(TraceMask_t type, u32* regs, u32 opcode)
|
||||
{
|
||||
static char disasm[TRACE_STRING_LENGTH];
|
||||
memset(disasm, 0, sizeof disasm);
|
||||
switch (type) {
|
||||
case TRACE_ARM7_THUMB: Disassemble_thumb(opcode, disasm, ARMv4T); break;
|
||||
case TRACE_ARM7_ARM: Disassemble_arm(opcode, disasm, ARMv4T); break;
|
||||
case TRACE_ARM9_THUMB: Disassemble_thumb(opcode, disasm, ARMv5TE); break;
|
||||
case TRACE_ARM9_ARM: Disassemble_arm(opcode, disasm, ARMv5TE); break;
|
||||
default: __builtin_unreachable();
|
||||
}
|
||||
TraceCallback(type, opcode, regs, disasm, NDS::GetSysClockCycles(2));
|
||||
}
|
||||
|
||||
ECL_EXPORT void SetTraceCallback(void (*callback)(TraceMask_t mask, u32 opcode, u32* regs, char* disasm, u32 cyclesOff), TraceMask_t mask)
|
||||
{
|
||||
TraceCallback = callback;
|
||||
TraceMask = callback ? mask : TRACE_NONE;
|
||||
}
|
||||
|
||||
ECL_EXPORT void GetDisassembly(TraceMask_t type, u32 opcode, char* ret)
|
||||
{
|
||||
static char disasm[TRACE_STRING_LENGTH];
|
||||
memset(disasm, 0, sizeof disasm);
|
||||
switch (type) {
|
||||
case TRACE_ARM7_THUMB: Disassemble_thumb(opcode, disasm, ARMv4T); break;
|
||||
case TRACE_ARM7_ARM: Disassemble_arm(opcode, disasm, ARMv4T); break;
|
||||
case TRACE_ARM9_THUMB: Disassemble_thumb(opcode, disasm, ARMv5TE); break;
|
||||
case TRACE_ARM9_ARM: Disassemble_arm(opcode, disasm, ARMv5TE); break;
|
||||
default: __builtin_unreachable();
|
||||
}
|
||||
memcpy(ret, disasm, TRACE_STRING_LENGTH);
|
||||
}
|
||||
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
extern uintptr_t FrameThreadProc;
|
||||
extern void (*ThreadStartCallback)();
|
||||
}
|
||||
|
||||
ECL_EXPORT uintptr_t GetFrameThreadProc()
|
||||
{
|
||||
return Platform::FrameThreadProc;
|
||||
}
|
||||
|
||||
ECL_EXPORT void SetThreadStartCallback(void (*callback)())
|
||||
{
|
||||
Platform::ThreadStartCallback = callback;
|
||||
}
|
||||
|
||||
ECL_EXPORT u32 GetNANDSize()
|
||||
{
|
||||
if (NANDFilePtr)
|
||||
{
|
||||
NANDFilePtr->seekg(0, std::ios::end);
|
||||
return NANDFilePtr->tellg();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ECL_EXPORT void GetNANDData(char* buf)
|
||||
{
|
||||
if (NANDFilePtr)
|
||||
{
|
||||
u32 sz = GetNANDSize();
|
||||
NANDFilePtr->seekg(0);
|
||||
NANDFilePtr->read(buf, sz);
|
||||
}
|
||||
}
|
||||
|
||||
namespace GPU { void ResetVRAMCache(); }
|
||||
|
||||
ECL_EXPORT void ResetCaches()
|
||||
{
|
||||
GPU::ResetVRAMCache();
|
||||
}
|
||||
|
|
|
@ -1,338 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <mutex>
|
||||
#include "Platform.h"
|
||||
#include "BizConfig.h"
|
||||
|
||||
bool NdsSaveRamIsDirty = false;
|
||||
std::stringstream* NANDFilePtr = NULL;
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
|
||||
void Init(int argc, char** argv)
|
||||
{
|
||||
}
|
||||
|
||||
void DeInit()
|
||||
{
|
||||
}
|
||||
|
||||
void StopEmu()
|
||||
{
|
||||
}
|
||||
|
||||
int InstanceID()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string InstanceFileSuffix()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
int GetConfigInt(ConfigEntry entry)
|
||||
{
|
||||
const int imgsizes[] = {0, 256, 512, 1024, 2048, 4096};
|
||||
|
||||
switch (entry)
|
||||
{
|
||||
#ifdef JIT_ENABLED
|
||||
case JIT_MaxBlockSize: return Config::JIT_MaxBlockSize;
|
||||
#endif
|
||||
|
||||
case DLDI_ImageSize: return imgsizes[Config::DLDISize];
|
||||
|
||||
case DSiSD_ImageSize: return imgsizes[Config::DSiSDSize];
|
||||
|
||||
case Firm_Language: return Config::FirmwareLanguage;
|
||||
case Firm_BirthdayMonth: return Config::FirmwareBirthdayMonth;
|
||||
case Firm_BirthdayDay: return Config::FirmwareBirthdayDay;
|
||||
case Firm_Color: return Config::FirmwareFavouriteColour;
|
||||
|
||||
case AudioBitrate: return Config::AudioBitrate;
|
||||
|
||||
case TimeAtBoot: return Config::TimeAtBoot;
|
||||
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool GetConfigBool(ConfigEntry entry)
|
||||
{
|
||||
switch (entry)
|
||||
{
|
||||
#ifdef JIT_ENABLED
|
||||
case JIT_Enable: return Config::JIT_Enable != 0;
|
||||
case JIT_LiteralOptimizations: return Config::JIT_LiteralOptimisations != 0;
|
||||
case JIT_BranchOptimizations: return Config::JIT_BranchOptimisations != 0;
|
||||
case JIT_FastMemory: return Config::JIT_FastMemory != 0;
|
||||
#endif
|
||||
|
||||
case ExternalBIOSEnable: return Config::ExternalBIOSEnable != 0;
|
||||
|
||||
case DLDI_Enable: return Config::DLDIEnable != 0;
|
||||
case DLDI_ReadOnly: return Config::DLDIReadOnly != 0;
|
||||
case DLDI_FolderSync: return Config::DLDIFolderSync != 0;
|
||||
|
||||
case DSiSD_Enable: return Config::DSiSDEnable != 0;
|
||||
case DSiSD_ReadOnly: return Config::DSiSDReadOnly != 0;
|
||||
case DSiSD_FolderSync: return Config::DSiSDFolderSync != 0;
|
||||
|
||||
case Firm_OverrideSettings: return Config::FirmwareOverrideSettings != 0;
|
||||
|
||||
case UseRealTime: return Config::UseRealTime != 0;
|
||||
case FixedBootTime: return Config::FixedBootTime != 0;
|
||||
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string GetConfigString(ConfigEntry entry)
|
||||
{
|
||||
switch (entry)
|
||||
{
|
||||
case BIOS9Path: return Config::BIOS9Path;
|
||||
case BIOS7Path: return Config::BIOS7Path;
|
||||
case FirmwarePath: return Config::FirmwarePath;
|
||||
|
||||
case DSi_BIOS9Path: return Config::DSiBIOS9Path;
|
||||
case DSi_BIOS7Path: return Config::DSiBIOS7Path;
|
||||
case DSi_FirmwarePath: return Config::DSiFirmwarePath;
|
||||
case DSi_NANDPath: return Config::DSiNANDPath;
|
||||
|
||||
case DLDI_ImagePath: return Config::DLDISDPath;
|
||||
case DLDI_FolderPath: return Config::DLDIFolderPath;
|
||||
|
||||
case DSiSD_ImagePath: return Config::DSiSDPath;
|
||||
case DSiSD_FolderPath: return Config::DSiSDFolderPath;
|
||||
|
||||
case Firm_Username: return Config::FirmwareUsername;
|
||||
case Firm_Message: return Config::FirmwareMessage;
|
||||
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
bool GetConfigArray(ConfigEntry entry, void* data)
|
||||
{
|
||||
switch (entry)
|
||||
{
|
||||
case Firm_MAC:
|
||||
{
|
||||
std::string& mac_in = Config::FirmwareMAC;
|
||||
u8* mac_out = (u8*)data;
|
||||
|
||||
int o = 0;
|
||||
u8 tmp = 0;
|
||||
for (int i = 0; i < 18; i++)
|
||||
{
|
||||
char c = mac_in[i];
|
||||
if (c == '\0') break;
|
||||
|
||||
int n;
|
||||
if (c >= '0' && c <= '9') n = c - '0';
|
||||
else if (c >= 'a' && c <= 'f') n = c - 'a' + 10;
|
||||
else if (c >= 'A' && c <= 'F') n = c - 'A' + 10;
|
||||
else continue;
|
||||
|
||||
if (!(o & 1))
|
||||
tmp = n;
|
||||
else
|
||||
mac_out[o >> 1] = n | (tmp << 4);
|
||||
|
||||
o++;
|
||||
if (o >= 12) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FILE* OpenFile(std::string path, std::string mode, bool mustexist)
|
||||
{
|
||||
if (path == Config::DSiNANDPath) return reinterpret_cast<FILE*>(NANDFilePtr);
|
||||
|
||||
return fopen(path.c_str(), mode.c_str());
|
||||
}
|
||||
|
||||
FILE* OpenLocalFile(std::string path, std::string mode)
|
||||
{
|
||||
if (path == Config::DSiNANDPath) return reinterpret_cast<FILE*>(NANDFilePtr);
|
||||
|
||||
return fopen(path.c_str(), mode.c_str());
|
||||
}
|
||||
|
||||
uintptr_t FrameThreadProc = 0;
|
||||
std::function<void()> ThreadEntryFunc = nullptr;
|
||||
void (*ThreadStartCallback)() = nullptr;
|
||||
|
||||
void ThreadEntry()
|
||||
{
|
||||
ThreadEntryFunc();
|
||||
}
|
||||
|
||||
Thread* Thread_Create(std::function<void()> func)
|
||||
{
|
||||
ThreadEntryFunc = func;
|
||||
FrameThreadProc = reinterpret_cast<uintptr_t>(ThreadEntry);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Thread_Free(Thread* thread)
|
||||
{
|
||||
}
|
||||
|
||||
void Thread_Wait(Thread* thread) // hijacked to act as a thread start, consider this "wait for start of thread"
|
||||
{
|
||||
ThreadStartCallback();
|
||||
}
|
||||
|
||||
Semaphore* Semaphore_Create()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Semaphore_Free(Semaphore* sema)
|
||||
{
|
||||
}
|
||||
|
||||
void Semaphore_Reset(Semaphore* sema)
|
||||
{
|
||||
}
|
||||
|
||||
void Semaphore_Wait(Semaphore* sema)
|
||||
{
|
||||
}
|
||||
|
||||
void Semaphore_Post(Semaphore* sema, int count)
|
||||
{
|
||||
}
|
||||
|
||||
Mutex* Mutex_Create()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Mutex_Free(Mutex* mutex)
|
||||
{
|
||||
}
|
||||
|
||||
void Mutex_Lock(Mutex* mutex)
|
||||
{
|
||||
}
|
||||
|
||||
void Mutex_Unlock(Mutex* mutex)
|
||||
{
|
||||
}
|
||||
|
||||
bool Mutex_TryLock(Mutex* mutex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void WriteNDSSave(const u8* savedata, u32 savelen, u32 writeoffset, u32 writelen)
|
||||
{
|
||||
NdsSaveRamIsDirty = true;
|
||||
}
|
||||
|
||||
void WriteGBASave(const u8* savedata, u32 savelen, u32 writeoffset, u32 writelen)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool MP_Init()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void MP_DeInit()
|
||||
{
|
||||
}
|
||||
|
||||
void MP_Begin()
|
||||
{
|
||||
}
|
||||
|
||||
void MP_End()
|
||||
{
|
||||
}
|
||||
|
||||
int MP_SendPacket(u8* data, int len, u64 timestamp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MP_RecvPacket(u8* data, u64* timestamp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MP_SendCmd(u8* data, int len, u64 timestamp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MP_SendReply(u8* data, int len, u64 timestamp, u16 aid)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MP_SendAck(u8* data, int len, u64 timestamp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MP_RecvHostPacket(u8* data, u64* timestamp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
u16 MP_RecvReplies(u8* data, u64 timestamp, u16 aidmask)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool LAN_Init()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void LAN_DeInit()
|
||||
{
|
||||
}
|
||||
|
||||
int LAN_SendPacket(u8* data, int len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LAN_RecvPacket(u8* data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Sleep(u64 usecs)
|
||||
{
|
||||
}
|
||||
|
||||
void Camera_Start(int num)
|
||||
{
|
||||
}
|
||||
|
||||
void Camera_Stop(int num)
|
||||
{
|
||||
}
|
||||
|
||||
void Camera_CaptureFrame(int num, u32* frame, int width, int height, bool yuv)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
#include "BizConfig.h"
|
||||
|
||||
#include <emulibc.h>
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
|
||||
struct ConfigCallbackInterface
|
||||
{
|
||||
bool (*GetBoolean)(ConfigEntry entry);
|
||||
int (*GetInteger)(ConfigEntry entry);
|
||||
void (*GetString)(ConfigEntry entry, char* buffer, int bufferSize);
|
||||
bool (*GetArray)(ConfigEntry entry, void* buffer);
|
||||
};
|
||||
|
||||
ECL_INVISIBLE static ConfigCallbackInterface ConfigCallbacks;
|
||||
|
||||
void SetConfigCallbacks(ConfigCallbackInterface& configCallbackInterface)
|
||||
{
|
||||
ConfigCallbacks = configCallbackInterface;
|
||||
}
|
||||
|
||||
bool GetConfigBool(ConfigEntry entry)
|
||||
{
|
||||
return ConfigCallbacks.GetBoolean(entry);
|
||||
}
|
||||
|
||||
int GetConfigInt(ConfigEntry entry)
|
||||
{
|
||||
return ConfigCallbacks.GetInteger(entry);
|
||||
}
|
||||
|
||||
std::string GetConfigString(ConfigEntry entry)
|
||||
{
|
||||
char buffer[4096]{};
|
||||
ConfigCallbacks.GetString(entry, buffer, sizeof(buffer));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
bool GetConfigArray(ConfigEntry entry, void* data)
|
||||
{
|
||||
return ConfigCallbacks.GetArray(entry, data);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef BIZCONFIG_H
|
||||
#define BIZCONFIG_H
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
|
||||
struct ConfigCallbackInterface;
|
||||
void SetConfigCallbacks(ConfigCallbackInterface& configCallbackInterface);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,280 @@
|
|||
#include "BizFile.h"
|
||||
|
||||
#include <emulibc.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
|
||||
struct FileCallbackInterface
|
||||
{
|
||||
int (*GetLength)(const char* path);
|
||||
void (*GetData)(const char* path, u8* buffer);
|
||||
};
|
||||
|
||||
ECL_INVISIBLE static FileCallbackInterface FileCallbacks;
|
||||
|
||||
void SetFileCallbacks(FileCallbackInterface& fileCallbackInterface)
|
||||
{
|
||||
FileCallbacks = fileCallbackInterface;
|
||||
}
|
||||
|
||||
struct FileHandle
|
||||
{
|
||||
public:
|
||||
FileHandle(u8* data_, size_t size_, FileMode mode_)
|
||||
: data(data_)
|
||||
, pos(0)
|
||||
, size(size_)
|
||||
, mode(mode_)
|
||||
{
|
||||
}
|
||||
|
||||
bool IsEndOfFile()
|
||||
{
|
||||
return pos == size;
|
||||
}
|
||||
|
||||
bool ReadLine(char* str, int count)
|
||||
{
|
||||
if (!Readable())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (count < 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t len = std::min(size - pos, (size_t)(count - 1));
|
||||
u8* end = (u8*)memchr(&data[pos], '\n', len);
|
||||
len = end ? (end + 1) - &data[pos] : len;
|
||||
memcpy(str, &data[pos], len);
|
||||
pos += len;
|
||||
str[len] = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Seek(s64 offset, FileSeekOrigin origin)
|
||||
{
|
||||
size_t newPos;
|
||||
switch (origin)
|
||||
{
|
||||
case FileSeekOrigin::Start:
|
||||
newPos = offset;
|
||||
break;
|
||||
case FileSeekOrigin::Current:
|
||||
newPos = pos + offset;
|
||||
break;
|
||||
case FileSeekOrigin::End:
|
||||
newPos = size + offset;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (newPos > size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pos = newPos;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Rewind()
|
||||
{
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
size_t Read(void* data_, u64 count)
|
||||
{
|
||||
if (!Readable())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
count = std::min(count, (u64)(size - pos));
|
||||
memcpy(data_, data.get(), count);
|
||||
pos += count;
|
||||
return count;
|
||||
}
|
||||
|
||||
size_t Write(const void* data_, u64 count)
|
||||
{
|
||||
if (!Writable())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
count = std::min(count, (u64)(size - pos));
|
||||
memcpy(data.get(), data_, count);
|
||||
pos += count;
|
||||
return count;
|
||||
}
|
||||
|
||||
size_t Length()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<u8[]> data;
|
||||
size_t pos, size;
|
||||
FileMode mode;
|
||||
|
||||
bool Readable()
|
||||
{
|
||||
return (mode & FileMode::Read) == FileMode::Read;
|
||||
}
|
||||
|
||||
bool Writable()
|
||||
{
|
||||
return (mode & FileMode::Write) == FileMode::Write;
|
||||
}
|
||||
};
|
||||
|
||||
static std::unordered_map<std::string, std::pair<std::unique_ptr<u8[]>, size_t>> FileBufferCache;
|
||||
|
||||
// TODO - I don't like this approach with NAND
|
||||
// Perhaps instead it would be better to use FileFlush to write to disk
|
||||
// (guarded by frontend determinism switch, of course)
|
||||
|
||||
ECL_EXPORT u32 GetNANDSize()
|
||||
{
|
||||
auto path = GetConfigString(ConfigEntry::DSi_NANDPath);
|
||||
if (auto cache = FileBufferCache.find(path); cache != FileBufferCache.end())
|
||||
{
|
||||
return cache->second.second;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ECL_EXPORT void GetNANDData(u8* buf)
|
||||
{
|
||||
auto path = GetConfigString(ConfigEntry::DSi_NANDPath);
|
||||
if (auto cache = FileBufferCache.find(path); cache != FileBufferCache.end())
|
||||
{
|
||||
memcpy(buf, cache->second.first.get(), cache->second.second);
|
||||
}
|
||||
}
|
||||
|
||||
FileHandle* OpenFile(const std::string& path, FileMode mode)
|
||||
{
|
||||
if ((mode & FileMode::ReadWrite) == FileMode::None)
|
||||
{
|
||||
// something went wrong here
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (auto cache = FileBufferCache.find(path); cache != FileBufferCache.end())
|
||||
{
|
||||
return new FileHandle(cache->second.first.get(), cache->second.second, mode);
|
||||
}
|
||||
|
||||
size_t size = FileCallbacks.GetLength(path.c_str());
|
||||
if (size == 0)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto data = std::make_unique<u8[]>(size);
|
||||
FileCallbacks.GetData(path.c_str(), data.get());
|
||||
|
||||
auto ret = new FileHandle(data.get(), size, mode);
|
||||
FileBufferCache.emplace(path, std::make_pair(std::move(data), size));
|
||||
return ret;
|
||||
}
|
||||
|
||||
FileHandle* OpenLocalFile(const std::string& path, FileMode mode)
|
||||
{
|
||||
return OpenFile(path, mode);
|
||||
}
|
||||
|
||||
bool FileExists(const std::string& name)
|
||||
{
|
||||
if (auto cache = FileBufferCache.find(name); cache != FileBufferCache.end())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return FileCallbacks.GetLength(name.c_str()) > 0;
|
||||
}
|
||||
|
||||
bool LocalFileExists(const std::string& name)
|
||||
{
|
||||
return FileExists(name);
|
||||
}
|
||||
|
||||
bool CloseFile(FileHandle* file)
|
||||
{
|
||||
delete file;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsEndOfFile(FileHandle* file)
|
||||
{
|
||||
return file->IsEndOfFile();
|
||||
}
|
||||
|
||||
bool FileReadLine(char* str, int count, FileHandle* file)
|
||||
{
|
||||
return file->ReadLine(str, count);
|
||||
}
|
||||
|
||||
bool FileSeek(FileHandle* file, s64 offset, FileSeekOrigin origin)
|
||||
{
|
||||
return file->Seek(offset, origin);
|
||||
}
|
||||
|
||||
void FileRewind(FileHandle* file)
|
||||
{
|
||||
file->Rewind();
|
||||
}
|
||||
|
||||
u64 FileRead(void* data, u64 size, u64 count, FileHandle* file)
|
||||
{
|
||||
return file->Read(data, size * count);
|
||||
}
|
||||
|
||||
bool FileFlush(FileHandle* file)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
u64 FileWrite(const void* data, u64 size, u64 count, FileHandle* file)
|
||||
{
|
||||
return file->Write(data, size * count);
|
||||
}
|
||||
|
||||
u64 FileWriteFormatted(FileHandle* file, const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
size_t bufferSize = vsnprintf(nullptr, 0, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
if ((int)bufferSize < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto buffer = std::make_unique<char[]>(bufferSize + 1);
|
||||
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buffer.get(), bufferSize + 1, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
return file->Write(buffer.get(), bufferSize);
|
||||
}
|
||||
|
||||
u64 FileLength(FileHandle* file)
|
||||
{
|
||||
return file->Length();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef BIZFILE_H
|
||||
#define BIZFILE_H
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
|
||||
struct FileCallbackInterface;
|
||||
void SetFileCallbacks(FileCallbackInterface& fileCallbackInterface);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,39 @@
|
|||
#include "BizLog.h"
|
||||
|
||||
#include <emulibc.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
|
||||
ECL_INVISIBLE static LogCallback_t LogCallback;
|
||||
|
||||
void SetLogCallback(LogCallback_t logCallback)
|
||||
{
|
||||
LogCallback = logCallback;
|
||||
}
|
||||
|
||||
void Log(LogLevel level, const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
size_t bufferSize = vsnprintf(nullptr, 0, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
if ((int)bufferSize < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto buffer = std::make_unique<char[]>(bufferSize + 1);
|
||||
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buffer.get(), bufferSize + 1, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
LogCallback(level, buffer.get());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef BIZLOG_H
|
||||
#define BIZLOG_H
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
|
||||
using LogCallback_t = void (*)(LogLevel level, const char* message);
|
||||
void SetLogCallback(LogCallback_t logCallback);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,173 @@
|
|||
#include "Platform.h"
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
|
||||
void Init(int argc, char** argv)
|
||||
{
|
||||
}
|
||||
|
||||
void DeInit()
|
||||
{
|
||||
}
|
||||
|
||||
void SignalStop(StopReason reason)
|
||||
{
|
||||
}
|
||||
|
||||
int InstanceID()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string InstanceFileSuffix()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
Semaphore* Semaphore_Create()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Semaphore_Free(Semaphore* sema)
|
||||
{
|
||||
}
|
||||
|
||||
void Semaphore_Reset(Semaphore* sema)
|
||||
{
|
||||
}
|
||||
|
||||
void Semaphore_Wait(Semaphore* sema)
|
||||
{
|
||||
}
|
||||
|
||||
void Semaphore_Post(Semaphore* sema, int count)
|
||||
{
|
||||
}
|
||||
|
||||
Mutex* Mutex_Create()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Mutex_Free(Mutex* mutex)
|
||||
{
|
||||
}
|
||||
|
||||
void Mutex_Lock(Mutex* mutex)
|
||||
{
|
||||
}
|
||||
|
||||
void Mutex_Unlock(Mutex* mutex)
|
||||
{
|
||||
}
|
||||
|
||||
bool Mutex_TryLock(Mutex* mutex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MP_Init()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void MP_DeInit()
|
||||
{
|
||||
}
|
||||
|
||||
void MP_Begin()
|
||||
{
|
||||
}
|
||||
|
||||
void MP_End()
|
||||
{
|
||||
}
|
||||
|
||||
int MP_SendPacket(u8* data, int len, u64 timestamp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MP_RecvPacket(u8* data, u64* timestamp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MP_SendCmd(u8* data, int len, u64 timestamp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MP_SendReply(u8* data, int len, u64 timestamp, u16 aid)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MP_SendAck(u8* data, int len, u64 timestamp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MP_RecvHostPacket(u8* data, u64* timestamp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
u16 MP_RecvReplies(u8* data, u64 timestamp, u16 aidmask)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool LAN_Init()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void LAN_DeInit()
|
||||
{
|
||||
}
|
||||
|
||||
int LAN_SendPacket(u8* data, int len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LAN_RecvPacket(u8* data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Sleep(u64 usecs)
|
||||
{
|
||||
}
|
||||
|
||||
void Camera_Start(int num)
|
||||
{
|
||||
}
|
||||
|
||||
void Camera_Stop(int num)
|
||||
{
|
||||
}
|
||||
|
||||
void Camera_CaptureFrame(int num, u32* frame, int width, int height, bool yuv)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
DynamicLibrary* DynamicLibrary_Load(const char* lib)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void DynamicLibrary_Unload(DynamicLibrary* lib)
|
||||
{
|
||||
}
|
||||
|
||||
void* DynamicLibrary_LoadFunction(DynamicLibrary* lib, const char* name)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
#include "NDS.h"
|
||||
#include "NDSCart.h"
|
||||
#include "GBACart.h"
|
||||
#include "DSi.h"
|
||||
#include "DSi_NAND.h"
|
||||
#include "Platform.h"
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
|
||||
constexpr u32 DSIWARE_CATEGORY = 0x00030004;
|
||||
|
||||
static bool NdsSaveRamIsDirty = false;
|
||||
static bool GbaSaveRamIsDirty = false;
|
||||
|
||||
ECL_EXPORT void PutSaveRam(u8* data, u32 len)
|
||||
{
|
||||
const u32 ndsSaveLen = NDSCart::GetSaveMemoryLength();
|
||||
const u32 gbaSaveLen = GBACart::GetSaveMemoryLength();
|
||||
|
||||
if (len >= ndsSaveLen)
|
||||
{
|
||||
NDS::LoadSave(data, len);
|
||||
NdsSaveRamIsDirty = false;
|
||||
|
||||
data += ndsSaveLen;
|
||||
len -= ndsSaveLen;
|
||||
|
||||
if (gbaSaveLen && len >= gbaSaveLen)
|
||||
{
|
||||
GBACart::LoadSave(data, gbaSaveLen);
|
||||
GbaSaveRamIsDirty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ECL_EXPORT void GetSaveRam(u8* data)
|
||||
{
|
||||
const u32 ndsSaveLen = NDSCart::GetSaveMemoryLength();
|
||||
const u32 gbaSaveLen = GBACart::GetSaveMemoryLength();
|
||||
|
||||
if (ndsSaveLen)
|
||||
{
|
||||
memcpy(data, NDSCart::GetSaveMemory(), ndsSaveLen);
|
||||
NdsSaveRamIsDirty = false;
|
||||
}
|
||||
|
||||
if (gbaSaveLen)
|
||||
{
|
||||
memcpy(data + ndsSaveLen, GBACart::GetSaveMemory(), gbaSaveLen);
|
||||
GbaSaveRamIsDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
ECL_EXPORT u32 GetSaveRamLength()
|
||||
{
|
||||
return NDSCart::GetSaveMemoryLength() + GBACart::GetSaveMemoryLength();
|
||||
}
|
||||
|
||||
ECL_EXPORT bool SaveRamIsDirty()
|
||||
{
|
||||
return NdsSaveRamIsDirty || GbaSaveRamIsDirty;
|
||||
}
|
||||
|
||||
ECL_EXPORT void ImportDSiWareSavs(u32 titleId)
|
||||
{
|
||||
if (DSi_NAND::Init(&DSi::ARM7iBIOS[0x8308]))
|
||||
{
|
||||
DSi_NAND::ImportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_PublicSav, "public.sav");
|
||||
DSi_NAND::ImportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_PrivateSav, "private.sav");
|
||||
DSi_NAND::ImportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_BannerSav, "banner.sav");
|
||||
DSi_NAND::DeInit();
|
||||
}
|
||||
}
|
||||
|
||||
ECL_EXPORT void ExportDSiWareSavs(u32 titleId)
|
||||
{
|
||||
if (DSi_NAND::Init(&DSi::ARM7iBIOS[0x8308]))
|
||||
{
|
||||
DSi_NAND::ExportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_PublicSav, "public.sav");
|
||||
DSi_NAND::ExportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_PrivateSav, "private.sav");
|
||||
DSi_NAND::ExportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_BannerSav, "banner.sav");
|
||||
DSi_NAND::DeInit();
|
||||
}
|
||||
}
|
||||
|
||||
ECL_EXPORT void DSiWareSavsLength(u32 titleId, u32* publicSavSize, u32* privateSavSize, u32* bannerSavSize)
|
||||
{
|
||||
*publicSavSize = *privateSavSize = *bannerSavSize = 0;
|
||||
if (DSi_NAND::Init(&DSi::ARM7iBIOS[0x8308]))
|
||||
{
|
||||
u32 version;
|
||||
NDSHeader header{};
|
||||
|
||||
DSi_NAND::GetTitleInfo(DSIWARE_CATEGORY, titleId, version, &header, nullptr);
|
||||
*publicSavSize = header.DSiPublicSavSize;
|
||||
*privateSavSize = header.DSiPrivateSavSize;
|
||||
*bannerSavSize = (header.AppFlags & 0x04) ? 0x4000 : 0;
|
||||
DSi_NAND::DeInit();
|
||||
}
|
||||
}
|
||||
|
||||
void WriteNDSSave(const u8* savedata, u32 savelen, u32 writeoffset, u32 writelen)
|
||||
{
|
||||
NdsSaveRamIsDirty = true;
|
||||
}
|
||||
|
||||
void WriteGBASave(const u8* savedata, u32 savelen, u32 writeoffset, u32 writelen)
|
||||
{
|
||||
GbaSaveRamIsDirty = true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
#include "Platform.h"
|
||||
|
||||
#include <emulibc.h>
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
|
||||
static uintptr_t FrameThreadProc = 0;
|
||||
static std::function<void()> ThreadEntryFunc = nullptr;
|
||||
static void (*ThreadStartCallback)() = nullptr;
|
||||
|
||||
ECL_EXPORT uintptr_t GetFrameThreadProc()
|
||||
{
|
||||
return FrameThreadProc;
|
||||
}
|
||||
|
||||
ECL_EXPORT void SetThreadStartCallback(void (*callback)())
|
||||
{
|
||||
ThreadStartCallback = callback;
|
||||
}
|
||||
|
||||
static void ThreadEntry()
|
||||
{
|
||||
ThreadEntryFunc();
|
||||
}
|
||||
|
||||
Thread* Thread_Create(std::function<void()> func)
|
||||
{
|
||||
ThreadEntryFunc = func;
|
||||
FrameThreadProc = reinterpret_cast<uintptr_t>(ThreadEntry);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Thread_Free(Thread* thread)
|
||||
{
|
||||
}
|
||||
|
||||
// hijacked to act as a thread start, consider this "wait for start of thread"
|
||||
void Thread_Wait(Thread* thread)
|
||||
{
|
||||
ThreadStartCallback();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,642 @@
|
|||
static const std::unordered_map<u32, GBASaveType> GbaCrcSaveTypeOverrides =
|
||||
{
|
||||
{ 0xEF365600, GBASaveType::SRAM },
|
||||
{ 0xE905937F, GBASaveType::FLASH512 },
|
||||
{ 0x689CAF43, GBASaveType::SRAM },
|
||||
{ 0x4E0F10FA, GBASaveType::EEPROM },
|
||||
{ 0x106ED779, GBASaveType::EEPROM },
|
||||
{ 0x91344285, GBASaveType::SRAM },
|
||||
{ 0xBA1F514A, GBASaveType::NONE },
|
||||
{ 0x11870BD9, GBASaveType::SRAM },
|
||||
{ 0x86A602AB, GBASaveType::NONE },
|
||||
{ 0x9D5E128C, GBASaveType::SRAM },
|
||||
{ 0xD05C86BB, GBASaveType::NONE },
|
||||
{ 0x0D72F2CC, GBASaveType::SRAM },
|
||||
{ 0xCA9B82DD, GBASaveType::SRAM },
|
||||
{ 0x28BAA30E, GBASaveType::SRAM },
|
||||
{ 0x35536183, GBASaveType::SRAM },
|
||||
{ 0xF5C8D8E8, GBASaveType::SRAM },
|
||||
{ 0x93B6599E, GBASaveType::SRAM },
|
||||
{ 0x284E3092, GBASaveType::SRAM },
|
||||
{ 0xE8156354, GBASaveType::SRAM },
|
||||
{ 0xD97DBFEC, GBASaveType::SRAM },
|
||||
{ 0xD0C91F74, GBASaveType::SRAM },
|
||||
{ 0x3D803E41, GBASaveType::EEPROM },
|
||||
{ 0x40A48276, GBASaveType::EEPROM },
|
||||
{ 0x10F9EDA4, GBASaveType::EEPROM },
|
||||
{ 0x26321120, GBASaveType::EEPROM },
|
||||
{ 0x2C79C2DE, GBASaveType::EEPROM },
|
||||
{ 0x639E9D3B, GBASaveType::EEPROM },
|
||||
{ 0x153F73D1, GBASaveType::NONE },
|
||||
{ 0xF74C1FA3, GBASaveType::NONE },
|
||||
{ 0x3F15FEAA, GBASaveType::NONE },
|
||||
{ 0x3FCAF2D0, GBASaveType::EEPROM },
|
||||
{ 0x8DD750EF, GBASaveType::EEPROM },
|
||||
{ 0x2C613DEF, GBASaveType::NONE },
|
||||
{ 0x285FE485, GBASaveType::EEPROM },
|
||||
{ 0xB61F99D4, GBASaveType::EEPROM },
|
||||
{ 0xEEA68C2E, GBASaveType::EEPROM },
|
||||
{ 0x6E140BFA, GBASaveType::EEPROM },
|
||||
{ 0x01B4D95E, GBASaveType::EEPROM },
|
||||
{ 0xF87EA3C3, GBASaveType::EEPROM },
|
||||
{ 0xE718D850, GBASaveType::EEPROM },
|
||||
{ 0xBEE3055A, GBASaveType::EEPROM },
|
||||
{ 0x4EF93D41, GBASaveType::EEPROM },
|
||||
{ 0x6A5BD4F0, GBASaveType::EEPROM },
|
||||
{ 0x170CC574, GBASaveType::EEPROM },
|
||||
{ 0xDFF9A0B1, GBASaveType::NONE },
|
||||
{ 0x59F208FC, GBASaveType::EEPROM },
|
||||
{ 0x3524F206, GBASaveType::NONE },
|
||||
{ 0x50927F3E, GBASaveType::EEPROM },
|
||||
{ 0xB99D538B, GBASaveType::SRAM },
|
||||
{ 0xFB67EFBC, GBASaveType::SRAM },
|
||||
{ 0xC90732D5, GBASaveType::NONE },
|
||||
{ 0xE144DED2, GBASaveType::EEPROM },
|
||||
{ 0xE37A0705, GBASaveType::NONE },
|
||||
{ 0xA519FEB5, GBASaveType::EEPROM },
|
||||
{ 0xE0E153B7, GBASaveType::SRAM },
|
||||
{ 0x3A1E789A, GBASaveType::SRAM },
|
||||
{ 0x88C1B562, GBASaveType::SRAM },
|
||||
{ 0x247EEB20, GBASaveType::SRAM },
|
||||
{ 0x379B3248, GBASaveType::SRAM },
|
||||
{ 0xE0C4FD69, GBASaveType::SRAM },
|
||||
{ 0x521B3091, GBASaveType::SRAM },
|
||||
{ 0x125C2E01, GBASaveType::SRAM },
|
||||
{ 0x5264C730, GBASaveType::SRAM },
|
||||
{ 0xB789DAC5, GBASaveType::SRAM },
|
||||
{ 0xC0E9EEBE, GBASaveType::SRAM },
|
||||
{ 0x60C38E52, GBASaveType::SRAM },
|
||||
{ 0x91B16892, GBASaveType::SRAM },
|
||||
{ 0x5F595157, GBASaveType::SRAM },
|
||||
{ 0x529F06A4, GBASaveType::SRAM },
|
||||
{ 0x1B8713C7, GBASaveType::SRAM },
|
||||
{ 0x2A524221, GBASaveType::SRAM },
|
||||
{ 0x0BA2FD1F, GBASaveType::SRAM },
|
||||
{ 0xF0C10E72, GBASaveType::SRAM },
|
||||
{ 0xCD9D8972, GBASaveType::SRAM },
|
||||
{ 0x335C5855, GBASaveType::SRAM },
|
||||
{ 0x4A805ED1, GBASaveType::SRAM },
|
||||
{ 0x93D3B218, GBASaveType::SRAM },
|
||||
{ 0x9DECC754, GBASaveType::SRAM },
|
||||
{ 0x1127B83E, GBASaveType::NONE },
|
||||
{ 0xB4090702, GBASaveType::EEPROM },
|
||||
{ 0xCE2B48C4, GBASaveType::EEPROM },
|
||||
{ 0xF8AF3359, GBASaveType::SRAM },
|
||||
{ 0xD38763E1, GBASaveType::SRAM },
|
||||
{ 0xB40D6854, GBASaveType::SRAM },
|
||||
{ 0x8146A270, GBASaveType::SRAM },
|
||||
{ 0x55CAE46A, GBASaveType::NONE },
|
||||
{ 0x2C00B4E6, GBASaveType::SRAM },
|
||||
{ 0xA7A84C31, GBASaveType::EEPROM512 },
|
||||
{ 0xB107C73D, GBASaveType::EEPROM512 },
|
||||
{ 0xBA829EAC, GBASaveType::EEPROM512 },
|
||||
{ 0x14E3EBCC, GBASaveType::EEPROM512 },
|
||||
{ 0xA934C4EE, GBASaveType::EEPROM },
|
||||
{ 0xE37CA939, GBASaveType::EEPROM },
|
||||
{ 0x709B5289, GBASaveType::EEPROM },
|
||||
{ 0x03294511, GBASaveType::EEPROM512 },
|
||||
{ 0x9AF01F01, GBASaveType::EEPROM },
|
||||
{ 0x5F1E5A48, GBASaveType::EEPROM512 },
|
||||
{ 0x6CD93829, GBASaveType::EEPROM },
|
||||
{ 0x92FDB8D6, GBASaveType::EEPROM512 },
|
||||
{ 0xFBFF3F04, GBASaveType::EEPROM },
|
||||
{ 0xF5801BD8, GBASaveType::EEPROM512 },
|
||||
{ 0x536669C1, GBASaveType::SRAM },
|
||||
{ 0xAD17D41E, GBASaveType::SRAM },
|
||||
{ 0x81462ABA, GBASaveType::SRAM },
|
||||
{ 0x5A5EF8E3, GBASaveType::SRAM },
|
||||
{ 0x8EE0ED6F, GBASaveType::SRAM },
|
||||
{ 0xAC355418, GBASaveType::SRAM },
|
||||
{ 0x95CCC956, GBASaveType::NONE },
|
||||
{ 0xF424858F, GBASaveType::NONE },
|
||||
{ 0x922D805A, GBASaveType::NONE },
|
||||
{ 0x7960926C, GBASaveType::SRAM },
|
||||
{ 0x5B8AAA03, GBASaveType::SRAM },
|
||||
{ 0x25B0B122, GBASaveType::SRAM },
|
||||
{ 0xC1F2B5EC, GBASaveType::SRAM },
|
||||
{ 0x872BC075, GBASaveType::NONE },
|
||||
{ 0x0A517352, GBASaveType::SRAM },
|
||||
{ 0x7E90CEA2, GBASaveType::SRAM },
|
||||
{ 0xF1098A5F, GBASaveType::SRAM },
|
||||
{ 0x85C837AF, GBASaveType::SRAM },
|
||||
{ 0x257E49F9, GBASaveType::NONE },
|
||||
{ 0xD1183501, GBASaveType::EEPROM },
|
||||
{ 0xABAF519C, GBASaveType::EEPROM },
|
||||
{ 0xA79872FE, GBASaveType::NONE },
|
||||
{ 0xB3780A4F, GBASaveType::EEPROM },
|
||||
{ 0x68076B62, GBASaveType::EEPROM },
|
||||
{ 0x4E63DCE0, GBASaveType::FLASH512 },
|
||||
{ 0xE6F5BDD5, GBASaveType::FLASH512 },
|
||||
{ 0xD9F19D76, GBASaveType::SRAM },
|
||||
{ 0xD125A6BB, GBASaveType::SRAM },
|
||||
{ 0xC4838CFA, GBASaveType::EEPROM },
|
||||
{ 0x7EE24793, GBASaveType::EEPROM },
|
||||
{ 0x41E7180E, GBASaveType::EEPROM },
|
||||
{ 0xECE42D0E, GBASaveType::EEPROM },
|
||||
{ 0xFFDA95BE, GBASaveType::EEPROM },
|
||||
{ 0xB7F022B9, GBASaveType::EEPROM },
|
||||
{ 0x1D910A62, GBASaveType::EEPROM },
|
||||
{ 0xF094A4CB, GBASaveType::EEPROM },
|
||||
{ 0x9CD07025, GBASaveType::EEPROM },
|
||||
{ 0xBAA4A82B, GBASaveType::EEPROM },
|
||||
{ 0xC8C889E2, GBASaveType::EEPROM },
|
||||
{ 0xDEA3B767, GBASaveType::SRAM },
|
||||
{ 0xA47246AE, GBASaveType::SRAM },
|
||||
{ 0xD2B431F8, GBASaveType::SRAM },
|
||||
{ 0x9D76826F, GBASaveType::SRAM },
|
||||
{ 0x2653401A, GBASaveType::SRAM },
|
||||
{ 0xB3005195, GBASaveType::SRAM },
|
||||
{ 0xAA14B198, GBASaveType::EEPROM },
|
||||
{ 0x195D7EA7, GBASaveType::EEPROM },
|
||||
{ 0xEBF89B0D, GBASaveType::EEPROM },
|
||||
{ 0x40958C2C, GBASaveType::EEPROM },
|
||||
{ 0x304BDFC3, GBASaveType::EEPROM },
|
||||
{ 0xA0EBB191, GBASaveType::NONE },
|
||||
{ 0x0E2ACA9E, GBASaveType::EEPROM },
|
||||
{ 0x526FDFFF, GBASaveType::EEPROM },
|
||||
{ 0x8EA9AFCC, GBASaveType::EEPROM },
|
||||
{ 0xCA893BC4, GBASaveType::NONE },
|
||||
{ 0xEC7869AE, GBASaveType::SRAM },
|
||||
{ 0x02F51696, GBASaveType::SRAM },
|
||||
{ 0x9AD45607, GBASaveType::FLASH512 },
|
||||
{ 0xA646601B, GBASaveType::FLASH512 },
|
||||
{ 0xFB6C590F, GBASaveType::EEPROM },
|
||||
{ 0xE368A67A, GBASaveType::SRAM },
|
||||
{ 0x2912E76E, GBASaveType::FLASH512 },
|
||||
{ 0x2AD292A4, GBASaveType::FLASH512 },
|
||||
{ 0x9A704AF8, GBASaveType::FLASH512 },
|
||||
{ 0xD111CC19, GBASaveType::FLASH512 },
|
||||
{ 0xAE57B39E, GBASaveType::FLASH512 },
|
||||
{ 0x6346FD59, GBASaveType::FLASH512 },
|
||||
{ 0x6CE771A5, GBASaveType::EEPROM },
|
||||
{ 0xCD2604DD, GBASaveType::EEPROM },
|
||||
{ 0xE4628D75, GBASaveType::EEPROM },
|
||||
{ 0x86C4F772, GBASaveType::SRAM },
|
||||
{ 0x1A1397DE, GBASaveType::SRAM },
|
||||
{ 0x96B54925, GBASaveType::EEPROM },
|
||||
{ 0xD047FFDF, GBASaveType::EEPROM },
|
||||
};
|
||||
|
||||
static const std::unordered_map<std::string, GBASaveType> GbaGameIdSaveTypeOverrides =
|
||||
{
|
||||
{ "A2GJ", GBASaveType::EEPROM },
|
||||
{ "A2HJ", GBASaveType::EEPROM },
|
||||
{ "A2IJ", GBASaveType::EEPROM },
|
||||
{ "A2JJ", GBASaveType::EEPROM },
|
||||
{ "A2OJ", GBASaveType::EEPROM },
|
||||
{ "A2QE", GBASaveType::SRAM },
|
||||
{ "A2QJ", GBASaveType::SRAM },
|
||||
{ "A2SE", GBASaveType::EEPROM },
|
||||
{ "A2SP", GBASaveType::EEPROM },
|
||||
{ "A2VJ", GBASaveType::EEPROM },
|
||||
{ "A2YE", GBASaveType::NONE },
|
||||
{ "A3AC", GBASaveType::EEPROM },
|
||||
{ "A3DE", GBASaveType::EEPROM512 },
|
||||
{ "A3DJ", GBASaveType::EEPROM512 },
|
||||
{ "A3IJ", GBASaveType::EEPROM },
|
||||
{ "A3NJ", GBASaveType::SRAM },
|
||||
{ "A3OJ", GBASaveType::SRAM },
|
||||
{ "A4GE", GBASaveType::EEPROM },
|
||||
{ "A4GJ", GBASaveType::EEPROM },
|
||||
{ "A4LJ", GBASaveType::EEPROM },
|
||||
{ "A4VJ", GBASaveType::SRAM },
|
||||
{ "A56J", GBASaveType::EEPROM },
|
||||
{ "A57J", GBASaveType::SRAM },
|
||||
{ "A59J", GBASaveType::EEPROM },
|
||||
{ "A5CE", GBASaveType::EEPROM },
|
||||
{ "A5CP", GBASaveType::EEPROM },
|
||||
{ "A5SJ", GBASaveType::EEPROM },
|
||||
{ "A63J", GBASaveType::EEPROM },
|
||||
{ "A64J", GBASaveType::EEPROM },
|
||||
{ "A6CJ", GBASaveType::SRAM },
|
||||
{ "A6GJ", GBASaveType::SRAM },
|
||||
{ "A6OE", GBASaveType::EEPROM },
|
||||
{ "A6OJ", GBASaveType::EEPROM },
|
||||
{ "A6OP", GBASaveType::EEPROM },
|
||||
{ "A6RE", GBASaveType::SRAM },
|
||||
{ "A82J", GBASaveType::EEPROM },
|
||||
{ "A83J", GBASaveType::EEPROM },
|
||||
{ "A85J", GBASaveType::EEPROM },
|
||||
{ "A87J", GBASaveType::EEPROM },
|
||||
{ "A8BS", GBASaveType::EEPROM },
|
||||
{ "A8LJ", GBASaveType::SRAM },
|
||||
{ "A8OJ", GBASaveType::EEPROM },
|
||||
{ "A8RJ", GBASaveType::SRAM },
|
||||
{ "A8ZJ", GBASaveType::EEPROM },
|
||||
{ "A9BS", GBASaveType::EEPROM },
|
||||
{ "A9HJ", GBASaveType::EEPROM },
|
||||
{ "A9LJ", GBASaveType::SRAM },
|
||||
{ "A9ME", GBASaveType::SRAM },
|
||||
{ "A9MP", GBASaveType::SRAM },
|
||||
{ "A9TJ", GBASaveType::EEPROM },
|
||||
{ "AA2C", GBASaveType::EEPROM },
|
||||
{ "AA2E", GBASaveType::EEPROM },
|
||||
{ "AA2J", GBASaveType::EEPROM },
|
||||
{ "AA2P", GBASaveType::EEPROM },
|
||||
{ "AABE", GBASaveType::EEPROM },
|
||||
{ "AABJ", GBASaveType::SRAM },
|
||||
{ "AABP", GBASaveType::EEPROM },
|
||||
{ "AAGJ", GBASaveType::EEPROM },
|
||||
{ "AALJ", GBASaveType::EEPROM },
|
||||
{ "AANJ", GBASaveType::SRAM },
|
||||
{ "AAPJ", GBASaveType::EEPROM },
|
||||
{ "AASJ", GBASaveType::EEPROM },
|
||||
{ "AAXJ", GBASaveType::EEPROM },
|
||||
{ "AB3E", GBASaveType::EEPROM },
|
||||
{ "AB4E", GBASaveType::EEPROM },
|
||||
{ "AB4J", GBASaveType::EEPROM },
|
||||
{ "ABFJ", GBASaveType::SRAM },
|
||||
{ "ABGJ", GBASaveType::EEPROM },
|
||||
{ "ABJE", GBASaveType::EEPROM },
|
||||
{ "ABJP", GBASaveType::EEPROM },
|
||||
{ "ABPE", GBASaveType::SRAM },
|
||||
{ "AC4J", GBASaveType::EEPROM },
|
||||
{ "AC5E", GBASaveType::SRAM },
|
||||
{ "ACBE", GBASaveType::EEPROM },
|
||||
{ "ACBJ", GBASaveType::EEPROM },
|
||||
{ "ACOJ", GBASaveType::EEPROM },
|
||||
{ "ACTX", GBASaveType::EEPROM },
|
||||
{ "ACTY", GBASaveType::EEPROM },
|
||||
{ "AD4P", GBASaveType::SRAM },
|
||||
{ "ADDJ", GBASaveType::EEPROM },
|
||||
{ "ADPJ", GBASaveType::EEPROM },
|
||||
{ "ADQE", GBASaveType::SRAM },
|
||||
{ "ADQJ", GBASaveType::SRAM },
|
||||
{ "ADQP", GBASaveType::SRAM },
|
||||
{ "ADZE", GBASaveType::SRAM },
|
||||
{ "AEAJ", GBASaveType::SRAM },
|
||||
{ "AECJ", GBASaveType::SRAM },
|
||||
{ "AEHJ", GBASaveType::EEPROM },
|
||||
{ "AEPP", GBASaveType::EEPROM },
|
||||
{ "AEWJ", GBASaveType::EEPROM },
|
||||
{ "AF3J", GBASaveType::EEPROM },
|
||||
{ "AF7J", GBASaveType::EEPROM },
|
||||
{ "AFNJ", GBASaveType::EEPROM },
|
||||
{ "AFUJ", GBASaveType::EEPROM },
|
||||
{ "AG6J", GBASaveType::SRAM },
|
||||
{ "AG9J", GBASaveType::SRAM },
|
||||
{ "AGDE", GBASaveType::SRAM },
|
||||
{ "AGNJ", GBASaveType::EEPROM },
|
||||
{ "AH3E", GBASaveType::SRAM },
|
||||
{ "AH3J", GBASaveType::SRAM },
|
||||
{ "AH3P", GBASaveType::SRAM },
|
||||
{ "AH5J", GBASaveType::SRAM },
|
||||
{ "AH7J", GBASaveType::EEPROM },
|
||||
{ "AHAJ", GBASaveType::EEPROM },
|
||||
{ "AHHE", GBASaveType::EEPROM },
|
||||
{ "AHIJ", GBASaveType::EEPROM },
|
||||
{ "AHKJ", GBASaveType::SRAM },
|
||||
{ "AHMJ", GBASaveType::EEPROM512 },
|
||||
{ "AHVJ", GBASaveType::EEPROM },
|
||||
{ "AHXJ", GBASaveType::EEPROM },
|
||||
{ "AHZJ", GBASaveType::EEPROM },
|
||||
{ "AI7J", GBASaveType::EEPROM },
|
||||
{ "AISP", GBASaveType::EEPROM },
|
||||
{ "AJ3E", GBASaveType::SRAM },
|
||||
{ "AJ3P", GBASaveType::SRAM },
|
||||
{ "AJKJ", GBASaveType::EEPROM },
|
||||
{ "AJWJ", GBASaveType::EEPROM },
|
||||
{ "AK7J", GBASaveType::EEPROM },
|
||||
{ "AKDJ", GBASaveType::SRAM },
|
||||
{ "AKEJ", GBASaveType::SRAM },
|
||||
{ "AKGE", GBASaveType::EEPROM },
|
||||
{ "AKGJ", GBASaveType::EEPROM },
|
||||
{ "AKGP", GBASaveType::EEPROM },
|
||||
{ "AKTJ", GBASaveType::EEPROM },
|
||||
{ "AKVJ", GBASaveType::EEPROM },
|
||||
{ "AL4E", GBASaveType::SRAM },
|
||||
{ "AL4J", GBASaveType::SRAM },
|
||||
{ "ALFE", GBASaveType::EEPROM },
|
||||
{ "ALFJ", GBASaveType::EEPROM },
|
||||
{ "ALFP", GBASaveType::EEPROM },
|
||||
{ "ALJE", GBASaveType::EEPROM },
|
||||
{ "ALNE", GBASaveType::EEPROM },
|
||||
{ "ALOE", GBASaveType::EEPROM },
|
||||
{ "ALOP", GBASaveType::EEPROM },
|
||||
{ "ALQJ", GBASaveType::SRAM },
|
||||
{ "ALUE", GBASaveType::EEPROM512 },
|
||||
{ "AM7J", GBASaveType::SRAM },
|
||||
{ "AMFE", GBASaveType::SRAM },
|
||||
{ "AMFJ", GBASaveType::SRAM },
|
||||
{ "AMGJ", GBASaveType::EEPROM },
|
||||
{ "AMGP", GBASaveType::EEPROM },
|
||||
{ "AMHE", GBASaveType::EEPROM },
|
||||
{ "AMHJ", GBASaveType::EEPROM },
|
||||
{ "AMHP", GBASaveType::EEPROM },
|
||||
{ "AMYE", GBASaveType::EEPROM },
|
||||
{ "AMYJ", GBASaveType::EEPROM },
|
||||
{ "AMYP", GBASaveType::EEPROM },
|
||||
{ "AN3E", GBASaveType::EEPROM },
|
||||
{ "AN3J", GBASaveType::EEPROM },
|
||||
{ "AN3X", GBASaveType::EEPROM },
|
||||
{ "AN5J", GBASaveType::EEPROM },
|
||||
{ "AN7J", GBASaveType::EEPROM },
|
||||
{ "AN8E", GBASaveType::EEPROM },
|
||||
{ "AN8J", GBASaveType::EEPROM },
|
||||
{ "AN8P", GBASaveType::EEPROM },
|
||||
{ "AN9J", GBASaveType::EEPROM },
|
||||
{ "ANJE", GBASaveType::EEPROM },
|
||||
{ "ANLE", GBASaveType::EEPROM },
|
||||
{ "ANNJ", GBASaveType::EEPROM },
|
||||
{ "ANOJ", GBASaveType::SRAM },
|
||||
{ "ANSJ", GBASaveType::EEPROM },
|
||||
{ "ANTJ", GBASaveType::SRAM },
|
||||
{ "ANYJ", GBASaveType::SRAM },
|
||||
{ "AO2J", GBASaveType::EEPROM },
|
||||
{ "AOPJ", GBASaveType::EEPROM },
|
||||
{ "AOWE", GBASaveType::EEPROM },
|
||||
{ "AOWP", GBASaveType::EEPROM },
|
||||
{ "AP9P", GBASaveType::SRAM },
|
||||
{ "APNJ", GBASaveType::EEPROM },
|
||||
{ "APUJ", GBASaveType::EEPROM },
|
||||
{ "AQ2J", GBASaveType::SRAM },
|
||||
{ "AQ2P", GBASaveType::SRAM },
|
||||
{ "AR8E", GBASaveType::EEPROM512 },
|
||||
{ "ARJJ", GBASaveType::EEPROM },
|
||||
{ "ARNJ", GBASaveType::EEPROM },
|
||||
{ "AROP", GBASaveType::EEPROM512 },
|
||||
{ "ASFJ", GBASaveType::EEPROM },
|
||||
{ "AT3D", GBASaveType::EEPROM },
|
||||
{ "AT3E", GBASaveType::EEPROM },
|
||||
{ "AT3F", GBASaveType::EEPROM },
|
||||
{ "AT6E", GBASaveType::EEPROM },
|
||||
{ "ATBJ", GBASaveType::EEPROM },
|
||||
{ "ATDJ", GBASaveType::SRAM },
|
||||
{ "ATFP", GBASaveType::EEPROM },
|
||||
{ "ATYJ", GBASaveType::EEPROM },
|
||||
{ "ATZJ", GBASaveType::SRAM },
|
||||
{ "AUCJ", GBASaveType::EEPROM },
|
||||
{ "AUEJ", GBASaveType::SRAM },
|
||||
{ "AWIJ", GBASaveType::EEPROM },
|
||||
{ "AWKJ", GBASaveType::EEPROM },
|
||||
{ "AWUE", GBASaveType::EEPROM },
|
||||
{ "AWUP", GBASaveType::EEPROM },
|
||||
{ "AWXJ", GBASaveType::EEPROM },
|
||||
{ "AWZJ", GBASaveType::SRAM },
|
||||
{ "AX2E", GBASaveType::EEPROM },
|
||||
{ "AX2P", GBASaveType::EEPROM },
|
||||
{ "AXBJ", GBASaveType::EEPROM },
|
||||
{ "AY2P", GBASaveType::EEPROM },
|
||||
{ "AY8E", GBASaveType::SRAM },
|
||||
{ "AY8J", GBASaveType::SRAM },
|
||||
{ "AY8P", GBASaveType::SRAM },
|
||||
{ "AYAJ", GBASaveType::SRAM },
|
||||
{ "AYCE", GBASaveType::EEPROM },
|
||||
{ "AYCP", GBASaveType::EEPROM },
|
||||
{ "AYHE", GBASaveType::EEPROM512 },
|
||||
{ "AYLE", GBASaveType::SRAM },
|
||||
{ "AYLJ", GBASaveType::SRAM },
|
||||
{ "AYMJ", GBASaveType::SRAM },
|
||||
{ "AYSJ", GBASaveType::EEPROM },
|
||||
{ "AZ2E", GBASaveType::SRAM },
|
||||
{ "AZ2J", GBASaveType::SRAM },
|
||||
{ "AZAJ", GBASaveType::EEPROM },
|
||||
{ "AZBJ", GBASaveType::EEPROM },
|
||||
{ "AZLE", GBASaveType::EEPROM },
|
||||
{ "AZLJ", GBASaveType::EEPROM },
|
||||
{ "AZLP", GBASaveType::EEPROM },
|
||||
{ "AZUE", GBASaveType::EEPROM },
|
||||
{ "AZUJ", GBASaveType::EEPROM },
|
||||
{ "AZUP", GBASaveType::EEPROM },
|
||||
{ "B08J", GBASaveType::EEPROM },
|
||||
{ "B26E", GBASaveType::EEPROM },
|
||||
{ "B2DE", GBASaveType::EEPROM },
|
||||
{ "B2DJ", GBASaveType::EEPROM },
|
||||
{ "B2DP", GBASaveType::EEPROM },
|
||||
{ "B2KJ", GBASaveType::EEPROM },
|
||||
{ "B2OJ", GBASaveType::EEPROM },
|
||||
{ "B2TE", GBASaveType::EEPROM },
|
||||
{ "B34E", GBASaveType::EEPROM },
|
||||
{ "B3CJ", GBASaveType::EEPROM },
|
||||
{ "B3JE", GBASaveType::NONE },
|
||||
{ "B3JP", GBASaveType::NONE },
|
||||
{ "B3KJ", GBASaveType::SRAM },
|
||||
{ "B3PJ", GBASaveType::EEPROM },
|
||||
{ "B3TJ", GBASaveType::EEPROM },
|
||||
{ "B3YE", GBASaveType::EEPROM },
|
||||
{ "B3YP", GBASaveType::EEPROM },
|
||||
{ "B4GJ", GBASaveType::SRAM },
|
||||
{ "B4KJ", GBASaveType::EEPROM },
|
||||
{ "B4LJ", GBASaveType::EEPROM },
|
||||
{ "B4PJ", GBASaveType::EEPROM },
|
||||
{ "B4RJ", GBASaveType::EEPROM },
|
||||
{ "B4SJ", GBASaveType::SRAM },
|
||||
{ "B52P", GBASaveType::EEPROM },
|
||||
{ "B53E", GBASaveType::EEPROM },
|
||||
{ "B54E", GBASaveType::EEPROM },
|
||||
{ "B5AP", GBASaveType::EEPROM },
|
||||
{ "B6ME", GBASaveType::EEPROM },
|
||||
{ "B7ME", GBASaveType::EEPROM },
|
||||
{ "B8AE", GBASaveType::EEPROM },
|
||||
{ "B8CE", GBASaveType::SRAM },
|
||||
{ "B8CJ", GBASaveType::SRAM },
|
||||
{ "B8CP", GBASaveType::SRAM },
|
||||
{ "B8SE", GBASaveType::EEPROM },
|
||||
{ "BAQP", GBASaveType::EEPROM },
|
||||
{ "BAXJ", GBASaveType::SRAM },
|
||||
{ "BAZJ", GBASaveType::EEPROM },
|
||||
{ "BB2E", GBASaveType::EEPROM },
|
||||
{ "BB2P", GBASaveType::EEPROM },
|
||||
{ "BBME", GBASaveType::EEPROM },
|
||||
{ "BBMJ", GBASaveType::EEPROM },
|
||||
{ "BBYE", GBASaveType::EEPROM },
|
||||
{ "BBYX", GBASaveType::EEPROM },
|
||||
{ "BC2J", GBASaveType::EEPROM },
|
||||
{ "BC2S", GBASaveType::EEPROM },
|
||||
{ "BCME", GBASaveType::EEPROM },
|
||||
{ "BCMJ", GBASaveType::EEPROM },
|
||||
{ "BCSP", GBASaveType::EEPROM },
|
||||
{ "BDHJ", GBASaveType::SRAM },
|
||||
{ "BDKJ", GBASaveType::EEPROM },
|
||||
{ "BDTE", GBASaveType::EEPROM },
|
||||
{ "BDTJ", GBASaveType::EEPROM },
|
||||
{ "BDXE", GBASaveType::EEPROM },
|
||||
{ "BDXJ", GBASaveType::EEPROM },
|
||||
{ "BDYJ", GBASaveType::SRAM },
|
||||
{ "BECJ", GBASaveType::EEPROM },
|
||||
{ "BEFE", GBASaveType::EEPROM },
|
||||
{ "BEFP", GBASaveType::EEPROM },
|
||||
{ "BEJJ", GBASaveType::EEPROM },
|
||||
{ "BENE", GBASaveType::EEPROM },
|
||||
{ "BENP", GBASaveType::EEPROM },
|
||||
{ "BEYE", GBASaveType::EEPROM },
|
||||
{ "BEYP", GBASaveType::EEPROM },
|
||||
{ "BFCJ", GBASaveType::EEPROM },
|
||||
{ "BFEE", GBASaveType::EEPROM },
|
||||
{ "BFEP", GBASaveType::EEPROM },
|
||||
{ "BFJE", GBASaveType::EEPROM },
|
||||
{ "BFJJ", GBASaveType::EEPROM },
|
||||
{ "BFMJ", GBASaveType::EEPROM },
|
||||
{ "BFQE", GBASaveType::EEPROM },
|
||||
{ "BFRP", GBASaveType::EEPROM },
|
||||
{ "BG3E", GBASaveType::EEPROM },
|
||||
{ "BG8J", GBASaveType::EEPROM },
|
||||
{ "BGAJ", GBASaveType::EEPROM },
|
||||
{ "BGBJ", GBASaveType::EEPROM },
|
||||
{ "BGHJ", GBASaveType::EEPROM },
|
||||
{ "BGMJ", GBASaveType::EEPROM },
|
||||
{ "BGNJ", GBASaveType::EEPROM },
|
||||
{ "BGQE", GBASaveType::EEPROM },
|
||||
{ "BGXJ", GBASaveType::EEPROM },
|
||||
{ "BH9E", GBASaveType::EEPROM },
|
||||
{ "BH9P", GBASaveType::EEPROM },
|
||||
{ "BH9X", GBASaveType::EEPROM },
|
||||
{ "BHBE", GBASaveType::EEPROM },
|
||||
{ "BHBP", GBASaveType::EEPROM },
|
||||
{ "BHCJ", GBASaveType::EEPROM },
|
||||
{ "BHFJ", GBASaveType::EEPROM },
|
||||
{ "BHGE", GBASaveType::EEPROM },
|
||||
{ "BHGP", GBASaveType::EEPROM },
|
||||
{ "BHLE", GBASaveType::SRAM },
|
||||
{ "BHTE", GBASaveType::EEPROM },
|
||||
{ "BHTJ", GBASaveType::EEPROM },
|
||||
{ "BHUE", GBASaveType::EEPROM },
|
||||
{ "BHUP", GBASaveType::EEPROM },
|
||||
{ "BIMP", GBASaveType::EEPROM },
|
||||
{ "BIMX", GBASaveType::EEPROM },
|
||||
{ "BIPJ", GBASaveType::EEPROM },
|
||||
{ "BISJ", GBASaveType::EEPROM },
|
||||
{ "BITJ", GBASaveType::EEPROM },
|
||||
{ "BJPP", GBASaveType::EEPROM },
|
||||
{ "BK2J", GBASaveType::SRAM },
|
||||
{ "BK3J", GBASaveType::EEPROM },
|
||||
{ "BK4J", GBASaveType::SRAM },
|
||||
{ "BK5J", GBASaveType::SRAM },
|
||||
{ "BKBJ", GBASaveType::SRAM },
|
||||
{ "BKCJ", GBASaveType::EEPROM },
|
||||
{ "BKCS", GBASaveType::EEPROM },
|
||||
{ "BKEJ", GBASaveType::EEPROM },
|
||||
{ "BKIJ", GBASaveType::EEPROM },
|
||||
{ "BKKJ", GBASaveType::EEPROM },
|
||||
{ "BKME", GBASaveType::EEPROM512 },
|
||||
{ "BKMJ", GBASaveType::EEPROM512 },
|
||||
{ "BKMP", GBASaveType::EEPROM512 },
|
||||
{ "BKOJ", GBASaveType::EEPROM },
|
||||
{ "BKUJ", GBASaveType::EEPROM },
|
||||
{ "BKVJ", GBASaveType::EEPROM },
|
||||
{ "BKZE", GBASaveType::EEPROM },
|
||||
{ "BKZI", GBASaveType::EEPROM },
|
||||
{ "BKZS", GBASaveType::EEPROM },
|
||||
{ "BKZX", GBASaveType::EEPROM },
|
||||
{ "BL9E", GBASaveType::EEPROM },
|
||||
{ "BLDP", GBASaveType::EEPROM },
|
||||
{ "BLDS", GBASaveType::EEPROM },
|
||||
{ "BLFE", GBASaveType::EEPROM },
|
||||
{ "BLIJ", GBASaveType::EEPROM },
|
||||
{ "BLME", GBASaveType::EEPROM },
|
||||
{ "BLMP", GBASaveType::EEPROM },
|
||||
{ "BM2J", GBASaveType::EEPROM },
|
||||
{ "BM9J", GBASaveType::SRAM },
|
||||
{ "BMDE", GBASaveType::EEPROM },
|
||||
{ "BMFE", GBASaveType::EEPROM },
|
||||
{ "BMOJ", GBASaveType::SRAM },
|
||||
{ "BMPJ", GBASaveType::SRAM },
|
||||
{ "BMRJ", GBASaveType::EEPROM },
|
||||
{ "BMWJ", GBASaveType::EEPROM },
|
||||
{ "BMYJ", GBASaveType::SRAM },
|
||||
{ "BMZJ", GBASaveType::EEPROM },
|
||||
{ "BMZP", GBASaveType::EEPROM },
|
||||
{ "BNBE", GBASaveType::EEPROM },
|
||||
{ "BNGJ", GBASaveType::SRAM },
|
||||
{ "BNMJ", GBASaveType::SRAM },
|
||||
{ "BO2J", GBASaveType::EEPROM },
|
||||
{ "BO3J", GBASaveType::EEPROM },
|
||||
{ "BO8K", GBASaveType::EEPROM },
|
||||
{ "BOBJ", GBASaveType::SRAM },
|
||||
{ "BOVJ", GBASaveType::EEPROM },
|
||||
{ "BP3J", GBASaveType::EEPROM },
|
||||
{ "BPIE", GBASaveType::EEPROM },
|
||||
{ "BPNJ", GBASaveType::EEPROM },
|
||||
{ "BPPE", GBASaveType::SRAM },
|
||||
{ "BPPJ", GBASaveType::SRAM },
|
||||
{ "BPPP", GBASaveType::SRAM },
|
||||
{ "BPQJ", GBASaveType::EEPROM },
|
||||
{ "BPVP", GBASaveType::EEPROM },
|
||||
{ "BPVX", GBASaveType::EEPROM },
|
||||
{ "BPVY", GBASaveType::EEPROM },
|
||||
{ "BQAJ", GBASaveType::EEPROM },
|
||||
{ "BQBJ", GBASaveType::EEPROM },
|
||||
{ "BQSJ", GBASaveType::EEPROM },
|
||||
{ "BQTF", GBASaveType::EEPROM },
|
||||
{ "BQTP", GBASaveType::EEPROM },
|
||||
{ "BQTX", GBASaveType::EEPROM },
|
||||
{ "BQVE", GBASaveType::EEPROM },
|
||||
{ "BQVP", GBASaveType::EEPROM },
|
||||
{ "BQVX", GBASaveType::EEPROM },
|
||||
{ "BQZE", GBASaveType::EEPROM },
|
||||
{ "BQZP", GBASaveType::EEPROM },
|
||||
{ "BREE", GBASaveType::SRAM },
|
||||
{ "BREJ", GBASaveType::SRAM },
|
||||
{ "BRGE", GBASaveType::EEPROM },
|
||||
{ "BRIJ", GBASaveType::SRAM },
|
||||
{ "BRLP", GBASaveType::EEPROM },
|
||||
{ "BRPJ", GBASaveType::EEPROM },
|
||||
{ "BS5J", GBASaveType::EEPROM },
|
||||
{ "BSFJ", GBASaveType::EEPROM },
|
||||
{ "BSKE", GBASaveType::EEPROM },
|
||||
{ "BSKJ", GBASaveType::EEPROM },
|
||||
{ "BT2E", GBASaveType::EEPROM },
|
||||
{ "BT2P", GBASaveType::EEPROM },
|
||||
{ "BT3J", GBASaveType::EEPROM },
|
||||
{ "BT4E", GBASaveType::EEPROM },
|
||||
{ "BT8E", GBASaveType::EEPROM },
|
||||
{ "BT8P", GBASaveType::EEPROM },
|
||||
{ "BTAE", GBASaveType::EEPROM },
|
||||
{ "BTAJ", GBASaveType::EEPROM },
|
||||
{ "BTAP", GBASaveType::EEPROM },
|
||||
{ "BTOE", GBASaveType::EEPROM },
|
||||
{ "BTVE", GBASaveType::EEPROM },
|
||||
{ "BTYE", GBASaveType::EEPROM },
|
||||
{ "BUCE", GBASaveType::EEPROM },
|
||||
{ "BUFE", GBASaveType::EEPROM },
|
||||
{ "BUHJ", GBASaveType::EEPROM512 },
|
||||
{ "BUOE", GBASaveType::EEPROM },
|
||||
{ "BUOJ", GBASaveType::EEPROM },
|
||||
{ "BUOP", GBASaveType::EEPROM },
|
||||
{ "BURE", GBASaveType::EEPROM },
|
||||
{ "BUZE", GBASaveType::EEPROM },
|
||||
{ "BVHJ", GBASaveType::SRAM },
|
||||
{ "BWDJ", GBASaveType::EEPROM },
|
||||
{ "BWIE", GBASaveType::EEPROM },
|
||||
{ "BWIP", GBASaveType::EEPROM },
|
||||
{ "BWOP", GBASaveType::EEPROM },
|
||||
{ "BWSE", GBASaveType::SRAM },
|
||||
{ "BWXJ", GBASaveType::EEPROM },
|
||||
{ "BX4E", GBASaveType::EEPROM },
|
||||
{ "BX5E", GBASaveType::EEPROM },
|
||||
{ "BX5P", GBASaveType::EEPROM },
|
||||
{ "BXFD", GBASaveType::EEPROM },
|
||||
{ "BXFE", GBASaveType::EEPROM },
|
||||
{ "BXFP", GBASaveType::EEPROM },
|
||||
{ "BXKE", GBASaveType::SRAM },
|
||||
{ "BXKP", GBASaveType::SRAM },
|
||||
{ "BY6E", GBASaveType::SRAM },
|
||||
{ "BY6J", GBASaveType::SRAM },
|
||||
{ "BY6P", GBASaveType::SRAM },
|
||||
{ "BYDE", GBASaveType::SRAM },
|
||||
{ "BYDP", GBASaveType::SRAM },
|
||||
{ "BYPP", GBASaveType::EEPROM },
|
||||
{ "BYPX", GBASaveType::EEPROM },
|
||||
{ "BYPY", GBASaveType::EEPROM },
|
||||
{ "BYSJ", GBASaveType::SRAM },
|
||||
{ "BYUE", GBASaveType::EEPROM },
|
||||
{ "BYUJ", GBASaveType::EEPROM },
|
||||
{ "BYUP", GBASaveType::EEPROM },
|
||||
{ "BZFJ", GBASaveType::SRAM },
|
||||
{ "BZME", GBASaveType::EEPROM },
|
||||
{ "BZMP", GBASaveType::EEPROM },
|
||||
{ "BZOJ", GBASaveType::EEPROM },
|
||||
{ "BZWJ", GBASaveType::EEPROM },
|
||||
{ "FLBJ", GBASaveType::EEPROM },
|
||||
{ "FMRJ", GBASaveType::EEPROM },
|
||||
{ "FPTJ", GBASaveType::EEPROM },
|
||||
{ "MRDK", GBASaveType::FLASH512 },
|
||||
{ "RARE", GBASaveType::NONE },
|
||||
{ "U32E", GBASaveType::EEPROM },
|
||||
{ "U32J", GBASaveType::EEPROM },
|
||||
{ "U32P", GBASaveType::EEPROM },
|
||||
{ "U33J", GBASaveType::EEPROM },
|
||||
{ "U3IE", GBASaveType::EEPROM },
|
||||
{ "U3IJ", GBASaveType::EEPROM },
|
||||
{ "U3IP", GBASaveType::EEPROM },
|
||||
};
|
|
@ -4,9 +4,10 @@ CXXFLAGS := -DMELONDS_VERSION="" \
|
|||
-I./melonDS/src -I./melonDS/src/teakra/include \
|
||||
-Wall -Wextra -Werror=int-to-pointer-cast \
|
||||
-Wfatal-errors -Wno-unused-parameter -Wno-unused-variable \
|
||||
-Wno-unused-but-set-variable -Wno-sign-compare \
|
||||
-Wno-deprecated-declarations -Wno-missing-braces \
|
||||
-Wno-bitwise-instead-of-logical -Wno-unused-private-field \
|
||||
-Wno-unused-but-set-variable -Wno-unused-function \
|
||||
-Wno-sign-compare -Wno-deprecated-declarations \
|
||||
-Wno-missing-braces -Wno-bitwise-instead-of-logical \
|
||||
-Wno-unused-private-field -Wno-logical-op-parentheses \
|
||||
-fno-strict-aliasing -std=c++17
|
||||
|
||||
TARGET = melonDS.wbx
|
||||
|
@ -40,6 +41,7 @@ CORE_SRCS = \
|
|||
GPU3D_Soft.cpp \
|
||||
NDS.cpp \
|
||||
NDSCart.cpp \
|
||||
ROMList.cpp \
|
||||
RTC.cpp \
|
||||
Savestate.cpp \
|
||||
SPI.cpp \
|
||||
|
@ -70,14 +72,23 @@ MISC_SRCS = \
|
|||
xxhash/xxhash.c \
|
||||
blip_buf/blip_buf.c \
|
||||
|
||||
BIZPLATFORM_SRCS = \
|
||||
BizPlatform/BizConfig.cpp \
|
||||
BizPlatform/BizFile.cpp \
|
||||
BizPlatform/BizLog.cpp \
|
||||
BizPlatform/BizPlatformStubs.cpp \
|
||||
BizPlatform/BizSaveManager.cpp \
|
||||
BizPlatform/BizThread.cpp \
|
||||
|
||||
SRCS = \
|
||||
$(addprefix melonDS/src/,$(CORE_SRCS)) \
|
||||
$(addprefix melonDS/src/teakra/src/,$(TEAKRA_SRCS)) \
|
||||
$(addprefix melonDS/src/fatfs/,$(FATFS_SRCS)) \
|
||||
$(addprefix melonDS/src/,$(MISC_SRCS)) \
|
||||
BizConfig.cpp \
|
||||
$(BIZPLATFORM_SRCS) \
|
||||
BizDebugging.cpp \
|
||||
BizFileManager.cpp \
|
||||
BizInterface.cpp \
|
||||
BizPlatform.cpp \
|
||||
dthumb.c
|
||||
|
||||
include ../common.mak
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef DTHUMB_H
|
||||
#define DTHUMB_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define DTHUMB_STRING_LENGTH 80
|
||||
|
||||
// only 32-bit legacy architectures with THUMB support
|
||||
typedef enum
|
||||
{
|
||||
ARMv4T, //ARM v4, THUMB v1
|
||||
ARMv5TE, //ARM v5, THUMB v2
|
||||
ARMv6, //ARM v6, THUMB v3
|
||||
} ARMARCH;
|
||||
|
||||
uint32_t Disassemble_thumb(uint32_t code, char str[DTHUMB_STRING_LENGTH], ARMARCH tv);
|
||||
void Disassemble_arm(uint32_t code, char str[DTHUMB_STRING_LENGTH], ARMARCH av);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1 +1 @@
|
|||
Subproject commit a7e1f6a0838c11801228c5695d68428d007648ed
|
||||
Subproject commit 270f7083caaf477b7ca3456eed9721c3ef239f41
|
Loading…
Reference in New Issue