mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
2d915c3fa9
Phase 1 of the cycle-budgeted precise interrupt-take-point fix (root cause: compiled blocks take IRQs only at block edges; HW + the dirty-RAM interpreter take them at the exact instruction — oracle-confirmed at the Tomba 2 logo Timer1 debounce). Design validated with ChatGPT; full spec in PRECISE_IRQ_SLICE.md. This commit lands the additive, no-behavior-change foundation (Task #2) plus the prior session's diagnostic take-PC capture, and a build-hygiene dedup: - cycles_to_next_event() (interrupts.c): single source of truth — min guest-cycle distance to the next DELIVERABLE interrupt (source raises its I_STAT bit AND that bit is unmasked in i_mask). Aggregates VBLANK + per-peripheral queries. - timers/cdrom/dma/sio _cycles_to_irq(i_mask): each peripheral owns its own next-IRQ-distance query; all conservative under-estimates (smaller => slice more => never run past an event). - debug_server: cycles_to_next_event command for live validation. - interrupts.c: take-PC capture into the IRQ_DELIVER event-ring aux (prior session's diagnostic; records the architectural take-PC for cross-backend diff). - overlay_loader.c: remove duplicate psx_native_bad_entry definition (HEAD had it twice; would not link cleanly). Live-validated at the logo: returns the VBLANK distance, correctly excludes the three free-running (unarmed/masked) timers and idle CD/DMA/SIO. Runtime-only, no regen. The two-tier executor (Task #3) that consumes this is next. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
40 lines
1.2 KiB
C
40 lines
1.2 KiB
C
#ifndef PSXRECOMP_TIMERS_H
|
|
#define PSXRECOMP_TIMERS_H
|
|
|
|
#include <stdint.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#define TIMER_BASE 0x1F801100
|
|
|
|
void timers_init(void);
|
|
void timers_get_snapshot(uint16_t counter[3], uint32_t mode[3],
|
|
uint16_t target[3], int32_t irq_line[3],
|
|
uint32_t frac[3]);
|
|
void timers_set_snapshot(const uint16_t counter[3], const uint32_t mode[3],
|
|
const uint16_t target[3], const int32_t irq_line[3],
|
|
const uint32_t frac[3]);
|
|
|
|
/* MMIO read/write for 0x1F801100..0x1F80112F.
|
|
* Accepts 16-bit or 32-bit access (caller zero-extends). */
|
|
uint32_t timers_read(uint32_t addr);
|
|
void timers_write(uint32_t addr, uint32_t value);
|
|
|
|
/* Advance all timers by guest CPU cycles. Used by native block-cycle builds. */
|
|
void timers_advance(uint32_t cycles);
|
|
|
|
/* Cycle-budgeted precise event slicing: guest CPU cycles until a timer raises a
|
|
* DELIVERABLE IRQ (unmasked in i_mask + mode-armed). UINT32_MAX if none. */
|
|
uint32_t timers_cycles_to_irq(uint32_t i_mask);
|
|
|
|
/* Legacy coarse tick used by interpreter/oracle builds. */
|
|
void timers_tick(int cycles);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* PSXRECOMP_TIMERS_H */
|