n64: support ROMs bigger than 63.9375 MiB (#1354)

Currently, the n64 core is limited to ROMs whose size is 63.9375 MiB
(also known as 64 MiB - 64 KiB). The reason is twofold: first, only 64
MiB are actually mapped in the PI bus; second, the last 64 KiB are
shadowed by the ISViewer debugging device.

ISViewer addresses sit in the last 64 KiB of the 64th MiB, so when the
ROM is larger than that (for instance, it is exactly 64 MiB), we should
simply disable ISViewer. In the long run, there will be a better
debugging solution which doesn't sit in the PI address space anyway.

Moreover, N64 supports basically ROM of unlimited size, there is no 64
MiB limit. This commit also allows that by simply mapping the whole ROM
into the PI address bus, whatever the actual size is.
This commit is contained in:
Giovanni Bajo authored and GitHub committed 2023-12-28 09:17:52 +00:00
1 parent 432c4e3b2a
commit 1478637209
3 files changed
+22 -17

No files matched your search

+6 -4
View File
@@ -47,10 +47,12 @@ auto Cartridge::connect() -> void {
rtc.load();
isviewer.ram.allocate(64_KiB);
isviewer.tracer = node->append<Node::Debugger::Tracer::Notification>("ISViewer", "Cartridge");
isviewer.tracer->setAutoLineBreak(false);
isviewer.tracer->setTerminal(true);
if(rom.size <= 0x03fe'ffff && system.homebrewMode) {
isviewer.ram.allocate(64_KiB);
isviewer.tracer = node->append<Node::Debugger::Tracer::Notification>("ISViewer", "Cartridge");
isviewer.tracer->setAutoLineBreak(false);
isviewer.tracer->setTerminal(true);
}
debugger.load(node);
+2
View File
@@ -42,6 +42,8 @@ struct Cartridge {
Memory::Writable ram; //unserialized
Node::Debugger::Tracer::Notification tracer;
auto enabled() -> bool { return ram.size; }
//isviewer.cpp
auto messageChar(char c) -> void;
auto readHalf(u32 address) -> u16;
+14 -13
View File
@@ -43,13 +43,13 @@ inline auto PI::busRead(u32 address) -> u32 {
if(cartridge.flash) return cartridge.flash.read<Size>(address);
return unmapped;
}
if(address <= 0x13fe'ffff) {
if(cartridge.rom ) return cartridge.rom.read<Size>(address);
return unmapped;
if(cartridge.isviewer.enabled() && address >= 0x13f0'0000 && address <= 0x13ff'ffff) {
return cartridge.isviewer.read<Size>(address);
}
if(address <= 0x13ff'ffff) return cartridge.isviewer.read<Size>(address);
if(address <= 0x7fff'ffff) return unmapped;
return unmapped; //accesses here actually lock out the RCP
if(address <= 0x1000'0000 + cartridge.rom.size - 1) {
return cartridge.rom.read<Size>(address);
}
return unmapped;
}
inline auto PI::writeWord(u32 address, u32 data, Thread& thread) -> void {
@@ -93,18 +93,19 @@ inline auto PI::busWrite(u32 address, u32 data) -> void {
if(cartridge.flash) return cartridge.flash.write<Size>(address, data);
return;
}
if(address <= 0x13fe'ffff) {
if(cartridge.rom ) return cartridge.rom.write<Size>(address, data);
return;
}
if(address <= 0x13ff'ffff) {
if(system.homebrewMode) {
if(address >= 0x13f0'0000 && address <= 0x13ff'ffff) {
if(cartridge.isviewer.enabled()) {
writeForceFinish(); //Debugging channel for homebrew, be gentle
return cartridge.isviewer.write<Size>(address, data);
} else {
} else if (!system.homebrewMode) {
debug(unhandled, "[PI::busWrite] attempt to write to ISViewer: enable homebrew mode in settings to enable ISViewer emulation");
} else {
debug(unhandled, "[PI::busWrite] attempt to write to ISViewer: ROM is too big so ISViewer is disabled");
}
}
if(address <= 0x1000'0000 + cartridge.rom.size - 1) {
return cartridge.rom.write<Size>(address, data);
}
if(address <= 0x7fff'ffff) return;
}