make use of my new small utility library
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include <MemoryHelpers.hpp>
|
||||
#include <ircolib/mem_access.hpp>
|
||||
#include <log.hpp>
|
||||
|
||||
namespace Util {
|
||||
@@ -29,17 +29,17 @@ FORCE_INLINE void SwapN64Rom(std::vector<u8> &rom, u32 endianness) {
|
||||
|
||||
switch (endianness) {
|
||||
case V64:
|
||||
SwapBuffer<u16>(rom);
|
||||
ircolib::SwapBuffer<u16>(rom);
|
||||
if constexpr (!toBE)
|
||||
SwapBuffer<u32>(rom);
|
||||
ircolib::SwapBuffer<u32>(rom);
|
||||
break;
|
||||
case N64:
|
||||
if constexpr (toBE)
|
||||
SwapBuffer<u32>(rom);
|
||||
ircolib::SwapBuffer<u32>(rom);
|
||||
break;
|
||||
case Z64:
|
||||
if constexpr (!toBE)
|
||||
SwapBuffer<u32>(rom);
|
||||
ircolib::SwapBuffer<u32>(rom);
|
||||
break;
|
||||
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!");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
Disassembler::DisassemblyResult Disassembler::DisassembleSimple(const u32 address, const u32 instruction) const {
|
||||
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);
|
||||
|
||||
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 {
|
||||
n64::Core& core = n64::Core::GetInstance();
|
||||
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);
|
||||
|
||||
if (count <= 0)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include <capstone/capstone.h>
|
||||
#include <utils/log.hpp>
|
||||
#include <utils/MemoryHelpers.hpp>
|
||||
#include <ircolib/mem_access.hpp>
|
||||
#include <array>
|
||||
|
||||
struct Disassembler {
|
||||
|
||||
@@ -240,7 +240,7 @@ u32 JIT::Step() {
|
||||
}
|
||||
|
||||
void JIT::DumpBlockCacheToDisk() const {
|
||||
Util::WriteFileBinary(code.getCode<u8*>(), code.getSize(), "jit.dump");
|
||||
ircolib::WriteFileBinary(code.getCode<u8*>(), code.getSize(), "jit.dump");
|
||||
}
|
||||
#endif
|
||||
} // namespace n64
|
||||
|
||||
@@ -47,10 +47,10 @@ void Mem::LoadSRAM(SaveType save_type, fs::path path) {
|
||||
saveData.unmap();
|
||||
}
|
||||
|
||||
auto sramVec = Util::ReadFileBinary(sramPath);
|
||||
auto sramVec = ircolib::ReadFileBinary(sramPath);
|
||||
if (sramVec.empty()) {
|
||||
Util::WriteFileBinary(std::array<u8, SRAM_SIZE>{}, sramPath);
|
||||
sramVec = Util::ReadFileBinary(sramPath);
|
||||
ircolib::WriteFileBinary(std::array<u8, SRAM_SIZE>{}, sramPath);
|
||||
sramVec = ircolib::ReadFileBinary(sramPath);
|
||||
}
|
||||
|
||||
if (sramVec.size() != SRAM_SIZE) {
|
||||
@@ -107,7 +107,7 @@ void Mem::LoadROM(const bool isArchive, const std::string &filename) {
|
||||
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);
|
||||
|
||||
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';
|
||||
}
|
||||
|
||||
const u32 checksum = Util::crc32(0, &rom.cart[0x40], 0x9c0);
|
||||
const u32 checksum = SDL_crc32(0, &rom.cart[0x40], 0x9C0);
|
||||
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);
|
||||
rom.pal = IsROMPAL();
|
||||
}
|
||||
@@ -147,33 +147,33 @@ u8 Mem::Read(const u32 paddr) {
|
||||
n64::Registers& regs = n64::Core::GetRegs();
|
||||
const SI &si = mmio.si;
|
||||
|
||||
if(Util::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, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM<u8>(paddr);
|
||||
if(ircolib::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
|
||||
const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
|
||||
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(Util::IsInsideRange(paddr, AI_REGION_START, AI_REGION_END)) {
|
||||
if(ircolib::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) return mmio.pi.BusRead<u8, false>(paddr);
|
||||
if(ircolib::IsInsideRange(paddr, AI_REGION_START, AI_REGION_END)) {
|
||||
const u32 w = mmio.ai.Read(paddr & ~3);
|
||||
const int offs = 3 - (paddr & 3);
|
||||
return w >> offs * 8 & 0xff;
|
||||
}
|
||||
|
||||
if(Util::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
|
||||
Util::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) {
|
||||
if(ircolib::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
|
||||
ircolib::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) {
|
||||
Util::Error::GetInstance().Throw(
|
||||
{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");
|
||||
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(Util::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
|
||||
Util::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
|
||||
Util::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
|
||||
Util::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return 0;
|
||||
if(ircolib::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_RAM_REGION_START, PIF_RAM_REGION_END)) return si.pif.ram[paddr - PIF_RAM_REGION_START];
|
||||
if(ircolib::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
|
||||
ircolib::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
|
||||
ircolib::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
|
||||
ircolib::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return 0;
|
||||
|
||||
Util::Error::GetInstance().Throw(
|
||||
{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();
|
||||
const SI &si = mmio.si;
|
||||
|
||||
if(Util::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, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM<u16>(paddr);
|
||||
if(ircolib::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
|
||||
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(Util::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);
|
||||
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(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(Util::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
|
||||
Util::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
|
||||
Util::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
|
||||
Util::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return 0;
|
||||
if(ircolib::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) return mmio.pi.BusRead<u16, false>(paddr);
|
||||
if(ircolib::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
|
||||
ircolib::IsInsideRange(paddr, MMIO_REGION_START_2, MMIO_REGION_END_2)) return mmio.Read(paddr);
|
||||
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(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(ircolib::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
|
||||
ircolib::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
|
||||
ircolib::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
|
||||
ircolib::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return 0;
|
||||
|
||||
Util::Error::GetInstance().Throw(
|
||||
{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();
|
||||
const SI &si = mmio.si;
|
||||
|
||||
if(Util::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, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM<u32>(paddr);
|
||||
if(ircolib::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
|
||||
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(Util::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);
|
||||
if(ircolib::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) return mmio.pi.BusRead<u32, false>(paddr);
|
||||
if(ircolib::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
|
||||
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(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(Util::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
|
||||
Util::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
|
||||
Util::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
|
||||
Util::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return 0;
|
||||
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(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(ircolib::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
|
||||
ircolib::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
|
||||
ircolib::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
|
||||
ircolib::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return 0;
|
||||
|
||||
Util::Error::GetInstance().Throw(
|
||||
{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();
|
||||
const SI &si = mmio.si;
|
||||
|
||||
if(Util::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, RDRAM_REGION_START, RDRAM_REGION_END)) return mmio.rdp.ReadRDRAM<u64>(paddr);
|
||||
if(ircolib::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
|
||||
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(Util::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);
|
||||
if(ircolib::IsInsideRange(paddr, CART_REGION_START_2_1, CART_REGION_END_1_2)) return mmio.pi.BusRead<u64, false>(paddr);
|
||||
if(ircolib::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
|
||||
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(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(Util::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
|
||||
Util::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
|
||||
Util::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
|
||||
Util::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return 0;
|
||||
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(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(ircolib::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
|
||||
ircolib::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
|
||||
ircolib::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
|
||||
ircolib::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return 0;
|
||||
|
||||
Util::Error::GetInstance().Throw(
|
||||
{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();
|
||||
SI &si = mmio.si;
|
||||
|
||||
if(Util::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, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM<u8>(paddr, val); return; }
|
||||
if(ircolib::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
|
||||
val = val << (8 * (3 - (paddr & 3)));
|
||||
auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
|
||||
paddr = (paddr & 0xFFF) & ~3;
|
||||
Util::WriteAccess<u32>(dest, paddr, val);
|
||||
ircolib::WriteAccess<u32>(dest, paddr, val);
|
||||
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);
|
||||
mmio.pi.BusWrite<u8, false>(paddr, val);
|
||||
return;
|
||||
}
|
||||
|
||||
if(Util::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>!");
|
||||
if(ircolib::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
|
||||
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)));
|
||||
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();
|
||||
return;
|
||||
}
|
||||
|
||||
if(Util::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
|
||||
Util::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
|
||||
Util::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
|
||||
Util::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END) ||
|
||||
Util::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return;
|
||||
if(ircolib::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
|
||||
ircolib::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
|
||||
ircolib::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
|
||||
ircolib::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END) ||
|
||||
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);
|
||||
}
|
||||
@@ -323,37 +323,37 @@ void Mem::WriteInterpreter<u16>(u32 paddr, u32 val) {
|
||||
n64::Registers& regs = n64::Core::GetRegs();
|
||||
SI &si = mmio.si;
|
||||
|
||||
if(Util::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, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM<u16>(paddr, val); return; }
|
||||
if(ircolib::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
|
||||
val = val << (16 * !(paddr & 2));
|
||||
auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
|
||||
paddr = (paddr & 0xFFF) & ~3;
|
||||
Util::WriteAccess<u32>(dest, paddr, val);
|
||||
ircolib::WriteAccess<u32>(dest, paddr, val);
|
||||
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);
|
||||
mmio.pi.BusWrite<u16, false>(paddr, val);
|
||||
return;
|
||||
}
|
||||
|
||||
if(Util::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>!");
|
||||
if(ircolib::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
|
||||
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));
|
||||
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();
|
||||
return;
|
||||
}
|
||||
|
||||
if(Util::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
|
||||
Util::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
|
||||
Util::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
|
||||
Util::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END) ||
|
||||
Util::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return;
|
||||
if(ircolib::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
|
||||
ircolib::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
|
||||
ircolib::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
|
||||
ircolib::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END) ||
|
||||
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);
|
||||
}
|
||||
@@ -377,33 +377,33 @@ void Mem::WriteInterpreter<u32>(const u32 paddr, const u32 val) {
|
||||
n64::Registers& regs = n64::Core::GetRegs();
|
||||
SI &si = mmio.si;
|
||||
|
||||
if(Util::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, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM<u32>(paddr, val); return; }
|
||||
if(ircolib::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
mmio.pi.BusWrite<u32, false>(paddr, val);
|
||||
return;
|
||||
}
|
||||
|
||||
if(Util::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; }
|
||||
if(ircolib::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
|
||||
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)) {
|
||||
Util::WriteAccess<u32>(si.pif.ram, paddr - PIF_RAM_REGION_START, std::byteswap(val));
|
||||
if(ircolib::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) {
|
||||
ircolib::WriteAccess<u32>(si.pif.ram, paddr - PIF_RAM_REGION_START, std::byteswap(val));
|
||||
si.pif.ProcessCommands();
|
||||
return;
|
||||
}
|
||||
|
||||
if(Util::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
|
||||
Util::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
|
||||
Util::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
|
||||
Util::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END) ||
|
||||
Util::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return;
|
||||
if(ircolib::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
|
||||
ircolib::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
|
||||
ircolib::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
|
||||
ircolib::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END) ||
|
||||
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);
|
||||
}
|
||||
@@ -436,34 +436,34 @@ void Mem::WriteInterpreter(const u32 paddr, u64 val) {
|
||||
n64::Registers& regs = n64::Core::GetRegs();
|
||||
SI &si = mmio.si;
|
||||
|
||||
if(Util::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, RDRAM_REGION_START, RDRAM_REGION_END)) { mmio.rdp.WriteRDRAM<u64>(paddr, val); return; }
|
||||
if(ircolib::IsInsideRange(paddr, DMEM_REGION_START, RSP_MEM_REGION_END)) {
|
||||
auto &dest = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem;
|
||||
val >>= 32;
|
||||
Util::WriteAccess<u32>(dest, paddr & 0xfff, val);
|
||||
ircolib::WriteAccess<u32>(dest, paddr & 0xfff, val);
|
||||
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);
|
||||
mmio.pi.BusWrite<false>(paddr, val);
|
||||
return;
|
||||
}
|
||||
|
||||
if(Util::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>!");
|
||||
if(ircolib::IsInsideRange(paddr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
|
||||
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)) {
|
||||
Util::WriteAccess<u64>(si.pif.ram, paddr - PIF_RAM_REGION_START, std::byteswap(val));
|
||||
if(ircolib::IsInsideRange(paddr, PIF_RAM_REGION_START, PIF_RAM_REGION_END)) {
|
||||
ircolib::WriteAccess<u64>(si.pif.ram, paddr - PIF_RAM_REGION_START, std::byteswap(val));
|
||||
si.pif.ProcessCommands();
|
||||
return;
|
||||
}
|
||||
|
||||
if(Util::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
|
||||
Util::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
|
||||
Util::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
|
||||
Util::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END) ||
|
||||
Util::IsInsideRange(paddr, UNUSED_START_4, UNUSED_END_4)) return;
|
||||
if(ircolib::IsInsideRange(paddr, UNUSED_START_1, UNUSED_END_1) || // unused
|
||||
ircolib::IsInsideRange(paddr, UNUSED_START_2, UNUSED_END_2) ||
|
||||
ircolib::IsInsideRange(paddr, UNUSED_START_3, UNUSED_END_3) ||
|
||||
ircolib::IsInsideRange(paddr, PIF_ROM_REGION_START, PIF_ROM_REGION_END) ||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -102,22 +102,22 @@ struct Mem {
|
||||
std::vector<u8> temp{};
|
||||
temp.resize(RDRAM_SIZE);
|
||||
std::ranges::copy(mmio.rdp.rdram, temp.begin());
|
||||
Util::SwapBuffer<u32>(temp);
|
||||
Util::WriteFileBinary(temp, "rdram.bin");
|
||||
ircolib::SwapBuffer<u32>(temp);
|
||||
ircolib::WriteFileBinary(temp, "rdram.bin");
|
||||
}
|
||||
|
||||
FORCE_INLINE void DumpIMEM() const {
|
||||
std::array<u8, IMEM_SIZE> temp{};
|
||||
std::ranges::copy(mmio.rsp.imem, temp.begin());
|
||||
Util::SwapBuffer<u32>(temp);
|
||||
Util::WriteFileBinary(temp, "imem.bin");
|
||||
ircolib::SwapBuffer<u32>(temp);
|
||||
ircolib::WriteFileBinary(temp, "imem.bin");
|
||||
}
|
||||
|
||||
FORCE_INLINE void DumpDMEM() const {
|
||||
std::array<u8, DMEM_SIZE> temp{};
|
||||
std::ranges::copy(mmio.rsp.dmem, temp.begin());
|
||||
Util::SwapBuffer<u32>(temp);
|
||||
Util::WriteFileBinary(temp, "dmem.bin");
|
||||
ircolib::SwapBuffer<u32>(temp);
|
||||
ircolib::WriteFileBinary(temp, "dmem.bin");
|
||||
}
|
||||
|
||||
MMIO mmio;
|
||||
|
||||
@@ -25,21 +25,21 @@ void RDP::WriteRDRAM<u8>(const size_t idx, const u8 v) {
|
||||
template <>
|
||||
void RDP::WriteRDRAM<u16>(const size_t idx, const u16 v) {
|
||||
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 <>
|
||||
void RDP::WriteRDRAM<u32>(const size_t idx, const u32 v) {
|
||||
if (idx < RDRAM_SIZE) [[likely]] {
|
||||
Util::WriteAccess<u32>(rdram, idx, v);
|
||||
ircolib::WriteAccess<u32>(rdram, idx, v);
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void RDP::WriteRDRAM<u64>(const size_t idx, const u64 v) {
|
||||
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 <>
|
||||
u16 RDP::ReadRDRAM<u16>(const size_t idx) {
|
||||
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;
|
||||
}
|
||||
@@ -62,7 +62,7 @@ u16 RDP::ReadRDRAM<u16>(const size_t idx) {
|
||||
template <>
|
||||
u32 RDP::ReadRDRAM<u32>(const size_t idx) {
|
||||
if (idx < RDRAM_SIZE) [[likely]]
|
||||
return Util::ReadAccess<u32>(rdram, idx);
|
||||
return ircolib::ReadAccess<u32>(rdram, idx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -70,7 +70,7 @@ u32 RDP::ReadRDRAM<u32>(const size_t idx) {
|
||||
template <>
|
||||
u64 RDP::ReadRDRAM<u64>(const size_t idx) {
|
||||
if (idx < RDRAM_SIZE) [[likely]]
|
||||
return Util::ReadAccess<u64>(rdram, idx);
|
||||
return ircolib::ReadAccess<u64>(rdram, idx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -223,7 +223,7 @@ void RDP::RunCommand() {
|
||||
|
||||
if (dpc.status.xbusDmemDma) {
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
@@ -232,7 +232,7 @@ void RDP::RunCommand() {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include <MemoryHelpers.hpp>
|
||||
#include <ircolib/mem_access.hpp>
|
||||
#include <MemoryRegions.hpp>
|
||||
#include <array>
|
||||
#include <core/RDP.hpp>
|
||||
@@ -150,7 +150,7 @@ struct RSP {
|
||||
|
||||
FORCE_INLINE void Step() {
|
||||
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;
|
||||
pc = nextPC & 0xFFC;
|
||||
nextPC += 4;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <cfenv>
|
||||
#include <cmath>
|
||||
#include <Core.hpp>
|
||||
#include <utils/FloatingPoint.hpp>
|
||||
#include <ircolib/floats.hpp>
|
||||
|
||||
namespace n64 {
|
||||
template <>
|
||||
@@ -503,7 +503,7 @@ void Cop1::ceills(const Instruction instr) {
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, instr.fs());
|
||||
if (!CheckCVTArg<s64>(fs))
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -514,7 +514,7 @@ void Cop1::ceilld(const Instruction instr) {
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, instr.fs());
|
||||
if (!CheckCVTArg<s64>(fs))
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -525,7 +525,7 @@ void Cop1::ceilws(const Instruction instr) {
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, instr.fs());
|
||||
if (!CheckCVTArg<s32>(fs))
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -536,7 +536,7 @@ void Cop1::ceilwd(const Instruction instr) {
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, instr.fs());
|
||||
if (!CheckCVTArg<s32>(fs))
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -666,7 +666,7 @@ void Cop1::cvtwd(const Instruction instr) {
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, instr.fs());
|
||||
if (!CheckCVTArg<s32>(fs))
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -677,7 +677,7 @@ void Cop1::cvtws(const Instruction instr) {
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, instr.fs());
|
||||
if (!CheckCVTArg<s32>(fs))
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -688,7 +688,7 @@ void Cop1::cvtls(const Instruction instr) {
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, instr.fs());
|
||||
if (!CheckCVTArg<s64>(fs))
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -728,7 +728,7 @@ void Cop1::cvtld(const Instruction instr) {
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, instr.fs());
|
||||
if (!CheckCVTArg<s64>(fs))
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1128,7 +1128,7 @@ void Cop1::roundls(const Instruction instr) {
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, instr.fs());
|
||||
if (!CheckCVTArg<s64>(fs))
|
||||
return;
|
||||
CHECK_FPE_CONST(s64, fd, Util::roundNearest(fs))
|
||||
CHECK_FPE_CONST(s64, fd, ircolib::roundNearest(fs))
|
||||
if (fd != fs && SetCauseInexact()) {
|
||||
regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC);
|
||||
return;
|
||||
@@ -1143,7 +1143,7 @@ void Cop1::roundld(const Instruction instr) {
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, instr.fs());
|
||||
if (!CheckCVTArg<s64>(fs))
|
||||
return;
|
||||
CHECK_FPE_CONST(s64, fd, Util::roundNearest(fs))
|
||||
CHECK_FPE_CONST(s64, fd, ircolib::roundNearest(fs))
|
||||
if (fd != fs && SetCauseInexact()) {
|
||||
regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC);
|
||||
return;
|
||||
@@ -1158,7 +1158,7 @@ void Cop1::roundws(const Instruction instr) {
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, instr.fs());
|
||||
if (!CheckCVTArg<s32>(fs))
|
||||
return;
|
||||
CHECK_FPE_CONV_CONST(s32, fd, Util::roundNearest(fs))
|
||||
CHECK_FPE_CONV_CONST(s32, fd, ircolib::roundNearest(fs))
|
||||
if (fd != fs && SetCauseInexact()) {
|
||||
regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC);
|
||||
return;
|
||||
@@ -1173,7 +1173,7 @@ void Cop1::roundwd(const Instruction instr) {
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, instr.fs());
|
||||
if (!CheckCVTArg<s32>(fs))
|
||||
return;
|
||||
CHECK_FPE_CONV_CONST(s32, fd, Util::roundNearest(fs))
|
||||
CHECK_FPE_CONV_CONST(s32, fd, ircolib::roundNearest(fs))
|
||||
if (fd != fs && SetCauseInexact()) {
|
||||
regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC);
|
||||
return;
|
||||
@@ -1188,7 +1188,7 @@ void Cop1::floorls(const Instruction instr) {
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, instr.fs());
|
||||
if (!CheckCVTArg<s64>(fs))
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1199,7 +1199,7 @@ void Cop1::floorld(const Instruction instr) {
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, instr.fs());
|
||||
if (!CheckCVTArg<s64>(fs))
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1210,7 +1210,7 @@ void Cop1::floorws(const Instruction instr) {
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, instr.fs());
|
||||
if (!CheckCVTArg<s32>(fs))
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1221,7 +1221,7 @@ void Cop1::floorwd(const Instruction instr) {
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, instr.fs());
|
||||
if (!CheckCVTArg<s32>(fs))
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1232,7 +1232,7 @@ void Cop1::truncws(const Instruction instr) {
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, instr.fs());
|
||||
if (!CheckCVTArg<s32>(fs))
|
||||
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()) {
|
||||
regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC);
|
||||
return;
|
||||
@@ -1247,7 +1247,7 @@ void Cop1::truncwd(const Instruction instr) {
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, instr.fs());
|
||||
if (!CheckCVTArg<s32>(fs))
|
||||
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()) {
|
||||
regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC);
|
||||
return;
|
||||
@@ -1262,7 +1262,7 @@ void Cop1::truncls(const Instruction instr) {
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, instr.fs());
|
||||
if (!CheckCVTArg<s64>(fs))
|
||||
return;
|
||||
CHECK_FPE_CONST(s64, fd, Util::roundTrunc(fs))
|
||||
CHECK_FPE_CONST(s64, fd, ircolib::roundTrunc(fs))
|
||||
if (static_cast<float>(fd) != fs && SetCauseInexact()) {
|
||||
regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC);
|
||||
return;
|
||||
@@ -1277,7 +1277,7 @@ void Cop1::truncld(const Instruction instr) {
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, instr.fs());
|
||||
if (!CheckCVTArg<s64>(fs))
|
||||
return;
|
||||
CHECK_FPE_CONST(s64, fd, Util::roundTrunc(fs))
|
||||
CHECK_FPE_CONST(s64, fd, ircolib::roundTrunc(fs))
|
||||
if (static_cast<double>(fd) != fs && SetCauseInexact()) {
|
||||
regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC);
|
||||
return;
|
||||
|
||||
@@ -33,12 +33,12 @@ void Flash::Load(SaveType saveType, const std::string &path) {
|
||||
saveData.unmap();
|
||||
}
|
||||
|
||||
auto flashVec = Util::ReadFileBinary(flashPath);
|
||||
auto flashVec = ircolib::ReadFileBinary(flashPath);
|
||||
if (flashVec.empty()) {
|
||||
std::vector<u8> dummy{};
|
||||
dummy.resize(FLASH_SIZE);
|
||||
Util::WriteFileBinary(dummy, flashPath);
|
||||
flashVec = Util::ReadFileBinary(flashPath);
|
||||
ircolib::WriteFileBinary(dummy, flashPath);
|
||||
flashVec = ircolib::ReadFileBinary(flashPath);
|
||||
}
|
||||
|
||||
if (flashVec.size() != FLASH_SIZE) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include <MemoryHelpers.hpp>
|
||||
#include <ircolib/mem_access.hpp>
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
namespace n64 {
|
||||
|
||||
@@ -188,7 +188,7 @@ auto PI::BusRead<u16, false>(u32 addr) -> u16 {
|
||||
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);
|
||||
}
|
||||
return Util::ReadAccess<u16>(mem.rom.cart, index);
|
||||
return ircolib::ReadAccess<u16>(mem.rom.cart, index);
|
||||
}
|
||||
default:
|
||||
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
|
||||
switch (addr) {
|
||||
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:
|
||||
panic("Read from ISViewer flush!");
|
||||
default:
|
||||
@@ -270,7 +270,7 @@ auto PI::BusRead<u32, false>(u32 addr) -> u32 {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Util::ReadAccess<u32>(mem.rom.cart, index);
|
||||
return ircolib::ReadAccess<u32>(mem.rom.cart, index);
|
||||
}
|
||||
default:
|
||||
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:
|
||||
switch (addr) {
|
||||
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;
|
||||
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
|
||||
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:
|
||||
panic("Should never end up here! Access to address {:08X} which did not match any PI bus regions!", addr);
|
||||
|
||||
@@ -50,10 +50,10 @@ void PIF::MaybeLoadMempak() {
|
||||
mempak.unmap();
|
||||
}
|
||||
|
||||
auto mempakVec = Util::ReadFileBinary(mempakPath);
|
||||
auto mempakVec = ircolib::ReadFileBinary(mempakPath);
|
||||
if (mempak.empty()) {
|
||||
Util::WriteFileBinary(std::array<u8, MEMPAK_SIZE>{}, mempakPath);
|
||||
mempakVec = Util::ReadFileBinary(mempakPath);
|
||||
ircolib::WriteFileBinary(std::array<u8, MEMPAK_SIZE>{}, mempakPath);
|
||||
mempakVec = ircolib::ReadFileBinary(mempakPath);
|
||||
}
|
||||
|
||||
if (mempakVec.size() != MEMPAK_SIZE) {
|
||||
@@ -104,11 +104,11 @@ void PIF::LoadEeprom(const SaveType saveType, const std::string &path) {
|
||||
|
||||
eepromSize = GetSaveSize(saveType);
|
||||
|
||||
auto eepromVec = Util::ReadFileBinary(eepromPath);
|
||||
auto eepromVec = ircolib::ReadFileBinary(eepromPath);
|
||||
if (eepromVec.empty()) {
|
||||
std::vector<u8> dummy{};
|
||||
dummy.resize(GetSaveSize(saveType));
|
||||
Util::WriteFileBinary(dummy, eepromPath);
|
||||
ircolib::WriteFileBinary(dummy, eepromPath);
|
||||
eepromVec = dummy;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ static_assert(sizeof(TASMovieControllerData) == 4);
|
||||
|
||||
void MupenMovie::Load(const fs::path &path) {
|
||||
filename = path.stem().string();
|
||||
loadedTasMovie = Util::ReadFileBinary(path.string());
|
||||
loadedTasMovie = ircolib::ReadFileBinary(path.string());
|
||||
if (!IsLoaded()) {
|
||||
error("Error loading movie!");
|
||||
return;
|
||||
|
||||
@@ -446,7 +446,7 @@ void Cop0::decode(const Instruction instr) {
|
||||
|
||||
template <>
|
||||
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);
|
||||
|
||||
tlbError = DISALLOWED_ADDRESS;
|
||||
@@ -456,10 +456,10 @@ bool Cop0::MapVirtualAddress<u32, true>(const TLBAccessType accessType, const u6
|
||||
template <>
|
||||
bool Cop0::MapVirtualAddress<u32, false>(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
|
||||
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);
|
||||
|
||||
if(Util::IsInsideRange(segment, 4, 5)) {
|
||||
if(ircolib::IsInsideRange(segment, 4, 5)) {
|
||||
paddr = vaddr & 0x1FFFFFFF;
|
||||
return true;
|
||||
}
|
||||
@@ -474,7 +474,7 @@ bool Cop0::MapVirtualAddress<u32, false>(const TLBAccessType accessType, const u
|
||||
|
||||
template <>
|
||||
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);
|
||||
|
||||
tlbError = DISALLOWED_ADDRESS;
|
||||
@@ -483,13 +483,13 @@ bool Cop0::MapVirtualAddress<u64, true>(const TLBAccessType accessType, const u6
|
||||
|
||||
template <>
|
||||
bool Cop0::MapVirtualAddress<u64, false>(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) {
|
||||
if(Util::IsInsideRange(vaddr, 0x0000000000000000, 0x000000FFFFFFFFFF) || // VREGION_XKUSEG
|
||||
Util::IsInsideRange(vaddr, 0x4000000000000000, 0x400000FFFFFFFFFF) || // VREGION_XKSSEG
|
||||
Util::IsInsideRange(vaddr, 0xC000000000000000, 0xC00000FF7FFFFFFF) || // VREGION_XKSEG
|
||||
Util::IsInsideRange(vaddr, 0xFFFFFFFFE0000000, 0xFFFFFFFFFFFFFFFF)) // VREGION_CKSEG3
|
||||
if(ircolib::IsInsideRange(vaddr, 0x0000000000000000, 0x000000FFFFFFFFFF) || // VREGION_XKUSEG
|
||||
ircolib::IsInsideRange(vaddr, 0x4000000000000000, 0x400000FFFFFFFFFF) || // VREGION_XKSSEG
|
||||
ircolib::IsInsideRange(vaddr, 0xC000000000000000, 0xC00000FF7FFFFFFF) || // VREGION_XKSEG
|
||||
ircolib::IsInsideRange(vaddr, 0xFFFFFFFFE0000000, 0xFFFFFFFFFFFFFFFF)) // VREGION_CKSEG3
|
||||
return ProbeTLB(accessType, vaddr, paddr);
|
||||
|
||||
if(Util::IsInsideRange(vaddr, 0x8000000000000000, 0xBFFFFFFFFFFFFFFF)) { // VREGION_XKPHYS
|
||||
if(ircolib::IsInsideRange(vaddr, 0x8000000000000000, 0xBFFFFFFFFFFFFFFF)) { // VREGION_XKPHYS
|
||||
if (!kernelMode)
|
||||
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;
|
||||
}
|
||||
|
||||
if(Util::IsInsideRange(vaddr, 0xFFFFFFFF80000000, 0xFFFFFFFF9FFFFFFF) || // VREGION_CKSEG0
|
||||
Util::IsInsideRange(vaddr, 0xFFFFFFFFA0000000, 0xFFFFFFFFBFFFFFFF)) { // VREGION_CKSEG1
|
||||
if(ircolib::IsInsideRange(vaddr, 0xFFFFFFFF80000000, 0xFFFFFFFF9FFFFFFF) || // VREGION_CKSEG0
|
||||
ircolib::IsInsideRange(vaddr, 0xFFFFFFFFA0000000, 0xFFFFFFFFBFFFFFFF)) { // VREGION_CKSEG1
|
||||
u32 cut = u32(vaddr) >> 28;
|
||||
u32 num = cut == 0xA;
|
||||
// Identical to ksegX in 32 bit mode.
|
||||
@@ -521,9 +521,9 @@ bool Cop0::MapVirtualAddress<u64, false>(const TLBAccessType accessType, const u
|
||||
return true;
|
||||
}
|
||||
|
||||
if(Util::IsInsideRange(vaddr, 0x0000010000000000, 0x3FFFFFFFFFFFFFFF) || // VREGION_XBAD1
|
||||
Util::IsInsideRange(vaddr, 0x4000010000000000, 0x7FFFFFFFFFFFFFFF) || // VREGION_XBAD2
|
||||
Util::IsInsideRange(vaddr, 0xC00000FF80000000, 0xFFFFFFFF7FFFFFFF)) { // VREGION_XBAD3
|
||||
if(ircolib::IsInsideRange(vaddr, 0x0000010000000000, 0x3FFFFFFFFFFFFFFF) || // VREGION_XBAD1
|
||||
ircolib::IsInsideRange(vaddr, 0x4000010000000000, 0x7FFFFFFFFFFFFFFF) || // VREGION_XBAD2
|
||||
ircolib::IsInsideRange(vaddr, 0xC00000FF80000000, 0xFFFFFFFF7FFFFFFF)) { // VREGION_XBAD3
|
||||
tlbError = DISALLOWED_ADDRESS;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <ircolib/types.hpp>
|
||||
#ifdef USE_NEON
|
||||
#include <sse2neon.h>
|
||||
#else
|
||||
@@ -7,14 +7,14 @@
|
||||
#include <smmintrin.h>
|
||||
#endif
|
||||
|
||||
using u8 = uint8_t;
|
||||
using u16 = uint16_t;
|
||||
using u32 = uint32_t;
|
||||
using u64 = uint64_t;
|
||||
using s8 = int8_t;
|
||||
using s16 = int16_t;
|
||||
using s32 = int32_t;
|
||||
using s64 = int64_t;
|
||||
using u8 = ircolib::u8;
|
||||
using u16 = ircolib::u16;
|
||||
using u32 = ircolib::u32;
|
||||
using u64 = ircolib::u64;
|
||||
using s8 = ircolib::s8;
|
||||
using s16 = ircolib::s16;
|
||||
using s32 = ircolib::s32;
|
||||
using s64 = ircolib::s64;
|
||||
using u128 = __uint128_t;
|
||||
using s128 = __int128_t;
|
||||
using m128i = __m128i;
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
namespace Util {
|
||||
std::vector<u8> OpenROM(const std::string &filename, size_t &sizeAdjusted) {
|
||||
auto buf = ReadFileBinary(filename);
|
||||
sizeAdjusted = NextPow2(buf.size());
|
||||
auto buf = ircolib::ReadFileBinary(filename);
|
||||
sizeAdjusted = ircolib::NextPow2(buf.size());
|
||||
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; })) {
|
||||
const auto size = ar_entry_get_size(archive);
|
||||
sizeAdjusted = NextPow2(size);
|
||||
sizeAdjusted = ircolib::NextPow2(size);
|
||||
buf.resize(sizeAdjusted);
|
||||
ar_entry_uncompress(archive, buf.data(), size);
|
||||
break;
|
||||
|
||||
@@ -3,44 +3,11 @@
|
||||
#include <log.hpp>
|
||||
#include <vector>
|
||||
#include <filesystem>
|
||||
#include <ircolib/file.hpp>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
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> OpenArchive(const std::string &path, size_t &sizeAdjusted);
|
||||
} // namespace Util
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user