mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
Merge remote-tracking branch 'origin/master' into landtmp/493
This commit is contained in:
@@ -27,6 +27,9 @@
|
||||
#include "overlay_backend.h"
|
||||
#include "cpu_state.h"
|
||||
#include "pgxp.h"
|
||||
#ifndef PSX_NO_DEBUG_TOOLS
|
||||
#include "psx_disasm.h"
|
||||
#endif
|
||||
#include "dma.h"
|
||||
#include "gpu.h"
|
||||
#include "gpu_render.h" /* gr_scale + gr_render_display_hires (screenshot_hires) */
|
||||
@@ -5185,6 +5188,60 @@ static void handle_get_registers(int id, const char *json)
|
||||
free(buf);
|
||||
}
|
||||
|
||||
/* disasm: disassemble guest instructions. {"cmd":"disasm","addr":"0x8001121C",
|
||||
* "count":32}. Reads live guest memory, so it works on EXE code and on
|
||||
* RAM-installed/overlay code alike. Uses the recompiler's MIPS decoder.
|
||||
* Reads go through psx_peek_word (main RAM / scratchpad / BIOS ROM only, no
|
||||
* device reads, no read hooks); a word outside those comes back as
|
||||
* {"word":null,"text":"<unreadable>"}. Compiled only with the debug tools,
|
||||
* like the sources it needs (runtime.cmake). */
|
||||
#ifndef PSX_NO_DEBUG_TOOLS
|
||||
static void handle_disasm(int id, const char *json)
|
||||
{
|
||||
char addr_str[32];
|
||||
if (!json_get_str(json, "addr", addr_str, sizeof(addr_str))) {
|
||||
send_err(id, "missing addr"); return;
|
||||
}
|
||||
const char *hex = addr_str;
|
||||
if (hex[0] == '0' && (hex[1] == 'x' || hex[1] == 'X')) hex += 2;
|
||||
char *hex_end = NULL;
|
||||
unsigned long long addr_val = strtoull(hex, &hex_end, 16);
|
||||
if (hex_end == hex || *hex_end != '\0' || addr_val > 0xFFFFFFFFull) {
|
||||
send_err(id, "bad addr"); return;
|
||||
}
|
||||
uint32_t addr = (uint32_t)addr_val & ~3u;
|
||||
int count = json_get_int(json, "count", 16);
|
||||
if (count < 1) count = 1;
|
||||
if (count > 256) count = 256;
|
||||
|
||||
size_t bufsz = 512u + (size_t)count * 160u;
|
||||
char *out = (char *)malloc(bufsz);
|
||||
if (!out) { send_err(id, "oom"); return; }
|
||||
int pos = snprintf(out, bufsz,
|
||||
"{\"id\":%d,\"ok\":true,\"addr\":\"0x%08X\",\"count\":%d,\"lines\":[",
|
||||
id, addr, count);
|
||||
char text[128];
|
||||
for (int i = 0; i < count; i++) {
|
||||
uint32_t a = addr + (uint32_t)i * 4u;
|
||||
uint32_t w = 0;
|
||||
if (!psx_peek_word(a, &w)) {
|
||||
pos += snprintf(out + pos, bufsz - (size_t)pos,
|
||||
"%s{\"addr\":\"0x%08X\",\"word\":null,\"text\":\"<unreadable>\"}",
|
||||
i ? "," : "", a);
|
||||
continue;
|
||||
}
|
||||
text[0] = '\0';
|
||||
(void)psx_disasm_one(w, a, text, (int)sizeof(text));
|
||||
pos += snprintf(out + pos, bufsz - (size_t)pos,
|
||||
"%s{\"addr\":\"0x%08X\",\"word\":\"0x%08X\",\"text\":\"%s\"}",
|
||||
i ? "," : "", a, w, text);
|
||||
}
|
||||
pos += snprintf(out + pos, bufsz - (size_t)pos, "]}");
|
||||
debug_server_send_line(out);
|
||||
free(out);
|
||||
}
|
||||
#endif /* !PSX_NO_DEBUG_TOOLS */
|
||||
|
||||
static void handle_read_ram(int id, const char *json)
|
||||
{
|
||||
char addr_str[32];
|
||||
@@ -10073,7 +10130,7 @@ static void wtrace_fill_entry(WriteTraceEntry *e, uint64_t seq,
|
||||
* instead of the stale last-CPU-store PC (which is meaningless mid-DMA). */
|
||||
if (g_dma_exec_depth > 0) {
|
||||
e->dma_ch = (int8_t)g_dma_cur_ch;
|
||||
if (g_dma_initiator_pc) e->pc = g_dma_initiator_pc;
|
||||
e->pc = g_dma_initiator_pc; /* 0 = unknown; never a stale CPU store PC */
|
||||
} else {
|
||||
e->dma_ch = -1;
|
||||
}
|
||||
@@ -11680,6 +11737,22 @@ static void handle_wtrace_dump(int id, const char *json)
|
||||
if (json_get_str(json, "addr_hi", hi_str, sizeof(hi_str)))
|
||||
filter_hi = hex_to_u32(hi_str) & 0x1FFFFFFFu;
|
||||
|
||||
/* Filter the recorded producer PC, segment-masked like the address filter
|
||||
* (KSEG0/KSEG1/KUSEG alias). DMA entries use the initiator PC stored by
|
||||
* wtrace_fill_entry; an unknown (0) initiator matches only when no PC
|
||||
* bound is given. Post-hoc only: recording, fingerprints and guest
|
||||
* execution are unchanged. pc_lo/pc_hi echo the raw request. */
|
||||
uint32_t pc_lo = 0, pc_hi = 0xFFFFFFFFu;
|
||||
int pc_filtered = 0;
|
||||
/* Default upper bound sits above every masked PC so no entry is excluded. */
|
||||
uint32_t pc_lo_m = 0, pc_hi_m = 0x20000000u;
|
||||
if (json_get_str(json, "pc_lo", lo_str, sizeof(lo_str))) {
|
||||
pc_lo = hex_to_u32(lo_str); pc_lo_m = pc_lo & 0x1FFFFFFFu; pc_filtered = 1;
|
||||
}
|
||||
if (json_get_str(json, "pc_hi", hi_str, sizeof(hi_str))) {
|
||||
pc_hi = hex_to_u32(hi_str); pc_hi_m = pc_hi & 0x1FFFFFFFu; pc_filtered = 1;
|
||||
}
|
||||
|
||||
/* Optional frame-window filter — the "query the ring for the window of
|
||||
* interest" primitive. Lets a caller reach entries in the MIDDLE of a deep,
|
||||
* high-traffic ring (which oldest-N / newest-N paging cannot). -1 = unbounded. */
|
||||
@@ -11703,8 +11776,9 @@ static void handle_wtrace_dump(int id, const char *json)
|
||||
size_t pos = 0;
|
||||
uint32_t emitted = 0;
|
||||
pos += snprintf(buf + pos, BUF_SZ - pos,
|
||||
"{\"id\":%d,\"ok\":true,\"total\":%llu,\"available\":%u,\"entries\":[",
|
||||
id, (unsigned long long)total, avail);
|
||||
"{\"id\":%d,\"ok\":true,\"total\":%llu,\"available\":%u,"
|
||||
"\"pc_lo\":\"0x%08X\",\"pc_hi\":\"0x%08X\",\"entries\":[",
|
||||
id, (unsigned long long)total, avail, pc_lo, pc_hi);
|
||||
for (uint32_t i = 0; i < avail && emitted < MAX_OUT && pos < BUF_SZ - 256; i++) {
|
||||
uint32_t idx;
|
||||
if (newest_first) {
|
||||
@@ -11715,6 +11789,10 @@ static void handle_wtrace_dump(int id, const char *json)
|
||||
}
|
||||
WriteTraceEntry *e = &s_wtrace[idx];
|
||||
if (e->addr < filter_lo || e->addr >= filter_hi) continue;
|
||||
if (pc_filtered) {
|
||||
uint32_t epc = e->pc & 0x1FFFFFFFu;
|
||||
if (e->pc == 0 || epc < pc_lo_m || epc >= pc_hi_m) continue;
|
||||
}
|
||||
if (frame_lo >= 0 && (int)e->frame < frame_lo) continue;
|
||||
if (frame_hi >= 0 && (int)e->frame > frame_hi) continue;
|
||||
pos += snprintf(buf + pos, BUF_SZ - pos,
|
||||
@@ -14789,6 +14867,9 @@ static const CmdEntry s_commands[] = {
|
||||
{ "c0_history", handle_c0_history },
|
||||
{ "capture_quads", handle_capture_quads },
|
||||
{ "get_quads", handle_get_quads },
|
||||
#ifndef PSX_NO_DEBUG_TOOLS
|
||||
{ "disasm", handle_disasm },
|
||||
#endif
|
||||
{ "gte_state", handle_gte_state },
|
||||
{ "gte_ring_dump", handle_gte_ring_dump },
|
||||
{ "gte_intpl_dump", handle_gte_intpl_dump },
|
||||
|
||||
Reference in New Issue
Block a user