mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
Merge pull request #541 from RetroPortingToolKit/feat/mod-uncharged-guest-call
Add uncharged guest calls: run a guest function in zero guest time
This commit is contained in:
@@ -144,6 +144,23 @@ void psx_mod_write_code_word(uint32_t address, uint32_t value);
|
||||
uint32_t psx_mod_call_guest(struct CPUState* cpu, uint32_t function,
|
||||
uint32_t return_address, uint32_t a0, uint32_t a1,
|
||||
uint32_t a2, uint32_t a3);
|
||||
/* psx_mod_call_guest in zero guest time, for CPU/RAM work a game spends guest
|
||||
* time on while it loads (allocators, decoders, table builds). Every RAM,
|
||||
* register and device effect of the callee is kept, as if it executed in an
|
||||
* instant at the call's guest cycle: none of its cycles are charged, no
|
||||
* device advances and no interrupt is taken while it runs, and the caller's
|
||||
* pending mult/div, GTE and load-pipeline timing is as it was before the
|
||||
* call. Device work the callee starts (a DMA, a CD command) proceeds in guest
|
||||
* time after the return. A callee that executes more than budget_cycles
|
||||
* (0 = no limit) is charged in full from then on, so one that waits on a
|
||||
* device still completes; *charged (optional) is then set to 1. Inside a
|
||||
* render pass or another uncharged call, time is already frozen and this is
|
||||
* psx_mod_call_guest. The outcome depends only on guest state, so netplay
|
||||
* peers and rollback re-simulation agree. Returns v0. */
|
||||
uint32_t psx_mod_call_guest_uncharged(struct CPUState* cpu, uint32_t function,
|
||||
uint32_t return_address, uint32_t a0,
|
||||
uint32_t a1, uint32_t a2, uint32_t a3,
|
||||
uint32_t budget_cycles, int* charged);
|
||||
/* Deliver disc sectors into RAM exactly as a completed CD-ROM DMA would
|
||||
* (overlay capture, executable-page invalidation, CD DMA log when lba >= 0).
|
||||
* Word-aligned address and length. Returns 0 when the span leaves RAM. */
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#ifndef PSX_CYCLE_FREEZE_H
|
||||
#define PSX_CYCLE_FREEZE_H
|
||||
|
||||
/* Render-pass time freeze (render_pass.c, docs/RENDER_PASSES.md).
|
||||
/* Guest-time freeze: render passes (render_pass.c, docs/RENDER_PASSES.md)
|
||||
* and uncharged guest calls (mod_plugins.h psx_mod_call_guest_uncharged).
|
||||
*
|
||||
* Runtime-only: generated and overlay code never sees this header. It is kept
|
||||
* out of psx_cycles.h on purpose, because psx_cycles.h is part of the
|
||||
@@ -24,6 +25,10 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
extern int g_psx_render_pass_active;
|
||||
/* Set while guest time is frozen, by a render pass or an uncharged call:
|
||||
* devices are not serviced and no interrupt is delivered. Pass-only effects
|
||||
* (rolled-back stores, synchronous DMA) key on g_psx_render_pass_active. */
|
||||
extern int g_psx_guest_time_frozen;
|
||||
typedef struct PsxCycleFreeze {
|
||||
uint64_t cycle_count;
|
||||
uint64_t next_service;
|
||||
@@ -42,6 +47,18 @@ int psx_cycle_freeze_begin(PsxCycleFreeze *save, uint64_t watchdog_cycles,
|
||||
void (*overrun)(void));
|
||||
void psx_cycle_freeze_end(const PsxCycleFreeze *save);
|
||||
|
||||
/* Uncharged span: the same freeze without the pass's rollback. Code run
|
||||
* between begin and end keeps every effect on RAM, registers and devices, as
|
||||
* if it executed in an instant at the start cycle: end() puts the clock back,
|
||||
* so none of its cycles are charged, no device advanced and no interrupt was
|
||||
* taken meanwhile. A span that executes more than `budget_cycles` (0 = no
|
||||
* limit) thaws: from then on it runs on the live clock and all its cycles are
|
||||
* charged, so a callee that waits on a device still completes. begin()
|
||||
* returns 0 while time is already frozen (the caller then simply runs the
|
||||
* code). end() returns 1 when the span stayed uncharged. Spans do not nest. */
|
||||
int psx_cycle_uncharged_begin(PsxCycleFreeze *save, uint64_t budget_cycles);
|
||||
int psx_cycle_uncharged_end(const PsxCycleFreeze *save);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user