clamping logic + sdr fix + rsp.status gets written the same way as RSP::Write on RSP::MTC0

This commit is contained in:
CocoSimone
2022-09-25 22:02:31 +02:00
parent c0fa20b10f
commit a711093b55
11 changed files with 55 additions and 59 deletions

View File

@@ -61,6 +61,7 @@ target_include_directories(parallel-rdp PUBLIC
parallel-rdp-standalone/util
../../src/n64
../../src/n64/core/
../../src/n64/core/mmio
../../src/n64/core/cpu/
../../src/n64/core/cpu/registers
parallel-rdp-standalone

View File

@@ -43,8 +43,8 @@ void App::Run() {
char* droppedDir = event.drop.file;
if(droppedDir) {
LoadROM(droppedDir);
free(droppedDir);
}
free(droppedDir);
} break;
}
}

View File

@@ -126,14 +126,14 @@ void Core::UpdateController(const u8* state) {
s8 xaxis = 0;
if(state[SDL_SCANCODE_LEFT]) {
xaxis = -128;
xaxis = -127;
} else if(state[SDL_SCANCODE_RIGHT]) {
xaxis = 127;
}
s8 yaxis = 0;
if(state[SDL_SCANCODE_DOWN]) {
yaxis = -128;
yaxis = -127;
} else if(state[SDL_SCANCODE_UP]) {
yaxis = 127;
}

View File

@@ -34,28 +34,23 @@ inline void HandleInterrupt(Registers& regs) {
}
inline void Cpu::disassembly(u32 instr) {
auto found = std::find(instructionsLogged.begin(), instructionsLogged.end(), instr);
size_t count;
cs_insn *insn;
if(found == instructionsLogged.end()) {
instructionsLogged.push_back(instr);
size_t count;
cs_insn *insn;
u8 code[4];
memcpy(code, &instr, 4);
u8 code[4];
memcpy(code, &instr, 4);
count = cs_disasm(handle, code, 4, regs.pc, 0, &insn);
count = cs_disasm(handle, code, 4, regs.pc, 0, &insn);
if (count > 0) {
size_t j;
for (j = 0; j < count; j++) {
fmt::print("0x{:016X}:\t{}\t\t{}\n", insn[j].address, insn[j].mnemonic, insn[j].op_str);
}
if (count > 0) {
size_t j;
for (j = 0; j < count; j++) {
fmt::print("0x{:016X}:\t{}\t\t{}\n", insn[j].address, insn[j].mnemonic, insn[j].op_str);
}
cs_free(insn, count);
} else
printf("ERROR: Failed to disassemble given code!\n");
}
cs_free(insn, count);
} else
printf("ERROR: Failed to disassemble given code!\n");
}
void Cpu::Step(Mem& mem) {

View File

@@ -26,8 +26,6 @@ private:
void disassembly(u32 instr);
friend struct Cop1;
std::vector<u32> instructionsLogged;
void special(Mem&, u32);
void regimm(u32);
void Exec(Mem&, u32);

View File

@@ -67,25 +67,7 @@ void RSP::Write(Mem& mem, Registers& regs, u32 addr, u32 value) {
spDMALen.raw = value;
DMA<true>(spDMALen, mem.GetRDRAM(), *this, spDMASPAddr.bank);
} break;
case 0x04040010: {
auto write = SPStatusWrite{.raw = value};
CLEAR_SET(spStatus.halt, write.clearHalt, write.setHalt);
if(write.clearBroke) spStatus.broke = false;
if(write.clearIntr && !write.setIntr)
InterruptLower(mi, regs, Interrupt::SP);
if(write.setIntr && !write.clearIntr)
InterruptRaise(mi, regs, Interrupt::SP);
CLEAR_SET(spStatus.singleStep, write.clearSstep, write.setSstep);
CLEAR_SET(spStatus.interruptOnBreak, write.clearIntrOnBreak, write.setIntrOnBreak);
CLEAR_SET(spStatus.signal0Set, write.clearSignal0, write.setSignal0);
CLEAR_SET(spStatus.signal1Set, write.clearSignal1, write.setSignal1);
CLEAR_SET(spStatus.signal2Set, write.clearSignal2, write.setSignal2);
CLEAR_SET(spStatus.signal3Set, write.clearSignal3, write.setSignal3);
CLEAR_SET(spStatus.signal4Set, write.clearSignal4, write.setSignal4);
CLEAR_SET(spStatus.signal5Set, write.clearSignal5, write.setSignal5);
CLEAR_SET(spStatus.signal6Set, write.clearSignal6, write.setSignal6);
CLEAR_SET(spStatus.signal7Set, write.clearSignal7, write.setSignal7);
} break;
case 0x04040010: WriteStatus(mi, regs, value); break;
case 0x0404001C: ReleaseSemaphore(); break;
case 0x04080000:
if(spStatus.halt) {

View File

@@ -2,6 +2,7 @@
#include <n64/core/mmio/MI.hpp>
#include <n64/core/RDP.hpp>
#include <n64/memory_regions.hpp>
#include <Interrupt.hpp>
#define RSP_BYTE(addr, buf) (buf[BYTE_ADDRESS(addr) & 0xFFF])
#define GET_RSP_HALF(addr, buf) ((RSP_BYTE(addr, buf) << 8) | RSP_BYTE((addr) + 1, buf))
@@ -22,14 +23,14 @@ union SPStatus {
unsigned ioFull:1;
unsigned singleStep:1;
unsigned interruptOnBreak:1;
unsigned signal0Set:1;
unsigned signal1Set:1;
unsigned signal2Set:1;
unsigned signal3Set:1;
unsigned signal4Set:1;
unsigned signal5Set:1;
unsigned signal6Set:1;
unsigned signal7Set:1;
unsigned signal0:1;
unsigned signal1:1;
unsigned signal2:1;
unsigned signal3:1;
unsigned signal4:1;
unsigned signal5:1;
unsigned signal6:1;
unsigned signal7:1;
unsigned:17;
};
};
@@ -169,6 +170,26 @@ struct RSP {
return val;
}
inline void WriteStatus(MI& mi, Registers& regs, u32 value) {
auto write = SPStatusWrite{.raw = value};
CLEAR_SET(spStatus.halt, write.clearHalt, write.setHalt);
if(write.clearBroke) spStatus.broke = false;
if(write.clearIntr && !write.setIntr)
InterruptLower(mi, regs, Interrupt::SP);
if(write.setIntr && !write.clearIntr)
InterruptRaise(mi, regs, Interrupt::SP);
CLEAR_SET(spStatus.singleStep, write.clearSstep, write.setSstep);
CLEAR_SET(spStatus.interruptOnBreak, write.clearIntrOnBreak, write.setIntrOnBreak);
CLEAR_SET(spStatus.signal0, write.clearSignal0, write.setSignal0);
CLEAR_SET(spStatus.signal1, write.clearSignal1, write.setSignal1);
CLEAR_SET(spStatus.signal2, write.clearSignal2, write.setSignal2);
CLEAR_SET(spStatus.signal3, write.clearSignal3, write.setSignal3);
CLEAR_SET(spStatus.signal4, write.clearSignal4, write.setSignal4);
CLEAR_SET(spStatus.signal5, write.clearSignal5, write.setSignal5);
CLEAR_SET(spStatus.signal6, write.clearSignal6, write.setSignal6);
CLEAR_SET(spStatus.signal7, write.clearSignal7, write.setSignal7);
}
inline u16 VCCasU16() {
u16 val = 0;
for(int i = 0; i < 8; i++) {

View File

@@ -242,7 +242,7 @@ void Cpu::lwl(Mem& mem, u32 instr) {
u32 shift = 8 * ((address ^ 0) & 3);
u32 mask = 0xFFFFFFFF << shift;
u32 data = mem.Read32<false>(regs, paddr & ~3, regs.oldPC);
s32 result = (s32) ((regs.gpr[RT(instr)] & ~mask) | (data << shift));
s32 result = s32((regs.gpr[RT(instr)] & ~mask) | (data << shift));
regs.gpr[RT(instr)] = result;
}
}
@@ -257,7 +257,7 @@ void Cpu::lwr(Mem& mem, u32 instr) {
u32 shift = 8 * ((address ^ 3) & 3);
u32 mask = 0xFFFFFFFF >> shift;
u32 data = mem.Read32<false>(regs, paddr & ~3, regs.oldPC);
s32 result = (s32) ((regs.gpr[RT(instr)] & ~mask) | (data >> shift));
s32 result = s32((regs.gpr[RT(instr)] & ~mask) | (data >> shift));
regs.gpr[RT(instr)] = result;
}
}
@@ -420,7 +420,7 @@ void Cpu::sdl(Mem& mem, u32 instr) {
s32 shift = 8 * ((address ^ 0) & 7);
u64 mask = 0xFFFFFFFFFFFFFFFF >> shift;
u64 data = mem.Read64<false>(regs, paddr & ~7, regs.oldPC);
s64 rt = regs.gpr[RT(instr)];
u64 rt = regs.gpr[RT(instr)];
mem.Write64<false>(regs, paddr & ~7, (data & ~mask) | (rt >> shift), regs.oldPC);
}
}
@@ -435,7 +435,7 @@ void Cpu::sdr(Mem& mem, u32 instr) {
s32 shift = 8 * ((address ^ 7) & 7);
u64 mask = 0xFFFFFFFFFFFFFFFF << shift;
u64 data = mem.Read64<false>(regs, paddr & ~7, regs.oldPC);
s64 rt = regs.gpr[RT(instr)];
u64 rt = regs.gpr[RT(instr)];
mem.Write64<false>(regs, paddr & ~7, (data & ~mask) | (rt << shift), regs.oldPC);
}
}

View File

@@ -59,7 +59,7 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
cartAddr = cart_addr + len;
InterruptRaise(mi, regs, Interrupt::PI);
status &= 0xFFFFFFFE;
//util::logdebug("PI DMA from RDP RAM to CARTRIDGE (size: {} KiB, {:08X} to {:08X})\n", len, dramAddr, cartAddr);
util::logdebug("PI DMA from RDRAM to CARTRIDGE (size: {} KiB, {:08X} to {:08X})\n", len, dramAddr, cartAddr);
} break;
case 0x0460000C: {
u32 len = (val & 0x00FFFFFF) + 1;
@@ -76,7 +76,7 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
cartAddr = cart_addr + len;
InterruptRaise(mi, regs, Interrupt::PI);
status &= 0xFFFFFFFE;
//util::logdebug("PI DMA from CARTRIDGE to RDP RAM (size: {} KiB, {:08X} to {:08X})\n", len, cartAddr, dramAddr);
util::logdebug("PI DMA from CARTRIDGE to RDRAM (size: {} KiB, {:08X} to {:08X})\n", len, cart_addr, dram_addr);
} break;
case 0x04600010:
if(val & 2) {

View File

@@ -20,7 +20,6 @@ inline void special(MI& mi, Registers& regs, RSP& rsp, u32 instr) {
case 0x07: rsp.srav(instr); break;
case 0x08: rsp.jr(instr); break;
case 0x09: rsp.jalr(instr); break;
case 0x0C:
case 0x0D:
rsp.spStatus.halt = true;
rsp.spStatus.broke = true;

View File

@@ -60,7 +60,7 @@ inline void SetCop0Reg(Registers& regs, Mem& mem, u8 index, u32 val) {
rsp.spDMALen.raw = val;
rsp.DMA<true>(rsp.spDMALen, mem.GetRDRAM(), rsp, rsp.spDMASPAddr.bank);
break;
case 4: rsp.spStatus.raw = val; break;
case 4: rsp.WriteStatus(mi, regs, val); break;
case 7:
if(val == 0) {
ReleaseSemaphore(rsp);
@@ -337,7 +337,7 @@ void RSP::srlv(u32 instr) {
}
void RSP::srav(u32 instr) {
u8 sa = (gpr[RS(instr)]) & 0x1F;
u8 sa = gpr[RS(instr)] & 0x1F;
s32 rt = gpr[RT(instr)];
s32 result = rt >> sa;
gpr[RD(instr)] = result;