mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
621a92d49b
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>
57 lines
1.9 KiB
C
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
|