preliminary dynarec work

This commit is contained in:
CocoSimone
2022-10-30 16:50:43 +01:00
parent 1265279069
commit 35b4d5ab9e
35 changed files with 6727 additions and 153 deletions

View File

@@ -25,21 +25,20 @@ add_executable(natsukashii
${FRONTEND_HEADERS}
main.cpp
common.hpp
util.hpp
n64/Scheduler.cpp
n64/Scheduler.hpp)
util.hpp)
target_include_directories(natsukashii PRIVATE
.
n64
n64/core
n64/core/cpu/
n64/core/cpu/registers
n64/core/interpreter/
n64/core/interpreter/registers
n64/core/mmio
n64/core/rsp
frontend
frontend/imgui
../external
../external/xbyak
../external/imgui/imgui
../external/parallel-rdp/
../external/nativefiledialog-extended/src/include
@@ -54,8 +53,8 @@ file(REMOVE
${PROJECT_BINARY_DIR}/resources/shader.vert)
if(WIN32)
add_compile_definitions(NOMINMAX _CRT_SECURE_NO_WARNINGS)
add_compile_options(/EHa)
target_compile_definitions(natsukashii PUBLIC NOMINMAX _CRT_SECURE_NO_WARNINGS)
target_compile_options(natsukashii PUBLIC /EHa)
endif()
target_link_libraries(natsukashii PRIVATE SDL2::SDL2main SDL2::SDL2 capstone-static nfd parallel-rdp fmt::fmt imgui nlohmann_json::nlohmann_json)

View File

@@ -7,11 +7,12 @@
namespace n64 {
Core::Core() {
cpu = std::make_unique<Interpreter>();
Stop();
}
void Core::Stop() {
cpu.Reset();
cpu->Reset();
mem.Reset();
pause = true;
romLoaded = false;
@@ -19,13 +20,13 @@ void Core::Stop() {
CartInfo Core::LoadROM(const std::string& rom_) {
rom = rom_;
cpu.Reset();
cpu->Reset();
mem.Reset();
pause = false;
romLoaded = true;
CartInfo cartInfo = mem.LoadROM(rom);
DoPIFHLE(mem, cpu.regs, cartInfo);
DoPIFHLE(mem, cpu->regs, cartInfo);
return cartInfo;
}
@@ -41,11 +42,11 @@ void Core::Run(Window& window, float volumeL, float volumeR) {
mmio.vi.current = (i << 1) + field;
if ((mmio.vi.current & 0x3FE) == mmio.vi.intr) {
InterruptRaise(mmio.mi, cpu.regs, Interrupt::VI);
InterruptRaise(mmio.mi, cpu->regs, Interrupt::VI);
}
for(;cycles <= mmio.vi.cyclesPerHalfline; cycles++, frameCycles++) {
cpu.Step(mem);
cpu->Step(mem);
cpuSteps++;
if(mmio.rsp.spStatus.halt) {
mmio.rsp.steps = 0;
@@ -58,25 +59,25 @@ void Core::Run(Window& window, float volumeL, float volumeR) {
while(mmio.rsp.steps > 0) {
mmio.rsp.steps--;
mmio.rsp.Step(cpu.regs, mem);
mmio.rsp.Step(cpu->regs, mem);
}
}
mmio.ai.Step(mem, cpu.regs, 1, volumeL, volumeR);
scheduler.tick(1, mem, cpu.regs);
mmio.ai.Step(mem, cpu->regs, 1, volumeL, volumeR);
scheduler.tick(1, mem, cpu->regs);
}
cycles -= mmio.vi.cyclesPerHalfline;
}
if ((mmio.vi.current & 0x3FE) == mmio.vi.intr) {
InterruptRaise(mmio.mi, cpu.regs, Interrupt::VI);
InterruptRaise(mmio.mi, cpu->regs, Interrupt::VI);
}
UpdateScreenParallelRdp(*this, window, GetVI());
int missedCycles = N64_CYCLES_PER_FRAME - frameCycles;
mmio.ai.Step(mem, cpu.regs, missedCycles, volumeL, volumeR);
mmio.ai.Step(mem, cpu->regs, missedCycles, volumeL, volumeR);
} else if(pause && romLoaded) {
UpdateScreenParallelRdp(*this, window, GetVI());
} else if(pause && !romLoaded) {

View File

@@ -1,6 +1,6 @@
#pragma once
#include <SDL_events.h>
#include <Cpu.hpp>
#include <Interpreter.hpp>
#include <Mem.hpp>
#include <string>
@@ -27,6 +27,6 @@ struct Core {
bool done = false;
std::string rom;
Mem mem;
Cpu cpu;
std::unique_ptr<BaseCpu> cpu;
};
}

View File

@@ -1,6 +1,6 @@
#include <Scheduler.hpp>
#include <Mem.hpp>
#include <Registers.hpp>
#include <core/registers/Registers.hpp>
Scheduler scheduler;

12
src/n64/core/BaseCpu.hpp Normal file
View File

@@ -0,0 +1,12 @@
#pragma
#include <core/registers/Registers.hpp>
namespace n64 {
struct BaseCpu {
virtual ~BaseCpu() {}
Registers regs;
virtual void Step(Mem& mem) {}
virtual void Reset() {}
};
}

11
src/n64/core/Dynarec.cpp Normal file
View File

@@ -0,0 +1,11 @@
#include <Dynarec.hpp>
namespace n64 {
void Dynarec::Reset() {
}
void Dynarec::Step(Mem &mem) {
}
}

12
src/n64/core/Dynarec.hpp Normal file
View File

@@ -0,0 +1,12 @@
#pragma once
#include <BaseCpu.hpp>
#include <xbyak/xbyak.h>
namespace n64 {
struct Dynarec : BaseCpu {
void Step(Mem& mem) override;
void Reset() override;
private:
Xbyak::CodeGenerator code;
};
}

View File

@@ -1,8 +1,8 @@
#include <n64/core/Cpu.hpp>
#include <n64/core/Interpreter.hpp>
#include <util.hpp>
namespace n64 {
void Cpu::Reset() {
void Interpreter::Reset() {
regs.Reset();
}
@@ -25,7 +25,7 @@ inline void CheckCompareInterrupt(MI& mi, Registers& regs) {
}
}
inline void Cpu::disassembly(u32 instr) {
inline void Interpreter::disassembly(u32 instr) {
size_t count;
cs_insn *insn;
@@ -45,7 +45,7 @@ inline void Cpu::disassembly(u32 instr) {
printf("ERROR: Failed to disassemble given code!\n");
}
void Cpu::Step(Mem& mem) {
void Interpreter::Step(Mem& mem) {
regs.gpr[0] = 0;
CheckCompareInterrupt(mem.mmio.mi, regs);

View File

@@ -1,24 +1,24 @@
#pragma once
#include <Registers.hpp>
#include <BaseCpu.hpp>
#include <core/registers/Registers.hpp>
#include <Mem.hpp>
#include <capstone/capstone.h>
#include <vector>
namespace n64 {
struct Cpu {
Cpu() {
struct Interpreter : BaseCpu {
Interpreter() {
if(cs_open(CS_ARCH_MIPS, CS_MODE_MIPS64, &handle) != CS_ERR_OK) {
util::panic("Could not initialize capstone!\n");
}
Reset();
}
~Cpu() {
~Interpreter() {
cs_close(&handle);
}
void Reset();
void Step(Mem&);
Registers regs;
void Reset() override;
void Step(Mem&) override;
private:
csh handle;

View File

@@ -1,7 +1,7 @@
#include <n64/core/MMIO.hpp>
#include <util.hpp>
#include <n64/core/Mem.hpp>
#include <n64/core/cpu/Registers.hpp>
#include <core/registers/Registers.hpp>
namespace n64 {
MMIO::MMIO () {

View File

@@ -1,8 +1,8 @@
#include <Mem.hpp>
#include <fstream>
#include <n64/core/cpu/Registers.hpp>
#include <n64/core/cpu/registers/Cop0.hpp>
#include <n64/core/Cpu.hpp>
#include <core/registers/Registers.hpp>
#include <core/registers/Cop0.hpp>
#include <n64/core/Interpreter.hpp>
namespace n64 {
Mem::Mem() {

View File

@@ -1,5 +1,5 @@
#include <n64/core/cpu/registers/Cop0.hpp>
#include <n64/core/cpu/Registers.hpp>
#include <core/registers/Cop0.hpp>
#include <core/registers/Registers.hpp>
#include <util.hpp>
namespace n64 {

View File

@@ -1,5 +1,5 @@
#include <n64/core/cpu/registers/Cop1.hpp>
#include <n64/core/cpu/Registers.hpp>
#include <core/registers/Cop1.hpp>
#include <core/registers/Registers.hpp>
#include <n64/core/Mem.hpp>
#include <cmath>
#include <cfenv>

View File

@@ -1,8 +1,8 @@
#include <n64/core/Cpu.hpp>
#include <n64/core/Interpreter.hpp>
#include <util.hpp>
namespace n64 {
void Cpu::special(Mem& mem, u32 instr) {
void Interpreter::special(Mem& mem, u32 instr) {
u8 mask = (instr & 0x3F);
// 00rr_rccc
switch (mask) { // TODO: named constants for clearer code
@@ -67,7 +67,7 @@ void Cpu::special(Mem& mem, u32 instr) {
}
}
void Cpu::regimm(u32 instr) {
void Interpreter::regimm(u32 instr) {
u8 mask = ((instr >> 16) & 0x1F);
// 000r_rccc
switch (mask) { // TODO: named constants for clearer code
@@ -90,7 +90,7 @@ void Cpu::regimm(u32 instr) {
}
}
void Cpu::Exec(Mem& mem, u32 instr) {
void Interpreter::Exec(Mem& mem, u32 instr) {
u8 mask = (instr >> 26) & 0x3f;
// 00rr_rccc
switch(mask) { // TODO: named constants for clearer code

View File

@@ -1,4 +1,4 @@
#include <n64/core/Cpu.hpp>
#include <n64/core/Interpreter.hpp>
#include <util.hpp>
#define se_imm(x) ((s16)((x) & 0xFFFF))
@@ -7,7 +7,7 @@
#define check_signed_underflow(op1, op2, res) (((((op1) ^ (op2)) & ((op1) ^ (res))) >> ((sizeof(res) * 8) - 1)) & 1)
namespace n64 {
void Cpu::add(u32 instr) {
void Interpreter::add(u32 instr) {
u32 rs = (s32)regs.gpr[RS(instr)];
u32 rt = (s32)regs.gpr[RT(instr)];
u32 result = rs + rt;
@@ -18,14 +18,14 @@ void Cpu::add(u32 instr) {
}
}
void Cpu::addu(u32 instr) {
void Interpreter::addu(u32 instr) {
s32 rs = (s32)regs.gpr[RS(instr)];
s32 rt = (s32)regs.gpr[RT(instr)];
s32 result = rs + rt;
regs.gpr[RD(instr)] = result;
}
void Cpu::addi(u32 instr) {
void Interpreter::addi(u32 instr) {
u32 rs = regs.gpr[RS(instr)];
u32 imm = s32(s16(instr));
u32 result = rs + imm;
@@ -36,14 +36,14 @@ void Cpu::addi(u32 instr) {
}
}
void Cpu::addiu(u32 instr) {
void Interpreter::addiu(u32 instr) {
s32 rs = (s32)regs.gpr[RS(instr)];
s16 imm = (s16)(instr);
s32 result = rs + imm;
regs.gpr[RT(instr)] = result;
}
void Cpu::dadd(u32 instr) {
void Interpreter::dadd(u32 instr) {
u64 rs = regs.gpr[RS(instr)];
u64 rt = regs.gpr[RT(instr)];
u64 result = rt + rs;
@@ -54,13 +54,13 @@ void Cpu::dadd(u32 instr) {
}
}
void Cpu::daddu(u32 instr) {
void Interpreter::daddu(u32 instr) {
s64 rs = regs.gpr[RS(instr)];
s64 rt = regs.gpr[RT(instr)];
regs.gpr[RD(instr)] = rs + rt;
}
void Cpu::daddi(u32 instr) {
void Interpreter::daddi(u32 instr) {
u64 imm = s64(s16(instr));
u64 rs = regs.gpr[RS(instr)];
u64 result = imm + rs;
@@ -71,13 +71,13 @@ void Cpu::daddi(u32 instr) {
}
}
void Cpu::daddiu(u32 instr) {
void Interpreter::daddiu(u32 instr) {
s16 imm = (s16)(instr);
s64 rs = regs.gpr[RS(instr)];
regs.gpr[RT(instr)] = rs + imm;
}
void Cpu::div(u32 instr) {
void Interpreter::div(u32 instr) {
s64 dividend = (s32)regs.gpr[RS(instr)];
s64 divisor = (s32)regs.gpr[RT(instr)];
@@ -96,7 +96,7 @@ void Cpu::div(u32 instr) {
}
}
void Cpu::divu(u32 instr) {
void Interpreter::divu(u32 instr) {
u32 dividend = regs.gpr[RS(instr)];
u32 divisor = regs.gpr[RT(instr)];
if(divisor == 0) {
@@ -110,7 +110,7 @@ void Cpu::divu(u32 instr) {
}
}
void Cpu::ddiv(u32 instr) {
void Interpreter::ddiv(u32 instr) {
s64 dividend = regs.gpr[RS(instr)];
s64 divisor = regs.gpr[RT(instr)];
if (dividend == 0x8000000000000000 && divisor == 0xFFFFFFFFFFFFFFFF) {
@@ -131,7 +131,7 @@ void Cpu::ddiv(u32 instr) {
}
}
void Cpu::ddivu(u32 instr) {
void Interpreter::ddivu(u32 instr) {
u64 dividend = regs.gpr[RS(instr)];
u64 divisor = regs.gpr[RT(instr)];
if(divisor == 0) {
@@ -145,14 +145,14 @@ void Cpu::ddivu(u32 instr) {
}
}
void Cpu::branch(bool cond, s64 address) {
void Interpreter::branch(bool cond, s64 address) {
regs.delaySlot = true;
if (cond) {
regs.nextPC = address;
}
}
void Cpu::branch_likely(bool cond, s64 address) {
void Interpreter::branch_likely(bool cond, s64 address) {
regs.delaySlot = true;
if (cond) {
regs.nextPC = address;
@@ -161,44 +161,44 @@ void Cpu::branch_likely(bool cond, s64 address) {
}
}
void Cpu::b(u32 instr, bool cond) {
void Interpreter::b(u32 instr, bool cond) {
s64 offset = (s64)se_imm(instr) << 2;
s64 address = regs.pc + offset;
branch(cond, address);
}
void Cpu::blink(u32 instr, bool cond) {
void Interpreter::blink(u32 instr, bool cond) {
regs.gpr[31] = regs.nextPC;
s64 offset = (s64)se_imm(instr) << 2;
s64 address = regs.pc + offset;
branch(cond, address);
}
void Cpu::bl(u32 instr, bool cond) {
void Interpreter::bl(u32 instr, bool cond) {
s64 offset = (s64)se_imm(instr) << 2;
s64 address = regs.pc + offset;
branch_likely(cond, address);
}
void Cpu::bllink(u32 instr, bool cond) {
void Interpreter::bllink(u32 instr, bool cond) {
regs.gpr[31] = regs.nextPC;
s64 offset = (s64)se_imm(instr) << 2;
s64 address = regs.pc + offset;
branch_likely(cond, address);
}
void Cpu::lui(u32 instr) {
void Interpreter::lui(u32 instr) {
s64 val = (s16)instr;
val <<= 16;
regs.gpr[RT(instr)] = val;
}
void Cpu::lb(Mem& mem, u32 instr) {
void Interpreter::lb(Mem& mem, u32 instr) {
u64 address = regs.gpr[RS(instr)] + (s16)instr;
regs.gpr[RT(instr)] = (s8)mem.Read8(regs, address, regs.oldPC);
}
void Cpu::lh(Mem& mem, u32 instr) {
void Interpreter::lh(Mem& mem, u32 instr) {
u64 address = regs.gpr[RS(instr)] + (s16)instr;
if (check_address_error(address, 0b1)) {
HandleTLBException(regs, address);
@@ -209,7 +209,7 @@ void Cpu::lh(Mem& mem, u32 instr) {
regs.gpr[RT(instr)] = (s16)mem.Read16(regs, address, regs.oldPC);
}
void Cpu::lw(Mem& mem, u32 instr) {
void Interpreter::lw(Mem& mem, u32 instr) {
s16 offset = instr;
u64 address = regs.gpr[RS(instr)] + offset;
if (check_address_error(address, 0b11)) {
@@ -227,7 +227,7 @@ void Cpu::lw(Mem& mem, u32 instr) {
}
}
void Cpu::ll(Mem& mem, u32 instr) {
void Interpreter::ll(Mem& mem, u32 instr) {
s64 address = regs.gpr[RS(instr)] + (s16)instr;
u32 physical;
if (!MapVAddr(regs, LOAD, address, physical)) {
@@ -241,7 +241,7 @@ void Cpu::ll(Mem& mem, u32 instr) {
regs.cop0.LLAddr = physical >> 4;
}
void Cpu::lwl(Mem& mem, u32 instr) {
void Interpreter::lwl(Mem& mem, u32 instr) {
u64 address = regs.gpr[RS(instr)] + (s16)instr;
u32 paddr = 0;
if(!MapVAddr(regs, LOAD, address, paddr)) {
@@ -256,7 +256,7 @@ void Cpu::lwl(Mem& mem, u32 instr) {
}
}
void Cpu::lwr(Mem& mem, u32 instr) {
void Interpreter::lwr(Mem& mem, u32 instr) {
u64 address = regs.gpr[RS(instr)] + (s16)instr;
u32 paddr = 0;
if(!MapVAddr(regs, LOAD, address, paddr)) {
@@ -271,7 +271,7 @@ void Cpu::lwr(Mem& mem, u32 instr) {
}
}
void Cpu::ld(Mem& mem, u32 instr) {
void Interpreter::ld(Mem& mem, u32 instr) {
s64 address = regs.gpr[RS(instr)] + (s16)instr;
if (check_address_error(address, 0b111)) {
HandleTLBException(regs, address);
@@ -283,7 +283,7 @@ void Cpu::ld(Mem& mem, u32 instr) {
regs.gpr[RT(instr)] = value;
}
void Cpu::lld(Mem& mem, u32 instr) {
void Interpreter::lld(Mem& mem, u32 instr) {
s64 address = regs.gpr[RS(instr)] + (s16)instr;
u32 paddr;
if (!MapVAddr(regs, LOAD, address, paddr)) {
@@ -297,7 +297,7 @@ void Cpu::lld(Mem& mem, u32 instr) {
regs.cop0.LLAddr = paddr >> 4;
}
void Cpu::ldl(Mem& mem, u32 instr) {
void Interpreter::ldl(Mem& mem, u32 instr) {
u64 address = regs.gpr[RS(instr)] + (s16)instr;
u32 paddr = 0;
if (!MapVAddr(regs, LOAD, address, paddr)) {
@@ -312,7 +312,7 @@ void Cpu::ldl(Mem& mem, u32 instr) {
}
}
void Cpu::ldr(Mem& mem, u32 instr) {
void Interpreter::ldr(Mem& mem, u32 instr) {
u64 address = regs.gpr[RS(instr)] + (s16)instr;
u32 paddr;
if (!MapVAddr(regs, LOAD, address, paddr)) {
@@ -327,13 +327,13 @@ void Cpu::ldr(Mem& mem, u32 instr) {
}
}
void Cpu::lbu(Mem& mem, u32 instr) {
void Interpreter::lbu(Mem& mem, u32 instr) {
u64 address = regs.gpr[RS(instr)] + (s16)instr;
u8 value = mem.Read8(regs, address, regs.oldPC);
regs.gpr[RT(instr)] = value;
}
void Cpu::lhu(Mem& mem, u32 instr) {
void Interpreter::lhu(Mem& mem, u32 instr) {
s64 address = regs.gpr[RS(instr)] + (s16)instr;
if (check_address_error(address, 0b1)) {
HandleTLBException(regs, address);
@@ -345,7 +345,7 @@ void Cpu::lhu(Mem& mem, u32 instr) {
regs.gpr[RT(instr)] = value;
}
void Cpu::lwu(Mem& mem, u32 instr) {
void Interpreter::lwu(Mem& mem, u32 instr) {
s64 address = regs.gpr[RS(instr)] + (s16)instr;
if (check_address_error(address, 0b11)) {
HandleTLBException(regs, address);
@@ -357,12 +357,12 @@ void Cpu::lwu(Mem& mem, u32 instr) {
regs.gpr[RT(instr)] = value;
}
void Cpu::sb(Mem& mem, u32 instr) {
void Interpreter::sb(Mem& mem, u32 instr) {
u32 address = regs.gpr[RS(instr)] + (s16)instr;
mem.Write8(regs, address, regs.gpr[RT(instr)], regs.oldPC);
}
void Cpu::sc(Mem& mem, u32 instr) {
void Interpreter::sc(Mem& mem, u32 instr) {
s64 address = regs.gpr[RS(instr)] + (s16)instr;
if (check_address_error(address, 0b11)) {
HandleTLBException(regs, address);
@@ -377,7 +377,7 @@ void Cpu::sc(Mem& mem, u32 instr) {
regs.cop0.llbit = false;
}
void Cpu::scd(Mem& mem, u32 instr) {
void Interpreter::scd(Mem& mem, u32 instr) {
s64 address = regs.gpr[RS(instr)] + (s16)instr;
if (check_address_error(address, 0b111)) {
HandleTLBException(regs, address);
@@ -393,7 +393,7 @@ void Cpu::scd(Mem& mem, u32 instr) {
regs.cop0.llbit = false;
}
void Cpu::sh(Mem& mem, u32 instr) {
void Interpreter::sh(Mem& mem, u32 instr) {
s64 address = regs.gpr[RS(instr)] + (s16)instr;
if (check_address_error(address, 0b1)) {
HandleTLBException(regs, address);
@@ -410,7 +410,7 @@ void Cpu::sh(Mem& mem, u32 instr) {
}
}
void Cpu::sw(Mem& mem, u32 instr) {
void Interpreter::sw(Mem& mem, u32 instr) {
s16 offset = instr;
u64 address = regs.gpr[RS(instr)] + offset;
if (check_address_error(address, 0b11)) {
@@ -428,7 +428,7 @@ void Cpu::sw(Mem& mem, u32 instr) {
}
}
void Cpu::sd(Mem& mem, u32 instr) {
void Interpreter::sd(Mem& mem, u32 instr) {
s64 address = regs.gpr[RS(instr)] + (s16)instr;
if (check_address_error(address, 0b11)) {
HandleTLBException(regs, address);
@@ -446,7 +446,7 @@ void Cpu::sd(Mem& mem, u32 instr) {
}
void Cpu::sdl(Mem& mem, u32 instr) {
void Interpreter::sdl(Mem& mem, u32 instr) {
u64 address = regs.gpr[RS(instr)] + (s16)instr;
u32 paddr;
if (!MapVAddr(regs, STORE, address, paddr)) {
@@ -461,7 +461,7 @@ void Cpu::sdl(Mem& mem, u32 instr) {
}
}
void Cpu::sdr(Mem& mem, u32 instr) {
void Interpreter::sdr(Mem& mem, u32 instr) {
u64 address = regs.gpr[RS(instr)] + (s16)instr;
u32 paddr;
if (!MapVAddr(regs, STORE, address, paddr)) {
@@ -476,7 +476,7 @@ void Cpu::sdr(Mem& mem, u32 instr) {
}
}
void Cpu::swl(Mem& mem, u32 instr) {
void Interpreter::swl(Mem& mem, u32 instr) {
u64 address = regs.gpr[RS(instr)] + (s16)instr;
u32 paddr;
if (!MapVAddr(regs, STORE, address, paddr)) {
@@ -491,7 +491,7 @@ void Cpu::swl(Mem& mem, u32 instr) {
}
}
void Cpu::swr(Mem& mem, u32 instr) {
void Interpreter::swr(Mem& mem, u32 instr) {
u64 address = regs.gpr[RS(instr)] + (s16)instr;
u32 paddr;
if (!MapVAddr(regs, STORE, address, paddr)) {
@@ -506,21 +506,21 @@ void Cpu::swr(Mem& mem, u32 instr) {
}
}
void Cpu::ori(u32 instr) {
void Interpreter::ori(u32 instr) {
s64 imm = (u16)instr;
s64 result = imm | regs.gpr[RS(instr)];
regs.gpr[RT(instr)] = result;
}
void Cpu::or_(u32 instr) {
void Interpreter::or_(u32 instr) {
regs.gpr[RD(instr)] = regs.gpr[RS(instr)] | regs.gpr[RT(instr)];
}
void Cpu::nor(u32 instr) {
void Interpreter::nor(u32 instr) {
regs.gpr[RD(instr)] = ~(regs.gpr[RS(instr)] | regs.gpr[RT(instr)]);
}
void Cpu::j(u32 instr) {
void Interpreter::j(u32 instr) {
s32 target = (instr & 0x3ffffff) << 2;
s64 address = (regs.oldPC & ~0xfffffff) | target;
if (check_address_error(address, 0b11)) {
@@ -531,124 +531,124 @@ void Cpu::j(u32 instr) {
branch(true, address);
}
void Cpu::jal(u32 instr) {
void Interpreter::jal(u32 instr) {
regs.gpr[31] = regs.nextPC;
j(instr);
}
void Cpu::jalr(u32 instr) {
void Interpreter::jalr(u32 instr) {
branch(true, regs.gpr[RS(instr)]);
regs.gpr[RD(instr)] = regs.pc + 4;
}
void Cpu::slti(u32 instr) {
void Interpreter::slti(u32 instr) {
regs.gpr[RT(instr)] = regs.gpr[RS(instr)] < se_imm(instr);
}
void Cpu::sltiu(u32 instr) {
void Interpreter::sltiu(u32 instr) {
regs.gpr[RT(instr)] = (u64)regs.gpr[RS(instr)] < se_imm(instr);
}
void Cpu::slt(u32 instr) {
void Interpreter::slt(u32 instr) {
regs.gpr[RD(instr)] = regs.gpr[RS(instr)] < regs.gpr[RT(instr)];
}
void Cpu::sltu(u32 instr) {
void Interpreter::sltu(u32 instr) {
regs.gpr[RD(instr)] = (u64)regs.gpr[RS(instr)] < (u64)regs.gpr[RT(instr)];
}
void Cpu::xori(u32 instr) {
void Interpreter::xori(u32 instr) {
s64 imm = (u16)instr;
regs.gpr[RT(instr)] = regs.gpr[RS(instr)] ^ imm;
}
void Cpu::xor_(u32 instr) {
void Interpreter::xor_(u32 instr) {
regs.gpr[RD(instr)] = regs.gpr[RT(instr)] ^ regs.gpr[RS(instr)];
}
void Cpu::andi(u32 instr) {
void Interpreter::andi(u32 instr) {
s64 imm = (u16)instr;
regs.gpr[RT(instr)] = regs.gpr[RS(instr)] & imm;
}
void Cpu::and_(u32 instr) {
void Interpreter::and_(u32 instr) {
regs.gpr[RD(instr)] = regs.gpr[RS(instr)] & regs.gpr[RT(instr)];
}
void Cpu::sll(u32 instr) {
void Interpreter::sll(u32 instr) {
u8 sa = ((instr >> 6) & 0x1f);
s32 result = regs.gpr[RT(instr)] << sa;
regs.gpr[RD(instr)] = (s64)result;
}
void Cpu::sllv(u32 instr) {
void Interpreter::sllv(u32 instr) {
u8 sa = (regs.gpr[RS(instr)]) & 0x1F;
u32 rt = regs.gpr[RT(instr)];
s32 result = rt << sa;
regs.gpr[RD(instr)] = (s64)result;
}
void Cpu::dsll32(u32 instr) {
void Interpreter::dsll32(u32 instr) {
u8 sa = ((instr >> 6) & 0x1f);
s64 result = regs.gpr[RT(instr)] << (sa + 32);
regs.gpr[RD(instr)] = result;
}
void Cpu::dsll(u32 instr) {
void Interpreter::dsll(u32 instr) {
u8 sa = ((instr >> 6) & 0x1f);
s64 result = regs.gpr[RT(instr)] << sa;
regs.gpr[RD(instr)] = result;
}
void Cpu::dsllv(u32 instr) {
void Interpreter::dsllv(u32 instr) {
s64 sa = regs.gpr[RS(instr)] & 63;
s64 result = regs.gpr[RT(instr)] << sa;
regs.gpr[RD(instr)] = result;
}
void Cpu::srl(u32 instr) {
void Interpreter::srl(u32 instr) {
u32 rt = regs.gpr[RT(instr)];
u8 sa = ((instr >> 6) & 0x1f);
u32 result = rt >> sa;
regs.gpr[RD(instr)] = (s32)result;
}
void Cpu::srlv(u32 instr) {
void Interpreter::srlv(u32 instr) {
u8 sa = (regs.gpr[RS(instr)] & 0x1F);
u32 rt = regs.gpr[RT(instr)];
s32 result = rt >> sa;
regs.gpr[RD(instr)] = (s64)result;
}
void Cpu::dsrl(u32 instr) {
void Interpreter::dsrl(u32 instr) {
u64 rt = regs.gpr[RT(instr)];
u8 sa = ((instr >> 6) & 0x1f);
u64 result = rt >> sa;
regs.gpr[RD(instr)] = s64(result);
}
void Cpu::dsrlv(u32 instr) {
void Interpreter::dsrlv(u32 instr) {
u8 amount = (regs.gpr[RS(instr)] & 63);
u64 rt = regs.gpr[RT(instr)];
u64 result = rt >> amount;
regs.gpr[RD(instr)] = s64(result);
}
void Cpu::dsrl32(u32 instr) {
void Interpreter::dsrl32(u32 instr) {
u64 rt = regs.gpr[RT(instr)];
u8 sa = ((instr >> 6) & 0x1f);
u64 result = rt >> (sa + 32);
regs.gpr[RD(instr)] = s64(result);
}
void Cpu::sra(u32 instr) {
void Interpreter::sra(u32 instr) {
s64 rt = regs.gpr[RT(instr)];
u8 sa = ((instr >> 6) & 0x1f);
s32 result = rt >> sa;
regs.gpr[RD(instr)] = result;
}
void Cpu::srav(u32 instr) {
void Interpreter::srav(u32 instr) {
s64 rt = regs.gpr[RT(instr)];
s64 rs = regs.gpr[RS(instr)];
u8 sa = rs & 0x1f;
@@ -656,14 +656,14 @@ void Cpu::srav(u32 instr) {
regs.gpr[RD(instr)] = result;
}
void Cpu::dsra(u32 instr) {
void Interpreter::dsra(u32 instr) {
s64 rt = regs.gpr[RT(instr)];
u8 sa = ((instr >> 6) & 0x1f);
s64 result = rt >> sa;
regs.gpr[RD(instr)] = result;
}
void Cpu::dsrav(u32 instr) {
void Interpreter::dsrav(u32 instr) {
s64 rt = regs.gpr[RT(instr)];
s64 rs = regs.gpr[RS(instr)];
s64 sa = rs & 63;
@@ -671,14 +671,14 @@ void Cpu::dsrav(u32 instr) {
regs.gpr[RD(instr)] = result;
}
void Cpu::dsra32(u32 instr) {
void Interpreter::dsra32(u32 instr) {
s64 rt = regs.gpr[RT(instr)];
u8 sa = ((instr >> 6) & 0x1f);
s64 result = rt >> (sa + 32);
regs.gpr[RD(instr)] = result;
}
void Cpu::jr(u32 instr) {
void Interpreter::jr(u32 instr) {
s64 address = regs.gpr[RS(instr)];
if (check_address_error(address, 0b11)) {
HandleTLBException(regs, address);
@@ -688,7 +688,7 @@ void Cpu::jr(u32 instr) {
branch(true, address);
}
void Cpu::dsub(u32 instr) {
void Interpreter::dsub(u32 instr) {
s64 rt = regs.gpr[RT(instr)];
s64 rs = regs.gpr[RS(instr)];
s64 result = rs - rt;
@@ -699,14 +699,14 @@ void Cpu::dsub(u32 instr) {
}
}
void Cpu::dsubu(u32 instr) {
void Interpreter::dsubu(u32 instr) {
u64 rt = regs.gpr[RT(instr)];
u64 rs = regs.gpr[RS(instr)];
u64 result = rs - rt;
regs.gpr[RD(instr)] = s64(result);
}
void Cpu::sub(u32 instr) {
void Interpreter::sub(u32 instr) {
s32 rt = regs.gpr[RT(instr)];
s32 rs = regs.gpr[RS(instr)];
s32 result = rs - rt;
@@ -717,14 +717,14 @@ void Cpu::sub(u32 instr) {
}
}
void Cpu::subu(u32 instr) {
void Interpreter::subu(u32 instr) {
u32 rt = regs.gpr[RT(instr)];
u32 rs = regs.gpr[RS(instr)];
u32 result = rs - rt;
regs.gpr[RD(instr)] = (s64)((s32)result);
}
void Cpu::dmultu(u32 instr) {
void Interpreter::dmultu(u32 instr) {
u64 rt = regs.gpr[RT(instr)];
u64 rs = regs.gpr[RS(instr)];
u128 result = (u128)rt * (u128)rs;
@@ -732,7 +732,7 @@ void Cpu::dmultu(u32 instr) {
regs.hi = (s64)(result >> 64);
}
void Cpu::dmult(u32 instr) {
void Interpreter::dmult(u32 instr) {
s64 rt = regs.gpr[RT(instr)];
s64 rs = regs.gpr[RS(instr)];
s128 result = (s128)rt * (s128)rs;
@@ -740,7 +740,7 @@ void Cpu::dmult(u32 instr) {
regs.hi = result >> 64;
}
void Cpu::multu(u32 instr) {
void Interpreter::multu(u32 instr) {
u32 rt = regs.gpr[RT(instr)];
u32 rs = regs.gpr[RS(instr)];
u64 result = (u64)rt * (u64)rs;
@@ -748,7 +748,7 @@ void Cpu::multu(u32 instr) {
regs.hi = (s64)((s32)(result >> 32));
}
void Cpu::mult(u32 instr) {
void Interpreter::mult(u32 instr) {
s32 rt = regs.gpr[RT(instr)];
s32 rs = regs.gpr[RS(instr)];
s64 result = (s64)rt * (s64)rs;
@@ -756,23 +756,23 @@ void Cpu::mult(u32 instr) {
regs.hi = (s64)((s32)(result >> 32));
}
void Cpu::mflo(u32 instr) {
void Interpreter::mflo(u32 instr) {
regs.gpr[RD(instr)] = regs.lo;
}
void Cpu::mfhi(u32 instr) {
void Interpreter::mfhi(u32 instr) {
regs.gpr[RD(instr)] = regs.hi;
}
void Cpu::mtlo(u32 instr) {
void Interpreter::mtlo(u32 instr) {
regs.lo = regs.gpr[RS(instr)];
}
void Cpu::mthi(u32 instr) {
void Interpreter::mthi(u32 instr) {
regs.hi = regs.gpr[RS(instr)];
}
void Cpu::trap(bool cond) {
void Interpreter::trap(bool cond) {
if(cond) {
FireException(regs, ExceptionCode::Trap, 0, regs.oldPC);
}

View File

@@ -1,7 +1,7 @@
#include <n64/core/mmio/AI.hpp>
#include <util.hpp>
#include <n64/core/Mem.hpp>
#include <n64/core/cpu/Registers.hpp>
#include <core/registers/Registers.hpp>
#include <n64/core/Audio.hpp>
namespace n64 {

View File

@@ -1,6 +1,6 @@
#include <n64/core/mmio/Interrupt.hpp>
#include <n64/core/mmio/MI.hpp>
#include <n64/core/cpu/Registers.hpp>
#include <core/registers/Registers.hpp>
namespace n64 {
void InterruptRaise(MI &mi, Registers &regs, Interrupt intr) {

View File

@@ -1,5 +1,5 @@
#include <n64/core/mmio/MI.hpp>
#include <n64/core/cpu/Registers.hpp>
#include <core/registers/Registers.hpp>
#include <util.hpp>
#include <n64/core/mmio/Interrupt.hpp>

View File

@@ -1,7 +1,7 @@
#include <n64/core/mmio/PI.hpp>
#include <util.hpp>
#include <n64/core/Mem.hpp>
#include <n64/core/cpu/Registers.hpp>
#include <core/registers/Registers.hpp>
namespace n64 {
PI::PI() {

View File

@@ -1,6 +1,6 @@
#include <n64/core/mmio/PIF.hpp>
#include <n64/core/Mem.hpp>
#include <n64/core/cpu/Registers.hpp>
#include <core/registers/Registers.hpp>
#include <util.hpp>
#include "m64.hpp"

View File

@@ -1,6 +1,6 @@
#include <n64/core/mmio/VI.hpp>
#include <util.hpp>
#include <n64/core/cpu/Registers.hpp>
#include <core/registers/Registers.hpp>
#include <n64/core/mmio/MI.hpp>
#include <n64/core/mmio/Interrupt.hpp>

View File

@@ -1,7 +1,7 @@
#include <Cop0.hpp>
#include <core/registers/Cop0.hpp>
#include <util.hpp>
#include <n64/core/cpu/Registers.hpp>
#include <n64/core/Cpu.hpp>
#include <core/registers/Registers.hpp>
#include <n64/core/Interpreter.hpp>
namespace n64 {
Cop0::Cop0() {

View File

@@ -1,6 +1,6 @@
#include <n64/core/cpu/registers/Cop1.hpp>
#include <n64/core/cpu/Registers.hpp>
#include <n64/core/Cpu.hpp>
#include <core/registers/Cop1.hpp>
#include <core/registers/Registers.hpp>
#include <n64/core/Interpreter.hpp>
#include <util.hpp>
namespace n64 {
@@ -14,7 +14,7 @@ void Cop1::Reset() {
memset(fgr, 0, 32 * sizeof(FGR));
}
void Cop1::decode(Cpu& cpu, u32 instr) {
void Cop1::decode(Interpreter& cpu, u32 instr) {
Registers& regs = cpu.regs;
if(!regs.cop0.status.cu1) {
FireException(regs, ExceptionCode::CoprocessorUnusable, 1, regs.oldPC);

View File

@@ -1,5 +1,5 @@
#pragma once
#include <n64/core/cpu/registers/Cop0.hpp>
#include <core/registers/Cop0.hpp>
namespace n64 {
union FCR31 {
@@ -54,7 +54,7 @@ union FGR {
s64 raw;
};
struct Cpu;
struct Interpreter;
struct Registers;
struct Cop1 {
@@ -63,8 +63,8 @@ struct Cop1 {
FCR31 fcr31{};
FGR fgr[32]{};
void Reset();
void decode(Cpu&, u32);
friend struct Cpu;
void decode(Interpreter&, u32);
friend struct Interpreter;
private:
template <typename T>
inline void SetReg(Cop0& cop0, u8 index, T value) {

View File

@@ -1,4 +1,4 @@
#include <Registers.hpp>
#include <core/registers/Registers.hpp>
namespace n64 {
Registers::Registers() {

View File

@@ -1,6 +1,6 @@
#pragma once
#include <Cop0.hpp>
#include <Cop1.hpp>
#include <core/registers/Cop0.hpp>
#include <core/registers/Cop1.hpp>
namespace n64 {
struct Registers {

View File

@@ -1,6 +1,6 @@
#include <n64/core/RSP.hpp>
#include <util.hpp>
#include <n64/core/cpu/Registers.hpp>
#include <core/registers/Registers.hpp>
#include <Interrupt.hpp>
#include <Mem.hpp>

View File

@@ -1,6 +1,6 @@
#include <RSP.hpp>
#include <util.hpp>
#include <n64/core/cpu/Registers.hpp>
#include <core/registers/Registers.hpp>
#include <Mem.hpp>
#include <rcp_rsq.hpp>