Files
psxrecomp/runtime/include/psx_icache.h
T
Shokunin 621a92d49b runtime: apply cache-isolated (IsC) stores to the caches, as Beetle does
memory.c dropped every store made while SR.IsC was set. Beetle's
PS_CPU::WriteMemory sends them to the caches instead
(mednafen/psx/cpu.cpp:482-512), before any address decode:

- I-cache enabled (BIU bit 11) with a tag-test, invalidate or lock mode
  bit: the store rewrites the tag and valid bits of its line. This is how
  FlushCache (A 44h) and the boot cache init invalidate the I-cache.
- D-cache enabled with lock mode clear ((BIU & 0x81) == 0x80): the store
  lands in the scratchpad at addr & 0x3FF.
- Nothing reaches the bus, the BIU register at 0xFFFE0130 included.

psx_icache_isc_store transcribes the tag write; memory.c's three store
chokepoints call it (and the scratchpad write) first, so compiled code,
overlay shards and both interpreters share it. DMA writes are not CPU
stores and now bypass IsC, as in Beetle. A render pass applies the same
effect (its checkpoint restores tags and scratchpad), and the overlay
shadow record fails closed on an isolated store, which its replay
cannot redo.

isc_store_test drives the real memory.c and psx_icache.c: 15 of its
checks fail on master.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 17:12:55 -07:00

57 lines
1.9 KiB
C

#ifndef PSXRECOMP_PSX_ICACHE_H
#define PSXRECOMP_PSX_ICACHE_H
#include "cpu_state.h"
#ifdef __cplusplus
extern "C" {
#endif
extern uint32_t g_psx_icache_tv[1024];
extern int g_psx_icache_active;
extern int g_ls_replay_active;
void psx_icache_reset(void);
void psx_icache_fetch(CPUState *cpu, uint32_t addr);
void psx_icache_fetch_miss(CPUState *cpu, uint32_t addr);
/* BIU / cache control (0xFFFE0130) bits the cache model reads; names and values
* as Beetle's cpu.cpp BIU_* defines. */
#define PSX_BIU_ICACHE_ENABLE 0x800u /* BIU_ENABLE_ICACHE_S1 */
#define PSX_BIU_DCACHE_ENABLE 0x080u /* BIU_ENABLE_DCACHE */
#define PSX_BIU_TAG_TEST 0x004u /* BIU_TAG_TEST_MODE */
#define PSX_BIU_INVALIDATE 0x002u /* BIU_INVALIDATE_MODE */
#define PSX_BIU_LOCK 0x001u /* BIU_LOCK_MODE */
/* A CPU store made while SR.IsC is set, applied to the I-cache model: the
* I-cache half of Beetle PS_CPU::WriteMemory's IsC branch. With the I-cache
* enabled and a tag-test, invalidate or lock mode bit set, the store rewrites
* the tag and valid bits of the four words of its line; that is how FlushCache
* (A 44h) invalidates the cache. `biu` is the current 0xFFFE0130 value and
* `value` the stored register value (only its low byte lanes matter). */
void psx_icache_isc_store(uint32_t biu, uint32_t addr, uint32_t value);
/* Keep the interpreter's steady-state tag hit inside its translation unit.
* Misses use the shared slow path, preserving exact cache evolution/timing. */
static inline void psx_icache_fetch_interp(CPUState *cpu, uint32_t addr) {
#ifdef PSX_ENABLE_BLOCK_CYCLES
if (g_ls_replay_active) return;
if (g_psx_icache_active < 0) {
psx_icache_fetch(cpu, addr);
return;
}
if (!g_psx_icache_active) return;
uint32_t idx = (addr & 0xFFCu) >> 2;
if (g_psx_icache_tv[idx] == addr) return;
psx_icache_fetch_miss(cpu, addr);
#else
(void)cpu;
(void)addr;
#endif
}
#ifdef __cplusplus
}
#endif
#endif