make use of my new small utility library

This commit is contained in:
2026-03-25 15:50:47 +01:00
parent 0d1aa938e3
commit d9a620bc1f
20 changed files with 194 additions and 506 deletions

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#include <MemoryHelpers.hpp> #include <ircolib/mem_access.hpp>
#include <log.hpp> #include <log.hpp>
namespace Util { namespace Util {
@@ -29,17 +29,17 @@ FORCE_INLINE void SwapN64Rom(std::vector<u8> &rom, u32 endianness) {
switch (endianness) { switch (endianness) {
case V64: case V64:
SwapBuffer<u16>(rom); ircolib::SwapBuffer<u16>(rom);
if constexpr (!toBE) if constexpr (!toBE)
SwapBuffer<u32>(rom); ircolib::SwapBuffer<u32>(rom);
break; break;
case N64: case N64:
if constexpr (toBE) if constexpr (toBE)
SwapBuffer<u32>(rom); ircolib::SwapBuffer<u32>(rom);
break; break;
case Z64: case Z64:
if constexpr (!toBE) if constexpr (!toBE)
SwapBuffer<u32>(rom); ircolib::SwapBuffer<u32>(rom);
break; break;
default: default:
Error::GetInstance().Throw({Error::Severity::UNRECOVERABLE}, {Error::Type::ROM_LOAD_ERROR}, {}, {}, "Unrecognized rom format! Make sure this is a valid Nintendo 64 ROM dump!"); Error::GetInstance().Throw({Error::Severity::UNRECOVERABLE}, {Error::Type::ROM_LOAD_ERROR}, {}, {}, "Unrecognized rom format! Make sure this is a valid Nintendo 64 ROM dump!");

View File

@@ -4,7 +4,7 @@
Disassembler::DisassemblyResult Disassembler::DisassembleSimple(const u32 address, const u32 instruction) const { Disassembler::DisassemblyResult Disassembler::DisassembleSimple(const u32 address, const u32 instruction) const {
cs_insn *insn; cs_insn *insn;
const auto bytes = Util::IntegralToBuffer(std::byteswap(instruction)); const auto bytes = ircolib::IntegralToBuffer(std::byteswap(instruction));
const auto count = cs_disasm(handle, bytes.data(), bytes.size(), address, 0, &insn); const auto count = cs_disasm(handle, bytes.data(), bytes.size(), address, 0, &insn);
if (count <= 0) if (count <= 0)
@@ -30,7 +30,7 @@ Disassembler::DisassemblyResult Disassembler::DisassembleSimple(const u32 addres
Disassembler::DisassemblyResult Disassembler::DisassembleDetailed(const u32 address, const u32 instruction) const { Disassembler::DisassemblyResult Disassembler::DisassembleDetailed(const u32 address, const u32 instruction) const {
n64::Core& core = n64::Core::GetInstance(); n64::Core& core = n64::Core::GetInstance();
cs_insn *insn; cs_insn *insn;
const auto bytes = Util::IntegralToBuffer(std::byteswap(instruction)); const auto bytes = ircolib::IntegralToBuffer(std::byteswap(instruction));
const auto count = cs_disasm(handle, bytes.data(), bytes.size(), address, 0, &insn); const auto count = cs_disasm(handle, bytes.data(), bytes.size(), address, 0, &insn);
if (count <= 0) if (count <= 0)

View File

@@ -1,7 +1,7 @@
#pragma once #pragma once
#include <capstone/capstone.h> #include <capstone/capstone.h>
#include <utils/log.hpp> #include <utils/log.hpp>
#include <utils/MemoryHelpers.hpp> #include <ircolib/mem_access.hpp>
#include <array> #include <array>
struct Disassembler { struct Disassembler {

View File

@@ -240,7 +240,7 @@ u32 JIT::Step() {
} }
void JIT::DumpBlockCacheToDisk() const { void JIT::DumpBlockCacheToDisk() const {
Util::WriteFileBinary(code.getCode<u8*>(), code.getSize(), "jit.dump"); ircolib::WriteFileBinary(code.getCode<u8*>(), code.getSize(), "jit.dump");
} }
#endif #endif
} // namespace n64 } // namespace n64

View File

@@ -47,10 +47,10 @@ void Mem::LoadSRAM(SaveType save_type, fs::path path) {
saveData.unmap(); saveData.unmap();
} }
auto sramVec = Util::ReadFileBinary(sramPath); auto sramVec = ircolib::ReadFileBinary(sramPath);
if (sramVec.empty()) { if (sramVec.empty()) {
Util::WriteFileBinary(std::array<u8, SRAM_SIZE>{}, sramPath); ircolib::WriteFileBinary(std::array<u8, SRAM_SIZE>{}, sramPath);
sramVec = Util::ReadFileBinary(sramPath); sramVec = ircolib::ReadFileBinary(sramPath);
} }
if (sramVec.size() != SRAM_SIZE) { if (sramVec.size() != SRAM_SIZE) {
@@ -107,7 +107,7 @@ void Mem::LoadROM(const bool isArchive, const std::string &filename) {
buf = Util::OpenROM(filename, sizeAdjusted); buf = Util::OpenROM(filename, sizeAdjusted);
} }
endianness = std::byteswap(Util::ReadAccess<u32>(buf, 0)); endianness = std::byteswap(ircolib::ReadAccess<u32>(buf, 0));
Util::SwapN64Rom<true>(buf, endianness); Util::SwapN64Rom<true>(buf, endianness);
std::ranges::copy(buf, rom.cart.begin()); std::ranges::copy(buf, rom.cart.begin());
@@ -135,9 +135,9 @@ void Mem::LoadROM(const bool isArchive, const std::string &filename) {
rom.gameNameCart[i] = '\0'; rom.gameNameCart[i] = '\0';
} }
const u32 checksum = Util::crc32(0, &rom.cart[0x40], 0x9c0); const u32 checksum = SDL_crc32(0, &rom.cart[0x40], 0x9C0);
SetROMCIC(checksum, rom); SetROMCIC(checksum, rom);
endianness = std::byteswap(Util::ReadAccess<u32>(rom.cart, 0)); endianness = std::byteswap(ircolib::ReadAccess<u32>(rom.cart, 0));
Util::SwapN64Rom(rom.cart, endianness); Util::SwapN64Rom(rom.cart, endianness);
rom.pal = IsROMPAL(); rom.pal = IsROMPAL();
} }
@@ -147,33 +147,33 @@ u8 Mem::Read(const u32 paddr) {
n64::Registers& regs = n64::Core::GetRegs(); n64::Registers& regs = n64::Core::GetRegs();
const SI &si = mmio.si; const SI &si = mmio.si;
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM<u8>(paddr); if(ircolib::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM<u8>(paddr);
if(Util::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) { if(ircolib::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem; const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
return src[BYTE_ADDRESS(paddr & 0xfff)]; return src[BYTE_ADDRESS(paddr & 0xfff)];
} }
if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) return mmio.pi.BusRead<u8, false>(paddr); if(ircolib::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) return mmio.pi.BusRead<u8, false>(paddr);
if(Util::IsInsideRange(paddr, AI_REGION_START, AI_REGION_END)) { if(ircolib::IsInsideRange(paddr, AI_REGION_START, AI_REGION_END)) {
const u32 w = mmio.ai.Read(paddr & ~3); const u32 w = mmio.ai.Read(paddr & ~3);
const int offs = 3 - (paddr & 3); const int offs = 3 - (paddr & 3);
return w >> offs * 8 & 0xff; return w >> offs * 8 & 0xff;
} }
if(Util::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) || if(ircolib::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
Util::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) { ircolib::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) {
Util::Error::GetInstance().Throw( Util::Error::GetInstance().Throw(
{Util::Error::Severity::NON_FATAL}, {Util::Error::Type::MEM_INVALID_ACCESS}, regs.pc, {Util::Error::Severity::NON_FATAL}, {Util::Error::Type::MEM_INVALID_ACCESS}, regs.pc,
Util::Error::MemoryAccess{false, Util::Error::MemoryAccess::BYTE, paddr, 0}, "8-bit read access from MMIO"); Util::Error::MemoryAccess{false, Util::Error::MemoryAccess::BYTE, paddr, 0}, "8-bit read access from MMIO");
return 0; return 0;
} }
if(Util::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END)) return si.pif.bootrom[BYTE_ADDRESS(paddr) - PIF_ROM_REGION_START]; if(ircolib::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END)) return si.pif.bootrom[BYTE_ADDRESS(paddr) - PIF_ROM_REGION_START];
if(Util::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) return si.pif.ram[paddr - PIF_RAM_REGION_START]; if(ircolib::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) return si.pif.ram[paddr - PIF_RAM_REGION_START];
if(Util::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused if(ircolib::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
Util::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) || ircolib::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
Util::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) || ircolib::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
Util::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return 0; ircolib::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return 0;
Util::Error::GetInstance().Throw( Util::Error::GetInstance().Throw(
{Util::Error::Severity::NON_FATAL}, {Util::Error::Type::MEM_UNHANDLED_ACCESS}, regs.pc, {Util::Error::Severity::NON_FATAL}, {Util::Error::Type::MEM_UNHANDLED_ACCESS}, regs.pc,
@@ -186,21 +186,21 @@ u16 Mem::Read(const u32 paddr) {
n64::Registers& regs = n64::Core::GetRegs(); n64::Registers& regs = n64::Core::GetRegs();
const SI &si = mmio.si; const SI &si = mmio.si;
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM<u16>(paddr); if(ircolib::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM<u16>(paddr);
if(Util::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) { if(ircolib::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem; const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
return Util::ReadAccess<u16>(src, HALF_ADDRESS(paddr & 0xfff)); return ircolib::ReadAccess<u16>(src, HALF_ADDRESS(paddr & 0xfff));
} }
if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) return mmio.pi.BusRead<u16, false>(paddr); if(ircolib::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) return mmio.pi.BusRead<u16, false>(paddr);
if(Util::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) || if(ircolib::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
Util::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) return mmio.Read(paddr); ircolib::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) return mmio.Read(paddr);
if(Util::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END)) return Util::ReadAccess<u16>(si.pif.bootrom, HALF_ADDRESS(paddr) - PIF_ROM_REGION_START); if(ircolib::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END)) return ircolib::ReadAccess<u16>(si.pif.bootrom, HALF_ADDRESS(paddr) - PIF_ROM_REGION_START);
if(Util::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) return std::byteswap(Util::ReadAccess<u16>(si.pif.ram, paddr - PIF_RAM_REGION_START)); if(ircolib::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) return std::byteswap(ircolib::ReadAccess<u16>(si.pif.ram, paddr - PIF_RAM_REGION_START));
if(Util::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused if(ircolib::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
Util::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) || ircolib::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
Util::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) || ircolib::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
Util::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return 0; ircolib::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return 0;
Util::Error::GetInstance().Throw( Util::Error::GetInstance().Throw(
{Util::Error::Severity::NON_FATAL}, {Util::Error::Type::MEM_UNHANDLED_ACCESS}, regs.pc, {Util::Error::Severity::NON_FATAL}, {Util::Error::Type::MEM_UNHANDLED_ACCESS}, regs.pc,
@@ -213,22 +213,22 @@ u32 Mem::Read(const u32 paddr) {
n64::Registers& regs = n64::Core::GetRegs(); n64::Registers& regs = n64::Core::GetRegs();
const SI &si = mmio.si; const SI &si = mmio.si;
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM<u32>(paddr); if(ircolib::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM<u32>(paddr);
if(Util::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) { if(ircolib::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem; const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
return Util::ReadAccess<u32>(src, paddr & 0xfff); return ircolib::ReadAccess<u32>(src, paddr & 0xfff);
} }
if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) return mmio.pi.BusRead<u32, false>(paddr); if(ircolib::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) return mmio.pi.BusRead<u32, false>(paddr);
if(Util::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) || if(ircolib::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
Util::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) return mmio.Read(paddr); ircolib::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) return mmio.Read(paddr);
if(Util::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END)) return Util::ReadAccess<u32>(si.pif.bootrom, paddr - PIF_ROM_REGION_START); if(ircolib::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END)) return ircolib::ReadAccess<u32>(si.pif.bootrom, paddr - PIF_ROM_REGION_START);
if(Util::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) return std::byteswap(Util::ReadAccess<u32>(si.pif.ram, paddr - PIF_RAM_REGION_START)); if(ircolib::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) return std::byteswap(ircolib::ReadAccess<u32>(si.pif.ram, paddr - PIF_RAM_REGION_START));
if(Util::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused if(ircolib::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
Util::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) || ircolib::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
Util::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) || ircolib::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
Util::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return 0; ircolib::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return 0;
Util::Error::GetInstance().Throw( Util::Error::GetInstance().Throw(
{Util::Error::Severity::NON_FATAL}, {Util::Error::Type::MEM_UNHANDLED_ACCESS}, regs.pc, {Util::Error::Severity::NON_FATAL}, {Util::Error::Type::MEM_UNHANDLED_ACCESS}, regs.pc,
@@ -241,22 +241,22 @@ u64 Mem::Read(const u32 paddr) {
n64::Registers& regs = n64::Core::GetRegs(); n64::Registers& regs = n64::Core::GetRegs();
const SI &si = mmio.si; const SI &si = mmio.si;
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM<u64>(paddr); if(ircolib::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM<u64>(paddr);
if(Util::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) { if(ircolib::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem; const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
return Util::ReadAccess<u64>(src, paddr & 0xfff); return ircolib::ReadAccess<u64>(src, paddr & 0xfff);
} }
if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) return mmio.pi.BusRead<u64, false>(paddr); if(ircolib::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) return mmio.pi.BusRead<u64, false>(paddr);
if(Util::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) || if(ircolib::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
Util::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) return mmio.Read(paddr); ircolib::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) return mmio.Read(paddr);
if(Util::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END)) return Util::ReadAccess<u64>(si.pif.bootrom, paddr - PIF_ROM_REGION_START); if(ircolib::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END)) return ircolib::ReadAccess<u64>(si.pif.bootrom, paddr - PIF_ROM_REGION_START);
if(Util::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) return std::byteswap(Util::ReadAccess<u64>(si.pif.ram, paddr - PIF_RAM_REGION_START)); if(ircolib::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) return std::byteswap(ircolib::ReadAccess<u64>(si.pif.ram, paddr - PIF_RAM_REGION_START));
if(Util::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused if(ircolib::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
Util::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) || ircolib::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
Util::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) || ircolib::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
Util::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return 0; ircolib::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return 0;
Util::Error::GetInstance().Throw( Util::Error::GetInstance().Throw(
{Util::Error::Severity::NON_FATAL}, {Util::Error::Type::MEM_UNHANDLED_ACCESS}, regs.pc, {Util::Error::Severity::NON_FATAL}, {Util::Error::Type::MEM_UNHANDLED_ACCESS}, regs.pc,
@@ -269,37 +269,37 @@ void Mem::WriteInterpreter<u8>(u32 paddr, u32 val) {
n64::Registers& regs = n64::Core::GetRegs(); n64::Registers& regs = n64::Core::GetRegs();
SI &si = mmio.si; SI &si = mmio.si;
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM<u8>(paddr, val); return; } if(ircolib::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM<u8>(paddr, val); return; }
if(Util::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) { if(ircolib::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
val = val << (8 * (3 - (paddr & 3))); val = val << (8 * (3 - (paddr & 3)));
auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem; auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
paddr = (paddr & 0xFFF) & ~3; paddr = (paddr & 0xFFF) & ~3;
Util::WriteAccess<u32>(dest, paddr, val); ircolib::WriteAccess<u32>(dest, paddr, val);
return; return;
} }
if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) { if(ircolib::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) {
trace("BusWrite<u8> @ {:08X} = {:02X}", paddr, val); trace("BusWrite<u8> @ {:08X} = {:02X}", paddr, val);
mmio.pi.BusWrite<u8, false>(paddr, val); mmio.pi.BusWrite<u8, false>(paddr, val);
return; return;
} }
if(Util::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) || if(ircolib::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
Util::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) panic("MMIO Write<u8>!"); ircolib::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) panic("MMIO Write<u8>!");
if(Util::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) { if(ircolib::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) {
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.ram, paddr, std::byteswap(val)); ircolib::WriteAccess<u32>(si.pif.ram, paddr, std::byteswap(val));
si.pif.ProcessCommands(); si.pif.ProcessCommands();
return; return;
} }
if(Util::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused if(ircolib::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
Util::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) || ircolib::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
Util::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) || ircolib::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
Util::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END) || ircolib::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END) ||
Util::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return; ircolib::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return;
panic("Unimplemented 8-bit write at address {:08X} with value {:02X} (PC = {:016X})", paddr, val, (u64)regs.pc); panic("Unimplemented 8-bit write at address {:08X} with value {:02X} (PC = {:016X})", paddr, val, (u64)regs.pc);
} }
@@ -323,37 +323,37 @@ void Mem::WriteInterpreter<u16>(u32 paddr, u32 val) {
n64::Registers& regs = n64::Core::GetRegs(); n64::Registers& regs = n64::Core::GetRegs();
SI &si = mmio.si; SI &si = mmio.si;
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM<u16>(paddr, val); return; } if(ircolib::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM<u16>(paddr, val); return; }
if(Util::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) { if(ircolib::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
val = val << (16 * !(paddr & 2)); val = val << (16 * !(paddr & 2));
auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem; auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
paddr = (paddr & 0xFFF) & ~3; paddr = (paddr & 0xFFF) & ~3;
Util::WriteAccess<u32>(dest, paddr, val); ircolib::WriteAccess<u32>(dest, paddr, val);
return; return;
} }
if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) { if(ircolib::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) {
trace("BusWrite<u8> @ {:08X} = {:04X}", paddr, val); trace("BusWrite<u8> @ {:08X} = {:04X}", paddr, val);
mmio.pi.BusWrite<u16, false>(paddr, val); mmio.pi.BusWrite<u16, false>(paddr, val);
return; return;
} }
if(Util::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) || if(ircolib::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
Util::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) panic("MMIO Write<u16>!"); ircolib::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) panic("MMIO Write<u16>!");
if(Util::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) { if(ircolib::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) {
val = val << (16 * !(paddr & 2)); val = val << (16 * !(paddr & 2));
paddr &= ~3; paddr &= ~3;
Util::WriteAccess<u32>(si.pif.ram, paddr - PIF_RAM_REGION_START, std::byteswap(val)); ircolib::WriteAccess<u32>(si.pif.ram, paddr - PIF_RAM_REGION_START, std::byteswap(val));
si.pif.ProcessCommands(); si.pif.ProcessCommands();
return; return;
} }
if(Util::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused if(ircolib::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
Util::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) || ircolib::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
Util::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) || ircolib::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
Util::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END) || ircolib::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END) ||
Util::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return; ircolib::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return;
panic("Unimplemented 16-bit write at address {:08X} with value {:04X} (PC = {:016X})", paddr, val, (u64)regs.pc); panic("Unimplemented 16-bit write at address {:08X} with value {:04X} (PC = {:016X})", paddr, val, (u64)regs.pc);
} }
@@ -377,33 +377,33 @@ void Mem::WriteInterpreter<u32>(const u32 paddr, const u32 val) {
n64::Registers& regs = n64::Core::GetRegs(); n64::Registers& regs = n64::Core::GetRegs();
SI &si = mmio.si; SI &si = mmio.si;
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM<u32>(paddr, val); return; } if(ircolib::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM<u32>(paddr, val); return; }
if(Util::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) { if(ircolib::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem; auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
Util::WriteAccess<u32>(dest, paddr & 0xfff, val); ircolib::WriteAccess<u32>(dest, paddr & 0xfff, val);
return; return;
} }
if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) { if(ircolib::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) {
trace("BusWrite<u8> @ {:08X} = {:08X}", paddr, val); trace("BusWrite<u8> @ {:08X} = {:08X}", paddr, val);
mmio.pi.BusWrite<u32, false>(paddr, val); mmio.pi.BusWrite<u32, false>(paddr, val);
return; return;
} }
if(Util::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) || if(ircolib::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
Util::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) { mmio.Write(paddr, val); return; } ircolib::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) { mmio.Write(paddr, val); return; }
if(Util::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) { if(ircolib::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) {
Util::WriteAccess<u32>(si.pif.ram, paddr - PIF_RAM_REGION_START, std::byteswap(val)); ircolib::WriteAccess<u32>(si.pif.ram, paddr - PIF_RAM_REGION_START, std::byteswap(val));
si.pif.ProcessCommands(); si.pif.ProcessCommands();
return; return;
} }
if(Util::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused if(ircolib::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
Util::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) || ircolib::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
Util::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) || ircolib::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
Util::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END) || ircolib::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END) ||
Util::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return; ircolib::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return;
panic("Unimplemented 32-bit write at address {:08X} with value {:08X} (PC = {:016X})", paddr, val, (u64)regs.pc); panic("Unimplemented 32-bit write at address {:08X} with value {:08X} (PC = {:016X})", paddr, val, (u64)regs.pc);
} }
@@ -436,34 +436,34 @@ void Mem::WriteInterpreter(const u32 paddr, u64 val) {
n64::Registers& regs = n64::Core::GetRegs(); n64::Registers& regs = n64::Core::GetRegs();
SI &si = mmio.si; SI &si = mmio.si;
if(Util::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM<u64>(paddr, val); return; } if(ircolib::IsInsideRange(paddr, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM<u64>(paddr, val); return; }
if(Util::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) { if(ircolib::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem; auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
val >>= 32; val >>= 32;
Util::WriteAccess<u32>(dest, paddr & 0xfff, val); ircolib::WriteAccess<u32>(dest, paddr & 0xfff, val);
return; return;
} }
if(Util::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) { if(ircolib::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) {
trace("BusWrite<u64> @ {:08X} = {:016X}", paddr, val); trace("BusWrite<u64> @ {:08X} = {:016X}", paddr, val);
mmio.pi.BusWrite<false>(paddr, val); mmio.pi.BusWrite<false>(paddr, val);
return; return;
} }
if(Util::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) || if(ircolib::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
Util::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) panic("MMIO Write<u64>!"); ircolib::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) panic("MMIO Write<u64>!");
if(Util::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) { if(ircolib::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) {
Util::WriteAccess<u64>(si.pif.ram, paddr - PIF_RAM_REGION_START, std::byteswap(val)); ircolib::WriteAccess<u64>(si.pif.ram, paddr - PIF_RAM_REGION_START, std::byteswap(val));
si.pif.ProcessCommands(); si.pif.ProcessCommands();
return; return;
} }
if(Util::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused if(ircolib::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
Util::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) || ircolib::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
Util::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) || ircolib::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
Util::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END) || ircolib::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END) ||
Util::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return; ircolib::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return;
panic("Unimplemented 64-bit write at address {:08X} with value {:016X} (PC = {:016X})", paddr, val, (u64)regs.pc); panic("Unimplemented 64-bit write at address {:08X} with value {:016X} (PC = {:016X})", paddr, val, (u64)regs.pc);
} }

View File

@@ -102,22 +102,22 @@ struct Mem {
std::vector<u8> temp{}; std::vector<u8> temp{};
temp.resize(RDRAM_SIZE); temp.resize(RDRAM_SIZE);
std::ranges::copy(mmio.rdp.rdram, temp.begin()); std::ranges::copy(mmio.rdp.rdram, temp.begin());
Util::SwapBuffer<u32>(temp); ircolib::SwapBuffer<u32>(temp);
Util::WriteFileBinary(temp, "rdram.bin"); ircolib::WriteFileBinary(temp, "rdram.bin");
} }
FORCE_INLINE void DumpIMEM() const { FORCE_INLINE void DumpIMEM() const {
std::array<u8, IMEM_SIZE> temp{}; std::array<u8, IMEM_SIZE> temp{};
std::ranges::copy(mmio.rsp.imem, temp.begin()); std::ranges::copy(mmio.rsp.imem, temp.begin());
Util::SwapBuffer<u32>(temp); ircolib::SwapBuffer<u32>(temp);
Util::WriteFileBinary(temp, "imem.bin"); ircolib::WriteFileBinary(temp, "imem.bin");
} }
FORCE_INLINE void DumpDMEM() const { FORCE_INLINE void DumpDMEM() const {
std::array<u8, DMEM_SIZE> temp{}; std::array<u8, DMEM_SIZE> temp{};
std::ranges::copy(mmio.rsp.dmem, temp.begin()); std::ranges::copy(mmio.rsp.dmem, temp.begin());
Util::SwapBuffer<u32>(temp); ircolib::SwapBuffer<u32>(temp);
Util::WriteFileBinary(temp, "dmem.bin"); ircolib::WriteFileBinary(temp, "dmem.bin");
} }
MMIO mmio; MMIO mmio;

View File

@@ -25,21 +25,21 @@ void RDP::WriteRDRAM<u8>(const size_t idx, const u8 v) {
template <> template <>
void RDP::WriteRDRAM<u16>(const size_t idx, const u16 v) { void RDP::WriteRDRAM<u16>(const size_t idx, const u16 v) {
if (const size_t real = HALF_ADDRESS(idx); real < RDRAM_SIZE) [[likely]] { if (const size_t real = HALF_ADDRESS(idx); real < RDRAM_SIZE) [[likely]] {
Util::WriteAccess<u16>(rdram, real, v); ircolib::WriteAccess<u16>(rdram, real, v);
} }
} }
template <> template <>
void RDP::WriteRDRAM<u32>(const size_t idx, const u32 v) { void RDP::WriteRDRAM<u32>(const size_t idx, const u32 v) {
if (idx < RDRAM_SIZE) [[likely]] { if (idx < RDRAM_SIZE) [[likely]] {
Util::WriteAccess<u32>(rdram, idx, v); ircolib::WriteAccess<u32>(rdram, idx, v);
} }
} }
template <> template <>
void RDP::WriteRDRAM<u64>(const size_t idx, const u64 v) { void RDP::WriteRDRAM<u64>(const size_t idx, const u64 v) {
if (idx < RDRAM_SIZE) [[likely]] { if (idx < RDRAM_SIZE) [[likely]] {
Util::WriteAccess<u64>(rdram, idx, v); ircolib::WriteAccess<u64>(rdram, idx, v);
} }
} }
@@ -54,7 +54,7 @@ u8 RDP::ReadRDRAM<u8>(const size_t idx) {
template <> template <>
u16 RDP::ReadRDRAM<u16>(const size_t idx) { u16 RDP::ReadRDRAM<u16>(const size_t idx) {
if (const size_t real = HALF_ADDRESS(idx); real < RDRAM_SIZE) [[likely]] if (const size_t real = HALF_ADDRESS(idx); real < RDRAM_SIZE) [[likely]]
return Util::ReadAccess<u16>(rdram, real); return ircolib::ReadAccess<u16>(rdram, real);
return 0; return 0;
} }
@@ -62,7 +62,7 @@ u16 RDP::ReadRDRAM<u16>(const size_t idx) {
template <> template <>
u32 RDP::ReadRDRAM<u32>(const size_t idx) { u32 RDP::ReadRDRAM<u32>(const size_t idx) {
if (idx < RDRAM_SIZE) [[likely]] if (idx < RDRAM_SIZE) [[likely]]
return Util::ReadAccess<u32>(rdram, idx); return ircolib::ReadAccess<u32>(rdram, idx);
return 0; return 0;
} }
@@ -70,7 +70,7 @@ u32 RDP::ReadRDRAM<u32>(const size_t idx) {
template <> template <>
u64 RDP::ReadRDRAM<u64>(const size_t idx) { u64 RDP::ReadRDRAM<u64>(const size_t idx) {
if (idx < RDRAM_SIZE) [[likely]] if (idx < RDRAM_SIZE) [[likely]]
return Util::ReadAccess<u64>(rdram, idx); return ircolib::ReadAccess<u64>(rdram, idx);
return 0; return 0;
} }
@@ -223,7 +223,7 @@ void RDP::RunCommand() {
if (dpc.status.xbusDmemDma) { if (dpc.status.xbusDmemDma) {
for (int i = 0; i < len; i += 4) { for (int i = 0; i < len; i += 4) {
const u32 cmd = Util::ReadAccess<u32>(mem.mmio.rsp.dmem, current + i & 0xFFF); const u32 cmd = ircolib::ReadAccess<u32>(mem.mmio.rsp.dmem, current + i & 0xFFF);
cmd_buf[remaining_cmds + (i >> 2)] = cmd; cmd_buf[remaining_cmds + (i >> 2)] = cmd;
} }
} else { } else {
@@ -232,7 +232,7 @@ void RDP::RunCommand() {
} }
for (int i = 0; i < len; i += 4) { for (int i = 0; i < len; i += 4) {
const u32 cmd = Util::ReadAccess<u32>(rdram, current + i); const u32 cmd = ircolib::ReadAccess<u32>(rdram, current + i);
cmd_buf[remaining_cmds + (i >> 2)] = cmd; cmd_buf[remaining_cmds + (i >> 2)] = cmd;
} }
} }

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#include <MemoryHelpers.hpp> #include <ircolib/mem_access.hpp>
#include <MemoryRegions.hpp> #include <MemoryRegions.hpp>
#include <array> #include <array>
#include <core/RDP.hpp> #include <core/RDP.hpp>
@@ -150,7 +150,7 @@ struct RSP {
FORCE_INLINE void Step() { FORCE_INLINE void Step() {
gpr[0] = 0; gpr[0] = 0;
const u32 instr = Util::ReadAccess<u32>(imem, pc & IMEM_DSIZE); const u32 instr = ircolib::ReadAccess<u32>(imem, pc & IMEM_DSIZE);
oldPC = pc & 0xFFC; oldPC = pc & 0xFFC;
pc = nextPC & 0xFFC; pc = nextPC & 0xFFC;
nextPC += 4; nextPC += 4;

View File

@@ -1,7 +1,7 @@
#include <cfenv> #include <cfenv>
#include <cmath> #include <cmath>
#include <Core.hpp> #include <Core.hpp>
#include <utils/FloatingPoint.hpp> #include <ircolib/floats.hpp>
namespace n64 { namespace n64 {
template <> template <>
@@ -503,7 +503,7 @@ void Cop1::ceills(const Instruction instr) {
const auto fs = FGR_S<float>(regs.cop0.status, instr.fs()); const auto fs = FGR_S<float>(regs.cop0.status, instr.fs());
if (!CheckCVTArg<s64>(fs)) if (!CheckCVTArg<s64>(fs))
return; return;
CHECK_FPE_CONST(s64, fd, Util::roundCeil(fs)); CHECK_FPE_CONST(s64, fd, ircolib::roundCeil(fs));
FGR_D<s64>(regs.cop0.status, instr.fd()) = fd; FGR_D<s64>(regs.cop0.status, instr.fd()) = fd;
} }
@@ -514,7 +514,7 @@ void Cop1::ceilld(const Instruction instr) {
const auto fs = FGR_S<double>(regs.cop0.status, instr.fs()); const auto fs = FGR_S<double>(regs.cop0.status, instr.fs());
if (!CheckCVTArg<s64>(fs)) if (!CheckCVTArg<s64>(fs))
return; return;
CHECK_FPE_CONST(s64, fd, Util::roundCeil(fs)) CHECK_FPE_CONST(s64, fd, ircolib::roundCeil(fs))
FGR_D<s64>(regs.cop0.status, instr.fd()) = fd; FGR_D<s64>(regs.cop0.status, instr.fd()) = fd;
} }
@@ -525,7 +525,7 @@ void Cop1::ceilws(const Instruction instr) {
const auto fs = FGR_S<float>(regs.cop0.status, instr.fs()); const auto fs = FGR_S<float>(regs.cop0.status, instr.fs());
if (!CheckCVTArg<s32>(fs)) if (!CheckCVTArg<s32>(fs))
return; return;
CHECK_FPE_CONV_CONST(s32, fd, Util::roundCeil(fs)) CHECK_FPE_CONV_CONST(s32, fd, ircolib::roundCeil(fs))
FGR_D<s32>(regs.cop0.status, instr.fd()) = fd; FGR_D<s32>(regs.cop0.status, instr.fd()) = fd;
} }
@@ -536,7 +536,7 @@ void Cop1::ceilwd(const Instruction instr) {
const auto fs = FGR_S<double>(regs.cop0.status, instr.fs()); const auto fs = FGR_S<double>(regs.cop0.status, instr.fs());
if (!CheckCVTArg<s32>(fs)) if (!CheckCVTArg<s32>(fs))
return; return;
CHECK_FPE_CONV_CONST(s32, fd, Util::roundCeil(fs)) CHECK_FPE_CONV_CONST(s32, fd, ircolib::roundCeil(fs))
FGR_D<s32>(regs.cop0.status, instr.fd()) = fd; FGR_D<s32>(regs.cop0.status, instr.fd()) = fd;
} }
@@ -666,7 +666,7 @@ void Cop1::cvtwd(const Instruction instr) {
const auto fs = FGR_S<double>(regs.cop0.status, instr.fs()); const auto fs = FGR_S<double>(regs.cop0.status, instr.fs());
if (!CheckCVTArg<s32>(fs)) if (!CheckCVTArg<s32>(fs))
return; return;
CHECK_FPE_CONV_CONST(s32, fd, Util::roundCurrent(fs)) CHECK_FPE_CONV_CONST(s32, fd, ircolib::roundCurrent(fs))
FGR_D<s32>(regs.cop0.status, instr.fd()) = fd; FGR_D<s32>(regs.cop0.status, instr.fd()) = fd;
} }
@@ -677,7 +677,7 @@ void Cop1::cvtws(const Instruction instr) {
const auto fs = FGR_S<float>(regs.cop0.status, instr.fs()); const auto fs = FGR_S<float>(regs.cop0.status, instr.fs());
if (!CheckCVTArg<s32>(fs)) if (!CheckCVTArg<s32>(fs))
return; return;
CHECK_FPE_CONV_CONST(s32, fd, Util::roundCurrent(fs)) CHECK_FPE_CONV_CONST(s32, fd, ircolib::roundCurrent(fs))
FGR_D<s32>(regs.cop0.status, instr.fd()) = fd; FGR_D<s32>(regs.cop0.status, instr.fd()) = fd;
} }
@@ -688,7 +688,7 @@ void Cop1::cvtls(const Instruction instr) {
const auto fs = FGR_S<float>(regs.cop0.status, instr.fs()); const auto fs = FGR_S<float>(regs.cop0.status, instr.fs());
if (!CheckCVTArg<s64>(fs)) if (!CheckCVTArg<s64>(fs))
return; return;
CHECK_FPE_CONST(s64, fd, Util::roundCurrent(fs)) CHECK_FPE_CONST(s64, fd, ircolib::roundCurrent(fs))
FGR_D<s64>(regs.cop0.status, instr.fd()) = fd; FGR_D<s64>(regs.cop0.status, instr.fd()) = fd;
} }
@@ -728,7 +728,7 @@ void Cop1::cvtld(const Instruction instr) {
const auto fs = FGR_S<double>(regs.cop0.status, instr.fs()); const auto fs = FGR_S<double>(regs.cop0.status, instr.fs());
if (!CheckCVTArg<s64>(fs)) if (!CheckCVTArg<s64>(fs))
return; return;
CHECK_FPE_CONST(s64, fd, Util::roundCurrent(fs)) CHECK_FPE_CONST(s64, fd, ircolib::roundCurrent(fs))
FGR_D<s64>(regs.cop0.status, instr.fd()) = fd; FGR_D<s64>(regs.cop0.status, instr.fd()) = fd;
} }
@@ -1128,7 +1128,7 @@ void Cop1::roundls(const Instruction instr) {
const auto fs = FGR_S<float>(regs.cop0.status, instr.fs()); const auto fs = FGR_S<float>(regs.cop0.status, instr.fs());
if (!CheckCVTArg<s64>(fs)) if (!CheckCVTArg<s64>(fs))
return; return;
CHECK_FPE_CONST(s64, fd, Util::roundNearest(fs)) CHECK_FPE_CONST(s64, fd, ircolib::roundNearest(fs))
if (fd != fs && SetCauseInexact()) { if (fd != fs && SetCauseInexact()) {
regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC); regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC);
return; return;
@@ -1143,7 +1143,7 @@ void Cop1::roundld(const Instruction instr) {
const auto fs = FGR_S<double>(regs.cop0.status, instr.fs()); const auto fs = FGR_S<double>(regs.cop0.status, instr.fs());
if (!CheckCVTArg<s64>(fs)) if (!CheckCVTArg<s64>(fs))
return; return;
CHECK_FPE_CONST(s64, fd, Util::roundNearest(fs)) CHECK_FPE_CONST(s64, fd, ircolib::roundNearest(fs))
if (fd != fs && SetCauseInexact()) { if (fd != fs && SetCauseInexact()) {
regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC); regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC);
return; return;
@@ -1158,7 +1158,7 @@ void Cop1::roundws(const Instruction instr) {
const auto fs = FGR_S<float>(regs.cop0.status, instr.fs()); const auto fs = FGR_S<float>(regs.cop0.status, instr.fs());
if (!CheckCVTArg<s32>(fs)) if (!CheckCVTArg<s32>(fs))
return; return;
CHECK_FPE_CONV_CONST(s32, fd, Util::roundNearest(fs)) CHECK_FPE_CONV_CONST(s32, fd, ircolib::roundNearest(fs))
if (fd != fs && SetCauseInexact()) { if (fd != fs && SetCauseInexact()) {
regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC); regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC);
return; return;
@@ -1173,7 +1173,7 @@ void Cop1::roundwd(const Instruction instr) {
const auto fs = FGR_S<double>(regs.cop0.status, instr.fs()); const auto fs = FGR_S<double>(regs.cop0.status, instr.fs());
if (!CheckCVTArg<s32>(fs)) if (!CheckCVTArg<s32>(fs))
return; return;
CHECK_FPE_CONV_CONST(s32, fd, Util::roundNearest(fs)) CHECK_FPE_CONV_CONST(s32, fd, ircolib::roundNearest(fs))
if (fd != fs && SetCauseInexact()) { if (fd != fs && SetCauseInexact()) {
regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC); regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC);
return; return;
@@ -1188,7 +1188,7 @@ void Cop1::floorls(const Instruction instr) {
const auto fs = FGR_S<float>(regs.cop0.status, instr.fs()); const auto fs = FGR_S<float>(regs.cop0.status, instr.fs());
if (!CheckCVTArg<s64>(fs)) if (!CheckCVTArg<s64>(fs))
return; return;
CHECK_FPE_CONST(s64, fd, Util::roundFloor(fs)) CHECK_FPE_CONST(s64, fd, ircolib::roundFloor(fs))
FGR_D<s64>(regs.cop0.status, instr.fd()) = fd; FGR_D<s64>(regs.cop0.status, instr.fd()) = fd;
} }
@@ -1199,7 +1199,7 @@ void Cop1::floorld(const Instruction instr) {
const auto fs = FGR_S<double>(regs.cop0.status, instr.fs()); const auto fs = FGR_S<double>(regs.cop0.status, instr.fs());
if (!CheckCVTArg<s64>(fs)) if (!CheckCVTArg<s64>(fs))
return; return;
CHECK_FPE_CONST(s64, fd, Util::roundFloor(fs)) CHECK_FPE_CONST(s64, fd, ircolib::roundFloor(fs))
FGR_D<s64>(regs.cop0.status, instr.fd()) = fd; FGR_D<s64>(regs.cop0.status, instr.fd()) = fd;
} }
@@ -1210,7 +1210,7 @@ void Cop1::floorws(const Instruction instr) {
const auto fs = FGR_S<float>(regs.cop0.status, instr.fs()); const auto fs = FGR_S<float>(regs.cop0.status, instr.fs());
if (!CheckCVTArg<s32>(fs)) if (!CheckCVTArg<s32>(fs))
return; return;
CHECK_FPE_CONV_CONST(s32, fd, Util::roundFloor(fs)) CHECK_FPE_CONV_CONST(s32, fd, ircolib::roundFloor(fs))
FGR_D<s32>(regs.cop0.status, instr.fd()) = fd; FGR_D<s32>(regs.cop0.status, instr.fd()) = fd;
} }
@@ -1221,7 +1221,7 @@ void Cop1::floorwd(const Instruction instr) {
const auto fs = FGR_S<double>(regs.cop0.status, instr.fs()); const auto fs = FGR_S<double>(regs.cop0.status, instr.fs());
if (!CheckCVTArg<s32>(fs)) if (!CheckCVTArg<s32>(fs))
return; return;
CHECK_FPE_CONV_CONST(s32, fd, Util::roundFloor(fs)) CHECK_FPE_CONV_CONST(s32, fd, ircolib::roundFloor(fs))
FGR_D<s32>(regs.cop0.status, instr.fd()) = fd; FGR_D<s32>(regs.cop0.status, instr.fd()) = fd;
} }
@@ -1232,7 +1232,7 @@ void Cop1::truncws(const Instruction instr) {
const auto fs = FGR_S<float>(regs.cop0.status, instr.fs()); const auto fs = FGR_S<float>(regs.cop0.status, instr.fs());
if (!CheckCVTArg<s32>(fs)) if (!CheckCVTArg<s32>(fs))
return; return;
CHECK_FPE_CONV_CONST(s32, fd, Util::roundTrunc(fs)) CHECK_FPE_CONV_CONST(s32, fd, ircolib::roundTrunc(fs))
if (static_cast<float>(fd) != fs && SetCauseInexact()) { if (static_cast<float>(fd) != fs && SetCauseInexact()) {
regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC); regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC);
return; return;
@@ -1247,7 +1247,7 @@ void Cop1::truncwd(const Instruction instr) {
const auto fs = FGR_S<double>(regs.cop0.status, instr.fs()); const auto fs = FGR_S<double>(regs.cop0.status, instr.fs());
if (!CheckCVTArg<s32>(fs)) if (!CheckCVTArg<s32>(fs))
return; return;
CHECK_FPE_CONV_CONST(s32, fd, Util::roundTrunc(fs)) CHECK_FPE_CONV_CONST(s32, fd, ircolib::roundTrunc(fs))
if (static_cast<double>(fd) != fs && SetCauseInexact()) { if (static_cast<double>(fd) != fs && SetCauseInexact()) {
regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC); regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC);
return; return;
@@ -1262,7 +1262,7 @@ void Cop1::truncls(const Instruction instr) {
const auto fs = FGR_S<float>(regs.cop0.status, instr.fs()); const auto fs = FGR_S<float>(regs.cop0.status, instr.fs());
if (!CheckCVTArg<s64>(fs)) if (!CheckCVTArg<s64>(fs))
return; return;
CHECK_FPE_CONST(s64, fd, Util::roundTrunc(fs)) CHECK_FPE_CONST(s64, fd, ircolib::roundTrunc(fs))
if (static_cast<float>(fd) != fs && SetCauseInexact()) { if (static_cast<float>(fd) != fs && SetCauseInexact()) {
regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC); regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC);
return; return;
@@ -1277,7 +1277,7 @@ void Cop1::truncld(const Instruction instr) {
const auto fs = FGR_S<double>(regs.cop0.status, instr.fs()); const auto fs = FGR_S<double>(regs.cop0.status, instr.fs());
if (!CheckCVTArg<s64>(fs)) if (!CheckCVTArg<s64>(fs))
return; return;
CHECK_FPE_CONST(s64, fd, Util::roundTrunc(fs)) CHECK_FPE_CONST(s64, fd, ircolib::roundTrunc(fs))
if (static_cast<double>(fd) != fs && SetCauseInexact()) { if (static_cast<double>(fd) != fs && SetCauseInexact()) {
regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC); regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC);
return; return;

View File

@@ -33,12 +33,12 @@ void Flash::Load(SaveType saveType, const std::string &path) {
saveData.unmap(); saveData.unmap();
} }
auto flashVec = Util::ReadFileBinary(flashPath); auto flashVec = ircolib::ReadFileBinary(flashPath);
if (flashVec.empty()) { if (flashVec.empty()) {
std::vector<u8> dummy{}; std::vector<u8> dummy{};
dummy.resize(FLASH_SIZE); dummy.resize(FLASH_SIZE);
Util::WriteFileBinary(dummy, flashPath); ircolib::WriteFileBinary(dummy, flashPath);
flashVec = Util::ReadFileBinary(flashPath); flashVec = ircolib::ReadFileBinary(flashPath);
} }
if (flashVec.size() != FLASH_SIZE) { if (flashVec.size() != FLASH_SIZE) {

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#include <MemoryHelpers.hpp> #include <ircolib/mem_access.hpp>
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
namespace n64 { namespace n64 {

View File

@@ -188,7 +188,7 @@ auto PI::BusRead<u16, false>(u32 addr) -> u16 {
if (index > mem.rom.cart.size() - 1) { if (index > mem.rom.cart.size() - 1) {
panic("Address 0x{:08X} accessed an index {}/0x{:X} outside the bounds of the ROM!", addr, index, index); panic("Address 0x{:08X} accessed an index {}/0x{:X} outside the bounds of the ROM!", addr, index, index);
} }
return Util::ReadAccess<u16>(mem.rom.cart, index); return ircolib::ReadAccess<u16>(mem.rom.cart, index);
} }
default: default:
panic("Should never end up here! Access to address {:08X} which did not match any PI bus regions!", addr); panic("Should never end up here! Access to address {:08X} which did not match any PI bus regions!", addr);
@@ -260,7 +260,7 @@ auto PI::BusRead<u32, false>(u32 addr) -> u32 {
if (index > mem.rom.cart.size() - 3) { // -3 because we're reading an entire word if (index > mem.rom.cart.size() - 3) { // -3 because we're reading an entire word
switch (addr) { switch (addr) {
case REGION_CART_ISVIEWER_BUFFER: case REGION_CART_ISVIEWER_BUFFER:
return std::byteswap<u32>(Util::ReadAccess<u32>(mem.isviewer, addr - SREGION_CART_ISVIEWER_BUFFER)); return std::byteswap<u32>(ircolib::ReadAccess<u32>(mem.isviewer, addr - SREGION_CART_ISVIEWER_BUFFER));
case CART_ISVIEWER_FLUSH: case CART_ISVIEWER_FLUSH:
panic("Read from ISViewer flush!"); panic("Read from ISViewer flush!");
default: default:
@@ -270,7 +270,7 @@ auto PI::BusRead<u32, false>(u32 addr) -> u32 {
return 0; return 0;
} }
return Util::ReadAccess<u32>(mem.rom.cart, index); return ircolib::ReadAccess<u32>(mem.rom.cart, index);
} }
default: default:
panic("Should never end up here! Access to address {:08X} which did not match any PI bus regions!", addr); panic("Should never end up here! Access to address {:08X} which did not match any PI bus regions!", addr);
@@ -314,7 +314,7 @@ void PI::BusWrite<u32, false>(u32 addr, u32 val) {
case REGION_PI_ROM: case REGION_PI_ROM:
switch (addr) { switch (addr) {
case REGION_CART_ISVIEWER_BUFFER: case REGION_CART_ISVIEWER_BUFFER:
Util::WriteAccess<u32>(mem.isviewer, addr - SREGION_CART_ISVIEWER_BUFFER, std::byteswap(val)); ircolib::WriteAccess<u32>(mem.isviewer, addr - SREGION_CART_ISVIEWER_BUFFER, std::byteswap(val));
break; break;
case CART_ISVIEWER_FLUSH: case CART_ISVIEWER_FLUSH:
{ {
@@ -368,7 +368,7 @@ auto PI::BusRead<u64, false>(u32 addr) -> u64 {
if (index > mem.rom.cart.size() - 7) { // -7 because we're reading an entire dword if (index > mem.rom.cart.size() - 7) { // -7 because we're reading an entire dword
panic("Address 0x{:08X} accessed an index {}/0x{:X} outside the bounds of the ROM!", addr, index, index); panic("Address 0x{:08X} accessed an index {}/0x{:X} outside the bounds of the ROM!", addr, index, index);
} }
return Util::ReadAccess<u64>(mem.rom.cart, index); return ircolib::ReadAccess<u64>(mem.rom.cart, index);
} }
default: default:
panic("Should never end up here! Access to address {:08X} which did not match any PI bus regions!", addr); panic("Should never end up here! Access to address {:08X} which did not match any PI bus regions!", addr);

View File

@@ -50,10 +50,10 @@ void PIF::MaybeLoadMempak() {
mempak.unmap(); mempak.unmap();
} }
auto mempakVec = Util::ReadFileBinary(mempakPath); auto mempakVec = ircolib::ReadFileBinary(mempakPath);
if (mempak.empty()) { if (mempak.empty()) {
Util::WriteFileBinary(std::array<u8, MEMPAK_SIZE>{}, mempakPath); ircolib::WriteFileBinary(std::array<u8, MEMPAK_SIZE>{}, mempakPath);
mempakVec = Util::ReadFileBinary(mempakPath); mempakVec = ircolib::ReadFileBinary(mempakPath);
} }
if (mempakVec.size() != MEMPAK_SIZE) { if (mempakVec.size() != MEMPAK_SIZE) {
@@ -104,11 +104,11 @@ void PIF::LoadEeprom(const SaveType saveType, const std::string &path) {
eepromSize = GetSaveSize(saveType); eepromSize = GetSaveSize(saveType);
auto eepromVec = Util::ReadFileBinary(eepromPath); auto eepromVec = ircolib::ReadFileBinary(eepromPath);
if (eepromVec.empty()) { if (eepromVec.empty()) {
std::vector<u8> dummy{}; std::vector<u8> dummy{};
dummy.resize(GetSaveSize(saveType)); dummy.resize(GetSaveSize(saveType));
Util::WriteFileBinary(dummy, eepromPath); ircolib::WriteFileBinary(dummy, eepromPath);
eepromVec = dummy; eepromVec = dummy;
} }

View File

@@ -31,7 +31,7 @@ static_assert(sizeof(TASMovieControllerData) == 4);
void MupenMovie::Load(const fs::path &path) { void MupenMovie::Load(const fs::path &path) {
filename = path.stem().string(); filename = path.stem().string();
loadedTasMovie = Util::ReadFileBinary(path.string()); loadedTasMovie = ircolib::ReadFileBinary(path.string());
if (!IsLoaded()) { if (!IsLoaded()) {
error("Error loading movie!"); error("Error loading movie!");
return; return;

View File

@@ -446,7 +446,7 @@ void Cop0::decode(const Instruction instr) {
template <> template <>
bool Cop0::MapVirtualAddress<u32, true>(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) { bool Cop0::MapVirtualAddress<u32, true>(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
if(Util::IsInsideRange(vaddr, START_VREGION_KUSEG, END_VREGION_KUSEG)) if(ircolib::IsInsideRange(vaddr, START_VREGION_KUSEG, END_VREGION_KUSEG))
return ProbeTLB(accessType, s64(s32(vaddr)), paddr); return ProbeTLB(accessType, s64(s32(vaddr)), paddr);
tlbError = DISALLOWED_ADDRESS; tlbError = DISALLOWED_ADDRESS;
@@ -456,10 +456,10 @@ bool Cop0::MapVirtualAddress<u32, true>(const TLBAccessType accessType, const u6
template <> template <>
bool Cop0::MapVirtualAddress<u32, false>(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) { bool Cop0::MapVirtualAddress<u32, false>(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
u8 segment = static_cast<u32>(vaddr) >> 29 & 7; u8 segment = static_cast<u32>(vaddr) >> 29 & 7;
if(Util::IsInsideRange(segment, 0, 3) || segment == 7) if(ircolib::IsInsideRange(segment, 0, 3) || segment == 7)
return ProbeTLB(accessType, static_cast<s32>(vaddr), paddr); return ProbeTLB(accessType, static_cast<s32>(vaddr), paddr);
if(Util::IsInsideRange(segment, 4, 5)) { if(ircolib::IsInsideRange(segment, 4, 5)) {
paddr = vaddr & 0x1FFFFFFF; paddr = vaddr & 0x1FFFFFFF;
return true; return true;
} }
@@ -474,7 +474,7 @@ bool Cop0::MapVirtualAddress<u32, false>(const TLBAccessType accessType, const u
template <> template <>
bool Cop0::MapVirtualAddress<u64, true>(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) { bool Cop0::MapVirtualAddress<u64, true>(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
if(Util::IsInsideRange(vaddr, 0x0000000000000000, 0x000000FFFFFFFFFF)) if(ircolib::IsInsideRange(vaddr, 0x0000000000000000, 0x000000FFFFFFFFFF))
return ProbeTLB(accessType, vaddr, paddr); return ProbeTLB(accessType, vaddr, paddr);
tlbError = DISALLOWED_ADDRESS; tlbError = DISALLOWED_ADDRESS;
@@ -483,13 +483,13 @@ bool Cop0::MapVirtualAddress<u64, true>(const TLBAccessType accessType, const u6
template <> template <>
bool Cop0::MapVirtualAddress<u64, false>(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) { bool Cop0::MapVirtualAddress<u64, false>(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
if(Util::IsInsideRange(vaddr, 0x0000000000000000, 0x000000FFFFFFFFFF) || // VREGION_XKUSEG if(ircolib::IsInsideRange(vaddr, 0x0000000000000000, 0x000000FFFFFFFFFF) || // VREGION_XKUSEG
Util::IsInsideRange(vaddr, 0x4000000000000000, 0x400000FFFFFFFFFF) || // VREGION_XKSSEG ircolib::IsInsideRange(vaddr, 0x4000000000000000, 0x400000FFFFFFFFFF) || // VREGION_XKSSEG
Util::IsInsideRange(vaddr, 0xC000000000000000, 0xC00000FF7FFFFFFF) || // VREGION_XKSEG ircolib::IsInsideRange(vaddr, 0xC000000000000000, 0xC00000FF7FFFFFFF) || // VREGION_XKSEG
Util::IsInsideRange(vaddr, 0xFFFFFFFFE0000000, 0xFFFFFFFFFFFFFFFF)) // VREGION_CKSEG3 ircolib::IsInsideRange(vaddr, 0xFFFFFFFFE0000000, 0xFFFFFFFFFFFFFFFF)) // VREGION_CKSEG3
return ProbeTLB(accessType, vaddr, paddr); return ProbeTLB(accessType, vaddr, paddr);
if(Util::IsInsideRange(vaddr, 0x8000000000000000, 0xBFFFFFFFFFFFFFFF)) { // VREGION_XKPHYS if(ircolib::IsInsideRange(vaddr, 0x8000000000000000, 0xBFFFFFFFFFFFFFFF)) { // VREGION_XKPHYS
if (!kernelMode) if (!kernelMode)
panic("Access to XKPHYS address 0x{:016X} when outside kernel mode!", vaddr); panic("Access to XKPHYS address 0x{:016X} when outside kernel mode!", vaddr);
@@ -510,8 +510,8 @@ bool Cop0::MapVirtualAddress<u64, false>(const TLBAccessType accessType, const u
return true; return true;
} }
if(Util::IsInsideRange(vaddr, 0xFFFFFFFF80000000, 0xFFFFFFFF9FFFFFFF) || // VREGION_CKSEG0 if(ircolib::IsInsideRange(vaddr, 0xFFFFFFFF80000000, 0xFFFFFFFF9FFFFFFF) || // VREGION_CKSEG0
Util::IsInsideRange(vaddr, 0xFFFFFFFFA0000000, 0xFFFFFFFFBFFFFFFF)) { // VREGION_CKSEG1 ircolib::IsInsideRange(vaddr, 0xFFFFFFFFA0000000, 0xFFFFFFFFBFFFFFFF)) { // VREGION_CKSEG1
u32 cut = u32(vaddr) >> 28; u32 cut = u32(vaddr) >> 28;
u32 num = cut == 0xA; u32 num = cut == 0xA;
// Identical to ksegX in 32 bit mode. // Identical to ksegX in 32 bit mode.
@@ -521,9 +521,9 @@ bool Cop0::MapVirtualAddress<u64, false>(const TLBAccessType accessType, const u
return true; return true;
} }
if(Util::IsInsideRange(vaddr, 0x0000010000000000, 0x3FFFFFFFFFFFFFFF) || // VREGION_XBAD1 if(ircolib::IsInsideRange(vaddr, 0x0000010000000000, 0x3FFFFFFFFFFFFFFF) || // VREGION_XBAD1
Util::IsInsideRange(vaddr, 0x4000010000000000, 0x7FFFFFFFFFFFFFFF) || // VREGION_XBAD2 ircolib::IsInsideRange(vaddr, 0x4000010000000000, 0x7FFFFFFFFFFFFFFF) || // VREGION_XBAD2
Util::IsInsideRange(vaddr, 0xC00000FF80000000, 0xFFFFFFFF7FFFFFFF)) { // VREGION_XBAD3 ircolib::IsInsideRange(vaddr, 0xC00000FF80000000, 0xFFFFFFFF7FFFFFFF)) { // VREGION_XBAD3
tlbError = DISALLOWED_ADDRESS; tlbError = DISALLOWED_ADDRESS;
return false; return false;
} }

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#include <cstdint> #include <ircolib/types.hpp>
#ifdef USE_NEON #ifdef USE_NEON
#include <sse2neon.h> #include <sse2neon.h>
#else #else
@@ -7,14 +7,14 @@
#include <smmintrin.h> #include <smmintrin.h>
#endif #endif
using u8 = uint8_t; using u8 = ircolib::u8;
using u16 = uint16_t; using u16 = ircolib::u16;
using u32 = uint32_t; using u32 = ircolib::u32;
using u64 = uint64_t; using u64 = ircolib::u64;
using s8 = int8_t; using s8 = ircolib::s8;
using s16 = int16_t; using s16 = ircolib::s16;
using s32 = int32_t; using s32 = ircolib::s32;
using s64 = int64_t; using s64 = ircolib::s64;
using u128 = __uint128_t; using u128 = __uint128_t;
using s128 = __int128_t; using s128 = __int128_t;
using m128i = __m128i; using m128i = __m128i;

View File

@@ -4,8 +4,8 @@
namespace Util { namespace Util {
std::vector<u8> OpenROM(const std::string &filename, size_t &sizeAdjusted) { std::vector<u8> OpenROM(const std::string &filename, size_t &sizeAdjusted) {
auto buf = ReadFileBinary(filename); auto buf = ircolib::ReadFileBinary(filename);
sizeAdjusted = NextPow2(buf.size()); sizeAdjusted = ircolib::NextPow2(buf.size());
return buf; return buf;
} }
@@ -40,7 +40,7 @@ std::vector<u8> OpenArchive(const std::string &path, size_t &sizeAdjusted) {
if (std::ranges::any_of(rom_exts, [&](const auto &x) { return extension == x; })) { if (std::ranges::any_of(rom_exts, [&](const auto &x) { return extension == x; })) {
const auto size = ar_entry_get_size(archive); const auto size = ar_entry_get_size(archive);
sizeAdjusted = NextPow2(size); sizeAdjusted = ircolib::NextPow2(size);
buf.resize(sizeAdjusted); buf.resize(sizeAdjusted);
ar_entry_uncompress(archive, buf.data(), size); ar_entry_uncompress(archive, buf.data(), size);
break; break;

View File

@@ -3,44 +3,11 @@
#include <log.hpp> #include <log.hpp>
#include <vector> #include <vector>
#include <filesystem> #include <filesystem>
#include <ircolib/file.hpp>
namespace fs = std::filesystem; namespace fs = std::filesystem;
namespace Util { namespace Util {
FORCE_INLINE std::vector<u8> ReadFileBinary(const std::string &path) {
std::ifstream file(path, std::ios::binary);
return {std::istreambuf_iterator{file}, {}};
}
FORCE_INLINE void WriteFileBinary(const std::vector<u8> &data, const std::string &path) {
std::ofstream file(path, std::ios::binary);
std::copy(data.begin(), data.end(), std::ostreambuf_iterator{file});
}
FORCE_INLINE void WriteFileBinary(const u8 *data, const size_t size, const std::string &path) {
FILE *out = fopen(path.c_str(), "wb");
fwrite(data, size, 1, out);
fclose(out);
}
template <size_t Size>
FORCE_INLINE void WriteFileBinary(const std::array<u8, Size> &data, const std::string &path) {
std::ofstream file(path, std::ios::binary);
std::copy(data.begin(), data.end(), std::ostreambuf_iterator{file});
}
FORCE_INLINE size_t NextPow2(size_t num) {
// Taken from "Bit Twiddling Hacks" by Sean Anderson:
// https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
--num;
num |= num >> 1;
num |= num >> 2;
num |= num >> 4;
num |= num >> 8;
num |= num >> 16;
return num + 1;
}
std::vector<u8> OpenROM(const std::string &filename, size_t &sizeAdjusted); std::vector<u8> OpenROM(const std::string &filename, size_t &sizeAdjusted);
std::vector<u8> OpenArchive(const std::string &path, size_t &sizeAdjusted); std::vector<u8> OpenArchive(const std::string &path, size_t &sizeAdjusted);
} // namespace Util } // namespace Util

View File

@@ -1,106 +0,0 @@
#pragma once
#include <cmath>
#include <common.hpp>
namespace Util {
static FORCE_INLINE auto roundCeil(float f) {
#ifdef SIMD_SUPPORT
__m128 t = _mm_set_ss(f);
t = _mm_round_ss(t, t, _MM_FROUND_TO_POS_INF);
return _mm_cvtss_f32(t);
#else
return ceilf(f);
#endif
}
static FORCE_INLINE auto roundCeil(double f) {
#ifdef SIMD_SUPPORT
__m128d t = _mm_set_sd(f);
t = _mm_round_sd(t, t, _MM_FROUND_TO_POS_INF);
return _mm_cvtsd_f64(t);
#else
return ceil(f);
#endif
}
static FORCE_INLINE auto roundNearest(float f) {
#ifdef SIMD_SUPPORT
__m128 t = _mm_set_ss(f);
t = _mm_round_ss(t, t, _MM_FROUND_TO_NEAREST_INT);
return _mm_cvtss_f32(t);
#else
return roundf(f);
#endif
}
static FORCE_INLINE auto roundNearest(double f) {
#ifdef SIMD_SUPPORT
__m128d t = _mm_set_sd(f);
t = _mm_round_sd(t, t, _MM_FROUND_TO_NEAREST_INT);
return _mm_cvtsd_f64(t);
#else
return round(f);
#endif
}
static FORCE_INLINE auto roundCurrent(float f) {
#ifdef SIMD_SUPPORT
auto t = _mm_set_ss(f);
t = _mm_round_ss(t, t, _MM_FROUND_CUR_DIRECTION);
return _mm_cvtss_f32(t);
#else
return rint(f);
#endif
}
static FORCE_INLINE auto roundCurrent(double f) {
#ifdef SIMD_SUPPORT
auto t = _mm_set_sd(f);
t = _mm_round_sd(t, t, _MM_FROUND_CUR_DIRECTION);
return _mm_cvtsd_f64(t);
#else
return rint(f);
#endif
}
static FORCE_INLINE auto roundFloor(float f) {
#ifdef SIMD_SUPPORT
__m128 t = _mm_set_ss(f);
t = _mm_round_ss(t, t, _MM_FROUND_TO_NEG_INF);
return _mm_cvtss_f32(t);
#else
return floor(f);
#endif
}
static FORCE_INLINE auto roundFloor(double f) {
#ifdef SIMD_SUPPORT
__m128d t = _mm_set_sd(f);
t = _mm_round_sd(t, t, _MM_FROUND_TO_NEG_INF);
return _mm_cvtsd_f64(t);
#else
return floor(f);
#endif
}
static FORCE_INLINE auto roundTrunc(float f) {
#ifdef SIMD_SUPPORT
__m128 t = _mm_set_ss(f);
t = _mm_round_ss(t, t, _MM_FROUND_TO_ZERO);
return _mm_cvtss_f32(t);
#else
return trunc(f);
#endif
}
static FORCE_INLINE auto roundTrunc(double f) {
#ifdef SIMD_SUPPORT
__m128d t = _mm_set_sd(f);
t = _mm_round_sd(t, t, _MM_FROUND_TO_ZERO);
return _mm_cvtsd_f64(t);
#else
return trunc(f);
#endif
}
} // namespace Util

View File

@@ -1,173 +0,0 @@
#pragma once
#include <common.hpp>
#include <cstring>
#include <functional>
#include <bit>
#include <algorithm>
#include <vector>
#include <concepts>
namespace Util {
static FORCE_INLINE std::vector<u8> IntegralToBuffer(const std::integral auto &val) {
std::vector<u8> ret{};
ret.resize(sizeof(val));
memcpy(ret.data(), &val, sizeof(val));
return ret;
}
static FORCE_INLINE constexpr bool IsInsideRange(const std::integral auto& addr,
const std::integral auto& start,
const std::integral auto& end) {
return addr >= start && addr <= end;
}
template <typename T>
static constexpr FORCE_INLINE T ReadAccess(const u8 *data, const u32 index);
template <typename T>
static constexpr FORCE_INLINE T ReadAccess(const std::vector<u8> &data, const u32 index);
template <typename T, size_t Size>
static constexpr FORCE_INLINE T ReadAccess(const std::array<u8, Size> &data, const u32 index);
template <typename T>
static constexpr FORCE_INLINE void WriteAccess(u8 *data, const u32 index, const T val);
template <typename T>
static constexpr FORCE_INLINE void WriteAccess(std::vector<u8> &data, const u32 index, const T val);
template <typename T, size_t Size>
static constexpr FORCE_INLINE void WriteAccess(std::array<u8, Size> &data, const u32 index, const T val);
template <>
constexpr FORCE_INLINE u64 ReadAccess(const u8 *data, const u32 index) {
u32 hi = *reinterpret_cast<const u32 *>(&data[index + 0]);
u32 lo = *reinterpret_cast<const u32 *>(&data[index + 4]);
const auto& result = static_cast<u64>(hi) << 32 | static_cast<u64>(lo);
return result;
}
template <typename T>
static constexpr FORCE_INLINE T ReadAccess(const u8 *data, const u32 index) {
return *reinterpret_cast<const T *>(&data[index]);
}
template <>
constexpr FORCE_INLINE u64 ReadAccess(const std::vector<u8> &data, const u32 index) {
u32 hi = *reinterpret_cast<const u32 *>(&data[index + 0]);
u32 lo = *reinterpret_cast<const u32 *>(&data[index + 4]);
return (static_cast<u64>(hi) << 32) | static_cast<u64>(lo);
}
template <typename T>
static constexpr FORCE_INLINE T ReadAccess(const std::vector<u8> &data, const u32 index) {
return *reinterpret_cast<const T *>(&data[index]);
}
template <size_t Size>
constexpr FORCE_INLINE u64 ReadAccess(const std::array<u8, Size> &data, const u32 index) {
u32 hi = *reinterpret_cast<const u32 *>(&data[index + 0]);
u32 lo = *reinterpret_cast<const u32 *>(&data[index + 4]);
return static_cast<u64>(hi) << 32 | static_cast<u64>(lo);
}
template <typename T, size_t Size>
static constexpr FORCE_INLINE T ReadAccess(const std::array<u8, Size> &data, const u32 index) {
return *reinterpret_cast<const T *>(&data[index]);
}
template <size_t Size>
constexpr FORCE_INLINE void WriteAccess(std::array<u8, Size> &data, const u32 index, const u64 val) {
const u32 hi = val >> 32;
const u32 lo = val;
*reinterpret_cast<u32 *>(&data[index + 0]) = hi;
*reinterpret_cast<u32 *>(&data[index + 4]) = lo;
}
template <typename T, size_t Size>
static constexpr FORCE_INLINE void WriteAccess(std::array<u8, Size> &data, const u32 index, const T val) {
*reinterpret_cast<T *>(&data[index]) = val;
}
template <>
constexpr FORCE_INLINE void WriteAccess(std::vector<u8> &data, const u32 index, const u64 val) {
const u32 hi = val >> 32;
const u32 lo = val;
*reinterpret_cast<u32 *>(&data[index + 0]) = hi;
*reinterpret_cast<u32 *>(&data[index + 4]) = lo;
}
template <typename T>
static constexpr FORCE_INLINE void WriteAccess(std::vector<u8> &data, const u32 index, const T val) {
*reinterpret_cast<T *>(&data[index]) = val;
}
template <>
constexpr FORCE_INLINE void WriteAccess(u8 *data, const u32 index, const u64 val) {
const u32 hi = val >> 32;
const u32 lo = val;
*reinterpret_cast<u32 *>(&data[index + 0]) = hi;
*reinterpret_cast<u32 *>(&data[index + 4]) = lo;
}
template <typename T>
static constexpr FORCE_INLINE void WriteAccess(u8 *data, const u32 index, const T val) {
*reinterpret_cast<T *>(&data[index]) = val;
}
template <typename T>
static constexpr FORCE_INLINE void SwapBuffer(std::vector<u8> &data) {
for (size_t i = 0; i < data.size(); i += sizeof(T)) {
const T original = *reinterpret_cast<T *>(&data[i]);
*reinterpret_cast<T *>(&data[i]) = std::byteswap(original);
}
}
template <typename T, size_t Size>
static constexpr FORCE_INLINE void SwapBuffer(std::array<u8, Size> &data) {
for (size_t i = 0; i < data.size(); i += sizeof(T)) {
const T original = *reinterpret_cast<T *>(&data[i]);
*reinterpret_cast<T *>(&data[i]) = std::byteswap(original);
}
}
static FORCE_INLINE u32 crc32(u32 crc, const u8 *buf, const size_t len) {
static u32 table[256];
static int have_table = 0;
if (have_table == 0) {
for (int i = 0; i < 256; i++) {
u32 rem = i;
for (int j = 0; j < 8; j++) {
if (rem & 1) {
rem >>= 1;
rem ^= 0xedb88320;
} else
rem >>= 1;
}
table[i] = rem;
}
have_table = 1;
}
crc = ~crc;
for (int i = 0; i < len; i++) {
const u8 octet = buf[i]; /* Cast to unsigned octet. */
crc = (crc >> 8) ^ table[(crc & 0xff) ^ octet];
}
return ~crc;
}
#ifdef _WIN32
FORCE_INLINE void *aligned_alloc(const size_t alignment, const size_t size) { return _aligned_malloc(size, alignment); }
FORCE_INLINE void aligned_free(void *ptr) { _aligned_free(ptr); }
#else
FORCE_INLINE void *aligned_alloc(const size_t alignment, const size_t size) {
return std::aligned_alloc(alignment, size);
}
FORCE_INLINE void aligned_free(void *ptr) { std::free(ptr); }
#endif
} // namespace Util