diff --git a/src/backend/core/mmio/PI.cpp b/src/backend/core/mmio/PI.cpp index ce209daf..61830a07 100644 --- a/src/backend/core/mmio/PI.cpp +++ b/src/backend/core/mmio/PI.cpp @@ -466,19 +466,19 @@ u32 PI::AccessTiming(const u8 domain, const u32 length) const { latency = piBsdDom1Lat + 1; pulse_width = piBsdDom1Pwd + 1; release = piBsdDom1Rls + 1; - page_size = std::pow(2, (piBsdDom1Pgs + 2)); + page_size = 1 << (piBsdDom1Pgs + 2); break; case 2: latency = piBsdDom2Lat + 1; pulse_width = piBsdDom2Pwd + 1; release = piBsdDom2Rls + 1; - page_size = std::pow(2, (piBsdDom2Pgs + 2)); + page_size = 1 << (piBsdDom2Pgs + 2); break; default: panic("Unknown PI domain: {}\n", domain); } - const uint32_t pages = ceil(static_cast(length) / page_size); + const uint32_t pages = static_cast(ceil(static_cast(length) / static_cast(page_size))); cycles += (14 + latency) * pages; cycles += (pulse_width + release) * (length / 2); @@ -492,8 +492,8 @@ void PI::DMA() { const s32 len = rdLen + 1; trace("PI DMA from RDRAM to CARTRIDGE (size: {} B, {:08X} to {:08X})", len, dramAddr, cartAddr); - if (mem.saveType == SAVE_FLASH_1m && cartAddr >= SREGION_PI_SRAM && cartAddr < 0x08010000) { - cartAddr = SREGION_PI_SRAM | ((cartAddr & 0xFFFFF) << 1); + if (mem.saveType == SAVE_FLASH_1m && cartAddr >= SREGION_PI_SRAM && cartAddr < (CART_REGION_START_2_2 + 1_mb)) { + cartAddr = SREGION_PI_SRAM | ((cartAddr & (1_mb-1)) << 1); } for (int i = 0; i < len; i++) { @@ -515,8 +515,8 @@ void PI::DMA() { const s32 len = wrLen + 1; trace("PI DMA from CARTRIDGE to RDRAM (size: {} B, {:08X} to {:08X})", len, cartAddr, dramAddr); - if (mem.saveType == SAVE_FLASH_1m && cartAddr >= SREGION_PI_SRAM && cartAddr < 0x08010000) { - cartAddr = SREGION_PI_SRAM | ((cartAddr & 0xFFFFF) << 1); + if (mem.saveType == SAVE_FLASH_1m && cartAddr >= SREGION_PI_SRAM && cartAddr < (CART_REGION_START_2_2 + 1_mb)) { + cartAddr = SREGION_PI_SRAM | ((cartAddr & (1_mb-1)) << 1); } for (u32 i = 0; i < len; i++) { diff --git a/src/backend/core/mmio/PIF.cpp b/src/backend/core/mmio/PIF.cpp index ba75d950..67b1161b 100644 --- a/src/backend/core/mmio/PIF.cpp +++ b/src/backend/core/mmio/PIF.cpp @@ -125,7 +125,7 @@ void PIF::LoadEeprom(const SaveType saveType, const std::string &path) { } } -enum CMDIndexes { CMD_LEN = 0, CMD_RES_LEN, CMD_IDX, CMD_START }; +enum CommandIndexes { COMMAND_LEN = 0, COMMAND_RESULT_LEN, COMMAND_INDEX, COMMAND_START }; void PIF::CICChallenge() { u8 challenge[30]; @@ -167,28 +167,32 @@ FORCE_INLINE u8 DataCRC(const u8 *data) { #define BCD_ENCODE(x) (((x) / 10) << 4 | ((x) % 10)) #define BCD_DECODE(x) (((x) >> 4) * 10 + ((x) & 15)) -void PIF::ProcessCommands(const Mem &mem) { - const u8 control = ram[63]; - if (control & 1) { - channel = 0; - int i = 0; - while (i < 63) { - u8 *cmd = &ram[i++]; +void PIF::ConfigureJoyBusFrame(const Mem& mem) { + channel = 0; + int i = 0; + while (i < 63) { + u8 *packet = &ram[i++]; + const u8& commandLength = packet[COMMAND_LEN] & 0x3F; - if (const u8 cmdlen = cmd[CMD_LEN] & 0x3F; cmdlen == 0 || cmdlen == 0x3D) { - channel++; - } else if (cmdlen == 0x3E) { + if (commandLength == 0) { + channel++; + } else if (commandLength == 0x3D) { + channel = 0; + channel++; + } else if (commandLength == 0x3E) { + break; + } else if (commandLength == 0x3F) { + continue; + } else { + const u8 r = ram[i++]; + if (r == 0xFE) { break; - } else if (cmdlen == 0x3F) { - } else { - const u8 r = ram[i++]; - if (r == 0xFE) { - break; - } - const u8 reslen = r & 0x3F; - u8 *res = &ram[i + cmdlen]; + } + const u8 reslen = r & 0x3F; + u8 *res = &ram[i + commandLength]; + const u8& commandIndex = packet[COMMAND_INDEX]; - switch (cmd[CMD_IDX]) { + switch (commandIndex) { case 0: case 0xff: ControllerID(res); @@ -196,61 +200,70 @@ void PIF::ProcessCommands(const Mem &mem) { break; case 1: if (!ReadButtons(res)) { - cmd[1] |= 0x80; + packet[COMMAND_RESULT_LEN] |= 0x80; } channel++; break; case 2: - MempakRead(cmd, res); + MempakRead(packet, res); break; case 3: - MempakWrite(cmd, res); + MempakWrite(packet, res); break; case 4: - EepromRead(cmd, res, mem); + EepromRead(packet, res, mem); break; case 5: - EepromWrite(cmd, res, mem); + EepromWrite(packet, res, mem); break; case 6: res[0] = 0x00; res[1] = 0x10; res[2] = 0x80; break; - case 7: - switch (cmd[CMD_START]) { - case 0: - case 1: - case 3: - break; - case 2: - { - auto now = std::time(nullptr); - const auto *gmtm = gmtime(&now); - res[0] = BCD_ENCODE(gmtm->tm_sec); - res[1] = BCD_ENCODE(gmtm->tm_min); - res[2] = BCD_ENCODE(gmtm->tm_hour) + 0x80; - res[3] = BCD_ENCODE(gmtm->tm_mday); - res[4] = BCD_ENCODE(gmtm->tm_wday); - res[5] = BCD_ENCODE(gmtm->tm_mon); - res[6] = BCD_ENCODE(gmtm->tm_year); - res[7] = (gmtm->tm_year - 1900) >= 100 ? 1 : 0; - } - break; - default: - panic("Invalid read RTC block {}", cmd[CMD_START]); + case 7: { + const u8& commandStart = packet[COMMAND_START]; + switch (commandStart) { + case 0: + case 1: + case 3: + break; + case 2: + { + auto now = std::time(nullptr); + const auto *gmtm = gmtime(&now); + res[0] = BCD_ENCODE(gmtm->tm_sec); + res[1] = BCD_ENCODE(gmtm->tm_min); + res[2] = BCD_ENCODE(gmtm->tm_hour) + 0x80; + res[3] = BCD_ENCODE(gmtm->tm_mday); + res[4] = BCD_ENCODE(gmtm->tm_wday); + res[5] = BCD_ENCODE(gmtm->tm_mon); + res[6] = BCD_ENCODE(gmtm->tm_year); + res[7] = (gmtm->tm_year - 1900) >= 100 ? 1 : 0; + res[8] = 0x80; + } + break; + default: + panic("Invalid read RTC block {}", commandStart); } - break; + } break; case 8: + res[0] = 0x00; break; default: - panic("Invalid PIF command: {:X}", cmd[2]); - } - - i += cmdlen + reslen; + panic("Invalid PIF command: {:X}", commandIndex); } + + i += commandLength + reslen; } } +} + +void PIF::ProcessCommands(const Mem &mem) { + const u8 control = ram[63]; + if (control & 1) { + ConfigureJoyBusFrame(mem); + } if (control & 0x02) { CICChallenge(); diff --git a/src/backend/core/mmio/PIF.hpp b/src/backend/core/mmio/PIF.hpp index b64bbff0..61a55d49 100644 --- a/src/backend/core/mmio/PIF.hpp +++ b/src/backend/core/mmio/PIF.hpp @@ -235,5 +235,7 @@ struct PIF { return joybusDevices[channel].accessoryType; } +private: + void ConfigureJoyBusFrame(const Mem &); }; } // namespace n64