support fully disabling dynarec

This commit is contained in:
Dillon Beliveau 2023-08-27 23:46:50 -07:00
parent 9f1e3f0df7
commit 91c198fe60
10 changed files with 76 additions and 1 deletions

View file

@ -1,5 +1,7 @@
#include "r4300i.h"
#ifdef N64_DYNAREC_ENABLED
#include <dynarec/dynarec.h>
#endif
#include <log.h>
#include <system/n64system.h>
#include <mem/n64bus.h>
@ -859,7 +861,9 @@ void cp0_status_updated() {
(N64CPU.cp0.kernel_mode && N64CPU.cp0.status.kx)
|| (N64CPU.cp0.supervisor_mode && N64CPU.cp0.status.sx)
|| (N64CPU.cp0.user_mode && N64CPU.cp0.status.ux);
#ifdef N64_DYNAREC_ENABLED
n64dynarec.sysconfig.fr = N64CP0.status.fr;
#endif
N64CP0.resolve_virtual_address = get_resolve_virtual_address_handler();
r4300i_interrupt_update();
}

View file

@ -8,7 +8,9 @@
#include <system/n64system.h>
#include <rdp/rdp.h>
#include <mem/n64bus.h>
#ifdef N64_DYNAREC_ENABLED
#include <cpu/dynarec/dynarec.h>
#endif
#include <mem/mem_util.h>
#include "rsp_types.h"
@ -216,9 +218,11 @@ INLINE void rsp_dma_write() {
// Invalidate all pages touched by the DMA
// This is probably unnecessary, since why would someone be copying code from the RSP to the CPU and then executing it?
#ifdef N64_DYNAREC_ENABLED
for (int j = 0; j < length; j += BLOCKCACHE_PAGE_SIZE) {
invalidate_dynarec_page(dram_address + j);
}
#endif
int skip = i == N64RSP.io.dma.count ? 0 : N64RSP.io.dma.skip;

View file

@ -4,7 +4,9 @@
#include <stdbool.h>
#include <assert.h>
#include <util.h>
#ifdef N64_DYNAREC_V1_ENABLED
#include <cpu/dynarec/rsp_dynarec.h>
#endif
#include "mips_instruction_decode.h"
#define SP_DMEM_SIZE 0x1000
@ -107,10 +109,14 @@ typedef union dram_addr {
ASSERTWORD(dram_addr_t);
#ifdef N64_DYNAREC_V1_ENABLED
typedef struct rsp_dynarec rsp_dynarec_t;
#endif
typedef struct rsp {
#ifdef N64_DYNAREC_V1_ENABLED
rsp_dynarec_t *dynarec;
#endif
u32 gpr[32];
u16 prev_pc;

View file

@ -44,8 +44,12 @@ int main(int argc, char** argv) {
bool help = false;
cflags_add_bool(flags, 'h', "help", &help, "Display this help message");
#ifdef N64_DYNAREC_ENABLED
bool interpreter = false;
cflags_add_bool(flags, 'i', "interpreter", &interpreter, "Force the use of the interpreter");
#else
bool interpreter = true;
#endif
bool software_mode = false;
cflags_add_bool(flags, 's', "software-mode", &software_mode, "Use software mode RDP (UNFINISHED!)");

View file

@ -14,7 +14,9 @@
#include <metrics.h>
#include <mem/pif.h>
#include <mem/mem_util.h>
#ifdef N64_DYNAREC_ENABLED
#include <cpu/dynarec/dynarec.h>
#endif
#include <frontend/audio.h>
#include <frontend/render.h>
#include <disassemble.h>
@ -22,7 +24,9 @@
static bool show_metrics_window = false;
static bool show_imgui_demo_window = false;
static bool show_settings_window = false;
#ifdef N64_DYNAREC_ENABLED
static bool show_dynarec_block_browser = false;
#endif
static bool is_fullscreen = false;
@ -122,7 +126,9 @@ void render_menubar() {
{
if (ImGui::MenuItem("Metrics", nullptr, show_metrics_window)) { show_metrics_window = !show_metrics_window; }
if (ImGui::MenuItem("Settings", nullptr, show_settings_window)) { show_settings_window = !show_settings_window; }
#ifdef N64_DYNAREC_ENABLED
if (ImGui::MenuItem("Dynarec Block Browser", nullptr, show_dynarec_block_browser)) { show_dynarec_block_browser = !show_dynarec_block_browser; }
#endif
if (ImGui::MenuItem("ImGui Demo Window", nullptr, show_imgui_demo_window)) { show_imgui_demo_window = !show_imgui_demo_window; }
ImGui::EndMenu();
}
@ -156,7 +162,9 @@ void render_metrics_window() {
rsp_steps.add_point(get_metric(METRIC_RSP_STEPS));
double frametime = 1000.0f / ImGui::GetIO().Framerate;
frame_times.add_point(frametime);
#ifdef N64_DYNAREC_ENABLED
codecache_bytes_used.add_point(n64dynarec.codecache_used);
#endif
audiostream_bytes_available.add_point(get_metric(METRIC_AUDIOSTREAM_AVAILABLE));
si_interrupts.add_point(get_metric(METRIC_SI_INTERRUPT));
@ -202,12 +210,14 @@ void render_metrics_window() {
ImPlot::EndPlot();
}
#ifdef N64_DYNAREC_ENABLED
ImPlot::SetNextAxisLimits(ImAxis_Y1, 0, n64dynarec.codecache_size, ImGuiCond_Always);
ImPlot::SetNextAxisLimits(ImAxis_X1, 0, METRICS_HISTORY_ITEMS, ImGuiCond_Always);
if (ImPlot::BeginPlot("Codecache bytes used")) {
ImPlot::PlotBars("Codecache bytes used", codecache_bytes_used.data, METRICS_HISTORY_ITEMS, 1, 0, flags, codecache_bytes_used.offset);
ImPlot::EndPlot();
}
#endif
ImGui::Text("Audio stream bytes available: %" PRId64, get_metric(METRIC_AUDIOSTREAM_AVAILABLE));
ImPlot::SetNextAxisLimits(ImAxis_Y1, 0, audiostream_bytes_available.max(), ImGuiCond_Always);
@ -238,6 +248,8 @@ void render_settings_window() {
ImGui::Begin("Settings", &show_settings_window);
ImGui::End();
}
#ifdef N64_DYNAREC_ENABLED
struct block {
block(u32 address, int outer_index, int inner_index) : address(address), outer_index(outer_index), inner_index(inner_index) {}
block() : block(0, 0, 0) {}
@ -372,6 +384,7 @@ void render_dynarec_block_browser() {
ImGui::EndGroup();
ImGui::End();
}
#endif
void render_ui() {
if (SDL_GetMouseFocus() || n64sys.mem.rom.rom == nullptr) {
@ -380,7 +393,9 @@ void render_ui() {
if (show_metrics_window) { render_metrics_window(); }
if (show_imgui_demo_window) { ImGui::ShowDemoWindow(&show_imgui_demo_window); }
if (show_settings_window) { render_settings_window(); }
#ifdef N64_DYNAREC_ENABLED
if (show_dynarec_block_browser) { render_dynarec_block_browser(); }
#endif
}
static VkAllocationCallbacks* g_Allocator = NULL;

View file

@ -4,7 +4,9 @@
#include <mem/mem_util.h>
#include <system/scheduler.h>
#include <mem/backup.h>
#ifdef N64_DYNAREC_ENABLED
#include <dynarec/dynarec.h>
#endif
#include <timing.h>
#include "pi.h"
@ -177,15 +179,19 @@ void write_word_pireg(u32 address, u32 value) {
u8 b = dma_cart_read_byte(cart_addr + i);
logtrace("CART to DRAM: Copying 0x%02X from 0x%08X to 0x%08X", b, cart_addr + i, dram_addr + i);
RDRAM_BYTE(dram_addr + i) = b;
#ifdef N64_DYNAREC_ENABLED
invalidate_dynarec_page(BYTE_ADDRESS(dram_addr + i));
#endif
}
#ifdef N64_DYNAREC_ENABLED
u32 begin_index = BLOCKCACHE_OUTER_INDEX(dram_addr);
u32 end_index = BLOCKCACHE_OUTER_INDEX(dram_addr + length);
for (u32 i = begin_index; i <= end_index; i++) {
invalidate_dynarec_page_by_index(i);
}
#endif
int complete_in = timing_pi_access(pi_get_domain(cart_addr), length);
n64sys.pi.dma_busy = true;

View file

@ -4,7 +4,9 @@
#include <interface/ai.h>
#include <cpu/rsp_interface.h>
#include <rdp/rdp.h>
#ifdef N64_DYNAREC_ENABLED
#include <cpu/dynarec/dynarec.h>
#endif
#include <rsp.h>
#include <interface/si.h>
#include <interface/pi.h>
@ -369,7 +371,9 @@ void n64_write_physical_dword(u32 address, u64 value) {
logfatal("Tried to write to unaligned DWORD");
}
logdebug("Writing 0x%016" PRIX64 " to [0x%08X]", value, address);
#ifdef N64_DYNAREC_ENABLED
invalidate_dynarec_page(address);
#endif
switch (address) {
case REGION_RDRAM:
dword_to_byte_array((u8*) &n64sys.mem.rdram, DWORD_ADDRESS(address) - SREGION_RDRAM, value);
@ -498,7 +502,9 @@ void n64_write_physical_word(u32 address, u32 value) {
logfatal("Tried to write to unaligned WORD");
}
logdebug("Writing 0x%08X to [0x%08X]", value, address);
#ifdef N64_DYNAREC_ENABLED
invalidate_dynarec_page(WORD_ADDRESS(address));
#endif
switch (address) {
case REGION_RDRAM:
word_to_byte_array((u8*) &n64sys.mem.rdram, WORD_ADDRESS(address) - SREGION_RDRAM, value);
@ -651,7 +657,9 @@ void n64_write_physical_half(u32 address, u32 value) {
logfatal("Tried to write to unaligned HALF");
}
logdebug("Writing 0x%04X to [0x%08X]", value & 0xFFFF, address);
#ifdef N64_DYNAREC_ENABLED
invalidate_dynarec_page(HALF_ADDRESS(address));
#endif
switch (address) {
case REGION_RDRAM:
half_to_byte_array((u8*) &n64sys.mem.rdram, HALF_ADDRESS(address) - SREGION_RDRAM, value);
@ -779,7 +787,9 @@ u16 n64_read_physical_half(u32 address) {
void n64_write_physical_byte(u32 address, u32 value) {
logdebug("Writing 0x%02X to [0x%08X]", value & 0xFF, address);
#ifdef N64_DYNAREC_ENABLED
invalidate_dynarec_page(BYTE_ADDRESS(address));
#endif
switch (address) {
case REGION_RDRAM:
n64sys.mem.rdram[BYTE_ADDRESS(address)] = value;

View file

@ -1,5 +1,7 @@
#include "crashdump.h"
#ifdef N64_DYNAREC_ENABLED
#include <dynarec/rsp_dynarec.h>
#endif
#include <generated/version.h>
#include <rsp.h>
@ -28,6 +30,7 @@ const char* n64_save_system_state(const char* crash_reason) {
crash_dump->scheduler_base = (uintptr_t)&n64scheduler;
memcpy(&crash_dump->scheduler, &n64scheduler, crash_dump->scheduler_size);
#ifdef N64_DYNAREC_ENABLED
crash_dump->dynarec_size = sizeof(n64_dynarec_t);
crash_dump->dynarec_base = (uintptr_t)&n64dynarec;
memcpy(&crash_dump->dynarec, &n64dynarec, crash_dump->dynarec_size);
@ -43,6 +46,7 @@ const char* n64_save_system_state(const char* crash_reason) {
crash_dump->rsp_codecache_size = RSP_CODECACHE_SIZE;
crash_dump->rsp_codecache_base = (uintptr_t)n64rsp.dynarec->codecache;
memcpy(&crash_dump->rsp_codecache, n64rsp.dynarec->codecache, crash_dump->rsp_codecache_size);
#endif
size_t needed = snprintf(NULL, 0, "%s.crashdump", n64sys.rom_path);
char* path_buf = malloc(needed + 1);

View file

@ -1,7 +1,9 @@
#ifndef N64_CRASHDUMP_H
#define N64_CRASHDUMP_H
#ifdef N64_DYNAREC_ENABLED
#include <dynarec/dynarec.h>
#endif
#include <system/n64system.h>
#include <system/scheduler.h>
#include <generated/version.h>
@ -28,6 +30,7 @@ typedef struct n64_crashdump {
uintptr_t scheduler_base;
scheduler_t scheduler;
#ifdef N64_DYNAREC_ENABLED
size_t dynarec_size;
uintptr_t dynarec_base;
n64_dynarec_t dynarec;
@ -43,6 +46,7 @@ typedef struct n64_crashdump {
size_t rsp_codecache_size;
uintptr_t rsp_codecache_base;
u8 rsp_codecache[RSP_CODECACHE_SIZE];
#endif
} n64_crashdump_t;

View file

@ -10,7 +10,10 @@
#include <interface/vi.h>
#include <interface/ai.h>
#include <cpu/rsp.h>
#ifdef N64_DYNAREC_ENABLED
#include <cpu/dynarec/dynarec.h>
#include <dynarec/rsp_dynarec.h>
#endif
#include <util.h>
#ifndef N64_WIN
#include <sys/mman.h>
@ -26,7 +29,6 @@
#include <frontend/device.h>
#include <interface/si.h>
#include <interface/pi.h>
#include <dynarec/rsp_dynarec.h>
#include <mem/pif.h>
#include <timing.h>
@ -83,7 +85,9 @@ void init_n64system(const char* rom_path, bool enable_frontend, bool enable_debu
n64sys.video_type = video_type;
mprotect_codecache();
#ifdef N64_DYNAREC_ENABLED
n64_dynarec_init(codecache, CODECACHE_SIZE);
#endif
#ifdef N64_DYNAREC_V1_ENABLED
N64RSP.dynarec = rsp_dynarec_init(rsp_codecache, RSP_CODECACHE_SIZE);
#endif
@ -159,18 +163,22 @@ void reset_n64system() {
n64sys.vi.num_fields = 1;
n64sys.vi.cycles_per_halfline = 1000;
#ifdef N64_DYNAREC_ENABLED
invalidate_dynarec_all_pages();
#endif
scheduler_reset();
scheduler_enqueue_relative((u64)n64sys.vi.cycles_per_halfline, SCHEDULER_VI_HALFLINE);
}
#ifdef N64_DYNAREC_ENABLED
INLINE int jit_system_step() {
int taken = n64_dynarec_step();
N64CP0.count += taken;
N64CP0.count &= 0x1FFFFFFFF;
return taken;
}
#endif
INLINE int interpreter_system_step_matchjit(const int cycles) {
for (int i = 0; i < cycles; i++) {
@ -308,7 +316,11 @@ int n64_system_step(bool dynarec, int steps) {
int taken;
if (dynarec) {
#ifdef N64_DYNAREC_ENABLED
taken = jit_system_step();
#else
logfatal("Dynarec is not enabled!");
#endif
} else {
taken = interpreter_system_step_matchjit(steps);
}
@ -350,6 +362,7 @@ void n64_queue_reset() {
scheduler_enqueue_relative(0, SCHEDULER_RESET_SYSTEM);
}
#ifdef N64_DYNAREC_ENABLED
void jit_system_loop() {
while (!should_quit) {
static int cpu_steps = 0;
@ -381,6 +394,7 @@ void jit_system_loop() {
}
force_persist_backup();
}
#endif
void interpreter_system_loop() {
while (!should_quit) {
@ -394,11 +408,15 @@ void interpreter_system_loop() {
}
void n64_system_loop() {
#ifdef N64_DYNAREC_ENABLED
if (n64sys.use_interpreter) {
#endif
interpreter_system_loop();
#ifdef N64_DYNAREC_ENABLED
} else {
jit_system_loop();
}
#endif
}
void n64_system_cleanup() {