rename emulator
This commit is contained in:
12
.github/workflows/build.yml
vendored
12
.github/workflows/build.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
|||||||
cmake -B build
|
cmake -B build
|
||||||
cd build
|
cd build
|
||||||
sudo make install
|
sudo make install
|
||||||
- name: Build natsukashii
|
- name: Build Gadolinium
|
||||||
run: |
|
run: |
|
||||||
cmake \
|
cmake \
|
||||||
-G Ninja \
|
-G Ninja \
|
||||||
@@ -31,11 +31,11 @@ jobs:
|
|||||||
- name: Collect artifacts
|
- name: Collect artifacts
|
||||||
run: |
|
run: |
|
||||||
mkdir upload
|
mkdir upload
|
||||||
cp -r build/{natsukashii,resources} upload
|
cp -r build/{gadolinium,resources} upload
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
uses: actions/upload-artifact@master
|
uses: actions/upload-artifact@master
|
||||||
with:
|
with:
|
||||||
name: natsukashii-linux
|
name: gadolinium-linux
|
||||||
path: upload
|
path: upload
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
build-windows:
|
build-windows:
|
||||||
@@ -49,14 +49,14 @@ jobs:
|
|||||||
vcpkg install sdl2[vulkan]:x64-windows
|
vcpkg install sdl2[vulkan]:x64-windows
|
||||||
vcpkg install fmt:x64-windows
|
vcpkg install fmt:x64-windows
|
||||||
vcpkg install nlohmann-json:x64-windows
|
vcpkg install nlohmann-json:x64-windows
|
||||||
- name: Build natsukashii
|
- name: Build Gadolinium
|
||||||
run: |
|
run: |
|
||||||
cmake -B build -T clangcl -DCAPSTONE_ARCHITECTURE_DEFAULT=OFF -DCAPSTONE_BUILD_TESTS=OFF -DCAPSTONE_MIPS_SUPPORT=ON -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release -S src
|
cmake -B build -T clangcl -DCAPSTONE_ARCHITECTURE_DEFAULT=OFF -DCAPSTONE_BUILD_TESTS=OFF -DCAPSTONE_MIPS_SUPPORT=ON -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release -S src
|
||||||
cmake --build build --config Release
|
cmake --build build --config Release
|
||||||
- name: Collect artifacts
|
- name: Collect artifacts
|
||||||
run: |
|
run: |
|
||||||
mkdir upload
|
mkdir upload
|
||||||
cp build/Release/natsukashii.exe upload
|
cp build/Release/gadolinium.exe upload
|
||||||
mkdir upload/resources
|
mkdir upload/resources
|
||||||
cp build/resources/* upload/resources
|
cp build/resources/* upload/resources
|
||||||
cp build/Release/SDL2.dll upload
|
cp build/Release/SDL2.dll upload
|
||||||
@@ -64,6 +64,6 @@ jobs:
|
|||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
uses: actions/upload-artifact@master
|
uses: actions/upload-artifact@master
|
||||||
with:
|
with:
|
||||||
name: natsukashii-windows
|
name: gadolinium-windows
|
||||||
path: upload
|
path: upload
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
# natsukashii
|
# Gadolinium
|
||||||
### _"Joyful nostalgia"_
|
|
||||||
|
|
||||||
[](https://www.codefactor.io/repository/github/cocosimone/natsukashii/overview/master)
|
[](https://www.codefactor.io/repository/github/cocosimone/Gadolinium/overview/master)
|
||||||
[](https://github.com/CocoSimone/natsukashii/actions/workflows/build.yml)
|
[](https://github.com/CocoSimone/Gadolinium/actions/workflows/build.yml)
|
||||||
|
|
||||||
Rewrite of my Nintendo 64 emulator "[shibumi](https://github.com/CocoSimone/shibumi)".
|
Rewrite of my Nintendo 64 emulator "[shibumi](https://github.com/CocoSimone/shibumi)".
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
cmake_minimum_required(VERSION 3.20)
|
cmake_minimum_required(VERSION 3.20)
|
||||||
project(natsukashii)
|
project(gadolinium)
|
||||||
|
|
||||||
set(BUILD_SHARED_LIBS OFF)
|
set(BUILD_SHARED_LIBS OFF)
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
@@ -18,7 +18,7 @@ add_subdirectory(../external/parallel-rdp prdp)
|
|||||||
add_subdirectory(../external/imgui imgui)
|
add_subdirectory(../external/imgui imgui)
|
||||||
add_subdirectory(../external/nativefiledialog-extended nfd)
|
add_subdirectory(../external/nativefiledialog-extended nfd)
|
||||||
|
|
||||||
add_executable(natsukashii
|
add_executable(gadolinium
|
||||||
${CORE_SOURCES}
|
${CORE_SOURCES}
|
||||||
${CORE_HEADERS}
|
${CORE_HEADERS}
|
||||||
${FRONTEND_SOURCES}
|
${FRONTEND_SOURCES}
|
||||||
@@ -29,7 +29,7 @@ add_executable(natsukashii
|
|||||||
n64/Scheduler.cpp
|
n64/Scheduler.cpp
|
||||||
n64/Scheduler.hpp)
|
n64/Scheduler.hpp)
|
||||||
|
|
||||||
target_include_directories(natsukashii PRIVATE
|
target_include_directories(gadolinium PRIVATE
|
||||||
.
|
.
|
||||||
n64
|
n64
|
||||||
n64/core
|
n64/core
|
||||||
@@ -58,4 +58,4 @@ if(WIN32)
|
|||||||
add_compile_options(/EHa)
|
add_compile_options(/EHa)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(natsukashii PRIVATE SDL2::SDL2main SDL2::SDL2 capstone-static nfd parallel-rdp fmt::fmt imgui nlohmann_json::nlohmann_json)
|
target_link_libraries(gadolinium PRIVATE SDL2::SDL2main SDL2::SDL2 capstone-static nfd parallel-rdp fmt::fmt imgui nlohmann_json::nlohmann_json)
|
||||||
@@ -25,9 +25,9 @@ void Window::InitSDL() {
|
|||||||
SDL_Init(SDL_INIT_EVERYTHING);
|
SDL_Init(SDL_INIT_EVERYTHING);
|
||||||
n64::InitAudio();
|
n64::InitAudio();
|
||||||
|
|
||||||
windowTitle = "natsukashii";
|
windowTitle = "Gadolinium";
|
||||||
window = SDL_CreateWindow(
|
window = SDL_CreateWindow(
|
||||||
"natsukashii",
|
"Gadolinium",
|
||||||
SDL_WINDOWPOS_CENTERED,
|
SDL_WINDOWPOS_CENTERED,
|
||||||
SDL_WINDOWPOS_CENTERED,
|
SDL_WINDOWPOS_CENTERED,
|
||||||
800, 600,
|
800, 600,
|
||||||
@@ -158,7 +158,7 @@ void Window::LoadROM(n64::Core& core, const std::string &path) {
|
|||||||
name = std::filesystem::path(path).stem().string();
|
name = std::filesystem::path(path).stem().string();
|
||||||
}
|
}
|
||||||
|
|
||||||
windowTitle = "natsukashii - " + name;
|
windowTitle = "Gadolinium - " + name;
|
||||||
shadowWindowTitle = windowTitle;
|
shadowWindowTitle = windowTitle;
|
||||||
|
|
||||||
SDL_SetWindowTitle(window, windowTitle.c_str());
|
SDL_SetWindowTitle(window, windowTitle.c_str());
|
||||||
@@ -210,7 +210,7 @@ void Window::Render(n64::Core& core) {
|
|||||||
LoadROM(core, core.rom);
|
LoadROM(core, core.rom);
|
||||||
}
|
}
|
||||||
if (ImGui::MenuItem("Stop")) {
|
if (ImGui::MenuItem("Stop")) {
|
||||||
windowTitle = "natsukashii";
|
windowTitle = "Gadolinium";
|
||||||
SDL_SetWindowTitle(window, windowTitle.c_str());
|
SDL_SetWindowTitle(window, windowTitle.c_str());
|
||||||
core.Stop();
|
core.Stop();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,11 +20,13 @@ struct Cpu {
|
|||||||
void Step(Mem&);
|
void Step(Mem&);
|
||||||
Registers regs;
|
Registers regs;
|
||||||
private:
|
private:
|
||||||
|
u64 cop2Latch{};
|
||||||
csh handle;
|
csh handle;
|
||||||
|
|
||||||
void disassembly(u32 instr);
|
void disassembly(u32 instr);
|
||||||
friend struct Cop1;
|
friend struct Cop1;
|
||||||
|
|
||||||
|
void cop2Decode(u32);
|
||||||
void special(Mem&, u32);
|
void special(Mem&, u32);
|
||||||
void regimm(u32);
|
void regimm(u32);
|
||||||
void Exec(Mem&, u32);
|
void Exec(Mem&, u32);
|
||||||
@@ -113,5 +115,12 @@ private:
|
|||||||
void ori(u32);
|
void ori(u32);
|
||||||
void xor_(u32);
|
void xor_(u32);
|
||||||
void xori(u32);
|
void xori(u32);
|
||||||
|
|
||||||
|
void mtc2(u32);
|
||||||
|
void mfc2(u32);
|
||||||
|
void dmtc2(u32);
|
||||||
|
void dmfc2(u32);
|
||||||
|
void ctc2(u32);
|
||||||
|
void cfc2(u32);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,4 +80,4 @@ struct RDP {
|
|||||||
RunCommand(mi, regs, rsp);
|
RunCommand(mi, regs, rsp);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // natsukashii
|
} // n64
|
||||||
|
|||||||
@@ -90,6 +90,23 @@ void Cpu::regimm(u32 instr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Cpu::cop2Decode(u32 instr) {
|
||||||
|
if(!regs.cop0.status.cu2) {
|
||||||
|
FireException(regs, ExceptionCode::CoprocessorUnusable, 2, regs.oldPC);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch(RS(instr)) {
|
||||||
|
case 0x00: mfc2(instr); break;
|
||||||
|
case 0x01: dmfc2(instr); break;
|
||||||
|
case 0x02: cfc2(instr); break;
|
||||||
|
case 0x04: mtc2(instr); break;
|
||||||
|
case 0x05: dmtc2(instr); break;
|
||||||
|
case 0x06: ctc2(instr); break;
|
||||||
|
default:
|
||||||
|
FireException(regs, ExceptionCode::ReservedInstruction, 2, regs.oldPC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Cpu::Exec(Mem& mem, u32 instr) {
|
void Cpu::Exec(Mem& mem, u32 instr) {
|
||||||
u8 mask = (instr >> 26) & 0x3f;
|
u8 mask = (instr >> 26) & 0x3f;
|
||||||
// 00rr_rccc
|
// 00rr_rccc
|
||||||
@@ -115,6 +132,7 @@ void Cpu::Exec(Mem& mem, u32 instr) {
|
|||||||
case 0x0F: lui(instr); break;
|
case 0x0F: lui(instr); break;
|
||||||
case 0x10: regs.cop0.decode(regs, mem, instr); break;
|
case 0x10: regs.cop0.decode(regs, mem, instr); break;
|
||||||
case 0x11: regs.cop1.decode(*this, instr); break;
|
case 0x11: regs.cop1.decode(*this, instr); break;
|
||||||
|
case 0x12: cop2Decode(instr); break;
|
||||||
case 0x14: bl(instr, regs.gpr[RS(instr)] == regs.gpr[RT(instr)]); break;
|
case 0x14: bl(instr, regs.gpr[RS(instr)] == regs.gpr[RT(instr)]); break;
|
||||||
case 0x15: bl(instr, regs.gpr[RS(instr)] != regs.gpr[RT(instr)]); break;
|
case 0x15: bl(instr, regs.gpr[RS(instr)] != regs.gpr[RT(instr)]); break;
|
||||||
case 0x16: bl(instr, regs.gpr[RS(instr)] <= 0); break;
|
case 0x16: bl(instr, regs.gpr[RS(instr)] <= 0); break;
|
||||||
|
|||||||
@@ -777,4 +777,30 @@ void Cpu::trap(bool cond) {
|
|||||||
FireException(regs, ExceptionCode::Trap, 0, regs.oldPC);
|
FireException(regs, ExceptionCode::Trap, 0, regs.oldPC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Cpu::mtc2(u32 instr) {
|
||||||
|
cop2Latch = regs.gpr[RT(instr)];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cpu::mfc2(u32 instr) {
|
||||||
|
s32 value = cop2Latch;
|
||||||
|
regs.gpr[RT(instr)] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cpu::dmtc2(u32 instr) {
|
||||||
|
cop2Latch = regs.gpr[RT(instr)];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cpu::dmfc2(u32 instr) {
|
||||||
|
regs.gpr[RT(instr)] = cop2Latch;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cpu::ctc2(u32) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cpu::cfc2(u32) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -61,6 +61,7 @@ void Cop1::decode(Cpu& cpu, u32 instr) {
|
|||||||
case 0x0D: truncws(regs, instr); break;
|
case 0x0D: truncws(regs, instr); break;
|
||||||
case 0x0E: ceilws(regs, instr); break;
|
case 0x0E: ceilws(regs, instr); break;
|
||||||
case 0x0F: floorws(regs, instr); break;
|
case 0x0F: floorws(regs, instr); break;
|
||||||
|
case 0x20: FireException(regs, ExceptionCode::FloatingPointError, 2, regs.oldPC); break;
|
||||||
case 0x21: cvtds(regs, instr); break;
|
case 0x21: cvtds(regs, instr); break;
|
||||||
case 0x24: cvtws(regs, instr); break;
|
case 0x24: cvtws(regs, instr); break;
|
||||||
case 0x25: cvtls(regs, instr); break;
|
case 0x25: cvtls(regs, instr); break;
|
||||||
@@ -80,7 +81,7 @@ void Cop1::decode(Cpu& cpu, u32 instr) {
|
|||||||
case 0x3D: ccond<float>(regs, instr, NGE); break;
|
case 0x3D: ccond<float>(regs, instr, NGE); break;
|
||||||
case 0x3E: ccond<float>(regs, instr, LE); break;
|
case 0x3E: ccond<float>(regs, instr, LE); break;
|
||||||
case 0x3F: ccond<float>(regs, instr, NGT); break;
|
case 0x3F: ccond<float>(regs, instr, NGT); break;
|
||||||
default: util::panic("Unimplemented COP1 function S[{} {}] ({:08X}) ({:016lX})", mask_fun >> 3, mask_fun & 7, instr, regs.oldPC);
|
default: util::panic("Unimplemented COP1 function S[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x11: // d
|
case 0x11: // d
|
||||||
@@ -102,6 +103,7 @@ void Cop1::decode(Cpu& cpu, u32 instr) {
|
|||||||
case 0x0E: ceilwd(regs, instr); break;
|
case 0x0E: ceilwd(regs, instr); break;
|
||||||
case 0x0F: floorwd(regs, instr); break;
|
case 0x0F: floorwd(regs, instr); break;
|
||||||
case 0x20: cvtsd(regs, instr); break;
|
case 0x20: cvtsd(regs, instr); break;
|
||||||
|
case 0x21: FireException(regs, ExceptionCode::FloatingPointError, 2, regs.oldPC); break;
|
||||||
case 0x24: cvtwd(regs, instr); break;
|
case 0x24: cvtwd(regs, instr); break;
|
||||||
case 0x25: cvtld(regs, instr); break;
|
case 0x25: cvtld(regs, instr); break;
|
||||||
case 0x30: ccond<double>(regs, instr, F); break;
|
case 0x30: ccond<double>(regs, instr, F); break;
|
||||||
@@ -120,7 +122,7 @@ void Cop1::decode(Cpu& cpu, u32 instr) {
|
|||||||
case 0x3D: ccond<double>(regs, instr, NGE); break;
|
case 0x3D: ccond<double>(regs, instr, NGE); break;
|
||||||
case 0x3E: ccond<double>(regs, instr, LE); break;
|
case 0x3E: ccond<double>(regs, instr, LE); break;
|
||||||
case 0x3F: ccond<double>(regs, instr, NGT); break;
|
case 0x3F: ccond<double>(regs, instr, NGT); break;
|
||||||
default: util::panic("Unimplemented COP1 function D[{} {}] ({:08X}) ({:016lX})", mask_fun >> 3, mask_fun & 7, instr, regs.oldPC);
|
default: util::panic("Unimplemented COP1 function D[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x14: // w
|
case 0x14: // w
|
||||||
@@ -131,7 +133,8 @@ void Cop1::decode(Cpu& cpu, u32 instr) {
|
|||||||
case 0x06: movw(regs, instr); break;
|
case 0x06: movw(regs, instr); break;
|
||||||
case 0x20: cvtsw(regs, instr); break;
|
case 0x20: cvtsw(regs, instr); break;
|
||||||
case 0x21: cvtdw(regs, instr); break;
|
case 0x21: cvtdw(regs, instr); break;
|
||||||
default: util::panic("Unimplemented COP1 function W[{} {}] ({:08X}) ({:016lX})", mask_fun >> 3, mask_fun & 7, instr, regs.oldPC);
|
case 0x24: FireException(regs, ExceptionCode::FloatingPointError, 2, regs.oldPC); break;
|
||||||
|
default: util::panic("Unimplemented COP1 function W[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x15: // l
|
case 0x15: // l
|
||||||
@@ -142,7 +145,8 @@ void Cop1::decode(Cpu& cpu, u32 instr) {
|
|||||||
case 0x06: movl(regs, instr); break;
|
case 0x06: movl(regs, instr); break;
|
||||||
case 0x20: cvtsl(regs, instr); break;
|
case 0x20: cvtsl(regs, instr); break;
|
||||||
case 0x21: cvtdl(regs, instr); break;
|
case 0x21: cvtdl(regs, instr); break;
|
||||||
default: util::panic("Unimplemented COP1 function L[{} {}] ({:08X}) ({:016lX})", mask_fun >> 3, mask_fun & 7, instr, regs.oldPC);
|
case 0x24: FireException(regs, ExceptionCode::FloatingPointError, 2, regs.oldPC); break;
|
||||||
|
default: util::panic("Unimplemented COP1 function L[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: util::panic("Unimplemented COP1 instruction {} {}", mask_sub >> 3, mask_sub & 7);
|
default: util::panic("Unimplemented COP1 instruction {} {}", mask_sub >> 3, mask_sub & 7);
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#include <n64/core/cpu/registers/Cop1.hpp>
|
#include <n64/core/cpu/registers/Cop1.hpp>
|
||||||
#include <n64/core/cpu/Registers.hpp>
|
#include <n64/core/cpu/Registers.hpp>
|
||||||
#include <n64/core/Mem.hpp>
|
#include <n64/core/Mem.hpp>
|
||||||
#include <util.hpp>
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cfenv>
|
#include <cfenv>
|
||||||
|
|
||||||
@@ -228,7 +227,7 @@ inline bool CalculateCondition(Registers& regs, T fs, T ft, CompConds cond) {
|
|||||||
if(std::isnan(fs) || std::isnan(ft)) {
|
if(std::isnan(fs) || std::isnan(ft)) {
|
||||||
regs.cop1.fcr31.flag_invalid_operation = true;
|
regs.cop1.fcr31.flag_invalid_operation = true;
|
||||||
regs.cop1.fcr31.cause_invalid_operation = true;
|
regs.cop1.fcr31.cause_invalid_operation = true;
|
||||||
FireException(regs, ExceptionCode::FloatingPointError, 0, regs.oldPC);
|
FireException(regs, ExceptionCode::FloatingPointError, 1, regs.oldPC);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CalculateCondition(regs, fs, ft, static_cast<CompConds>(cond - 8));
|
return CalculateCondition(regs, fs, ft, static_cast<CompConds>(cond - 8));
|
||||||
|
|||||||
@@ -36,9 +36,6 @@ void DMA(Mem& mem, Registers& regs) {
|
|||||||
MMIO& mmio = mem.mmio;
|
MMIO& mmio = mem.mmio;
|
||||||
SI& si = mmio.si;
|
SI& si = mmio.si;
|
||||||
si.status.dmaBusy = false;
|
si.status.dmaBusy = false;
|
||||||
if(si.status.dmaBusy) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
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++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user