Map physical addresses for fastmem + minor optimization
This commit is contained in:
@@ -53,8 +53,6 @@ target_include_directories(gadolinium PRIVATE
|
|||||||
${SDL2_INCLUDE_DIR}
|
${SDL2_INCLUDE_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(gadolinium PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
|
|
||||||
|
|
||||||
file(COPY ${PROJECT_SOURCE_DIR}/../resources/ DESTINATION ${PROJECT_BINARY_DIR}/resources/)
|
file(COPY ${PROJECT_SOURCE_DIR}/../resources/ DESTINATION ${PROJECT_BINARY_DIR}/resources/)
|
||||||
file(REMOVE
|
file(REMOVE
|
||||||
${PROJECT_BINARY_DIR}/resources/mario.png
|
${PROJECT_BINARY_DIR}/resources/mario.png
|
||||||
@@ -66,4 +64,21 @@ if(WIN32)
|
|||||||
add_compile_options(/EHa)
|
add_compile_options(/EHa)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(${CMAKE_BUILD_TYPE} MATCHES Release)
|
||||||
|
set_property(TARGET gadolinium PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||||
|
if(WIN32)
|
||||||
|
add_compile_options(/O2)
|
||||||
|
else()
|
||||||
|
add_compile_options(-O3)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
if(WIN32)
|
||||||
|
add_compile_options(/Od)
|
||||||
|
else()
|
||||||
|
add_compile_options(-fsanitize=address)
|
||||||
|
add_link_options(-fsanitize=address)
|
||||||
|
add_compile_options(-g)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
target_link_libraries(gadolinium PRIVATE discord-rpc SDL2::SDL2main SDL2::SDL2 capstone-static nfd parallel-rdp fmt::fmt imgui nlohmann_json::nlohmann_json)
|
target_link_libraries(gadolinium PRIVATE discord-rpc SDL2::SDL2main SDL2::SDL2 capstone-static nfd parallel-rdp fmt::fmt imgui nlohmann_json::nlohmann_json)
|
||||||
@@ -15,7 +15,7 @@ struct Window {
|
|||||||
[[nodiscard]] bool gotClosed(SDL_Event event);
|
[[nodiscard]] bool gotClosed(SDL_Event event);
|
||||||
ImFont *uiFont{}, *codeFont{};
|
ImFont *uiFont{}, *codeFont{};
|
||||||
u32 windowID{};
|
u32 windowID{};
|
||||||
float volumeL = 0.01, volumeR = 0.01;
|
float volumeL = 0.0, volumeR = 0.0;
|
||||||
void LoadROM(n64::Core& core, const std::string& path);
|
void LoadROM(n64::Core& core, const std::string& path);
|
||||||
private:
|
private:
|
||||||
bool lockVolume = true;
|
bool lockVolume = true;
|
||||||
|
|||||||
@@ -16,21 +16,16 @@ void Mem::Reset() {
|
|||||||
std::fill(writePages.begin(), writePages.end(), 0);
|
std::fill(writePages.begin(), writePages.end(), 0);
|
||||||
|
|
||||||
for(int i = 0; i < 2048; i++) {
|
for(int i = 0; i < 2048; i++) {
|
||||||
const auto pointer = (uintptr_t) &mmio.rdp.dram[(i * PAGE_SIZE) & RDRAM_DSIZE];
|
const auto addr = (i * PAGE_SIZE) & RDRAM_DSIZE;
|
||||||
readPages[i + 0x80000] = pointer;
|
const auto pointer = (uintptr_t) &mmio.rdp.rdram[addr];
|
||||||
readPages[i + 0xA0000] = pointer;
|
readPages[i] = pointer;
|
||||||
writePages[i + 0x80000] = pointer;
|
writePages[i] = pointer;
|
||||||
writePages[i + 0xA0000] = pointer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
readPages[0x84000] = (uintptr_t) &mmio.rsp.dmem[0];
|
readPages[0x4000] = (uintptr_t) &mmio.rsp.dmem[0];
|
||||||
readPages[0xA4000] = (uintptr_t) &mmio.rsp.dmem[0];
|
readPages[0x4001] = (uintptr_t) &mmio.rsp.imem[0];
|
||||||
readPages[0x84001] = (uintptr_t) &mmio.rsp.imem[0];
|
writePages[0x4000] = (uintptr_t) &mmio.rsp.dmem[0];
|
||||||
readPages[0xA4001] = (uintptr_t) &mmio.rsp.imem[0];
|
writePages[0x4001] = (uintptr_t) &mmio.rsp.imem[0];
|
||||||
writePages[0x84000] = (uintptr_t) &mmio.rsp.dmem[0];
|
|
||||||
writePages[0xA4000] = (uintptr_t) &mmio.rsp.dmem[0];
|
|
||||||
writePages[0x84001] = (uintptr_t) &mmio.rsp.imem[0];
|
|
||||||
writePages[0xA4001] = (uintptr_t) &mmio.rsp.imem[0];
|
|
||||||
|
|
||||||
sram.resize(SRAM_SIZE);
|
sram.resize(SRAM_SIZE);
|
||||||
std::fill(sram.begin(), sram.end(), 0);
|
std::fill(sram.begin(), sram.end(), 0);
|
||||||
@@ -94,22 +89,22 @@ template bool MapVAddr<false>(Registers& regs, TLBAccessType accessType, u64 vad
|
|||||||
|
|
||||||
template <bool tlb>
|
template <bool tlb>
|
||||||
u8 Mem::Read8(n64::Registers ®s, u64 vaddr, s64 pc) {
|
u8 Mem::Read8(n64::Registers ®s, u64 vaddr, s64 pc) {
|
||||||
const auto page = (vaddr & 0xFFFFFFFF) >> 12;
|
|
||||||
const auto offset = vaddr & 0xFFF;
|
|
||||||
const auto pointer = readPages[page];
|
|
||||||
|
|
||||||
if(pointer) {
|
|
||||||
return ((u8*)pointer)[BYTE_ADDRESS(offset)];
|
|
||||||
} else {
|
|
||||||
u32 paddr = vaddr;
|
u32 paddr = vaddr;
|
||||||
if (!MapVAddr<tlb>(regs, LOAD, vaddr, paddr)) {
|
if (!MapVAddr<tlb>(regs, LOAD, vaddr, paddr)) {
|
||||||
HandleTLBException(regs, vaddr);
|
HandleTLBException(regs, vaddr);
|
||||||
FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, pc);
|
FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto page = paddr >> 12;
|
||||||
|
const auto offset = paddr & 0xFFF;
|
||||||
|
const auto pointer = readPages[page];
|
||||||
|
|
||||||
|
if(pointer) {
|
||||||
|
return ((u8*)pointer)[BYTE_ADDRESS(offset)];
|
||||||
|
} else {
|
||||||
switch (paddr) {
|
switch (paddr) {
|
||||||
case 0x00000000 ... 0x007FFFFF:
|
case 0x00000000 ... 0x007FFFFF:
|
||||||
return mmio.rdp.dram[BYTE_ADDRESS(paddr)];
|
return mmio.rdp.rdram[BYTE_ADDRESS(paddr)];
|
||||||
case 0x04000000 ... 0x0403FFFF:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
if ((paddr >> 12) & 1)
|
if ((paddr >> 12) & 1)
|
||||||
return mmio.rsp.imem[BYTE_ADDRESS(paddr) & IMEM_DSIZE];
|
return mmio.rsp.imem[BYTE_ADDRESS(paddr) & IMEM_DSIZE];
|
||||||
@@ -145,22 +140,22 @@ u8 Mem::Read8(n64::Registers ®s, u64 vaddr, s64 pc) {
|
|||||||
|
|
||||||
template <bool tlb>
|
template <bool tlb>
|
||||||
u16 Mem::Read16(n64::Registers ®s, u64 vaddr, s64 pc) {
|
u16 Mem::Read16(n64::Registers ®s, u64 vaddr, s64 pc) {
|
||||||
const auto page = (vaddr & 0xFFFFFFFF) >> 12;
|
|
||||||
const auto offset = vaddr & 0xFFF;
|
|
||||||
const auto pointer = readPages[page];
|
|
||||||
|
|
||||||
if(pointer) {
|
|
||||||
return util::ReadAccess<u16>((u8*)pointer, HALF_ADDRESS(offset));
|
|
||||||
} else {
|
|
||||||
u32 paddr = vaddr;
|
u32 paddr = vaddr;
|
||||||
if (!MapVAddr<tlb>(regs, LOAD, vaddr, paddr)) {
|
if (!MapVAddr<tlb>(regs, LOAD, vaddr, paddr)) {
|
||||||
HandleTLBException(regs, vaddr);
|
HandleTLBException(regs, vaddr);
|
||||||
FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, pc);
|
FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto page = paddr >> 12;
|
||||||
|
const auto offset = paddr & 0xFFF;
|
||||||
|
const auto pointer = readPages[page];
|
||||||
|
|
||||||
|
if(pointer) {
|
||||||
|
return util::ReadAccess<u16>((u8*)pointer, HALF_ADDRESS(offset));
|
||||||
|
} else {
|
||||||
switch (paddr) {
|
switch (paddr) {
|
||||||
case 0x00000000 ... 0x007FFFFF:
|
case 0x00000000 ... 0x007FFFFF:
|
||||||
return util::ReadAccess<u16>(mmio.rdp.dram.data(), HALF_ADDRESS(paddr));
|
return util::ReadAccess<u16>(mmio.rdp.rdram.data(), HALF_ADDRESS(paddr));
|
||||||
case 0x04000000 ... 0x0403FFFF:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
if ((paddr >> 12) & 1)
|
if ((paddr >> 12) & 1)
|
||||||
return util::ReadAccess<u16>(mmio.rsp.imem, HALF_ADDRESS(paddr) & IMEM_DSIZE);
|
return util::ReadAccess<u16>(mmio.rsp.imem, HALF_ADDRESS(paddr) & IMEM_DSIZE);
|
||||||
@@ -191,22 +186,22 @@ u16 Mem::Read16(n64::Registers ®s, u64 vaddr, s64 pc) {
|
|||||||
|
|
||||||
template <bool tlb>
|
template <bool tlb>
|
||||||
u32 Mem::Read32(n64::Registers ®s, u64 vaddr, s64 pc) {
|
u32 Mem::Read32(n64::Registers ®s, u64 vaddr, s64 pc) {
|
||||||
const auto page = (vaddr & 0xFFFFFFFF) >> 12;
|
u32 paddr = vaddr;
|
||||||
const auto offset = vaddr & 0xFFF;
|
if (!MapVAddr<tlb>(regs, LOAD, vaddr, paddr)) {
|
||||||
|
HandleTLBException(regs, vaddr);
|
||||||
|
FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto page = paddr >> 12;
|
||||||
|
const auto offset = paddr & 0xFFF;
|
||||||
const auto pointer = readPages[page];
|
const auto pointer = readPages[page];
|
||||||
|
|
||||||
if(pointer) {
|
if(pointer) {
|
||||||
return util::ReadAccess<u32>((u8*)pointer, offset);
|
return util::ReadAccess<u32>((u8*)pointer, offset);
|
||||||
} else {
|
} else {
|
||||||
u32 paddr = vaddr;
|
|
||||||
if(!MapVAddr<tlb>(regs, LOAD, vaddr, paddr)) {
|
|
||||||
HandleTLBException(regs, vaddr);
|
|
||||||
FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, pc);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(paddr) {
|
switch(paddr) {
|
||||||
case 0x00000000 ... 0x007FFFFF:
|
case 0x00000000 ... 0x007FFFFF:
|
||||||
return util::ReadAccess<u32>(mmio.rdp.dram.data(), paddr);
|
return util::ReadAccess<u32>(mmio.rdp.rdram.data(), paddr);
|
||||||
case 0x04000000 ... 0x0403FFFF:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
if((paddr >> 12) & 1)
|
if((paddr >> 12) & 1)
|
||||||
return util::ReadAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE);
|
return util::ReadAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE);
|
||||||
@@ -231,22 +226,22 @@ u32 Mem::Read32(n64::Registers ®s, u64 vaddr, s64 pc) {
|
|||||||
|
|
||||||
template <bool tlb>
|
template <bool tlb>
|
||||||
u64 Mem::Read64(n64::Registers ®s, u64 vaddr, s64 pc) {
|
u64 Mem::Read64(n64::Registers ®s, u64 vaddr, s64 pc) {
|
||||||
const auto page = (vaddr & 0xFFFFFFFF) >> 12;
|
|
||||||
const auto offset = vaddr & 0xFFF;
|
|
||||||
const auto pointer = readPages[page];
|
|
||||||
|
|
||||||
if(pointer) {
|
|
||||||
return util::ReadAccess<u64>((u8*)pointer, offset);
|
|
||||||
} else {
|
|
||||||
u32 paddr = vaddr;
|
u32 paddr = vaddr;
|
||||||
if (!MapVAddr<tlb>(regs, LOAD, vaddr, paddr)) {
|
if (!MapVAddr<tlb>(regs, LOAD, vaddr, paddr)) {
|
||||||
HandleTLBException(regs, vaddr);
|
HandleTLBException(regs, vaddr);
|
||||||
FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, pc);
|
FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto page = paddr >> 12;
|
||||||
|
const auto offset = paddr & 0xFFF;
|
||||||
|
const auto pointer = readPages[page];
|
||||||
|
|
||||||
|
if(pointer) {
|
||||||
|
return util::ReadAccess<u64>((u8*)pointer, offset);
|
||||||
|
} else {
|
||||||
switch (paddr) {
|
switch (paddr) {
|
||||||
case 0x00000000 ... 0x007FFFFF:
|
case 0x00000000 ... 0x007FFFFF:
|
||||||
return util::ReadAccess<u64>(mmio.rdp.dram.data(), paddr);
|
return util::ReadAccess<u64>(mmio.rdp.rdram.data(), paddr);
|
||||||
case 0x04000000 ... 0x0403FFFF:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
if ((paddr >> 12) & 1)
|
if ((paddr >> 12) & 1)
|
||||||
return util::ReadAccess<u64>(mmio.rsp.imem, paddr & IMEM_DSIZE);
|
return util::ReadAccess<u64>(mmio.rsp.imem, paddr & IMEM_DSIZE);
|
||||||
@@ -285,22 +280,27 @@ template u64 Mem::Read64<true>(n64::Registers ®s, u64 vaddr, s64 pc);
|
|||||||
|
|
||||||
template <bool tlb>
|
template <bool tlb>
|
||||||
void Mem::Write8(Registers& regs, u64 vaddr, u32 val, s64 pc) {
|
void Mem::Write8(Registers& regs, u64 vaddr, u32 val, s64 pc) {
|
||||||
const auto page = (vaddr & 0xFFFFFFFF) >> 12;
|
|
||||||
const auto offset = vaddr & 0xFFF;
|
|
||||||
const auto pointer = writePages[page];
|
|
||||||
|
|
||||||
if(pointer) {
|
|
||||||
((u8*)pointer)[BYTE_ADDRESS(offset)] = val;
|
|
||||||
} else {
|
|
||||||
u32 paddr = vaddr;
|
u32 paddr = vaddr;
|
||||||
if (!MapVAddr<tlb>(regs, STORE, vaddr, paddr)) {
|
if (!MapVAddr<tlb>(regs, LOAD, vaddr, paddr)) {
|
||||||
HandleTLBException(regs, vaddr);
|
HandleTLBException(regs, vaddr);
|
||||||
FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, pc);
|
FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto page = paddr >> 12;
|
||||||
|
auto offset = paddr & 0xFFF;
|
||||||
|
const auto pointer = readPages[page];
|
||||||
|
|
||||||
|
if(pointer) {
|
||||||
|
if(paddr >= 0x04000000 && paddr <= 0x0403FFFF) {
|
||||||
|
val = val << (8 * (3 - (paddr & 3)));
|
||||||
|
offset = (offset & DMEM_DSIZE) & ~3;
|
||||||
|
}
|
||||||
|
|
||||||
|
((u8*)pointer)[BYTE_ADDRESS(offset)] = val;
|
||||||
|
} else {
|
||||||
switch (paddr) {
|
switch (paddr) {
|
||||||
case 0x00000000 ... 0x007FFFFF:
|
case 0x00000000 ... 0x007FFFFF:
|
||||||
mmio.rdp.dram[BYTE_ADDRESS(paddr)] = val;
|
mmio.rdp.rdram[BYTE_ADDRESS(paddr)] = val;
|
||||||
break;
|
break;
|
||||||
case 0x04000000 ... 0x0403FFFF:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
val = val << (8 * (3 - (paddr & 3)));
|
val = val << (8 * (3 - (paddr & 3)));
|
||||||
@@ -339,22 +339,27 @@ void Mem::Write8(Registers& regs, u64 vaddr, u32 val, s64 pc) {
|
|||||||
|
|
||||||
template <bool tlb>
|
template <bool tlb>
|
||||||
void Mem::Write16(Registers& regs, u64 vaddr, u32 val, s64 pc) {
|
void Mem::Write16(Registers& regs, u64 vaddr, u32 val, s64 pc) {
|
||||||
const auto page = (vaddr & 0xFFFFFFFF) >> 12;
|
|
||||||
const auto offset = vaddr & 0xFFF;
|
|
||||||
const auto pointer = writePages[page];
|
|
||||||
|
|
||||||
if(pointer) {
|
|
||||||
util::WriteAccess<u16>((u8*)pointer, HALF_ADDRESS(offset), val);
|
|
||||||
} else {
|
|
||||||
u32 paddr = vaddr;
|
u32 paddr = vaddr;
|
||||||
if (!MapVAddr<tlb>(regs, STORE, vaddr, paddr)) {
|
if (!MapVAddr<tlb>(regs, STORE, vaddr, paddr)) {
|
||||||
HandleTLBException(regs, vaddr);
|
HandleTLBException(regs, vaddr);
|
||||||
FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, pc);
|
FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto page = paddr >> 12;
|
||||||
|
auto offset = paddr & 0xFFF;
|
||||||
|
const auto pointer = readPages[page];
|
||||||
|
|
||||||
|
if(pointer) {
|
||||||
|
if(paddr >= 0x04000000 && paddr <= 0x0403FFFF) {
|
||||||
|
val = val << (16 * !(paddr & 2));
|
||||||
|
offset &= ~3;
|
||||||
|
}
|
||||||
|
|
||||||
|
util::WriteAccess<u16>((u8*)pointer, HALF_ADDRESS(offset), val);
|
||||||
|
} else {
|
||||||
switch (paddr) {
|
switch (paddr) {
|
||||||
case 0x00000000 ... 0x007FFFFF:
|
case 0x00000000 ... 0x007FFFFF:
|
||||||
util::WriteAccess<u16>(mmio.rdp.dram.data(), HALF_ADDRESS(paddr), val);
|
util::WriteAccess<u16>(mmio.rdp.rdram.data(), HALF_ADDRESS(paddr), val);
|
||||||
break;
|
break;
|
||||||
case 0x04000000 ... 0x0403FFFF:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
val = val << (16 * !(paddr & 2));
|
val = val << (16 * !(paddr & 2));
|
||||||
@@ -393,22 +398,22 @@ void Mem::Write16(Registers& regs, u64 vaddr, u32 val, s64 pc) {
|
|||||||
|
|
||||||
template <bool tlb>
|
template <bool tlb>
|
||||||
void Mem::Write32(Registers& regs, u64 vaddr, u32 val, s64 pc) {
|
void Mem::Write32(Registers& regs, u64 vaddr, u32 val, s64 pc) {
|
||||||
const auto page = (vaddr & 0xFFFFFFFF) >> 12;
|
|
||||||
const auto offset = vaddr & 0xFFF;
|
|
||||||
const auto pointer = writePages[page];
|
|
||||||
|
|
||||||
if(pointer) {
|
|
||||||
util::WriteAccess<u32>((u8*)pointer, offset, val);
|
|
||||||
} else {
|
|
||||||
u32 paddr = vaddr;
|
u32 paddr = vaddr;
|
||||||
if(!MapVAddr<tlb>(regs, STORE, vaddr, paddr)) {
|
if(!MapVAddr<tlb>(regs, STORE, vaddr, paddr)) {
|
||||||
HandleTLBException(regs, vaddr);
|
HandleTLBException(regs, vaddr);
|
||||||
FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, pc);
|
FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto page = paddr >> 12;
|
||||||
|
auto offset = paddr & 0xFFF;
|
||||||
|
const auto pointer = readPages[page];
|
||||||
|
|
||||||
|
if(pointer) {
|
||||||
|
util::WriteAccess<u32>((u8*)pointer, offset, val);
|
||||||
|
} else {
|
||||||
switch(paddr) {
|
switch(paddr) {
|
||||||
case 0x00000000 ... 0x007FFFFF:
|
case 0x00000000 ... 0x007FFFFF:
|
||||||
util::WriteAccess<u32>(mmio.rdp.dram.data(), paddr, val);
|
util::WriteAccess<u32>(mmio.rdp.rdram.data(), paddr, val);
|
||||||
break;
|
break;
|
||||||
case 0x04000000 ... 0x0403FFFF:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
if(paddr & 0x1000)
|
if(paddr & 0x1000)
|
||||||
@@ -444,22 +449,25 @@ void Mem::Write32(Registers& regs, u64 vaddr, u32 val, s64 pc) {
|
|||||||
|
|
||||||
template <bool tlb>
|
template <bool tlb>
|
||||||
void Mem::Write64(Registers& regs, u64 vaddr, u64 val, s64 pc) {
|
void Mem::Write64(Registers& regs, u64 vaddr, u64 val, s64 pc) {
|
||||||
const auto page = (vaddr & 0xFFFFFFFF) >> 12;
|
|
||||||
const auto offset = vaddr & 0xFFF;
|
|
||||||
const auto pointer = writePages[page];
|
|
||||||
|
|
||||||
if(pointer) {
|
|
||||||
util::WriteAccess<u64>((u8*)pointer, offset, val);
|
|
||||||
} else {
|
|
||||||
u32 paddr = vaddr;
|
u32 paddr = vaddr;
|
||||||
if (!MapVAddr<tlb>(regs, STORE, vaddr, paddr)) {
|
if(!MapVAddr<tlb>(regs, STORE, vaddr, paddr)) {
|
||||||
HandleTLBException(regs, vaddr);
|
HandleTLBException(regs, vaddr);
|
||||||
FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, pc);
|
FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto page = paddr >> 12;
|
||||||
|
auto offset = paddr & 0xFFF;
|
||||||
|
const auto pointer = readPages[page];
|
||||||
|
|
||||||
|
if(pointer) {
|
||||||
|
if(paddr >= 0x04000000 && paddr <= 0x0403FFFF) {
|
||||||
|
val >>= 32;
|
||||||
|
}
|
||||||
|
util::WriteAccess<u64>((u8*)pointer, offset, val);
|
||||||
|
} else {
|
||||||
switch (paddr) {
|
switch (paddr) {
|
||||||
case 0x00000000 ... 0x007FFFFF:
|
case 0x00000000 ... 0x007FFFFF:
|
||||||
util::WriteAccess<u64>(mmio.rdp.dram.data(), paddr, val);
|
util::WriteAccess<u64>(mmio.rdp.rdram.data(), paddr, val);
|
||||||
break;
|
break;
|
||||||
case 0x04000000 ... 0x0403FFFF:
|
case 0x04000000 ... 0x0403FFFF:
|
||||||
val >>= 32;
|
val >>= 32;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ struct Mem {
|
|||||||
void Reset();
|
void Reset();
|
||||||
CartInfo LoadROM(const std::string&);
|
CartInfo LoadROM(const std::string&);
|
||||||
[[nodiscard]] auto GetRDRAM() -> u8* {
|
[[nodiscard]] auto GetRDRAM() -> u8* {
|
||||||
return mmio.rdp.dram.data();
|
return mmio.rdp.rdram.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool tlb = true>
|
template <bool tlb = true>
|
||||||
@@ -46,7 +46,7 @@ struct Mem {
|
|||||||
inline void DumpRDRAM() const {
|
inline void DumpRDRAM() const {
|
||||||
FILE *fp = fopen("rdram.dump", "wb");
|
FILE *fp = fopen("rdram.dump", "wb");
|
||||||
u8 *temp = (u8*)calloc(RDRAM_SIZE, 1);
|
u8 *temp = (u8*)calloc(RDRAM_SIZE, 1);
|
||||||
memcpy(temp, mmio.rdp.dram.data(), RDRAM_SIZE);
|
memcpy(temp, mmio.rdp.rdram.data(), RDRAM_SIZE);
|
||||||
util::SwapBuffer32(RDRAM_SIZE, temp);
|
util::SwapBuffer32(RDRAM_SIZE, temp);
|
||||||
fwrite(temp, 1, RDRAM_SIZE, fp);
|
fwrite(temp, 1, RDRAM_SIZE, fp);
|
||||||
free(temp);
|
free(temp);
|
||||||
@@ -72,6 +72,7 @@ struct Mem {
|
|||||||
free(temp);
|
free(temp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
std::vector<uintptr_t> writePages, readPages;
|
||||||
private:
|
private:
|
||||||
friend struct SI;
|
friend struct SI;
|
||||||
friend struct PI;
|
friend struct PI;
|
||||||
@@ -82,7 +83,6 @@ private:
|
|||||||
std::vector<u8> cart, sram;
|
std::vector<u8> cart, sram;
|
||||||
u8 pifBootrom[PIF_BOOTROM_SIZE]{};
|
u8 pifBootrom[PIF_BOOTROM_SIZE]{};
|
||||||
u8 isviewer[ISVIEWER_SIZE]{};
|
u8 isviewer[ISVIEWER_SIZE]{};
|
||||||
std::vector<uintptr_t> writePages, readPages;
|
|
||||||
size_t romMask;
|
size_t romMask;
|
||||||
|
|
||||||
void SetCICType(u32& cicType, u32 checksum) {
|
void SetCICType(u32& cicType, u32 checksum) {
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ RDP::RDP() {
|
|||||||
|
|
||||||
void RDP::Reset() {
|
void RDP::Reset() {
|
||||||
dpc.status.raw = 0x80;
|
dpc.status.raw = 0x80;
|
||||||
dram.resize(RDRAM_SIZE);
|
rdram.resize(RDRAM_SIZE);
|
||||||
std::fill(dram.begin(), dram.end(), 0);
|
std::fill(rdram.begin(), rdram.end(), 0);
|
||||||
memset(cmd_buf, 0, 0x100000);
|
memset(cmd_buf, 0, 0x100000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ void RDP::RunCommand(MI& mi, Registers& regs, RSP& rsp) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < len; i += 4) {
|
for (int i = 0; i < len; i += 4) {
|
||||||
u32 cmd = util::ReadAccess<u32>(dram.data(), current + i);
|
u32 cmd = util::ReadAccess<u32>(rdram.data(), current + i);
|
||||||
cmd_buf[remaining_cmds + (i >> 2)] = cmd;
|
cmd_buf[remaining_cmds + (i >> 2)] = cmd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ struct RDP {
|
|||||||
RDP();
|
RDP();
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
std::vector<u8> dram;
|
std::vector<u8> rdram;
|
||||||
[[nodiscard]] auto Read(u32 addr) const -> u32;
|
[[nodiscard]] auto Read(u32 addr) const -> u32;
|
||||||
void Write(MI& mi, Registers& regs, RSP& rsp, u32 addr, u32 val);
|
void Write(MI& mi, Registers& regs, RSP& rsp, u32 addr, u32 val);
|
||||||
void WriteStatus(MI& mi, Registers& regs, RSP& rsp, u32 val);
|
void WriteStatus(MI& mi, Registers& regs, RSP& rsp, u32 val);
|
||||||
|
|||||||
@@ -81,17 +81,19 @@ void AI::Step(Mem& mem, Registers& regs, int cpuCycles, float volumeL, float vol
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(dmaLen[0] && dmaEnable) {
|
if(dmaLen[0] && dmaEnable) {
|
||||||
|
if(volumeR > 0 && volumeL > 0) {
|
||||||
u32 addrHi = ((dmaAddr[0] >> 13) + dmaAddrCarry) & 0x7FF;
|
u32 addrHi = ((dmaAddr[0] >> 13) + dmaAddrCarry) & 0x7FF;
|
||||||
dmaAddr[0] = (addrHi << 13) | (dmaAddr[0] & 0x1FFF);
|
dmaAddr[0] = (addrHi << 13) | (dmaAddr[0] & 0x1FFF);
|
||||||
u32 data = util::ReadAccess<u32>(mem.mmio.rdp.dram.data(), dmaAddr[0] & RDRAM_DSIZE);
|
u32 data = util::ReadAccess<u32>(mem.mmio.rdp.rdram.data(), dmaAddr[0] & RDRAM_DSIZE);
|
||||||
s16 l = s16(data >> 16);
|
s16 l = s16(data >> 16);
|
||||||
s16 r = s16(data);
|
s16 r = s16(data);
|
||||||
|
|
||||||
PushSample((float)l / INT16_MAX, volumeL, (float)r / INT16_MAX, volumeR);
|
PushSample((float) l / INT16_MAX, volumeL, (float) r / INT16_MAX, volumeR);
|
||||||
|
|
||||||
u32 addrLo = (dmaAddr[0] + 4) & 0x1FFF;
|
u32 addrLo = (dmaAddr[0] + 4) & 0x1FFF;
|
||||||
dmaAddr[0] = (dmaAddr[0] & ~0x1FFF) | addrLo;
|
dmaAddr[0] = (dmaAddr[0] & ~0x1FFF) | addrLo;
|
||||||
dmaAddrCarry = addrLo == 0;
|
dmaAddrCarry = addrLo == 0;
|
||||||
|
}
|
||||||
dmaLen[0] -= 4;
|
dmaLen[0] -= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
|
|||||||
}
|
}
|
||||||
rdLen = len;
|
rdLen = len;
|
||||||
for(int i = 0; i < len; i++) {
|
for(int i = 0; i < len; i++) {
|
||||||
mem.cart[BYTE_ADDRESS(cart_addr + i) & mem.romMask] = mem.mmio.rdp.dram[BYTE_ADDRESS(dram_addr + i) & RDRAM_DSIZE];
|
mem.cart[BYTE_ADDRESS(cart_addr + i) & mem.romMask] = mem.mmio.rdp.rdram[BYTE_ADDRESS(dram_addr + i) & RDRAM_DSIZE];
|
||||||
}
|
}
|
||||||
dramAddr = dram_addr + len;
|
dramAddr = dram_addr + len;
|
||||||
cartAddr = cart_addr + len;
|
cartAddr = cart_addr + len;
|
||||||
@@ -68,7 +68,7 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
|
|||||||
}
|
}
|
||||||
wrLen = len;
|
wrLen = len;
|
||||||
for(int i = 0; i < len; i++) {
|
for(int i = 0; i < len; i++) {
|
||||||
mem.mmio.rdp.dram[BYTE_ADDRESS(dram_addr + i) & RDRAM_DSIZE] = mem.cart[BYTE_ADDRESS(cart_addr + i) & mem.romMask];
|
mem.mmio.rdp.rdram[BYTE_ADDRESS(dram_addr + i) & RDRAM_DSIZE] = mem.cart[BYTE_ADDRESS(cart_addr + i) & mem.romMask];
|
||||||
}
|
}
|
||||||
dramAddr = dram_addr + len;
|
dramAddr = dram_addr + len;
|
||||||
cartAddr = cart_addr + len;
|
cartAddr = cart_addr + len;
|
||||||
|
|||||||
@@ -39,11 +39,11 @@ void DMA(Mem& mem, Registers& regs) {
|
|||||||
if(si.toDram) {
|
if(si.toDram) {
|
||||||
ProcessPIFCommands(mem.pifRam, si.controller, mem);
|
ProcessPIFCommands(mem.pifRam, si.controller, mem);
|
||||||
for(int i = 0; i < 64; i++) {
|
for(int i = 0; i < 64; i++) {
|
||||||
mem.mmio.rdp.dram[BYTE_ADDRESS(si.dramAddr + i)] = mem.pifRam[i];
|
mem.mmio.rdp.rdram[BYTE_ADDRESS(si.dramAddr + i)] = mem.pifRam[i];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for(int i = 0; i < 64; i++) {
|
for(int i = 0; i < 64; i++) {
|
||||||
mem.pifRam[i] = mem.mmio.rdp.dram[BYTE_ADDRESS(si.dramAddr + i)];
|
mem.pifRam[i] = mem.mmio.rdp.rdram[BYTE_ADDRESS(si.dramAddr + i)];
|
||||||
}
|
}
|
||||||
util::logdebug("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})\n", si.pifAddr, si.dramAddr);
|
util::logdebug("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})\n", si.pifAddr, si.dramAddr);
|
||||||
ProcessPIFCommands(mem.pifRam, si.controller, mem);
|
ProcessPIFCommands(mem.pifRam, si.controller, mem);
|
||||||
|
|||||||
Reference in New Issue
Block a user