Small fixes and improvements

This commit is contained in:
SimoneN64
2023-03-19 15:24:59 +01:00
parent 357b5839ca
commit 95655b7001
7 changed files with 70 additions and 64 deletions

View File

@@ -127,9 +127,9 @@ u8 Mem::Read8(n64::Registers &regs, u32 paddr) {
paddr = (paddr + 2) & ~2; paddr = (paddr + 2) & ~2;
return rom.cart[BYTE_ADDRESS(paddr) & rom.mask]; return rom.cart[BYTE_ADDRESS(paddr) & rom.mask];
case 0x1FC00000 ... 0x1FC007BF: case 0x1FC00000 ... 0x1FC007BF:
return si.pif.pifBootrom[BYTE_ADDRESS(paddr) - 0x1FC00000]; return si.pif.bootrom[BYTE_ADDRESS(paddr) - 0x1FC00000];
case PIF_RAM_REGION: case PIF_RAM_REGION:
return si.pif.pifRam[paddr - PIF_RAM_REGION_START]; return si.pif.ram[paddr - PIF_RAM_REGION_START];
case 0x00800000 ... 0x03FFFFFF: case 0x00800000 ... 0x03FFFFFF:
case 0x04200000 ... 0x042FFFFF: case 0x04200000 ... 0x042FFFFF:
case 0x04900000 ... 0x0FFFFFFF: case 0x04900000 ... 0x0FFFFFFF:
@@ -167,9 +167,9 @@ u16 Mem::Read16(n64::Registers &regs, u32 paddr) {
paddr = (paddr + 2) & ~3; paddr = (paddr + 2) & ~3;
return Util::ReadAccess<u16>(rom.cart, HALF_ADDRESS(paddr) & rom.mask); return Util::ReadAccess<u16>(rom.cart, HALF_ADDRESS(paddr) & rom.mask);
case 0x1FC00000 ... 0x1FC007BF: case 0x1FC00000 ... 0x1FC007BF:
return Util::ReadAccess<u16>(si.pif.pifBootrom, HALF_ADDRESS(paddr) - 0x1FC00000); return Util::ReadAccess<u16>(si.pif.bootrom, HALF_ADDRESS(paddr) - 0x1FC00000);
case PIF_RAM_REGION: case PIF_RAM_REGION:
return be16toh(Util::ReadAccess<u16>(si.pif.pifRam, paddr - PIF_RAM_REGION_START)); return be16toh(Util::ReadAccess<u16>(si.pif.ram, paddr - PIF_RAM_REGION_START));
case 0x00800000 ... 0x03FFFFFF: case 0x00800000 ... 0x03FFFFFF:
case 0x04200000 ... 0x042FFFFF: case 0x04200000 ... 0x042FFFFF:
case 0x04900000 ... 0x0FFFFFFF: case 0x04900000 ... 0x0FFFFFFF:
@@ -204,9 +204,9 @@ u32 Mem::Read32(n64::Registers &regs, u32 paddr) {
case 0x10000000 ... 0x1FBFFFFF: case 0x10000000 ... 0x1FBFFFFF:
return Util::ReadAccess<u32>(rom.cart, paddr & rom.mask); return Util::ReadAccess<u32>(rom.cart, paddr & rom.mask);
case 0x1FC00000 ... 0x1FC007BF: case 0x1FC00000 ... 0x1FC007BF:
return Util::ReadAccess<u32>(si.pif.pifBootrom, paddr - 0x1FC00000); return Util::ReadAccess<u32>(si.pif.bootrom, paddr - 0x1FC00000);
case PIF_RAM_REGION: case PIF_RAM_REGION:
return be32toh(Util::ReadAccess<u32>(si.pif.pifRam, paddr - PIF_RAM_REGION_START)); return be32toh(Util::ReadAccess<u32>(si.pif.ram, paddr - PIF_RAM_REGION_START));
case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF: case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF:
case 0x04900000 ... 0x0FFFFFFF: case 0x1FC00800 ... 0xFFFFFFFF: return 0; case 0x04900000 ... 0x0FFFFFFF: case 0x1FC00800 ... 0xFFFFFFFF: return 0;
default: default:
@@ -240,9 +240,9 @@ u64 Mem::Read64(n64::Registers &regs, u32 paddr) {
case 0x10000000 ... 0x1FBFFFFF: case 0x10000000 ... 0x1FBFFFFF:
return Util::ReadAccess<u64>(rom.cart, paddr & rom.mask); return Util::ReadAccess<u64>(rom.cart, paddr & rom.mask);
case 0x1FC00000 ... 0x1FC007BF: case 0x1FC00000 ... 0x1FC007BF:
return Util::ReadAccess<u64>(si.pif.pifBootrom, paddr - 0x1FC00000); return Util::ReadAccess<u64>(si.pif.bootrom, paddr - 0x1FC00000);
case PIF_RAM_REGION: case PIF_RAM_REGION:
return be64toh(Util::ReadAccess<u64>(si.pif.pifRam, paddr - PIF_RAM_REGION_START)); return be64toh(Util::ReadAccess<u64>(si.pif.ram, paddr - PIF_RAM_REGION_START));
case 0x00800000 ... 0x03FFFFFF: case 0x00800000 ... 0x03FFFFFF:
case 0x04200000 ... 0x042FFFFF: case 0x04200000 ... 0x042FFFFF:
case 0x04900000 ... 0x0FFFFFFF: case 0x04900000 ... 0x0FFFFFFF:
@@ -305,8 +305,8 @@ void Mem::Write8(Registers& regs, u32 paddr, u32 val) {
case PIF_RAM_REGION: case PIF_RAM_REGION:
val = val << (8 * (3 - (paddr & 3))); val = val << (8 * (3 - (paddr & 3)));
paddr = (paddr - PIF_RAM_REGION_START) & ~3; paddr = (paddr - PIF_RAM_REGION_START) & ~3;
Util::WriteAccess<u32>(si.pif.pifRam, paddr, htobe32(val)); Util::WriteAccess<u32>(si.pif.ram, paddr, htobe32(val));
si.pif.ProcessPIFCommands(*this); si.pif.ProcessCommands(*this);
break; break;
case 0x00800000 ... 0x03FFFFFF: case 0x00800000 ... 0x03FFFFFF:
case 0x04200000 ... 0x042FFFFF: case 0x04200000 ... 0x042FFFFF:
@@ -356,8 +356,8 @@ void Mem::Write16(Registers& regs, u32 paddr, u32 val) {
case PIF_RAM_REGION: case PIF_RAM_REGION:
val = val << (16 * !(paddr & 2)); val = val << (16 * !(paddr & 2));
paddr &= ~3; paddr &= ~3;
Util::WriteAccess<u32>(si.pif.pifRam, paddr - PIF_RAM_REGION_START, htobe32(val)); Util::WriteAccess<u32>(si.pif.ram, paddr - PIF_RAM_REGION_START, htobe32(val));
si.pif.ProcessPIFCommands(*this); si.pif.ProcessCommands(*this);
break; break;
case 0x00800000 ... 0x03FFFFFF: case 0x00800000 ... 0x03FFFFFF:
case 0x04200000 ... 0x042FFFFF: case 0x04200000 ... 0x042FFFFF:
@@ -409,8 +409,8 @@ void Mem::Write32(Registers& regs, u32 paddr, u32 val) {
break; break;
case 0x14000000 ... 0x1FBFFFFF: break; case 0x14000000 ... 0x1FBFFFFF: break;
case PIF_RAM_REGION: case PIF_RAM_REGION:
Util::WriteAccess<u32>(si.pif.pifRam, paddr - PIF_RAM_REGION_START, htobe32(val)); Util::WriteAccess<u32>(si.pif.ram, paddr - PIF_RAM_REGION_START, htobe32(val));
si.pif.ProcessPIFCommands(*this); si.pif.ProcessCommands(*this);
break; break;
case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF: case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF:
case 0x08000000 ... 0x0FFFFFFF: case 0x04900000 ... 0x07FFFFFF: case 0x08000000 ... 0x0FFFFFFF: case 0x04900000 ... 0x07FFFFFF:
@@ -449,8 +449,8 @@ void Mem::Write64(Registers& regs, u32 paddr, u64 val) {
case 0x10000000 ... 0x1FBFFFFF: case 0x10000000 ... 0x1FBFFFFF:
break; break;
case PIF_RAM_REGION: case PIF_RAM_REGION:
Util::WriteAccess<u64>(si.pif.pifRam, paddr - PIF_RAM_REGION_START, htobe64(val)); Util::WriteAccess<u64>(si.pif.ram, paddr - PIF_RAM_REGION_START, htobe64(val));
si.pif.ProcessPIFCommands(*this); si.pif.ProcessCommands(*this);
break; break;
case 0x00800000 ... 0x03FFFFFF: case 0x00800000 ... 0x03FFFFFF:
case 0x04200000 ... 0x042FFFFF: case 0x04200000 ... 0x042FFFFF:

View File

@@ -11,7 +11,7 @@ RSP::RSP() {
void RSP::Reset() { void RSP::Reset() {
lastSuccessfulSPAddr.raw = 0; lastSuccessfulSPAddr.raw = 0;
lastSuccessfulDRAMAddr.raw = 0; lastSuccessfulDRAMAddr.raw = 0;
spStatus.raw = 0x1; spStatus.raw = 0;
spStatus.halt = true; spStatus.halt = true;
oldPC = 0; oldPC = 0;
pc = 0; pc = 0;

View File

@@ -13,14 +13,14 @@ void PIF::CICChallenge() {
// Split 15 bytes into 30 nibbles // Split 15 bytes into 30 nibbles
for (int i = 0; i < 15; i++) { for (int i = 0; i < 15; i++) {
challenge[i * 2 + 0] = (pifRam[0x30 + i] >> 4) & 0x0F; challenge[i * 2 + 0] = (ram[0x30 + i] >> 4) & 0x0F;
challenge[i * 2 + 1] = (pifRam[0x30 + i] >> 0) & 0x0F; challenge[i * 2 + 1] = (ram[0x30 + i] >> 0) & 0x0F;
} }
n64_cic_nus_6105((char*)challenge, (char*)response, CHL_LEN - 2); n64_cic_nus_6105((char*)challenge, (char*)response, CHL_LEN - 2);
for (int i = 0; i < 15; i++) { for (int i = 0; i < 15; i++) {
pifRam[0x30 + i] = (response[i * 2] << 4) + response[i * 2 + 1]; ram[0x30 + i] = (response[i * 2] << 4) + response[i * 2 + 1];
} }
} }
@@ -30,32 +30,33 @@ void PIF::ProcessPIFCommands(Mem &mem) {
channel = 0; channel = 0;
int i = 0; int i = 0;
while (i < 63) { while (i < 63) {
u8* cmd = &pifRam[i++]; u8* cmd = &ram[i++];
u8 cmdlen = cmd[0] & 0x3F; u8 cmdlen = cmd[CMD_LEN] & 0x3F;
if (cmdlen == 0) { if (cmdlen == 0) {
channel++; channel++;
} else if (cmdlen == 0x3D) { // 0xFD in PIF RAM = send reset signal to this pif channel } else if (cmdlen == 0x3D) {
channel++; channel++;
} else if (cmdlen == 0x3E) { // 0xFE in PIF RAM = end of commands } else if (cmdlen == 0x3E) {
break; break;
} else if (cmdlen == 0x3F) { } else if (cmdlen == 0x3F) {
continue; continue;
} else { } else {
u8 r = pifRam[i++]; u8 r = ram[i++];
r |= (1 << 7); if (r == 0xFE) {
if (r == 0xFE) { // 0xFE in PIF RAM = end of commands.
break; break;
} }
u8 reslen = r & 0x3F; // TODO: out of bounds access possible on invalid data u8 reslen = r & 0x3F;
u8* res = &pifRam[i + cmdlen]; u8* res = &ram[i + cmdlen];
switch (cmd[2]) { switch (cmd[CMD_IDX]) {
case 0xff: case 0xff:
ControllerID(res); ControllerID(res);
channel++;
break; break;
case 0: case 0:
ControllerID(res); ControllerID(res);
channel++;
break; break;
case 1: case 1:
UpdateController(); UpdateController();
@@ -88,13 +89,13 @@ void PIF::ProcessPIFCommands(Mem &mem) {
} }
} }
//if (control & 2) { if (control & 0x02) {
// CICChallenge(); CICChallenge();
// pifRam[63] &= ~2; ram[63] &= ~2;
//} }
if (control & 0x08) { if (control & 0x08) {
pifRam[63] &= ~8; ram[63] &= ~8;
} }
if (control & 0x30) { if (control & 0x30) {

View File

@@ -99,19 +99,27 @@ struct PIF {
void ControllerID(u8* res); void ControllerID(u8* res);
SDL_GameController* gamepad; SDL_GameController* gamepad;
JoybusDevice joybusDevices[6]{}; JoybusDevice joybusDevices[6]{};
u8 pifBootrom[PIF_BOOTROM_SIZE]{}, pifRam[PIF_RAM_SIZE]{}; u8 bootrom[PIF_BOOTROM_SIZE]{}, ram[PIF_RAM_SIZE]{}, *mempak, *eeprom;
int channel = 0; int channel = 0;
u8 Read(u32 addr) { u8 Read(u32 addr) {
addr &= 0x7FF; addr &= 0x7FF;
if(addr < 0x7c0) return pifBootrom[addr]; if(addr < 0x7c0) return bootrom[addr];
return pifRam[addr & PIF_RAM_DSIZE]; return ram[addr & PIF_RAM_DSIZE];
} }
void Write(u32 addr, u8 val) { void Write(u32 addr, u8 val) {
addr &= 0x7FF; addr &= 0x7FF;
if(addr < 0x7c0) return; if(addr < 0x7c0) return;
pifRam[addr & PIF_RAM_DSIZE] = val; ram[addr & PIF_RAM_DSIZE] = val;
}
inline AccessoryType getAccessoryType() const {
if (channel >= 4 || joybusDevices[channel].type != JOYBUS_CONTROLLER) {
return ACCESSORY_NONE;
} else {
return joybusDevices[channel].accessoryType;
}
} }
}; };
} }

View File

@@ -4,13 +4,12 @@
namespace n64 { namespace n64 {
void PIF::InitDevices(SaveType saveType) { void PIF::InitDevices(SaveType saveType) {
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) { //TODO: make this configurable
joybusDevices[i].type = JOYBUS_CONTROLLER; //TODO joybusDevices[i].type = JOYBUS_NONE;
if (joybusDevices[i].type) { joybusDevices[i].accessoryType = ACCESSORY_NONE;
// TODO: make this configurable
joybusDevices[i].accessoryType = ACCESSORY_MEMPACK;
}
} }
joybusDevices[0].type = JOYBUS_CONTROLLER;
joybusDevices[0].accessoryType = ACCESSORY_MEMPACK;
if (saveType == SAVE_EEPROM_4k) { if (saveType == SAVE_EEPROM_4k) {
joybusDevices[4].type = JOYBUS_4KB_EEPROM; joybusDevices[4].type = JOYBUS_4KB_EEPROM;
@@ -22,7 +21,7 @@ void PIF::InitDevices(SaveType saveType) {
joybusDevices[5].type = JOYBUS_NONE; joybusDevices[5].type = JOYBUS_NONE;
} }
void PIF::ControllerID(u8 *res) { void PIF::ControllerID(u8 *res) const {
if (channel < 6) { if (channel < 6) {
switch (joybusDevices[channel].type) { switch (joybusDevices[channel].type) {
case JOYBUS_NONE: case JOYBUS_NONE:
@@ -74,11 +73,9 @@ void PIF::ControllerID(u8 *res) {
} else { } else {
Util::panic("Device ID on unknown channel {}", channel); Util::panic("Device ID on unknown channel {}", channel);
} }
channel++;
} }
bool PIF::ReadButtons(u8* res) { bool PIF::ReadButtons(u8* res) const {
if(channel >= 6) { if(channel >= 6) {
res[0] = 0; res[0] = 0;
res[1] = 0; res[1] = 0;
@@ -96,20 +93,18 @@ bool PIF::ReadButtons(u8* res) {
return false; // Device not present return false; // Device not present
case JOYBUS_CONTROLLER: case JOYBUS_CONTROLLER:
if (TasMovieLoaded()) { if (TasMovieLoaded()) {
// Load inputs from TAS movie
Controller controller = TasNextInputs(); Controller controller = TasNextInputs();
res[0] = controller.byte1; res[0] = controller.byte1;
res[1] = controller.byte2; res[1] = controller.byte2;
res[2] = controller.joy_x; res[2] = controller.joy_x;
res[3] = controller.joy_y; res[3] = controller.joy_y;
} else { } else {
// Load inputs normally
res[0] = joybusDevices[channel].controller.byte1; res[0] = joybusDevices[channel].controller.byte1;
res[1] = joybusDevices[channel].controller.byte2; res[1] = joybusDevices[channel].controller.byte2;
res[2] = joybusDevices[channel].controller.joy_x; res[2] = joybusDevices[channel].controller.joy_x;
res[3] = joybusDevices[channel].controller.joy_y; res[3] = joybusDevices[channel].controller.joy_y;
} }
break; return true;
case JOYBUS_DANCEPAD: case JOYBUS_DANCEPAD:
case JOYBUS_VRU: case JOYBUS_VRU:
case JOYBUS_MOUSE: case JOYBUS_MOUSE:
@@ -120,6 +115,6 @@ bool PIF::ReadButtons(u8* res) {
return false; return false;
} }
return true; // Success! return true;
} }
} }

View File

@@ -12,6 +12,8 @@ void SI::Reset() {
dramAddr = 0; dramAddr = 0;
pifAddr = 0; pifAddr = 0;
memset(&pif.joybusDevices, 0, sizeof(JoybusDevice) * 6); memset(&pif.joybusDevices, 0, sizeof(JoybusDevice) * 6);
memset(&pif.bootrom, 0, PIF_BOOTROM_SIZE);
memset(&pif.ram, 0, PIF_RAM_SIZE);
} }
auto SI::Read(MI& mi, u32 addr) const -> u32 { auto SI::Read(MI& mi, u32 addr) const -> u32 {
@@ -36,17 +38,17 @@ void DMA(Mem& mem, Registers& regs) {
SI& si = mem.mmio.si; SI& si = mem.mmio.si;
si.status.dmaBusy = false; si.status.dmaBusy = false;
if(si.toDram) { if(si.toDram) {
si.pif.ProcessPIFCommands(mem); si.pif.ProcessCommands(mem);
for(int i = 0; i < 64; i++) { for(int i = 0; i < 64; i++) {
mem.mmio.rdp.rdram[BYTE_ADDRESS(si.dramAddr + i)] = si.pif.pifRam[i]; mem.mmio.rdp.rdram[BYTE_ADDRESS(si.dramAddr + i)] = si.pif.Read(si.pifAddr + i);
} }
Util::debug("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})\n", si.pifAddr, si.dramAddr); //Util::debug("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})\n", si.pifAddr, si.dramAddr);
} else { } else {
for(int i = 0; i < 64; i++) { for(int i = 0; i < 64; i++) {
si.pif.pifRam[i] = mem.mmio.rdp.rdram[BYTE_ADDRESS(si.dramAddr + i)]; si.pif.Write(si.pifAddr + i, mem.mmio.rdp.rdram[BYTE_ADDRESS(si.dramAddr + i)]);
} }
Util::debug("SI DMA from RDRAM to PIF RAM ({:08X} to {:08X})\n", si.dramAddr, si.pifAddr); //Util::debug("SI DMA from RDRAM to PIF RAM ({:08X} to {:08X})\n", si.dramAddr, si.pifAddr);
si.pif.ProcessPIFCommands(mem); si.pif.ProcessCommands(mem);
} }
InterruptRaise(mem.mmio.mi, regs, Interrupt::SI); InterruptRaise(mem.mmio.mi, regs, Interrupt::SI);
} }
@@ -66,7 +68,7 @@ void SI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
pifAddr = val & 0x1FFFFFFF; pifAddr = val & 0x1FFFFFFF;
status.dmaBusy = true; status.dmaBusy = true;
toDram = false; toDram = false;
scheduler.enqueueRelative({4065*3, DMA}); scheduler.enqueueRelative({SI_DMA_DELAY, DMA});
} break; } break;
case 0x04800018: case 0x04800018:
InterruptLower(mem.mmio.mi, regs, Interrupt::SI); InterruptLower(mem.mmio.mi, regs, Interrupt::SI);

View File

@@ -8,10 +8,10 @@ struct Settings {
Settings(n64::Core&); Settings(n64::Core&);
~Settings(); ~Settings();
float GetVolumeL() const { return volumeL; }; inline float GetVolumeL() const { return volumeL; };
float GetVolumeR() const { return volumeR; }; inline float GetVolumeR() const { return volumeR; };
bool GetLockChannels() const { return lockChannels; } inline bool GetLockChannels() const { return lockChannels; }
std::string GetCpuType() const { return cpuType; } inline std::string GetCpuType() const { return cpuType; }
void RenderWidget(bool& show); void RenderWidget(bool& show);
private: private: