Files
psxrecomp/runtime/include/memcard.h
T
Matthew Stanley fba58d76b3 Phase 4 interrupt fixes: RFE, GPR save/restore, DMA IRQ edge-trigger
Three interrupt delivery bugs fixed that were blocking shell progression:

1. RFE after handler exit: The exception handler's normal exit path
   (jmpbuf longjmp at 0xBFC10944) does not execute RFE. In our model
   the handler returns to psx_check_interrupts, not to the WaitEvent
   caller. Without RFE, IEc stays 0 forever after the first interrupt.
   Fix: apply RFE in psx_check_interrupts if IEc is still 0 after the
   handler returns.

2. GPR save/restore around handler dispatch: The handler's jmpbuf exit
   restores callee-saved registers from the kernel jmpbuf (intended for
   a non-local jump to WaitEvent's caller). In our model this corrupts
   the interrupted code's registers. Fix: save all GPRs before handler
   dispatch and restore them after, matching real hardware where the
   interrupted code's registers are preserved via TCB save/restore.

3. VBlank tick gated on !in_exception: The handler runs thousands of
   block leaders, each calling psx_check_interrupts. Without gating,
   dispatch_count advances inside the handler, firing new VBlanks that
   stack up and starve the main code. Fix: only increment dispatch_count
   and fire VBlank/timer ticks when not in exception handling.

4. DMA IRQ edge-triggered: update_master_irq() was level-triggered,
   re-asserting i_stat bit 3 on every call while master_flag=1. Combined
   with no BIOS callback to acknowledge DMA IRQs, this caused an
   interrupt storm. Fix: edge-detect master_flag 0->1 transition, and
   suppress DMA completion IRQs entirely since transfers are synchronous.

Also adds GPU debug diagnostics: GP0 command counters (nop/fill/draw/
env/copy), draw area/offset in gpu_state, vram_peek debug command.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 20:29:03 -07:00

32 lines
737 B
C

#ifndef PSXRECOMP_V4_MEMCARD_H
#define PSXRECOMP_V4_MEMCARD_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define MEMCARD_SIZE (128 * 1024) /* 128KB per card */
#define MEMCARD_SECTOR_SIZE 128
#define MEMCARD_SECTORS 1024
/* Initialize memcard subsystem. dir = directory for .mcd files (can be NULL). */
void memcard_init(const char* dir);
/* Read/write 128-byte sectors */
int memcard_read_sector(int card, int sector, uint8_t* buf);
int memcard_write_sector(int card, int sector, const uint8_t* buf);
/* Flush pending writes to disk */
void memcard_flush(int card);
/* Check if card is present */
int memcard_is_present(int card);
#ifdef __cplusplus
}
#endif
#endif /* PSXRECOMP_V4_MEMCARD_H */