Update ImGui
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace n64 {
|
||||
Mem::Mem() {
|
||||
cart = (u8*)calloc(CART_SIZE, 1);
|
||||
rom.cart = (u8*)calloc(CART_SIZE, 1);
|
||||
sram = (u8*)calloc(SRAM_SIZE, 1);
|
||||
Reset();
|
||||
}
|
||||
@@ -24,12 +24,27 @@ void Mem::Reset() {
|
||||
writePages[i] = pointer;
|
||||
}
|
||||
|
||||
memset(cart, 0, CART_SIZE);
|
||||
memset(rom.cart, 0, CART_SIZE);
|
||||
memset(sram, 0, SRAM_SIZE);
|
||||
mmio.Reset();
|
||||
}
|
||||
|
||||
CartInfo Mem::LoadROM(const std::string& filename) {
|
||||
inline void SetROMCIC(u32 checksum, ROM& rom) {
|
||||
switch (checksum) {
|
||||
case 0xEC8B1325: rom.cicType = CIC_NUS_7102; break; // 7102
|
||||
case 0x1DEB51A9: rom.cicType = CIC_NUS_6101; break; // 6101
|
||||
case 0xC08E5BD6: rom.cicType = CIC_NUS_6102_7101; break;
|
||||
case 0x03B8376A: rom.cicType = CIC_NUS_6103_7103; break;
|
||||
case 0xCF7F41DC: rom.cicType = CIC_NUS_6105_7105; break;
|
||||
case 0xD1059C6A: rom.cicType = CIC_NUS_6106_7106; break;
|
||||
default:
|
||||
Util::warn("Could not determine CIC TYPE! Checksum: 0x{:08X} is unknown!\n", checksum);
|
||||
rom.cicType = UNKNOWN_CIC_TYPE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Mem::LoadROM(const std::string& filename) {
|
||||
std::ifstream file(filename, std::ios::binary);
|
||||
file.unsetf(std::ios::skipws);
|
||||
|
||||
@@ -39,24 +54,46 @@ CartInfo Mem::LoadROM(const std::string& filename) {
|
||||
|
||||
file.seekg(0, std::ios::end);
|
||||
size_t size = file.tellg();
|
||||
size_t sizeAdjusted = Util::NextPow2(size);
|
||||
romMask = sizeAdjusted - 1;
|
||||
file.seekg(0, std::ios::beg);
|
||||
|
||||
file.read(reinterpret_cast<char*>(cart), size);
|
||||
|
||||
size_t sizeAdjusted = Util::NextPow2(size);
|
||||
rom.mask = sizeAdjusted - 1;
|
||||
u8* buf = (u8*)malloc(sizeAdjusted);
|
||||
file.read(reinterpret_cast<char*>(buf), size);
|
||||
file.close();
|
||||
|
||||
CartInfo result{};
|
||||
u32 endianness = be32toh(*reinterpret_cast<u32*>(buf));
|
||||
Util::SwapN64Rom<true>(sizeAdjusted, buf, endianness);
|
||||
|
||||
u32 cicChecksum;
|
||||
Util::SwapN64Rom(sizeAdjusted, cart, result.crc, cicChecksum);
|
||||
memcpy(mmio.rsp.dmem, cart, 0x1000);
|
||||
memcpy(rom.cart, buf, sizeAdjusted);
|
||||
rom.size = sizeAdjusted;
|
||||
memcpy(&rom.header, buf, sizeof(ROMHeader));
|
||||
memcpy(rom.gameNameCart, rom.header.imageName, sizeof(rom.header.imageName));
|
||||
|
||||
SetCICType(result.cicType, cicChecksum);
|
||||
result.isPAL = IsROMPAL();
|
||||
rom.header.clockRate = be32toh(rom.header.clockRate);
|
||||
rom.header.programCounter = be32toh(rom.header.programCounter);
|
||||
rom.header.release = be32toh(rom.header.release);
|
||||
rom.header.crc1 = be32toh(rom.header.crc1);
|
||||
rom.header.crc2 = be32toh(rom.header.crc2);
|
||||
rom.header.unknown = be64toh(rom.header.unknown);
|
||||
rom.header.unknown2 = be32toh(rom.header.unknown2);
|
||||
rom.header.manufacturerId = be32toh(rom.header.manufacturerId);
|
||||
rom.header.cartridgeId = be16toh(rom.header.cartridgeId);
|
||||
|
||||
return result;
|
||||
rom.code[0] = rom.header.manufacturerId & 0xFF;
|
||||
rom.code[1] = (rom.header.cartridgeId >> 8) & 0xFF;
|
||||
rom.code[2] = rom.header.cartridgeId & 0xFF;
|
||||
rom.code[3] = '\0';
|
||||
|
||||
for (int i = sizeof(rom.header.imageName) - 1; rom.gameNameCart[i] == ' '; i--) {
|
||||
rom.gameNameCart[i] = '\0';
|
||||
}
|
||||
|
||||
u32 checksum = Util::crc32(0, &rom.cart[0x40], 0x9c0);
|
||||
SetROMCIC(checksum, rom);
|
||||
endianness = be32toh(*reinterpret_cast<u32*>(rom.cart));
|
||||
Util::SwapN64Rom(sizeAdjusted, rom.cart, endianness);
|
||||
rom.pal = IsROMPAL();
|
||||
}
|
||||
|
||||
u8 Mem::Read8(n64::Registers ®s, u32 paddr) {
|
||||
@@ -88,7 +125,7 @@ u8 Mem::Read8(n64::Registers ®s, u32 paddr) {
|
||||
}
|
||||
case CART_REGION:
|
||||
paddr = (paddr + 2) & ~2;
|
||||
return cart[BYTE_ADDRESS(paddr) & romMask];
|
||||
return rom.cart[BYTE_ADDRESS(paddr) & rom.mask];
|
||||
case 0x1FC00000 ... 0x1FC007BF:
|
||||
return si.pif.pifBootrom[BYTE_ADDRESS(paddr) - 0x1FC00000];
|
||||
case PIF_RAM_REGION:
|
||||
@@ -128,7 +165,7 @@ u16 Mem::Read16(n64::Registers ®s, u32 paddr) {
|
||||
return mmio.Read(paddr);
|
||||
case 0x10000000 ... 0x1FBFFFFF:
|
||||
paddr = (paddr + 2) & ~3;
|
||||
return Util::ReadAccess<u16>(cart, HALF_ADDRESS(paddr) & romMask);
|
||||
return Util::ReadAccess<u16>(rom.cart, HALF_ADDRESS(paddr) & rom.mask);
|
||||
case 0x1FC00000 ... 0x1FC007BF:
|
||||
return Util::ReadAccess<u16>(si.pif.pifBootrom, HALF_ADDRESS(paddr) - 0x1FC00000);
|
||||
case PIF_RAM_REGION:
|
||||
@@ -165,7 +202,7 @@ u32 Mem::Read32(n64::Registers ®s, u32 paddr) {
|
||||
case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF:
|
||||
return mmio.Read(paddr);
|
||||
case 0x10000000 ... 0x1FBFFFFF:
|
||||
return Util::ReadAccess<u32>(cart, paddr & romMask);
|
||||
return Util::ReadAccess<u32>(rom.cart, paddr & rom.mask);
|
||||
case 0x1FC00000 ... 0x1FC007BF:
|
||||
return Util::ReadAccess<u32>(si.pif.pifBootrom, paddr - 0x1FC00000);
|
||||
case PIF_RAM_REGION:
|
||||
@@ -201,7 +238,7 @@ u64 Mem::Read64(n64::Registers ®s, u32 paddr) {
|
||||
case 0x04500000 ... 0x048FFFFF:
|
||||
return mmio.Read(paddr);
|
||||
case 0x10000000 ... 0x1FBFFFFF:
|
||||
return Util::ReadAccess<u64>(cart, paddr & romMask);
|
||||
return Util::ReadAccess<u64>(rom.cart, paddr & rom.mask);
|
||||
case 0x1FC00000 ... 0x1FC007BF:
|
||||
return Util::ReadAccess<u64>(si.pif.pifBootrom, paddr - 0x1FC00000);
|
||||
case PIF_RAM_REGION:
|
||||
@@ -274,7 +311,10 @@ void Mem::Write8(Registers& regs, u32 paddr, u32 val) {
|
||||
case 0x00800000 ... 0x03FFFFFF:
|
||||
case 0x04200000 ... 0x042FFFFF:
|
||||
case 0x08000000 ... 0x0FFFFFFF:
|
||||
Util::debug("SRAM 8 bit write {:02X}\n", val);
|
||||
break;
|
||||
case 0x04900000 ... 0x07FFFFFF:
|
||||
case 0x1FC00000 ... 0x1FC007BF:
|
||||
case 0x1FC00800 ... 0x7FFFFFFF:
|
||||
case 0x80000000 ... 0xFFFFFFFF:
|
||||
break;
|
||||
@@ -323,6 +363,7 @@ void Mem::Write16(Registers& regs, u32 paddr, u32 val) {
|
||||
case 0x04200000 ... 0x042FFFFF:
|
||||
case 0x08000000 ... 0x0FFFFFFF:
|
||||
case 0x04900000 ... 0x07FFFFFF:
|
||||
case 0x1FC00000 ... 0x1FC007BF:
|
||||
case 0x1FC00800 ... 0x7FFFFFFF:
|
||||
case 0x80000000 ... 0xFFFFFFFF:
|
||||
break;
|
||||
@@ -373,7 +414,8 @@ void Mem::Write32(Registers& regs, u32 paddr, u32 val) {
|
||||
break;
|
||||
case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF:
|
||||
case 0x08000000 ... 0x0FFFFFFF: case 0x04900000 ... 0x07FFFFFF:
|
||||
case 0x1FC00800 ... 0x7FFFFFFF: case 0x80000000 ... 0xFFFFFFFF: break;
|
||||
case 0x1FC00000 ... 0x1FC007BF: case 0x1FC00800 ... 0x7FFFFFFF:
|
||||
case 0x80000000 ... 0xFFFFFFFF: break;
|
||||
default: Util::panic("Unimplemented 32-bit write at address {:08X} with value {:0X} (PC = {:016X})\n", paddr, val, (u64)regs.pc);
|
||||
}
|
||||
}
|
||||
@@ -414,6 +456,7 @@ void Mem::Write64(Registers& regs, u32 paddr, u64 val) {
|
||||
case 0x04200000 ... 0x042FFFFF:
|
||||
case 0x08000000 ... 0x0FFFFFFF:
|
||||
case 0x04900000 ... 0x07FFFFFF:
|
||||
case 0x1FC00000 ... 0x1FC007BF:
|
||||
case 0x1FC00800 ... 0x7FFFFFFF:
|
||||
case 0x80000000 ... 0xFFFFFFFF:
|
||||
break;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <log.hpp>
|
||||
#include <Registers.hpp>
|
||||
#include <algorithm>
|
||||
#include <GameDB.hpp>
|
||||
|
||||
namespace n64 {
|
||||
struct CartInfo {
|
||||
@@ -17,13 +18,41 @@ struct CartInfo {
|
||||
|
||||
struct JIT;
|
||||
|
||||
struct ROMHeader {
|
||||
u8 initialValues[4];
|
||||
u32 clockRate;
|
||||
u32 programCounter;
|
||||
u32 release;
|
||||
u32 crc1;
|
||||
u32 crc2;
|
||||
u64 unknown;
|
||||
char imageName[20];
|
||||
u32 unknown2;
|
||||
u32 manufacturerId;
|
||||
u16 cartridgeId;
|
||||
char countryCode[2];
|
||||
u8 bootCode[4032];
|
||||
};
|
||||
|
||||
struct ROM {
|
||||
u8* cart;
|
||||
size_t size;
|
||||
size_t mask;
|
||||
ROMHeader header;
|
||||
CICType cicType;
|
||||
char gameNameCart[20];
|
||||
std::string gameNameDB;
|
||||
char code[4];
|
||||
bool pal;
|
||||
};
|
||||
|
||||
struct Mem {
|
||||
~Mem() {
|
||||
free(sram);
|
||||
}
|
||||
Mem();
|
||||
void Reset();
|
||||
CartInfo LoadROM(const std::string&);
|
||||
void LoadROM(const std::string&);
|
||||
[[nodiscard]] auto GetRDRAM() const -> u8* {
|
||||
return mmio.rdp.rdram;
|
||||
}
|
||||
@@ -73,47 +102,21 @@ struct Mem {
|
||||
fclose(fp);
|
||||
}
|
||||
uintptr_t writePages[PAGE_COUNT], readPages[PAGE_COUNT];
|
||||
ROM rom;
|
||||
SaveType saveType;
|
||||
private:
|
||||
friend struct SI;
|
||||
friend struct PI;
|
||||
friend struct AI;
|
||||
friend struct RSP;
|
||||
friend struct Core;
|
||||
u8* sram, *cart;
|
||||
u8* sram;
|
||||
u8 isviewer[ISVIEWER_SIZE]{};
|
||||
size_t romMask = 0;
|
||||
|
||||
static void SetCICType(u32& cicType, u32 checksum) {
|
||||
switch(checksum) {
|
||||
case 0xEC8B1325: // 7102
|
||||
cicType = CIC_NUS_7102;
|
||||
break;
|
||||
case 0x1DEB51A9: // 6101
|
||||
cicType = CIC_NUS_6101;
|
||||
break;
|
||||
case 0xC08E5BD6:
|
||||
cicType = CIC_NUS_6102_7101;
|
||||
break;
|
||||
case 0x03B8376A:
|
||||
cicType = CIC_NUS_6103_7103;
|
||||
break;
|
||||
case 0xCF7F41DC:
|
||||
cicType = CIC_NUS_6105_7105;
|
||||
break;
|
||||
case 0xD1059C6A:
|
||||
cicType = CIC_NUS_6106_7106;
|
||||
break;
|
||||
default:
|
||||
Util::warn("Could not determine CIC TYPE! Checksum: {:08X} is unknown!\n", checksum);
|
||||
cicType = UNKNOWN_CIC_TYPE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsROMPAL() {
|
||||
static const char pal_codes[] = {'D', 'F', 'I', 'P', 'S', 'U', 'X', 'Y'};
|
||||
return std::any_of(std::begin(pal_codes), std::end(pal_codes), [this](char a) {
|
||||
return cart[0x3e] == a;
|
||||
return rom.cart[0x3e] == a;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -52,7 +52,7 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
|
||||
}
|
||||
rdLen = len;
|
||||
for(int i = 0; i < len; i++) {
|
||||
mem.cart[BYTE_ADDRESS(cart_addr + i) & mem.romMask] = mem.mmio.rdp.rdram[BYTE_ADDRESS(dram_addr + i) & RDRAM_DSIZE];
|
||||
mem.rom.cart[BYTE_ADDRESS(cart_addr + i) & mem.rom.mask] = mem.mmio.rdp.rdram[BYTE_ADDRESS(dram_addr + i) & RDRAM_DSIZE];
|
||||
}
|
||||
dramAddr = dram_addr + len;
|
||||
cartAddr = cart_addr + len;
|
||||
@@ -68,7 +68,7 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
|
||||
}
|
||||
wrLen = len;
|
||||
for(int i = 0; i < len; i++) {
|
||||
mem.mmio.rdp.rdram[BYTE_ADDRESS(dram_addr + i) & RDRAM_DSIZE] = mem.cart[BYTE_ADDRESS(cart_addr + i) & mem.romMask];
|
||||
mem.mmio.rdp.rdram[BYTE_ADDRESS(dram_addr + i) & RDRAM_DSIZE] = mem.rom.cart[BYTE_ADDRESS(cart_addr + i) & mem.rom.mask];
|
||||
}
|
||||
dramAddr = dram_addr + len;
|
||||
cartAddr = cart_addr + len;
|
||||
|
||||
@@ -55,7 +55,22 @@ void PIF::ProcessPIFCommands(Mem& mem) {
|
||||
res[2] = controller.joy_x;
|
||||
res[3] = controller.joy_y;
|
||||
break;
|
||||
case 2: case 3: res[0] = 0; break;
|
||||
case 2:
|
||||
Util::print("MEMPAK READ\n");
|
||||
res[0] = 0;
|
||||
break;
|
||||
case 3:
|
||||
Util::print("MEMPAK WRITE\n");
|
||||
res[0] = 0;
|
||||
break;
|
||||
case 4:
|
||||
Util::print("EEPROM READ\n");
|
||||
res[0] = 0;
|
||||
break;
|
||||
case 5:
|
||||
Util::print("EEPROM WRITE\n");
|
||||
res[0] = 0;
|
||||
break;
|
||||
default: Util::panic("Unimplemented PIF command {}", cmd[2]);
|
||||
}
|
||||
|
||||
@@ -163,9 +178,7 @@ void PIF::UpdateController() {
|
||||
}
|
||||
}
|
||||
|
||||
void PIF::DoPIFHLE(Mem& mem, Registers& regs, CartInfo cartInfo) {
|
||||
u32 cicType = cartInfo.cicType;
|
||||
bool pal = cartInfo.isPAL;
|
||||
void PIF::DoPIFHLE(Mem& mem, Registers& regs, bool pal, CICType cicType) {
|
||||
mem.Write32(regs, PIF_RAM_REGION_START + 0x24, cicSeeds[cicType]);
|
||||
|
||||
switch(cicType) {
|
||||
@@ -426,12 +439,13 @@ void PIF::DoPIFHLE(Mem& mem, Registers& regs, CartInfo cartInfo) {
|
||||
regs.gpr[22] = (cicSeeds[cicType] >> 8) & 0xFF;
|
||||
regs.cop0.Reset();
|
||||
mem.Write32(regs, 0x04300004, 0x01010101);
|
||||
memcpy(mem.mmio.rsp.dmem, mem.rom.cart, 0x1000);
|
||||
regs.SetPC32(0xA4000040);
|
||||
}
|
||||
|
||||
void PIF::ExecutePIF(Mem& mem, Registers& regs, CartInfo cartInfo) {
|
||||
u32 cicType = cartInfo.cicType;
|
||||
bool pal = cartInfo.isPAL;
|
||||
void PIF::ExecutePIF(Mem& mem, Registers& regs) {
|
||||
CICType cicType = mem.rom.cicType;
|
||||
bool pal = mem.rom.pal;
|
||||
mem.Write32(regs, PIF_RAM_REGION_START + 0x24, cicSeeds[cicType]);
|
||||
switch(cicType) {
|
||||
case UNKNOWN_CIC_TYPE:
|
||||
@@ -447,6 +461,6 @@ void PIF::ExecutePIF(Mem& mem, Registers& regs, CartInfo cartInfo) {
|
||||
break;
|
||||
}
|
||||
|
||||
DoPIFHLE(mem, regs, cartInfo);
|
||||
DoPIFHLE(mem, regs, pal, cicType);
|
||||
}
|
||||
}
|
||||
@@ -44,10 +44,10 @@ constexpr u32 cicSeeds[] = {
|
||||
0x0,
|
||||
0x00043F3F, // CIC_NUS_6101
|
||||
0x00043F3F, // CIC_NUS_7102
|
||||
0x00003F3F, // CIC_NUS_6102_7101
|
||||
0x0000783F, // CIC_NUS_6103_7103
|
||||
0x0000913F, // CIC_NUS_6105_7105
|
||||
0x0000853F, // CIC_NUS_6106_7106
|
||||
0x00043F3F, // CIC_NUS_6102_7101
|
||||
0x00047878, // CIC_NUS_6103_7103
|
||||
0x00049191, // CIC_NUS_6105_7105
|
||||
0x00048585, // CIC_NUS_6106_7106
|
||||
};
|
||||
|
||||
enum CICType {
|
||||
@@ -64,12 +64,23 @@ struct CartInfo;
|
||||
|
||||
struct PIF {
|
||||
void ProcessPIFCommands(Mem&);
|
||||
void ExecutePIF(Mem& mem, Registers& regs, CartInfo cartInfo);
|
||||
void DoPIFHLE(Mem& mem, Registers& regs, CartInfo cartInfo);
|
||||
void ExecutePIF(Mem& mem, Registers& regs);
|
||||
void DoPIFHLE(Mem& mem, Registers& regs, bool pal, CICType cicType);
|
||||
void UpdateController();
|
||||
bool gamepadConnected = false;
|
||||
SDL_GameController* gamepad;
|
||||
Controller controller;
|
||||
u8 pifBootrom[PIF_BOOTROM_SIZE]{}, pifRam[PIF_RAM_SIZE];
|
||||
u8 Read(u32 addr) {
|
||||
addr &= 0x7FF;
|
||||
if(addr < 0x7c0) return pifBootrom[addr];
|
||||
return pifRam[addr];
|
||||
}
|
||||
|
||||
void Write(u32 addr, u8 val) {
|
||||
addr &= 0x7FF;
|
||||
if(addr < 0x7c0) return;
|
||||
pifRam[addr] = val;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -44,7 +44,6 @@ void DMA(Mem& mem, Registers& regs) {
|
||||
for(int i = 0; i < 64; i++) {
|
||||
si.pif.pifRam[i] = mem.mmio.rdp.rdram[BYTE_ADDRESS(si.dramAddr + i)];
|
||||
}
|
||||
Util::debug("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})\n", si.pifAddr, si.dramAddr);
|
||||
si.pif.ProcessPIFCommands(mem);
|
||||
}
|
||||
InterruptRaise(mem.mmio.mi, regs, Interrupt::SI);
|
||||
@@ -66,7 +65,7 @@ void SI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
|
||||
pifAddr = val & 0x1FFFFFFF;
|
||||
status.dmaBusy = true;
|
||||
toDram = false;
|
||||
scheduler.enqueueRelative({SI_DMA_DELAY, DMA});
|
||||
scheduler.enqueueRelative({4065*3, DMA});
|
||||
Util::debug("SI DMA from RDRAM to PIF RAM ({:08X} to {:08X})\n", dramAddr, pifAddr);
|
||||
} break;
|
||||
case 0x04800018:
|
||||
|
||||
Reference in New Issue
Block a user