mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 18:25:35 -04:00
e1dae7fcbd
Adds psx-oracle.exe alongside psx-runtime.exe, following the Genesis recomp hybrid pattern (two targets from shared sources): - psx-runtime: recompiled BIOS (stub_interpreter.c), port 4370 - psx-oracle: R3000A interpreter (psx_interpreter.c), port 4371 The interpreter implements the full MIPS I instruction set: ALU, shifts, mult/div, branches, jumps, loads/stores (incl LWL/LWR), COP0 (MFC0/MTC0/RFE), COP2/GTE (delegated to gte.cpp), SYSCALL/BREAK. Includes 1M-entry per-instruction trace ring and 64 PC breakpoints — the tooling gap that blocked VSync counter diagnosis (DuckStation's TCP debug server only had 2-3 breakpoint slots, no PC breakpoints). Also extends memory control register range to 0x1F80103C (was 0x1F801020) for the interpreter's early BIOS init path. Verified: oracle boots from BFC00000 and correctly executes the first 20+ BIOS instructions. Hits unknown SPECIAL func at PC=0x68 later in boot — instruction coverage issue to debug next session. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
60 lines
1.8 KiB
C
60 lines
1.8 KiB
C
/* psx_interpreter.h — R3000A interpreter for oracle builds.
|
|
*
|
|
* Oracle-only: provides a cycle-accurate reference implementation
|
|
* of the PSX CPU. Shares the same CPUState and memory bus as the
|
|
* recompiled native build. The native build links stub_interpreter.c
|
|
* instead (all functions are no-ops).
|
|
*
|
|
* Follows the Genesis/clown68000 pattern: two CMake targets from one
|
|
* source tree, gated by PSX_ORACLE_BUILD.
|
|
*/
|
|
|
|
#ifndef PSXRECOMP_V4_PSX_INTERPRETER_H
|
|
#define PSXRECOMP_V4_PSX_INTERPRETER_H
|
|
|
|
#include "cpu_state.h"
|
|
#include <stdint.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* Initialize interpreter state. Call once after CPUState is allocated. */
|
|
void interp_init(CPUState* cpu);
|
|
|
|
/* Execute exactly `count` instructions. Returns number actually executed
|
|
* (may be less if a breakpoint fires). */
|
|
uint32_t interp_step(CPUState* cpu, uint32_t count);
|
|
|
|
/* Run until breakpoint, halt, or max_instructions reached. */
|
|
uint32_t interp_run(CPUState* cpu, uint32_t max_instructions);
|
|
|
|
/* Check if interpreter hit a breakpoint on the last run. */
|
|
int interp_hit_breakpoint(void);
|
|
|
|
/* --- PC breakpoints --- */
|
|
int interp_break_add(uint32_t pc); /* returns slot, or -1 */
|
|
int interp_break_remove(uint32_t pc); /* returns 1 if removed */
|
|
void interp_break_clear_all(void);
|
|
|
|
/* --- Per-instruction trace ring --- */
|
|
typedef struct {
|
|
uint32_t pc;
|
|
uint32_t gpr[32];
|
|
uint32_t hi, lo;
|
|
uint32_t cop0_sr, cop0_cause, cop0_epc;
|
|
uint32_t insn; /* raw instruction word */
|
|
uint64_t seq; /* monotonic sequence number */
|
|
} InterpTraceEntry;
|
|
|
|
void interp_trace_enable(int on);
|
|
uint64_t interp_trace_count(void);
|
|
/* Get entry by index into ring (0 = oldest available). Returns NULL if OOB. */
|
|
const InterpTraceEntry* interp_trace_get(uint32_t ring_idx);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* PSXRECOMP_V4_PSX_INTERPRETER_H */
|