mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 18:25:35 -04:00
phase1.0a: sio_tick(int cycles) signature + cycle-paced macro stub
Pure signature change. No behavior change. Foundation for Phase 1.0b/c/d
which will incrementally add cycle-paced SIO byte timing.
- sio_tick(void) -> sio_tick(int cycles)
- legacy body ignores cycles via (void)cycles, runs original access-paced
IRQ countdown verbatim
- SIO_MODEL_CYCLE_PACED macro defined and defaults to 0; reserved for
future cycle-paced model (no #if branches engaged in this commit)
- callers updated to pass 0: sio_read, sio_write end, sio_card_burst_drain
loop body in sio.c; mmio_read32/16/8 I_STAT-read paths in memory.c;
interp_check_interrupts in psx_interpreter.c
Validation against committed baseline 8b0fc34: identical state at t=20s
(tx_writes=976, exception_entries=1215) and t=30s (tx_writes=5352);
pad polling armed 5768/5768 no_ack=0; 4x CROSS press succeeds; card txn
distribution matches baseline (10 txns reach bytes=15 ts=10 READ_DATA,
matching the SELECT-deassert fix from the previous commit).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -16,9 +16,14 @@ void sio_init(void);
|
||||
uint32_t sio_read(uint32_t addr);
|
||||
void sio_write(uint32_t addr, uint32_t value);
|
||||
|
||||
/* Advance SIO timing by one step. Called from psx_check_interrupts().
|
||||
* Fires pending IRQ7 after the transfer delay expires. */
|
||||
void sio_tick(void);
|
||||
/* Advance SIO timing.
|
||||
*
|
||||
* Phase 1.0a signature change. The cycles arg is reserved for a future
|
||||
* cycle-paced model (SIO_MODEL_CYCLE_PACED=1). With the default macro
|
||||
* setting (SIO_MODEL_CYCLE_PACED=0) the cycles arg is ignored and the
|
||||
* body behaves identically to the prior tick-once-per-call semantics —
|
||||
* fires pending IRQ7 after the transfer delay expires. */
|
||||
void sio_tick(int cycles);
|
||||
|
||||
/* Update pad button state. Buttons use PS1 convention: 0=pressed, 1=released.
|
||||
Bit layout: SELECT, L3, R3, START, UP, RIGHT, DOWN, LEFT,
|
||||
|
||||
@@ -217,7 +217,7 @@ static uint32_t mmio_read32(uint32_t addr) {
|
||||
return ram_size_reg;
|
||||
}
|
||||
/* Interrupts: 0x1F801070, 0x1F801074 */
|
||||
if (addr == 0x1F801070u) { sio_tick(); return i_stat; }
|
||||
if (addr == 0x1F801070u) { sio_tick(0); return i_stat; }
|
||||
if (addr == 0x1F801074u) return i_mask;
|
||||
/* DMA: 0x1F801080..0x1F8010FF */
|
||||
if (addr >= 0x1F801080u && addr <= 0x1F8010FFu) {
|
||||
@@ -306,7 +306,7 @@ static uint16_t mmio_read16(uint32_t addr) {
|
||||
return (uint16_t)sio_read(addr);
|
||||
}
|
||||
/* Interrupts */
|
||||
if (addr == 0x1F801070u) { sio_tick(); return (uint16_t)i_stat; }
|
||||
if (addr == 0x1F801070u) { sio_tick(0); return (uint16_t)i_stat; }
|
||||
if (addr == 0x1F801074u) return (uint16_t)i_mask;
|
||||
/* Timers: 0x1F801100..0x1F80112F */
|
||||
if (addr >= 0x1F801100u && addr <= 0x1F80112Fu) {
|
||||
@@ -362,7 +362,7 @@ static void mmio_write16(uint32_t addr, uint16_t val) {
|
||||
static uint8_t mmio_read8(uint32_t addr) {
|
||||
/* Interrupts: 0x1F801070..0x1F801077 (I_STAT, I_MASK) */
|
||||
if (addr >= 0x1F801070u && addr <= 0x1F801077u) {
|
||||
if (addr < 0x1F801074u) sio_tick();
|
||||
if (addr < 0x1F801074u) sio_tick(0);
|
||||
uint32_t val = (addr < 0x1F801074u) ? i_stat : i_mask;
|
||||
return (uint8_t)(val >> (8 * (addr & 3)));
|
||||
}
|
||||
|
||||
@@ -513,8 +513,9 @@ static void exec_one(CPUState* cpu) {
|
||||
/* ---- Interrupt injection ---- */
|
||||
|
||||
static void interp_check_interrupts(CPUState* cpu) {
|
||||
/* SIO tick. */
|
||||
sio_tick();
|
||||
/* SIO tick. cycles=0 in legacy mode (Phase 1.0a signature change;
|
||||
* body ignores cycles, behaves identically to original). */
|
||||
sio_tick(0);
|
||||
|
||||
/* VBlank / timer scheduling. */
|
||||
s_vblank_count++;
|
||||
|
||||
+13
-4
@@ -905,7 +905,7 @@ uint32_t sio_read(uint32_t addr) {
|
||||
* a tight BIOS polling loop within a single function. Advancing on
|
||||
* register access ensures the IRQ fires in time for the BIOS's
|
||||
* "clear, delay, check" card detection sequence. */
|
||||
sio_tick();
|
||||
sio_tick(0);
|
||||
|
||||
switch (addr) {
|
||||
case 0x1F801040: /* SIO_RX_DATA */
|
||||
@@ -1082,7 +1082,7 @@ void sio_write(uint32_t addr, uint32_t value) {
|
||||
/* Advance delayed IRQ after write processing (not before).
|
||||
* This ensures CTRL ACK writes clear the old IRQ before the
|
||||
* pending one fires. */
|
||||
sio_tick();
|
||||
sio_tick(0);
|
||||
}
|
||||
|
||||
void sio_get_freeze_diag(int *out_irq_pending, int *out_irq_countdown,
|
||||
@@ -1159,7 +1159,7 @@ static int sio_card_burst_drain(int max_iters) {
|
||||
reason = 2;
|
||||
break;
|
||||
}
|
||||
sio_tick();
|
||||
sio_tick(0);
|
||||
}
|
||||
|
||||
if (iters == max_iters) reason = 3;
|
||||
@@ -1188,7 +1188,16 @@ void sio_get_burst_stats(uint64_t out[10]) {
|
||||
out[9] = 0;
|
||||
}
|
||||
|
||||
void sio_tick(void) {
|
||||
/* Phase 1.0a: SIO_MODEL_CYCLE_PACED defaulting to 0 keeps the legacy
|
||||
* access-paced behavior unchanged. The cycles arg on sio_tick is
|
||||
* reserved for a future cycle-paced model and is ignored under
|
||||
* macro=0. */
|
||||
#ifndef SIO_MODEL_CYCLE_PACED
|
||||
#define SIO_MODEL_CYCLE_PACED 0
|
||||
#endif
|
||||
|
||||
void sio_tick(int cycles) {
|
||||
(void)cycles; /* reserved for cycle-paced model (Phase 1.0c+) */
|
||||
if (sio_irq_pending && sio_irq_countdown > 0) {
|
||||
sio_irq_countdown--;
|
||||
if (sio_irq_countdown == 0) {
|
||||
|
||||
Reference in New Issue
Block a user