fix pads, start RSP

This commit is contained in:
CocoSimone
2022-09-10 01:05:46 +02:00
parent 0b5a9ba0e7
commit 645a20931a
16 changed files with 131 additions and 78 deletions

View File

@@ -6,6 +6,9 @@ void App::Run() {
// Main loop
const u8* state = SDL_GetKeyboardState(nullptr);
while (!core.done) {
core.Run(window);
core.UpdateController(state);
SDL_Event event;
while (SDL_PollEvent(&event)) {
ImGui_ImplSDL2_ProcessEvent(&event);
@@ -36,10 +39,6 @@ void App::Run() {
} break;
} break;
}
core.UpdateController(state);
}
core.Run(window);
}
}

View File

@@ -3,6 +3,7 @@
#include <nfd.hpp>
#include <Core.hpp>
#include <utility>
#include <Audio.hpp>
VkInstance instance{};
@@ -20,6 +21,8 @@ Window::Window(n64::Core& core) {
void Window::InitSDL() {
SDL_Init(SDL_INIT_EVERYTHING);
n64::InitAudio();
window = SDL_CreateWindow(
"natsukashii",
SDL_WINDOWPOS_CENTERED,

View File

@@ -38,6 +38,7 @@ void Core::LoadROM(const std::string& rom_) {
void Core::Run(Window& window) {
MMIO& mmio = mem.mmio;
Controller& controller = mmio.si.controller;
int cycles = 0;
for(int field = 0; field < mmio.vi.numFields; field++) {
int frameCycles = 0;
@@ -56,7 +57,7 @@ void Core::Run(Window& window) {
mmio.rsp.Step(mmio.mi, cpu.regs, mmio.rdp);
mmio.rsp.Step(mmio.mi, cpu.regs, mmio.rdp);
//mmio.ai.Step(mem, cpu.regs, 1);
mmio.ai.Step(mem, cpu.regs, 1);
}
cycles -= mmio.vi.cyclesPerHalfline;
@@ -69,7 +70,7 @@ void Core::Run(Window& window) {
UpdateScreenParallelRdp(*this, window, GetVI());
int missedCycles = N64_CYCLES_PER_FRAME - frameCycles;
//mmio.ai.Step(mem, cpu.regs, missedCycles);
mmio.ai.Step(mem, cpu.regs, missedCycles);
} else if(pause && romLoaded) {
UpdateScreenParallelRdp(*this, window, GetVI());
} else if(pause && !romLoaded) {

View File

@@ -12,7 +12,7 @@ static SDL_AudioStream* audioStream = nullptr;
SDL_mutex* audioStreamMutex;
SDL_AudioSpec audioSpec;
SDL_AudioSpec request;
SDL_AudioDeviceID audioDev;
SDL_AudioDeviceID audioDev{};
#define LockAudioMutex() SDL_LockMutex(audioStreamMutex)
#define UnlockAudioMutex() SDL_UnlockMutex(audioStreamMutex)
@@ -48,7 +48,9 @@ void InitAudio() {
request.callback = audioCallback;
request.userdata = nullptr;
audioDev = SDL_OpenAudioDevice(nullptr, 0, &request, &audioSpec, 0);
if(!audioDev) {
audioDev = SDL_OpenAudioDevice(nullptr, 0, &request, &audioSpec, 0);
}
if(!audioDev) {
util::panic("Failed to initialize SDL Audio: {}", SDL_GetError());

View File

@@ -59,8 +59,12 @@ void FireException(Registers& regs, ExceptionCode code, int cop, s64 pc) {
util::panic("BEV bit set!\n");
} else {
switch(code) {
case Interrupt ... TLBModification:
case AddressErrorLoad ... Trap:
case Interrupt: case TLBModification:
case AddressErrorLoad: case AddressErrorStore:
case InstructionBusError: case DataBusError:
case Syscall: case Breakpoint:
case ReservedInstruction: case CoprocessorUnusable:
case Overflow: case Trap:
case FloatingPointError: case Watch:
regs.SetPC(s64(s32(0x80000180)));
break;

View File

@@ -7,16 +7,16 @@
namespace n64 {
struct Cpu {
Cpu() {
log = fopen("disasm.txt", "w");
if(cs_open(CS_ARCH_MIPS, CS_MODE_MIPS64, &handle) != CS_ERR_OK) {
util::panic("Could not initialize capstone!\n");
}
//log = fopen("disasm.txt", "w");
//if(cs_open(CS_ARCH_MIPS, CS_MODE_MIPS64, &handle) != CS_ERR_OK) {
// util::panic("Could not initialize capstone!\n");
//}
Reset();
}
~Cpu() {
fclose(log);
cs_close(&handle);
//fclose(log);
//cs_close(&handle);
}
void Reset();
void Step(Mem&);

View File

@@ -33,8 +33,8 @@ void RSP::Step(MI& mi, Registers& regs, RDP& rdp) {
if(!spStatus.halt) {
gpr[0] = 0;
u32 instr = util::ReadAccess<u32>(imem, pc & IMEM_DSIZE);
oldPC = pc & 0xFFF;
pc = nextPC & 0xFFF;
oldPC = pc & 0xFFC;
pc = nextPC & 0xFFC;
nextPC += 4;
Exec(mi, regs, rdp, instr);
}
@@ -120,7 +120,7 @@ void RSP::Write(Mem& mem, Registers& regs, u32 addr, u32 value) {
if(spStatus.halt) {
oldPC = pc;
pc = nextPC;
nextPC = value & 0xFFF;
nextPC = value & 0xFFC;
} break;
default: util::panic("Unimplemented SP register write {:08X}, val: {:08X}\n", addr, value);
}

View File

@@ -3,6 +3,12 @@
#include <n64/core/RDP.hpp>
#include <n64/memory_regions.hpp>
#define RSP_BYTE(addr) (dmem[BYTE_ADDRESS(addr) & 0xfff])
#define GET_RSP_HALF(addr) ((RSP_BYTE(addr) << 8) | RSP_BYTE((addr) + 1))
#define SET_RSP_HALF(addr, value) do { RSP_BYTE(addr) = ((value) >> 8) & 0xFF; RSP_BYTE((addr) + 1) = (value) & 0xFF;} while(0)
#define GET_RSP_WORD(addr) ((GET_RSP_HALF(addr) << 16) | GET_RSP_HALF((addr) + 2))
#define SET_RSP_WORD(addr, value) do { SET_RSP_HALF(addr, ((value) >> 16) & 0xFFFF); SET_RSP_HALF((addr) + 2, (value) & 0xFFFF);} while(0)
namespace n64 {
union SPStatus {
u32 raw;
@@ -154,6 +160,30 @@ struct RSP {
return val;
}
inline u32 ReadWord(u32 addr) {
return GET_RSP_WORD(addr);
}
inline void WriteWord(u32 addr, u32 val) {
SET_RSP_WORD(addr, val);
}
inline u16 ReadHalf(u32 addr) {
return GET_RSP_HALF(addr);
}
inline void WriteHalf(u32 addr, u16 val) {
SET_RSP_HALF(addr, val);
}
inline u8 ReadByte(u32 addr) {
return GET_RSP_WORD(addr);
}
inline void WriteByte(u32 addr, u8 val) {
SET_RSP_WORD(addr, val);
}
void add(u32 instr);
void addi(u32 instr);
void and_(u32 instr);

View File

@@ -11,9 +11,7 @@ Cop0::Cop0() {
void Cop0::Reset() {
cause.raw = 0xB000007C;
status.raw = 0x241000E0;
wired = 64;
index = 64;
PRId = 0x00000B00;
PRId = 0x00000B22;
Config = 0x7006E463;
EPC = 0xFFFFFFFFFFFFFFFF;
ErrorEPC = 0xFFFFFFFFFFFFFFFF;

View File

@@ -72,8 +72,8 @@ void AI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
}
}
void AI::Step(Mem& mem, Registers& regs, int) {
cycles += cycles;
void AI::Step(Mem& mem, Registers& regs, int cpuCycles) {
cycles += cpuCycles;
while(cycles > dac.period) {
if (dmaCount == 0) {
return;

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 rdram to cart (size: {:.2f} MiB)\n", (float)len / 1048576);
//util::logdebug("PI DMA from RDP RAM 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 cart to rdram (size: {:.2f} MiB)\n", (float)len / 1048576);
//util::logdebug("PI DMA from CARTRIDGE to RDP RAM (size: {} KiB, {:08X} to {:08X})\n", len, cartAddr, dramAddr);
} break;
case 0x04600010:
if(val & 2) {

View File

@@ -65,7 +65,7 @@ void ProcessPIFCommands(u8* pifRam, Controller& controller, Mem& mem) {
pifRam[63] = 128;
}
//mem->pif_ram[63] &= ~1;
//pifRam[63] &= ~1;
}
}

View File

@@ -34,23 +34,29 @@ void SI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
dramAddr = val;
break;
case 0x04800004: {
// if(!(status.raw & 3)) {
ProcessPIFCommands(mem.pifRam, controller, mem);
if(!(status.raw & 3)) {
ProcessPIFCommands(mem.pifRam, controller, mem);
u8 pifAddr = (val & 0x7FC) & PIF_RAM_DSIZE;
memcpy(&mem.mmio.rdp.dram[dramAddr & RDRAM_DSIZE],
&mem.pifRam[pifAddr], 64);
InterruptRaise(mem.mmio.mi, regs, Interrupt::SI);
status.intr = 1;
pifAddr = (val & 0x7FC) & PIF_RAM_DSIZE;
for(int i = 0; i < 64; i++) {
mem.mmio.rdp.dram[BYTE_ADDRESS(dramAddr + i) & RDRAM_DSIZE] = mem.pifRam[pifAddr + i];
}
InterruptRaise(mem.mmio.mi, regs, Interrupt::SI);
status.intr = 1;
//util::logdebug("SI DMA from PIF RAM to RDP RAM ({:08X} to {:08X})\n", pifAddr, dramAddr);
}
} break;
case 0x04800010: {
//if(!(status.raw & 3)) {
u8 pifAddr = (val & 0x7FC) & PIF_RAM_DSIZE;
memcpy(&mem.pifRam[pifAddr],
&mem.mmio.rdp.dram[dramAddr & RDRAM_DSIZE], 64);
ProcessPIFCommands(mem.pifRam, controller, mem);
InterruptRaise(mem.mmio.mi, regs, Interrupt::SI);
status.intr = 1;
if(!(status.raw & 3)) {
pifAddr = (val & 0x7FC) & PIF_RAM_DSIZE;
for(int i = 0; i < 64; i++) {
mem.pifRam[pifAddr + i] = mem.mmio.rdp.dram[BYTE_ADDRESS(dramAddr + i) & RDRAM_DSIZE];
}
ProcessPIFCommands(mem.pifRam, controller, mem);
InterruptRaise(mem.mmio.mi, regs, Interrupt::SI);
status.intr = 1;
//util::logdebug("SI DMA from RDP RAM to PIF RAM ({:08X} to {:08X})\n", dramAddr, pifAddr);
}
} break;
case 0x04800018:
InterruptLower(mem.mmio.mi, regs, Interrupt::SI);

View File

@@ -25,6 +25,7 @@ struct SI {
void Reset();
SIStatus status{};
u32 dramAddr{};
u32 pifAddr{};
Controller controller{};
auto Read(MI&, u32) const -> u32;

View File

@@ -1,26 +1,30 @@
#include <n64/core/RSP.hpp>
#include <util.hpp>
#include <n64/core/cpu/Registers.hpp>
#include <Interrupt.hpp>
namespace n64 {
inline void special(RSP& rsp, u32 instr) {
inline void special(MI& mi, Registers& regs, RSP& rsp, u32 instr) {
u8 mask = instr & 0x3f;
switch(mask) {
//case 0x00: rsp.sll(instr); break;
//case 0x04: rsp.sllv(instr); break;
case 0x00: rsp.sll(instr); break;
case 0x04: rsp.sllv(instr); break;
//case 0x08: rsp.jr(instr); break;
//case 0x0C:
//case 0x0D:
// rsp.spStatus.halt = true;
// rsp.spStatus.broke = true;
// break;
case 0x0C:
case 0x0D:
rsp.spStatus.halt = true;
rsp.spStatus.broke = true;
if(rsp.spStatus.interruptOnBreak) {
InterruptRaise(mi, regs, Interrupt::SP);
}
break;
//case 0x20: case 0x21:
// rsp.add(instr);
// break;
//case 0x24: rsp.and_(instr); break;
//case 0x25: rsp.or_(instr); break;
case 0x24: rsp.and_(instr); break;
case 0x25: rsp.or_(instr); break;
//case 0x27: rsp.nor(instr); break;
default: util::panic("Unhandled RSP special instruction {} {}\n", (mask >> 3) & 7, mask & 7);
default: util::panic("Unhandled RSP special instruction ({:06b})\n", mask);
}
}
@@ -56,7 +60,7 @@ inline void cop2(RSP& rsp, u32 instr) {
case 0x00:
switch(mask_sub) {
//case 0x02: rsp.cfc2(instr); break;
default: util::panic("Unhandled RSP COP2 sub {} {}\n", (mask_sub >> 3) & 3, mask_sub & 3);
default: util::panic("Unhandled RSP COP2 sub ({:06b})\n", mask_sub);
}
break;
//case 0x13: rsp.vabs(instr); break;
@@ -64,40 +68,40 @@ inline void cop2(RSP& rsp, u32 instr) {
//case 0x21: rsp.veq(instr); break;
//case 0x22: rsp.vne(instr); break;
//case 0x33: rsp.vmov(instr); break;
default: util::panic("Unhandled RSP COP2 {} {}\n", (mask >> 3) & 7, mask & 7);
default: util::panic("Unhandled RSP COP2 ({:06b})\n", mask);
}
}
inline void cop0(MI& mi, Registers& regs, RSP& rsp, RDP& rdp, u32 instr) {
u8 mask = (instr >> 21) & 0x1F;
switch(mask) {
//case 0x00: rsp.mfc0(rdp, instr); break;
//case 0x04: rsp.mtc0(mi, regs, rdp, instr); break;
default: util::panic("Unhandled RSP COP0 {} {}\n", (mask >> 3) & 3, mask & 7);
case 0x00: rsp.mfc0(rdp, instr); break;
case 0x04: rsp.mtc0(mi, regs, rdp, instr); break;
default: util::panic("Unhandled RSP COP0 ({:06b})\n", mask);
}
}
void RSP::Exec(MI &mi, Registers &regs, RDP &rdp, u32 instr) {
u8 mask = (instr >> 26) & 0x3F;
switch(mask) {
//case 0x00: special(*this, instr); break;
case 0x00: special(mi, regs, *this, instr); break;
case 0x01: regimm(*this, instr); break;
case 0x02: j(instr); break;
//case 0x03: jal(instr); break;
//case 0x04: b(instr, gpr[RT(instr)] == gpr[RS(instr)]); break;
//case 0x05: b(instr, gpr[RT(instr)] != gpr[RS(instr)]); break;
//case 0x07: b(instr, gpr[RS(instr)] > 0); break;
case 0x03: jal(instr); break;
case 0x04: b(instr, gpr[RT(instr)] == gpr[RS(instr)]); break;
case 0x05: b(instr, gpr[RT(instr)] != gpr[RS(instr)]); break;
case 0x07: b(instr, gpr[RS(instr)] > 0); break;
case 0x08: case 0x09: addi(instr); break;
//case 0x0C: andi(instr); break;
case 0x0C: andi(instr); break;
case 0x0D: ori(instr); break;
//case 0x0F: lui(instr); break;
//case 0x10: cop0(mi, regs, *this, rdp, instr); break;
case 0x0F: lui(instr); break;
case 0x10: cop0(mi, regs, *this, rdp, instr); break;
//case 0x12: cop2(*this, instr); break;
//case 0x21: lh(instr); break;
//case 0x23: lw(instr); break;
case 0x23: lw(instr); break;
//case 0x28: sb(instr); break;
//case 0x29: sh(instr); break;
//case 0x2B: sw(instr); break;
case 0x2B: sw(instr); break;
//case 0x32: lwc2(*this, instr); break;
//case 0x3A: swc2(*this, instr); break;
default: util::panic("Unhandled RSP instruction ({:06b})\n", mask);

View File

@@ -98,11 +98,11 @@ void RSP::addi(u32 instr) {
}
void RSP::and_(u32 instr) {
gpr[RD(instr)] = gpr[RT(instr)] & gpr[RS(instr)];
}
void RSP::andi(u32 instr) {
gpr[RT(instr)] = gpr[RS(instr)] & (u16)instr;
}
void RSP::cfc2(u32 instr) {
@@ -119,11 +119,13 @@ void RSP::lh(u32 instr) {
}
void RSP::lw(u32 instr) {
u32 address = gpr[BASE(instr)] + (s16)instr;
gpr[RT(instr)] = ReadWord(address);
}
void RSP::lui(u32 instr) {
u32 imm = ((u16)instr) << 16;
gpr[RT(instr)] = imm;
}
void RSP::lqv(u32 instr) {
@@ -136,7 +138,8 @@ void RSP::j(u32 instr) {
}
void RSP::jal(u32 instr) {
gpr[31] = nextPC;
j(instr);
}
void RSP::jr(u32 instr) {
@@ -147,15 +150,15 @@ void RSP::nor(u32 instr) {
}
void RSP::or_(u32 instr) {
}
void RSP::ori(u32 instr) {
s16 imm = instr;
gpr[RT(instr)] = imm | gpr[RS(instr)];
}
void RSP::or_(u32 instr) {
gpr[RD(instr)] = gpr[RT(instr)] | gpr[RS(instr)];
}
void RSP::sb(u32 instr) {
}
@@ -165,7 +168,8 @@ void RSP::sh(u32 instr) {
}
void RSP::sw(u32 instr) {
u32 address = gpr[BASE(instr)] + (s16)instr;
WriteWord(address, gpr[RT(instr)]);
}
void RSP::sqv(u32 instr) {
@@ -178,7 +182,8 @@ void RSP::sllv(u32 instr) {
}
void RSP::sll(u32 instr) {
u8 sa = (instr >> 6) & 0x1f;
gpr[RD(instr)] = gpr[RT(instr)] << sa;
}
void RSP::vabs(u32 instr) {