move controller logic to PIF

This commit is contained in:
CocoSimone
2023-02-19 14:54:26 +01:00
parent 50ec9a8a9e
commit e665f2d6e9
11 changed files with 154 additions and 151 deletions

View File

@@ -2,7 +2,6 @@
#include <ParallelRDPWrapper.hpp> #include <ParallelRDPWrapper.hpp>
#include <Window.hpp> #include <Window.hpp>
#include <algorithm> #include <algorithm>
#include <MupenMovie.hpp>
#include <Scheduler.hpp> #include <Scheduler.hpp>
namespace n64 { namespace n64 {
@@ -29,7 +28,7 @@ CartInfo Core::LoadROM(const std::string& rom_) {
CartInfo cartInfo = mem.LoadROM(rom); CartInfo cartInfo = mem.LoadROM(rom);
isPAL = cartInfo.isPAL; isPAL = cartInfo.isPAL;
ExecutePIF(mem, CpuGetRegs(), cartInfo); mem.mmio.si.pif.ExecutePIF(mem, CpuGetRegs(), cartInfo);
return cartInfo; return cartInfo;
} }
@@ -87,98 +86,5 @@ void Core::Run(Window& window, float volumeL, float volumeR) {
UpdateScreenParallelRdpNoGame(*this, window); UpdateScreenParallelRdpNoGame(*this, window);
} }
} }
if(debugger.enabled)
debugger.tick();
}
#define GET_BUTTON(gamepad, i) SDL_GameControllerGetButton(gamepad, i)
#define GET_AXIS(gamepad, axis) SDL_GameControllerGetAxis(gamepad, axis)
void Core::UpdateController(const u8* state) {
Controller &controller = mem.mmio.si.controller;
s8 xaxis = 0, yaxis = 0;
if(gamepadConnected) {
bool A = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_A);
bool B = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_X);
bool Z = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_TRIGGERLEFT) == 32767;
bool START = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_START);
bool DUP = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_DPAD_UP);
bool DDOWN = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_DPAD_DOWN);
bool DLEFT = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
bool DRIGHT = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
bool L = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
bool R = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
bool CUP = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_RIGHTY) <= -128;
bool CDOWN = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_RIGHTY) >= 127;
bool CLEFT = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_RIGHTX) <= -128;
bool CRIGHT = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_RIGHTX) >= 127;
controller.a = A;
controller.b = B;
controller.z = Z;
controller.start = START;
controller.dp_up = DUP;
controller.dp_down = DDOWN;
controller.dp_left = DLEFT;
controller.dp_right = DRIGHT;
controller.joy_reset = L && R && START;
controller.l = L;
controller.r = R;
controller.c_up = CUP;
controller.c_down = CDOWN;
controller.c_left = CLEFT;
controller.c_right = CRIGHT;
xaxis = (s8) std::clamp((GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_LEFTX) >> 8), -86, 86);
yaxis = (s8) std::clamp(-(GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_LEFTY) >> 8), -86, 86);
controller.joy_x = xaxis;
controller.joy_y = yaxis;
if (controller.joy_reset) {
controller.start = false;
controller.joy_x = 0;
controller.joy_y = 0;
}
} else {
controller.a = state[SDL_SCANCODE_X];
controller.b = state[SDL_SCANCODE_C];
controller.z = state[SDL_SCANCODE_Z];
controller.start = state[SDL_SCANCODE_RETURN];
controller.dp_up = state[SDL_SCANCODE_KP_8];
controller.dp_down = state[SDL_SCANCODE_KP_5];
controller.dp_left = state[SDL_SCANCODE_KP_4];
controller.dp_right = state[SDL_SCANCODE_KP_6];
controller.joy_reset = state[SDL_SCANCODE_RETURN] && state[SDL_SCANCODE_A] && state[SDL_SCANCODE_S];
controller.l = state[SDL_SCANCODE_A];
controller.r = state[SDL_SCANCODE_S];
controller.c_up = state[SDL_SCANCODE_I];
controller.c_down = state[SDL_SCANCODE_J];
controller.c_left = state[SDL_SCANCODE_K];
controller.c_right = state[SDL_SCANCODE_L];
if (state[SDL_SCANCODE_LEFT]) {
xaxis = -86;
} else if (state[SDL_SCANCODE_RIGHT]) {
xaxis = 86;
}
if (state[SDL_SCANCODE_DOWN]) {
yaxis = -86;
} else if (state[SDL_SCANCODE_UP]) {
yaxis = 86;
}
controller.joy_x = xaxis;
controller.joy_y = yaxis;
if (controller.joy_reset) {
controller.start = false;
controller.joy_x = 0;
controller.joy_y = 0;
}
}
} }
} }

View File

@@ -21,11 +21,10 @@ struct Core {
void Stop(); void Stop();
CartInfo LoadROM(const std::string&); CartInfo LoadROM(const std::string&);
void Run(Window&, float volumeL, float volumeR); void Run(Window&, float volumeL, float volumeR);
void UpdateController(const u8*);
void TogglePause() { pause = !pause; } void TogglePause() { pause = !pause; }
VI& GetVI() { return mem.mmio.vi; } VI& GetVI() { return mem.mmio.vi; }
void CpuReset() { void CpuReset() const {
switch(cpuType) { switch(cpuType) {
case CpuType::Dynarec: cpuDynarec->Reset(); break; case CpuType::Dynarec: cpuDynarec->Reset(); break;
case CpuType::Interpreter: cpuInterp->Reset(); break; case CpuType::Interpreter: cpuInterp->Reset(); break;
@@ -33,7 +32,7 @@ struct Core {
} }
} }
Registers& CpuGetRegs() { [[nodiscard]] Registers& CpuGetRegs() const {
switch(cpuType) { switch(cpuType) {
case CpuType::Dynarec: return cpuDynarec->regs; case CpuType::Dynarec: return cpuDynarec->regs;
case CpuType::Interpreter: return cpuInterp->regs; case CpuType::Interpreter: return cpuInterp->regs;
@@ -43,13 +42,6 @@ struct Core {
} }
static int CpuStep(Core& core) { static int CpuStep(Core& core) {
if (core.debugger.enabled && core.debugger.checkBreakpoint(core.CpuGetRegs().pc)) {
core.debugger.breakpointHit();
}
while (core.debugger.broken) {
SDL_Delay(1);
core.debugger.tick();
}
switch(core.cpuType) { switch(core.cpuType) {
case CpuType::Dynarec: return core.cpuDynarec->Step(core.mem); case CpuType::Dynarec: return core.cpuDynarec->Step(core.mem);
case CpuType::Interpreter: core.cpuInterp->Step(core.mem); return 1; case CpuType::Interpreter: core.cpuInterp->Step(core.mem); return 1;
@@ -63,8 +55,6 @@ struct Core {
bool pause = true; bool pause = true;
bool isPAL = false; bool isPAL = false;
bool romLoaded = false; bool romLoaded = false;
SDL_GameController* gamepad;
bool gamepadConnected = false;
bool done = false; bool done = false;
std::string rom; std::string rom;
Mem mem; Mem mem;

View File

@@ -69,6 +69,7 @@ u8 Mem::Read8(n64::Registers &regs, u32 paddr) {
const auto page = paddr >> 12; const auto page = paddr >> 12;
const auto offset = paddr & 0xFFF; const auto offset = paddr & 0xFFF;
const auto pointer = readPages[page]; const auto pointer = readPages[page];
SI& si = mmio.si;
if(pointer) { if(pointer) {
return ((u8*)pointer)[BYTE_ADDRESS(offset)]; return ((u8*)pointer)[BYTE_ADDRESS(offset)];
@@ -95,9 +96,9 @@ u8 Mem::Read8(n64::Registers &regs, u32 paddr) {
paddr = (paddr + 2) & ~2; paddr = (paddr + 2) & ~2;
return cart[BYTE_ADDRESS(paddr) & romMask]; return cart[BYTE_ADDRESS(paddr) & romMask];
case 0x1FC00000 ... 0x1FC007BF: case 0x1FC00000 ... 0x1FC007BF:
return pifBootrom[BYTE_ADDRESS(paddr) - 0x1FC00000]; return si.pif.pifBootrom[BYTE_ADDRESS(paddr) - 0x1FC00000];
case PIF_RAM_REGION: case PIF_RAM_REGION:
return pifRam[paddr - PIF_RAM_REGION_START]; return si.pif.pifRam[paddr - PIF_RAM_REGION_START];
case 0x00800000 ... 0x03FFFFFF: case 0x00800000 ... 0x03FFFFFF:
case 0x04200000 ... 0x042FFFFF: case 0x04200000 ... 0x042FFFFF:
case 0x04900000 ... 0x0FFFFFFF: case 0x04900000 ... 0x0FFFFFFF:
@@ -113,6 +114,7 @@ u16 Mem::Read16(n64::Registers &regs, u32 paddr) {
const auto page = paddr >> 12; const auto page = paddr >> 12;
const auto offset = paddr & 0xFFF; const auto offset = paddr & 0xFFF;
const auto pointer = readPages[page]; const auto pointer = readPages[page];
SI& si = mmio.si;
if(pointer) { if(pointer) {
return Util::ReadAccess<u16>((u8*)pointer, HALF_ADDRESS(offset)); return Util::ReadAccess<u16>((u8*)pointer, HALF_ADDRESS(offset));
@@ -134,9 +136,9 @@ u16 Mem::Read16(n64::Registers &regs, u32 paddr) {
paddr = (paddr + 2) & ~3; paddr = (paddr + 2) & ~3;
return Util::ReadAccess<u16>(cart, HALF_ADDRESS(paddr) & romMask); return Util::ReadAccess<u16>(cart, HALF_ADDRESS(paddr) & romMask);
case 0x1FC00000 ... 0x1FC007BF: case 0x1FC00000 ... 0x1FC007BF:
return Util::ReadAccess<u16>(pifBootrom, HALF_ADDRESS(paddr) - 0x1FC00000); return Util::ReadAccess<u16>(si.pif.pifBootrom, HALF_ADDRESS(paddr) - 0x1FC00000);
case PIF_RAM_REGION: case PIF_RAM_REGION:
return be16toh(Util::ReadAccess<u16>(pifRam, paddr - PIF_RAM_REGION_START)); return be16toh(Util::ReadAccess<u16>(si.pif.pifRam, paddr - PIF_RAM_REGION_START));
case 0x00800000 ... 0x03FFFFFF: case 0x00800000 ... 0x03FFFFFF:
case 0x04200000 ... 0x042FFFFF: case 0x04200000 ... 0x042FFFFF:
case 0x04900000 ... 0x0FFFFFFF: case 0x04900000 ... 0x0FFFFFFF:
@@ -152,6 +154,7 @@ u32 Mem::Read32(n64::Registers &regs, u32 paddr) {
const auto page = paddr >> 12; const auto page = paddr >> 12;
const auto offset = paddr & 0xFFF; const auto offset = paddr & 0xFFF;
const auto pointer = readPages[page]; const auto pointer = readPages[page];
SI& si = mmio.si;
if(pointer) { if(pointer) {
return Util::ReadAccess<u32>((u8*)pointer, offset); return Util::ReadAccess<u32>((u8*)pointer, offset);
@@ -170,9 +173,9 @@ u32 Mem::Read32(n64::Registers &regs, u32 paddr) {
case 0x10000000 ... 0x1FBFFFFF: case 0x10000000 ... 0x1FBFFFFF:
return Util::ReadAccess<u32>(cart, paddr & romMask); return Util::ReadAccess<u32>(cart, paddr & romMask);
case 0x1FC00000 ... 0x1FC007BF: case 0x1FC00000 ... 0x1FC007BF:
return Util::ReadAccess<u32>(pifBootrom, paddr - 0x1FC00000); return Util::ReadAccess<u32>(si.pif.pifBootrom, paddr - 0x1FC00000);
case PIF_RAM_REGION: case PIF_RAM_REGION:
return be32toh(Util::ReadAccess<u32>(pifRam, paddr - PIF_RAM_REGION_START)); return be32toh(Util::ReadAccess<u32>(si.pif.pifRam, paddr - PIF_RAM_REGION_START));
case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF: case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF:
case 0x04900000 ... 0x0FFFFFFF: case 0x1FC00800 ... 0xFFFFFFFF: return 0; case 0x04900000 ... 0x0FFFFFFF: case 0x1FC00800 ... 0xFFFFFFFF: return 0;
default: default:
@@ -185,6 +188,7 @@ u64 Mem::Read64(n64::Registers &regs, u32 paddr) {
const auto page = paddr >> 12; const auto page = paddr >> 12;
const auto offset = paddr & 0xFFF; const auto offset = paddr & 0xFFF;
const auto pointer = readPages[page]; const auto pointer = readPages[page];
SI& si = mmio.si;
if(pointer) { if(pointer) {
return Util::ReadAccess<u64>((u8*)pointer, offset); return Util::ReadAccess<u64>((u8*)pointer, offset);
@@ -205,9 +209,9 @@ u64 Mem::Read64(n64::Registers &regs, u32 paddr) {
case 0x10000000 ... 0x1FBFFFFF: case 0x10000000 ... 0x1FBFFFFF:
return Util::ReadAccess<u64>(cart, paddr & romMask); return Util::ReadAccess<u64>(cart, paddr & romMask);
case 0x1FC00000 ... 0x1FC007BF: case 0x1FC00000 ... 0x1FC007BF:
return Util::ReadAccess<u64>(pifBootrom, paddr - 0x1FC00000); return Util::ReadAccess<u64>(si.pif.pifBootrom, paddr - 0x1FC00000);
case PIF_RAM_REGION: case PIF_RAM_REGION:
return be64toh(Util::ReadAccess<u64>(pifRam, paddr - PIF_RAM_REGION_START)); return be64toh(Util::ReadAccess<u64>(si.pif.pifRam, paddr - PIF_RAM_REGION_START));
case 0x00800000 ... 0x03FFFFFF: case 0x00800000 ... 0x03FFFFFF:
case 0x04200000 ... 0x042FFFFF: case 0x04200000 ... 0x042FFFFF:
case 0x04900000 ... 0x0FFFFFFF: case 0x04900000 ... 0x0FFFFFFF:
@@ -243,6 +247,7 @@ void Mem::Write8(Registers& regs, u32 paddr, u32 val) {
const auto page = paddr >> 12; const auto page = paddr >> 12;
auto offset = paddr & 0xFFF; auto offset = paddr & 0xFFF;
const auto pointer = writePages[page]; const auto pointer = writePages[page];
SI& si = mmio.si;
if(pointer) { if(pointer) {
((u8*)pointer)[BYTE_ADDRESS(offset)] = val; ((u8*)pointer)[BYTE_ADDRESS(offset)] = val;
@@ -269,8 +274,8 @@ void Mem::Write8(Registers& regs, u32 paddr, u32 val) {
case PIF_RAM_REGION: case PIF_RAM_REGION:
val = val << (8 * (3 - (paddr & 3))); val = val << (8 * (3 - (paddr & 3)));
paddr = (paddr - PIF_RAM_REGION_START) & ~3; paddr = (paddr - PIF_RAM_REGION_START) & ~3;
Util::WriteAccess<u32>(pifRam, paddr, htobe32(val)); Util::WriteAccess<u32>(si.pif.pifRam, paddr, htobe32(val));
ProcessPIFCommands(pifRam, mmio.si.controller, *this); si.pif.ProcessPIFCommands(*this);
break; break;
case 0x00800000 ... 0x03FFFFFF: case 0x00800000 ... 0x03FFFFFF:
case 0x04200000 ... 0x042FFFFF: case 0x04200000 ... 0x042FFFFF:
@@ -290,6 +295,7 @@ void Mem::Write16(Registers& regs, u32 paddr, u32 val) {
const auto page = paddr >> 12; const auto page = paddr >> 12;
auto offset = paddr & 0xFFF; auto offset = paddr & 0xFFF;
const auto pointer = writePages[page]; const auto pointer = writePages[page];
SI& si = mmio.si;
if(pointer) { if(pointer) {
Util::WriteAccess<u16>((u8*)pointer, HALF_ADDRESS(offset), val); Util::WriteAccess<u16>((u8*)pointer, HALF_ADDRESS(offset), val);
@@ -316,8 +322,8 @@ void Mem::Write16(Registers& regs, u32 paddr, u32 val) {
case PIF_RAM_REGION: case PIF_RAM_REGION:
val = val << (16 * !(paddr & 2)); val = val << (16 * !(paddr & 2));
paddr &= ~3; paddr &= ~3;
Util::WriteAccess<u32>(pifRam, paddr - PIF_RAM_REGION_START, htobe32(val)); Util::WriteAccess<u32>(si.pif.pifRam, paddr - PIF_RAM_REGION_START, htobe32(val));
ProcessPIFCommands(pifRam, mmio.si.controller, *this); si.pif.ProcessPIFCommands(*this);
break; break;
case 0x00800000 ... 0x03FFFFFF: case 0x00800000 ... 0x03FFFFFF:
case 0x04200000 ... 0x042FFFFF: case 0x04200000 ... 0x042FFFFF:
@@ -337,6 +343,7 @@ void Mem::Write32(Registers& regs, u32 paddr, u32 val) {
const auto page = paddr >> 12; const auto page = paddr >> 12;
auto offset = paddr & 0xFFF; auto offset = paddr & 0xFFF;
const auto pointer = writePages[page]; const auto pointer = writePages[page];
SI& si = mmio.si;
if(pointer) { if(pointer) {
Util::WriteAccess<u32>((u8*)pointer, offset, val); Util::WriteAccess<u32>((u8*)pointer, offset, val);
@@ -367,8 +374,8 @@ void Mem::Write32(Registers& regs, u32 paddr, u32 val) {
break; break;
case 0x14000000 ... 0x1FBFFFFF: break; case 0x14000000 ... 0x1FBFFFFF: break;
case PIF_RAM_REGION: case PIF_RAM_REGION:
Util::WriteAccess<u32>(pifRam, paddr - PIF_RAM_REGION_START, htobe32(val)); Util::WriteAccess<u32>(si.pif.pifRam, paddr - PIF_RAM_REGION_START, htobe32(val));
ProcessPIFCommands(pifRam, mmio.si.controller, *this); si.pif.ProcessPIFCommands(*this);
break; break;
case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF: case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF:
case 0x08000000 ... 0x0FFFFFFF: case 0x04900000 ... 0x07FFFFFF: case 0x08000000 ... 0x0FFFFFFF: case 0x04900000 ... 0x07FFFFFF:
@@ -382,6 +389,7 @@ void Mem::Write64(Registers& regs, u32 paddr, u64 val) {
const auto page = paddr >> 12; const auto page = paddr >> 12;
auto offset = paddr & 0xFFF; auto offset = paddr & 0xFFF;
const auto pointer = writePages[page]; const auto pointer = writePages[page];
SI& si = mmio.si;
if(pointer) { if(pointer) {
Util::WriteAccess<u64>((u8*)pointer, offset, val); Util::WriteAccess<u64>((u8*)pointer, offset, val);
@@ -405,8 +413,8 @@ void Mem::Write64(Registers& regs, u32 paddr, u64 val) {
case 0x10000000 ... 0x1FBFFFFF: case 0x10000000 ... 0x1FBFFFFF:
break; break;
case PIF_RAM_REGION: case PIF_RAM_REGION:
Util::WriteAccess<u64>(pifRam, paddr - PIF_RAM_REGION_START, htobe64(val)); Util::WriteAccess<u64>(si.pif.pifRam, paddr - PIF_RAM_REGION_START, htobe64(val));
ProcessPIFCommands(pifRam, mmio.si.controller, *this); si.pif.ProcessPIFCommands(*this);
break; break;
case 0x00800000 ... 0x03FFFFFF: case 0x00800000 ... 0x03FFFFFF:
case 0x04200000 ... 0x042FFFFF: case 0x04200000 ... 0x042FFFFF:

View File

@@ -44,7 +44,6 @@ struct Mem {
void Write64(Registers&, u32, u64); void Write64(Registers&, u32, u64);
MMIO mmio; MMIO mmio;
u8 pifRam[PIF_RAM_SIZE]{};
inline void DumpRDRAM() const { inline void DumpRDRAM() const {
FILE *fp = fopen("rdram.dump", "wb"); FILE *fp = fopen("rdram.dump", "wb");
@@ -83,7 +82,6 @@ private:
friend struct RSP; friend struct RSP;
friend struct Core; friend struct Core;
u8* sram, *cart; u8* sram, *cart;
u8 pifBootrom[PIF_BOOTROM_SIZE]{};
u8 isviewer[ISVIEWER_SIZE]{}; u8 isviewer[ISVIEWER_SIZE]{};
size_t romMask = 0; size_t romMask = 0;
@@ -119,12 +117,6 @@ private:
return std::any_of(std::begin(pal_codes), std::end(pal_codes), [this](char a) { return std::any_of(std::begin(pal_codes), std::end(pal_codes), [this](char a) {
return cart[0x3e] == a; return cart[0x3e] == a;
}); });
// for (char pal_code : pal_codes) {
// if (cart[0x3e] == pal_code) {
// return true;
// }
// }
// return false;
} }
}; };
} }

View File

@@ -33,6 +33,7 @@ void RSP::Reset() {
divInLoaded = false; divInLoaded = false;
} }
/*
inline void logRSP(const RSP& rsp, const u32 instr) { inline void logRSP(const RSP& rsp, const u32 instr) {
Util::print("{:04X} {:08X} ", rsp.oldPC, instr); Util::print("{:04X} {:08X} ", rsp.oldPC, instr);
for (auto gpr : rsp.gpr) { for (auto gpr : rsp.gpr) {
@@ -63,6 +64,7 @@ inline void logRSP(const RSP& rsp, const u32 instr) {
Util::print(" {:04X} {:04X} {:02X}\n", rsp.GetVCC(), rsp.GetVCO(), rsp.GetVCE()); Util::print(" {:04X} {:04X} {:02X}\n", rsp.GetVCC(), rsp.GetVCO(), rsp.GetVCE());
Util::print("DMEM: {:02X}{:02X}\n", rsp.dmem[0x3c4], rsp.dmem[0x3c5]); Util::print("DMEM: {:02X}{:02X}\n", rsp.dmem[0x3c4], rsp.dmem[0x3c5]);
} }
*/
void RSP::Step(Registers& regs, Mem& mem) { void RSP::Step(Registers& regs, Mem& mem) {
gpr[0] = 0; gpr[0] = 0;

View File

@@ -3,11 +3,12 @@
#include <core/registers/Registers.hpp> #include <core/registers/Registers.hpp>
#include <log.hpp> #include <log.hpp>
#include <MupenMovie.hpp> #include <MupenMovie.hpp>
#include <SDL_keyboard.h>
namespace n64 { namespace n64 {
static int channel = 0; static int channel = 0;
void ProcessPIFCommands(u8* pifRam, Controller& controller, Mem& mem) { void PIF::ProcessPIFCommands(Mem& mem) {
u8 control = pifRam[63]; u8 control = pifRam[63];
if(control & 1) { if(control & 1) {
@@ -46,6 +47,8 @@ void ProcessPIFCommands(u8* pifRam, Controller& controller, Mem& mem) {
case 1: case 1:
if(tas_movie_loaded()) { if(tas_movie_loaded()) {
controller = tas_next_inputs(); controller = tas_next_inputs();
} else {
UpdateController();
} }
res[0] = controller.byte1; res[0] = controller.byte1;
res[1] = controller.byte2; res[1] = controller.byte2;
@@ -70,7 +73,97 @@ void ProcessPIFCommands(u8* pifRam, Controller& controller, Mem& mem) {
} }
} }
void DoPIFHLE(Mem& mem, Registers& regs, CartInfo cartInfo) { #define GET_BUTTON(gamepad, i) SDL_GameControllerGetButton(gamepad, i)
#define GET_AXIS(gamepad, axis) SDL_GameControllerGetAxis(gamepad, axis)
void PIF::UpdateController() {
const uint8_t* state = SDL_GetKeyboardState(nullptr);
s8 xaxis = 0, yaxis = 0;
if(gamepadConnected) {
bool A = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_A);
bool B = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_X);
bool Z = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_TRIGGERLEFT) == 32767;
bool START = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_START);
bool DUP = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_DPAD_UP);
bool DDOWN = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_DPAD_DOWN);
bool DLEFT = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
bool DRIGHT = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
bool L = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
bool R = GET_BUTTON(gamepad, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
bool CUP = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_RIGHTY) <= -128;
bool CDOWN = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_RIGHTY) >= 127;
bool CLEFT = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_RIGHTX) <= -128;
bool CRIGHT = GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_RIGHTX) >= 127;
controller.a = A;
controller.b = B;
controller.z = Z;
controller.start = START;
controller.dp_up = DUP;
controller.dp_down = DDOWN;
controller.dp_left = DLEFT;
controller.dp_right = DRIGHT;
controller.joy_reset = L && R && START;
controller.l = L;
controller.r = R;
controller.c_up = CUP;
controller.c_down = CDOWN;
controller.c_left = CLEFT;
controller.c_right = CRIGHT;
xaxis = (s8) std::clamp((GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_LEFTX) >> 8), -86, 86);
yaxis = (s8) std::clamp(-(GET_AXIS(gamepad, SDL_CONTROLLER_AXIS_LEFTY) >> 8), -86, 86);
controller.joy_x = xaxis;
controller.joy_y = yaxis;
if (controller.joy_reset) {
controller.start = false;
controller.joy_x = 0;
controller.joy_y = 0;
}
} else {
controller.a = state[SDL_SCANCODE_X];
controller.b = state[SDL_SCANCODE_C];
controller.z = state[SDL_SCANCODE_Z];
controller.start = state[SDL_SCANCODE_RETURN];
controller.dp_up = state[SDL_SCANCODE_KP_8];
controller.dp_down = state[SDL_SCANCODE_KP_5];
controller.dp_left = state[SDL_SCANCODE_KP_4];
controller.dp_right = state[SDL_SCANCODE_KP_6];
controller.joy_reset = state[SDL_SCANCODE_RETURN] && state[SDL_SCANCODE_A] && state[SDL_SCANCODE_S];
controller.l = state[SDL_SCANCODE_A];
controller.r = state[SDL_SCANCODE_S];
controller.c_up = state[SDL_SCANCODE_I];
controller.c_down = state[SDL_SCANCODE_J];
controller.c_left = state[SDL_SCANCODE_K];
controller.c_right = state[SDL_SCANCODE_L];
if (state[SDL_SCANCODE_LEFT]) {
xaxis = -86;
} else if (state[SDL_SCANCODE_RIGHT]) {
xaxis = 86;
}
if (state[SDL_SCANCODE_DOWN]) {
yaxis = -86;
} else if (state[SDL_SCANCODE_UP]) {
yaxis = 86;
}
controller.joy_x = xaxis;
controller.joy_y = yaxis;
if (controller.joy_reset) {
controller.start = false;
controller.joy_x = 0;
controller.joy_y = 0;
}
}
}
void PIF::DoPIFHLE(Mem& mem, Registers& regs, CartInfo cartInfo) {
u32 cicType = cartInfo.cicType; u32 cicType = cartInfo.cicType;
bool pal = cartInfo.isPAL; bool pal = cartInfo.isPAL;
mem.Write32(regs, PIF_RAM_REGION_START + 0x24, cicSeeds[cicType]); mem.Write32(regs, PIF_RAM_REGION_START + 0x24, cicSeeds[cicType]);
@@ -336,7 +429,7 @@ void DoPIFHLE(Mem& mem, Registers& regs, CartInfo cartInfo) {
regs.SetPC32(0xA4000040); regs.SetPC32(0xA4000040);
} }
void ExecutePIF(Mem& mem, Registers& regs, CartInfo cartInfo) { void PIF::ExecutePIF(Mem& mem, Registers& regs, CartInfo cartInfo) {
u32 cicType = cartInfo.cicType; u32 cicType = cartInfo.cicType;
bool pal = cartInfo.isPAL; bool pal = cartInfo.isPAL;
mem.Write32(regs, PIF_RAM_REGION_START + 0x24, cicSeeds[cicType]); mem.Write32(regs, PIF_RAM_REGION_START + 0x24, cicSeeds[cicType]);

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include <common.hpp> #include <MemoryRegions.hpp>
#include <SDL_gamecontroller.h>
namespace n64 { namespace n64 {
@@ -61,6 +62,14 @@ enum CICType {
struct CartInfo; struct CartInfo;
void ProcessPIFCommands(u8*, Controller&, Mem&); struct PIF {
void ExecutePIF(Mem& mem, Registers& regs, CartInfo cartInfo); void ProcessPIFCommands(Mem&);
void ExecutePIF(Mem& mem, Registers& regs, CartInfo cartInfo);
void DoPIFHLE(Mem& mem, Registers& regs, CartInfo cartInfo);
void UpdateController();
bool gamepadConnected = false;
SDL_GameController* gamepad;
Controller controller;
u8 pifBootrom[PIF_BOOTROM_SIZE]{}, pifRam[PIF_RAM_SIZE];
};
} }

View File

@@ -33,20 +33,19 @@ auto SI::Read(MI& mi, u32 addr) const -> u32 {
} }
void DMA(Mem& mem, Registers& regs) { void DMA(Mem& mem, Registers& regs) {
MMIO& mmio = mem.mmio; SI& si = mem.mmio.si;
SI& si = mmio.si;
si.status.dmaBusy = false; si.status.dmaBusy = false;
if(si.toDram) { if(si.toDram) {
ProcessPIFCommands(mem.pifRam, si.controller, mem); si.pif.ProcessPIFCommands(mem);
for(int i = 0; i < 64; i++) { for(int i = 0; i < 64; i++) {
mem.mmio.rdp.rdram[BYTE_ADDRESS(si.dramAddr + i)] = mem.pifRam[i]; mem.mmio.rdp.rdram[BYTE_ADDRESS(si.dramAddr + i)] = si.pif.pifRam[i];
} }
} else { } else {
for(int i = 0; i < 64; i++) { for(int i = 0; i < 64; i++) {
mem.pifRam[i] = mem.mmio.rdp.rdram[BYTE_ADDRESS(si.dramAddr + i)]; si.pif.pifRam[i] = mem.mmio.rdp.rdram[BYTE_ADDRESS(si.dramAddr + i)];
} }
Util::debug("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})\n", si.pifAddr, si.dramAddr); Util::debug("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})\n", si.pifAddr, si.dramAddr);
ProcessPIFCommands(mem.pifRam, si.controller, mem); si.pif.ProcessPIFCommands(mem);
} }
InterruptRaise(mem.mmio.mi, regs, Interrupt::SI); InterruptRaise(mem.mmio.mi, regs, Interrupt::SI);
} }

View File

@@ -32,6 +32,7 @@ struct SI {
auto Read(MI&, u32) const -> u32; auto Read(MI&, u32) const -> u32;
void Write(Mem&, Registers&, u32, u32); void Write(Mem&, Registers&, u32, u32);
PIF pif;
}; };
static void DMA(Mem& mem, Registers& regs); static void DMA(Mem& mem, Registers& regs);

View File

@@ -8,12 +8,11 @@ App::App() : window(core) {
} }
void App::Run() { void App::Run() {
const u8* state = SDL_GetKeyboardState(nullptr);
SDL_EventState(SDL_DROPFILE, SDL_ENABLE); SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
n64::SI& si = core.mem.mmio.si;
while (!core.done) { while (!core.done) {
core.Run(window, window.settings.GetVolumeL(), window.settings.GetVolumeL()); core.Run(window, window.settings.GetVolumeL(), window.settings.GetVolumeL());
core.UpdateController(state);
SDL_Event event; SDL_Event event;
while (SDL_PollEvent(&event)) { while (SDL_PollEvent(&event)) {
@@ -27,12 +26,12 @@ void App::Run() {
break; break;
case SDL_CONTROLLERDEVICEADDED: { case SDL_CONTROLLERDEVICEADDED: {
const int index = event.cdevice.which; const int index = event.cdevice.which;
core.gamepad = SDL_GameControllerOpen(index); si.pif.gamepad = SDL_GameControllerOpen(index);
core.gamepadConnected = true; si.pif.gamepadConnected = true;
} break; } break;
case SDL_CONTROLLERDEVICEREMOVED: case SDL_CONTROLLERDEVICEREMOVED:
SDL_GameControllerClose(core.gamepad); SDL_GameControllerClose(si.pif.gamepad);
core.gamepadConnected = false; si.pif.gamepadConnected = false;
break; break;
case SDL_KEYDOWN: case SDL_KEYDOWN:
switch(event.key.keysym.sym) { switch(event.key.keysym.sym) {

View File

@@ -67,8 +67,12 @@ Settings::Settings(n64::Core& core) {
settingsFile.close(); settingsFile.close();
switch(core.cpuType) { switch(core.cpuType) {
case n64::CpuType::Interpreter: core.cpuInterp = new n64::Interpreter; break; case n64::CpuType::Interpreter:
case n64::CpuType::Dynarec: core.cpuDynarec = new n64::JIT::Dynarec; break; core.cpuInterp = new n64::Interpreter;
break;
case n64::CpuType::Dynarec:
core.cpuDynarec = new n64::JIT::Dynarec;
break;
case n64::CpuType::NONE: case n64::CpuType::NONE:
Util::panic("BRUH\n"); Util::panic("BRUH\n");
} }