REFORGE

1994 / PUBLIC DOSSIER

PlayStation 1

A chaptered hardware reference with research coverage, visible citation status, and a separate production record.

CHAPTERS
8
PRODUCTION RECORD
NOT STARTED
SOURCE STATUS
EXTERNAL REFERENCES LINKED
MAKER
Sony
RELEASE
1994
ERA
Generation 5
CHAPTER 01

CPU Architecture — MIPS R3000A

CoreLSI CoreWare CW33300 (MIPS R3000A derivative) @ 33.8688 MHz.

Full MIPS I Instruction Set (every opcode)

Primary opcodes (bits 31-26)00h SPECIAL, 02h J, 03h JAL, 04h BEQ … 12h COP2 (GTE), 20h-26h loads, 28h-2Eh stores. SPECIAL funct (bits 5-0): 00h SLL, 08h JR, 18h MULT, 20h ADD, 24h AND, 2Ah SLT, etc. (full 64-entry table available).

32 General-Purpose Registers + HI/LO with standard ABI

$zero always 0 $at assembler temp $v0-$v1 return values

$a0-$a3
arguments

$t0-$t9 temps $s0-$s7 saved $k0-$k1 kernel $gp global pointer $sp stack (full descending) $fp frame pointer $ra return address

Load-Delay SlotsInstruction immediately after LW/LB/LH/MFC2/CFC2 sees old register value. Data arrives after the delay slot completes (critical for recomp hazard analysis).

Branch-Delay SlotsInstruction after J/JAL/Bxx always executes. On exception in delay slot: CAUSE.BD=1, EPC points to branch address. 5-Stage Pipeline: IF → ID → EX → MEM → WB. No interlocks.

Exception/Interrupt Handling (COP0)

SR (r12)IEc/KUc bits, Isc (cache isolation), Swc (cache swap), CU2 (GTE enable). Cause (r13): ExcCode, IP pending, BD flag. EPC (r14), BadVAddr (r8). RFE restores previous IE/KU bits.

Cache4 KB direct-mapped I-cache. 1 KB scratchpad at 1F800000h-1F8003FFh (used as fast data RAM when SR.Isc=1). Cache isolation mode routes loads/stores to scratchpad only.

GTE (Geometry Transformation Engine — COP2)

64 Data + 32 Control Registers (full list)

Data (0-31)V0-V2 vectors, RGBC, OTZ, IR0-IR3, SXY0-SXY2, SZ0-SZ3, RGB0-RGB2, MAC0-MAC3, IRGB/ORGB, LZCS/LZCR. Control (32-63): RT 3×3 matrix (1.3.12), TR/LLM/LCM translation matrices, BK/RBK/GBK/BBK, RFC/GFC/BFC far color, OFX/OFY (1.15.16), H (U16), DQA/DQB, ZSF3/ZSF4, FLAG (overflow/saturation bits).

Key Operations with Cycle Counts

RTPS15 cycles (perspective single) RTPT: 23 cycles (perspective triple) NCLIP: 8 cycles MVMVA (sf/mx/v/cv/lm): 8 cycles SQR: 5 cycles NCDS/NCDT/NCCS/NCCT: 19/44/17/39 cycles AVSZ3/AVSZ4: 5/6 cycles

MVMVA Full Pseudocode

MAC1-3 = (cv_translation + mx_matrix * v_vector) >> (sf ? 12 : 0) IR1-3 = saturate(MAC1-3, lm ? 0..7FFFh : -8000h..7FFFh) FLAG bits 30-12 updated on overflow/saturation

UNR Division Table (257 entries, verbatim for zero-jitter perspective)

FFh, FDh, FBh … 00h (full table embedded in REFORGE GTE header).

FLAG Saturation (cop2r63, 32 bits)

Bit 31Error summary 30-23: MAC overflow 22-20: IR1-IR3 saturation 19-17: RGB saturation 16: SZ3/OTZ saturation 15: RTPS divide overflow 14-13: SX2/SY2 saturation 12: IR0 saturation Full test vectors for every MVMVA variant (sf/mx/v/cv/lm) available.

Fixed-Point PrecisionMatrices 1.3.12 dominant. All math uses int64 accumulators + exact SAR + saturation. COP2 Instruction Encoding: 010010h + opcode in lower 25 bits.

CHAPTER 02

GPU

1 MB VRAM (2 MB on v2 arcade boards via GP1(09h).bit0=1).

Command-Based Rendering (GP0 at 1F801810h)

20hFlat shaded triangle (cmd + color + 3× YX) 30h: Gouraud triangle 24h/2Ch: Textured quads (with UV + CLUT + page) Full hex packet examples:200000FF 00100020 00300040 00500060 ; flat triangle

2C808080
00100020 00101010 00300040 … ; textured quad

GP1 Display Control (1F801814h)resolution, interlace, area, mode. Texture Formats: 4-bit CLUT (16 colors), 8-bit CLUT (256), 15-bit direct.

Semi-Transparency (GPUSTAT.5-6)

0: 0.5×B + 0.5×F 1: B + F 2: B − F 3: B + 0.25×F Dithering: 4×4 pattern (GP0(E1h).bit0). Render Area / Draw Offset: GP0(E3h-E5h). Display Resolutions: 256/320/368/512/640 × 240/480. GPUSTAT Register (1F801814h) full 32-bit layout for DMA direction, draw mode, texture page, busy flags, etc.

Revision Differences (v0 160-pin vs v2 208-pin)

Shadingv0 ((color/8)×texel)/2 vs v2 (color×texel)/16 GP0(03h) FIFO space taken only on v2 2 MB VRAM support on v2 (Y=512-1023 via GP1(09h))

Texture Cache (2 KB)mode-dependent blocks (4-bit=64×64 units). Eviction on same-entry conflict + VRAM 4-word fetch stall.

SPU (Sound Processing Unit) 24 ADPCM Voices, 512 KB sound RAM.

ADSR Envelope (32-bit register at 1F801C08h)

Full per-sample update with linear/exponential modes, shift/step, clamping (PhaseNegative snap to 0 on decrease).

Reverb Engine (22050 Hz, 112-cycle integration in voice loop)

Full comb + APF stages with registers at 1F801DC0h-DFFh. Buffer circular from mBASE to 7FFFEh with saturation and vIIR=-8000h negation bug. Noise Generator (global 16-bit LFSR parity) + pitch modulation (factor from previous voice output).

Gaussian Interpolation (512-entry table, 4-point)

Full verbatim table + math

$$\text{out} = \sum_{k=0}^{3} \text{gauss}[offset + i] \times \text{sample}_k \gg 15$$

768-Cycle Voice Loop (exact 44.1 kHz timing)

24 voices × 24 cycles + 32 cycles (CD/capture) + 112 cycles reverb + DMA4 preload stalls in unrelated slot. Registers ($1F801C00-$1F801DFF): voice volumes, pitch, start addr, ADSR, KON/KOFF, reverb enable, SPUCNT.

CHAPTER 03

Memory Map

$00000000-$001FFFFF
2 MB main RAM
$1F000000-$1F00FFFF
Expansion region 1
$1F800000-$1F8003FF
1 KB scratchpad
$1F801000-$1F802FFF
I/O (GPU 1810/1814, SPU C00-DFF, CD 1800, MDEC 1820, DMA 1080-10F4, timers, joypads, serial)
$80000000-$9FFFFFFF
KSEG0 cached mirror
$A0000000-$BFFFFFFF
KSEG1 uncached mirror
$BFC00000-$BFC7FFFF
512 KB BIOS ROM
CHAPTER 04

DMA

7 Channels

0 MDECin, 1 MDECout, 2 GPU, 3 CD-ROM, 4 SPU, 5 PIO (expansion), 6 OTC (ordering table clear). Control Registers (per channel + DPCR/DICR).

Sync Modes

0 burst, 1 block (DREQ), 2 linked-list (GPU OT).

DMA6 OTC + ClearOTagR (reverse fill)

for (i = depth-1; i >= 0; i--) { OT[i] = (i == depth-1 ? 0x00FFFFFF : (OT[i+1] | (len << 24))); } DMA2 GPU Linked-List parser with header (len << 24 | next) + terminator 00FFFFFFh. CD-ROM XA Audio (Mode 2 Form 2 sectors, 924h-byte ADPCM blocks interleaved). Double-Speed (Setmode bit7=1) + DMA3 burst after INT1 (231 words, first word FFFFh quirk). Sony filesystem support via BIOS. MDEC

Hardware JPEG-like FMV Decompression

CommandsMDEC(1) decode, MDEC(2) load quant tables, MDEC(3) load scale table. Quantization tables (luminance/chrominance, game-loaded). IDCT scale table (64 signed 16-bit values, verbatim hex). Zigzag table (full 64 entries). rl_decode_block pseudocode + yuv-to-rgb for colored macroblocks. Pipeline: CD → DMA0 → MDEC → DMA1 → GPU.

CHAPTER 05

I/O & Controllers

Joypad Serial Protocol (1F801040h SIO)01h address + 42h read command → ID 5Ah + buttons + DualShock analogs. DualShock Rumble (43h/4Dh config, 42h data bytes for M1/M2 motors). Vibration spin-down ~100-500 ms (M1 large motor). Memory Card Protocol (same bus): 81h 52h read / 57h write, 128-byte sectors, XOR checksum, /ACK per byte ≥2 µs. Multi-Tap IRQ10 shared line (resistor network) with long-response abort on empty Slot A. SIO1 Link Cable (1F801050h) for multiplayer (baud sync, null-modem).

Expansion Port Parallel I/O (1F801000h+) + DMA5. Timers 0-2 (1F801100h+): full MODE register with Hblank/Vblank sync modes, target/FFFF IRQ.

CHAPTER 06

BIOS

A0h/B0h/C0h Function Tables (jump via syscall)

A(00h) open, A(02h) read, A(33h) malloc, A(3Fh) printf, A(4Ah) InitPad, etc. Full parameter layouts (R4-R7 + stack words for extra args) + caller/callee conventions. File system, controller/memory card routines, exception handlers, TCB/EvCB structures. Scheduler: cooperative priority-based thread switching via ChangeTh.

CHAPTER 07

Recompilation Notes

Critical for Static Recompilation Engine

MIPS delay-slot hazard analysis + BD flag handling in basic blocks. GTE precision/jitter modeling (exact UNR table + FLAG saturation for all MVMVA variants). No Z-buffer → forced DMA6 OTC + linked-list DMA2 OT insertion. GPU packet variable-length parser + texture cache simulation pass (2 KB eviction logic). SPU 44.1 kHz timing-accurate host buffer (768-cycle voice loop with ADSR clamping, Gaussian 4-point interp, noise LFSR, reverb APF/comb, DMA4 preload stalls). MDEC pre-decode pipeline (rl_decode + IDCT + yuv-to-rgb to textures).

BIOS full syscall trampoline generator (A0/B0/C0 with param/stack validation). Timer/HBlank/VBlank interrupt hooks + cooperative scheduler simulation. Joypad SIO state machine + DualShock rumble timing + multi-tap IRQ10 interference handling. Memcard checksum/ACK state machine. SIO1 link cable emulation. PIO DMA5 expansion port hooks. GPU revision detection (v0/v2 shading + 2 MB VRAM + FIFO behavior). Full savestate delta compression (SPU voices, reverb buffer, GPU cache map, TCB/EvCB, timers).

CHAPTER 08

I/O Dispatch Reference (Iteration 10 Synthesis)

GTE (COP2) — Geometry Transformation Engine

Data Registers (cop2r0–31):

RegisterNameTypeDescription
r0–r5V0/V1/V2S16 XYZInput vectors
r6RGBCU8×4R/G/B + CODE
r7OTZU16Average Z (0..FFFFh saturated)
r8–r11IR0–IR3S16Intermediate results (1.3.12)
r12–r15SXY0–SXY3S16Screen coords (saturated -400h..+3FFh)
r16–r19SZ0–SZ3U16Z FIFO
r20–r22RGB0–RGB2U8×4Color FIFO
r24–r27MAC0–MAC3S32Accumulators
r28–r29IRGB/ORGB5:5:5RGB conversion
r30–r31LZCS/LZCRS32/U32Leading-zero count input/result

Control Registers (cop2r32–63):

RegisterNameTypeDescription
r32–r36RT11–RT33S16Rotation matrix (1.3.12)
r37–r39TRX/TRY/TRZS32Translation vector
r40–r44LLMS16Light matrix
r45–r47RBK/GBK/BBKS32Background color
r48–r52LCMS16Light-color matrix
r53–r55RFC/GFC/BFCS32Far color
r56–r57OFX/OFYS32Screen offset (1.15.16)
r58HU16Projection distance
r59–r60DQA/DQBS16/S32Depth cue coefficients
r61–r62ZSF3/ZSF4S16Average Z scale factors
r63FLAGU32Error bits (see below)

FLAG register (r63) bit layout:

BitDescription
31Error summary (any error)
30–25MAC1–MAC3 overflow positive/negative
24–22IR1–IR3 saturation
21–19RGB R/G/B saturation
18OTZ saturation
17Division overflow
16MAC0 overflow
15SX2 saturation
14SY2 saturation
13IR0 saturation
12SZ3 saturation

**All GTE Commands (MIPS encodingbits 31–26=010010, bit 25=sf, bits 0–5=cmd):**

CommandCyclesDescription
RTPS15Perspective transform single (+ UNR divide)
RTPT23Perspective transform triple
MVMVA848 matrix×vector variants (mx=0–3, v=0–3, cv=0–3)
NCLIP8Normal clip (MAC0 = cross product of SXY FIFO)
AVSZ35Average Z (3 values × ZSF3)
AVSZ46Average Z (4 values × ZSF4)
NCS/NCT14/30Normal color single/triple
NCDS/NCDT19/44Normal color depth-cue single/triple
NCCS/NCCT17/39Normal color color single/triple
SQR5Square of IR vector
OP6Outer product
GPF5General interpolation (far)
GPL5General interpolation (far + MAC)
DCPL8Depth-cue color light
DPCS/DPCT8/17Depth-cue single/triple
INTPL8Interpolation
CC11Color color
CDP13Color depth-cue

MVMVA pseudocode: MAC1-3 = (cv_translation + mx_matrix × v_vector) >> (sf ? 12 : 0), then IR1-3 = saturate(MAC1-3) with lm flag controlling range.

UNR Divide Table (257 entries, used by RTPS/RTPT perspective projection)

0xFF, 0xFD, 0xFB, 0xF9, 0xF7, 0xF5, 0xF3, 0xF1, 0xEF, 0xEE, 0xEC, 0xEA, 0xE8, 0xE6, 0xE4, 0xE3, 0xE1, 0xDF, ... (continues to entry 0x100; exact hardware Newton-Raphson approximation).

Pipeline Stalls: CPU halts on next COP2 or MFC2/CFC2 while GTE is busy (4-stage: load 1–2, MAC 3–12, saturation/FLAG 1, writeback 1).

DMA Controller ($1F801080–$1F8010F8)

DPCR ($1F8010F0): 3-bit priority (0=highest) + enable per channel + CPU priority bits 28–30.

DICR ($1F8010F4): IRQ enables/flags/master. Write-1-to-clear flag bits 24–30. Bit 23 = force IRQ. Bit 31 = master IRQ flag (read-only, computed from enables × flags).

Per-Channel Registers (base + N×$10):

OffsetNameDescription
+$00MADRMemory address
+$04BCRBlock count/size (words per block, number of blocks)
+$08CHCRChannel control: direction, memory step, sync mode 0/1/2, start/busy, chopping

Channel Map:

ChNamePurpose
0MDECinMDEC input (compressed data)
1MDECoutMDEC output (decoded pixels)
2GPUGPU command linked-list / image transfer
3CDROMCD-ROM data sector transfer
4SPUSound RAM transfer
5PIOExpansion port parallel I/O
6OTCOrdering Table Clear (reverse fill)

Ch2 Linked-List Walk (exact):

addr = MADR;
while (true) {
header = read32(addr);  // [31:24]=word count, [23:0]=next pointer
if ((header & 0x00FFFFFF) == 0x00FFFFFF) break;
for (i = 1; i <= (header >> 24); i++)
GPU_GP0(read32(addr + i * 4));
addr = header & 0x00FFFFFF;
}

Ch6 OTC Reverse: Backward write of linked-list pointers, fixed step -4, terminates with 0x00FFFFFF.

DMA Timing & Arbitration:

  • Base: 1 clock/word (GPU/MDEC/OTC), 4 clocks/word (SPU)
  • Hyper-page penalty: 17 clocks per 16 words + 1–2 refresh cycles per row boundary
  • Priority: lowest channel number wins ties
  • Chopping: DMA window (1<<N words) then CPU window (1<<M cycles)
  • Contention: GPU+SPU simultaneous → 30–70% bandwidth loss in 3D scenes

Root Counters / Timers ($1F801100–$1F801130)

Timer 0/1/2 MODE register bits:

BitDescription
0Sync enable
1–2Sync mode (free run / reset at Hblank / reset at Vblank / pause during blank)
3Reset counter on target match
4IRQ on target match
5IRQ on overflow ($FFFF)
6Repeat IRQ (0=one-shot, 1=repeat)
7IRQ toggle/pulse mode
8Clock source (Timer 0: system/dotclock, Timer 1: system/Hblank, Timer 2: system/system÷8)
10IRQ flag (read: 0=IRQ pending; write 0 to clear)
11Target reached flag
12Overflow reached flag

Exact behavior: Writing MODE resets counter to 0. Target reset holds counter at 0000h for 2 cycles. Overflow wraps after 1 cycle at $FFFF. IRQ pulse vs toggle configurable via bit 7.

SPU ($1F801C00–$1F801E00) — 24 Voices

Per-Voice Registers ($1F801C00 + N×$10):

OffsetNameDescription
+$00VOL_LVolume left (fixed or sweep mode)
+$02VOL_RVolume right (fixed or sweep mode)
+$04PITCHSample rate (0x1000 = 44.1 kHz base)
+$06START_ADDRADPCM start address (8-byte units in sound RAM)
+$08ADSR_LOAttack/Decay (shift/step/mode)
+$0AADSR_HISustain/Release (shift/step/mode/level)
+$0CADSR_VOLCurrent envelope volume (read)
+$0EREPEAT_ADDRLoop address (8-byte units)

ADSR Timing (at 44.1 kHz tick rate):

Cycles = 1 << max(0, shift - 11)
Step = stepValue << max(0, 11 - shift)

Exponential increasewhen volume > 0x6000, cycle count ×4. Exponential decrease: step = step × level / 0x8000.

Noise Generator (global): 16-bit Galois LFSR (taps at bits 15/12/11/10, XOR into bit 0). Timer = 0x20000 >> shift. Immediate reset on shift change.

Global SPU Controls:

AddressNameDescription
$1F801D80MAIN_VOL_L/RMaster volume left/right
$1F801D84REVERB_OUT_L/RReverb output volume
$1F801D88KONKey On (24-bit, bits 0–23 = voices 0–23)
$1F801D8CKOFFKey Off (24-bit)
$1F801D90PMONPitch modulation enable (24-bit)
$1F801D94NONNoise enable (24-bit)
$1F801D98EONReverb enable (24-bit)
$1F801D9CENDXVoice end status flags (read-only, 24-bit)
$1F801DA2mBASEReverb work area start address
$1F801DA6IRQ_ADDRSPU IRQ target address
$1F801DA8ADDRData transfer address
$1F801DAASPUCNTSPU control: master enable, reverb, IRQ9, transfer mode, CD/ext enable
$1F801DACSPUSTATSPU status (read-only)
$1F801DAECD_VOL_L/RCD audio volume
$1F801DB0EXT_VOL_L/RExternal audio volume

Reverb Canonical Presets (9 standard presets used by all games):

PresetBuffer SizeDescription
Room0x26C0 bytesSmall room reflection
Studio Small0x1F40 bytesTight studio reverb
Studio Medium0x4840 bytesMedium studio reverb
Studio Large0x6FE0 bytesLarge studio reverb
Hall0xADE0 bytesConcert hall reverb
Half Echo0x3C00 bytesSingle delayed reflection
Space EchoExtended echo effect
EchoStandard echo
CathedralLarge reverberant space

Reverb Math (22050 Hz effective, every multiply SAR 15 + saturate -8000h..+7FFFh):

Lin = vLIN * inputL; Rin = vRIN * inputR;
[mLSAME] = saturate((Lin + [dLSAME] * vWALL - [mLSAME-2]) * vIIR / 8000h + [mLSAME-2]);
[mRSAME] = analogous;
// diff-side, comb, APF1, APF2 identical structure
OutputL = saturate(Lout * vLOUT) / 8000h;
BufferAddress = max(mBASE, (BufferAddress + 2) & 0x7FFFE);

Pitch Modulation:

if (PMON bit set && voice > 0) {
factor = prev_voice_output + 0x8000;  // sign-extend glitch
step = (pitch * factor) >> 15 & 0xFFFF;
}
if (voice == 0) step = pitch;  // voice 0 cannot be modulated
step = min(step, 0x4000);      // clamp to prevent aliasing

Capture Buffers ($00000–$00FFF, 1 KB each): CD Left/Right + Voice 1 + Voice 3. Written every 44100 Hz tick. DMA-readable.

CD-ROM Controller ($1F801800–$1F801803)

INDEX port ($1F801800 bits 0–1): Selects register bank 0–3.

PortBank 0 ReadBank 0 WriteBank 1 ReadBank 1 Write
$1800StatusIndex selectStatusIndex select
$1801Response FIFOCommandResponse FIFO
$1802Data FIFOParameter FIFOData FIFOINT enable
$1803INT enable+flagINT flag (ack)INT enable+flagINT flag (ack)

Key Commands:

CmdNameINTDescription
$01GetStatINT3Return drive status byte
$02SetlocINT3Set seek target (3 BCD bytes: MM:SS:FF)
$06ReadNINT3→INT1Read with retry (ings/normal speed)
$08StopINT3Stop motor
$09PauseINT3Pause reading
$15SeekLINT3Seek (data mode)
$16SeekPINT3Seek (audio mode)
$19TestINT3Various test subfunctions
$1AGetIDINT3→INT2Disc identification + region
$1BReadSINT3→INT1Read without retry (ings/double speed)

Interrupt Types: INT1 = data ready, INT2 = complete, INT3 = acknowledge, INT4 = data end, INT5 = error. Acknowledge via writing $07/$1F to INT flag register.

XA-ADPCM: Setfilter selects file/channel. Always $900 raw bytes per sector when enabled.

Seek Timing by PU revision:

  • PU-7/8 (early): 400–800 ms spin-up, ±8 sector overshoot
  • PU-16/18/20 (late): 200–500 ms spin-up, ±2–5 sector overshoot

MDEC ($1F801820–$1F801828)

Commands (written to $1F801820):

CmdDescription
1Decode macroblock (bits specify depth 15/24-bit, signed/unsigned)
2Set quantization table (64 bytes, luminance or chrominance)
3Set IDCT scale table (64 signed 16-bit values)

Status Register ($1F801824): Busy flag, input FIFO full/empty, output FIFO full/empty, remaining word count.

Decode Pipeline: RLE unpack → zigzag reorder → scale × quantize → IDCT (fast 80-multiply or full 1024-multiply) → YCbCr→RGB conversion (15-bit or 24-bit output, 16×16 macroblock reorder).

DMA Request Timing: DMA0 requests every cycle while input FIFO not full and not busy. DMA1 requests while output FIFO not empty (1–2 CPU cycle latency). DecDCTReset(1) clears busy flag and FIFOs (quant/IDCT tables unchanged).

DICR ($1F8010F4) — DMA Interrupt Control Register

Bit layout:

BitsDescription
0–5Unknown/unused
6–14Not used
15Bus error flag
16–22IRQ enable per channel (0–6)
23Force IRQ (master IRQ regardless of channel flags)
24–30IRQ flags per channel (write-1-to-clear)
31Master IRQ flag (read-only): = force OR (master_enable AND (enables AND flags) != 0)

Complete I/O Register Dispatch Table

AddressNameR/WSide Effects
$1F801070I_STATR/WInterrupt status. AND-acknowledge: new = old & written (writing 0 clears bit)
$1F801074I_MASKR/WInterrupt enable mask (11 sources)
$1F801040JOY_DATAR/WJoypad RX data / TX data. Default $FFFF (no buttons). Protocol: addr $01, cmd $42, ID $5A + button bytes
$1F801044JOY_STATRbit1: RX FIFO not empty, bit2: TX ready, bit7: /ACK level
$1F801048JOY_MODER/WBaudrate reload, character length, parity
$1F80104AJOY_CTRLR/WTX enable, select, ACK, reset, RX enable, IRQ enables
$1F80104EJOY_BAUDR/WBaudrate divisor
$1F801810GP0WGPU command FIFO — render commands ($20 flat tri, $30 gouraud, $24/$2C textured), VRAM transfer ($A0/$C0)
$1F801814GP1/GPUSTATR/WRead: GPU status (bit26=cmd ready, bit28=VRAM ready, bit27=DMA dir, bit25=DMA req, bit31=odd field). Write: GPU control (reset, display, DMA mode, area, resolution)
$1F801820MDEC_CMDWMDEC command/data input
$1F801824MDEC_STATRMDEC status (busy, FIFO, remaining words)
$1F8010F0DPCRR/WDMA channel priority (3-bit per ch) + enable bits
$1F8010F4DICRR/WDMA interrupt control. Flags 24–30 are write-1-to-clear. Bit 23 = force IRQ. Bit 31 = master (read-only)
$1F801100T0_COUNTR/WTimer 0 current value
$1F801104T0_MODER/WTimer 0 mode (write resets counter). Clock: system or dotclock
$1F801108T0_TARGETR/WTimer 0 target value
$1F801110T1_COUNTR/WTimer 1 current value
$1F801114T1_MODER/WTimer 1 mode. Clock: system or Hblank
$1F801118T1_TARGETR/WTimer 1 target value
$1F801120T2_COUNTR/WTimer 2 current value
$1F801124T2_MODER/WTimer 2 mode. Clock: system or system÷8
$1F801128T2_TARGETR/WTimer 2 target value
$1F801800CDROM_STATUSRCD-ROM status + index select (W)
$1F801801CDROM_CMD/RESPR/WCommand (W bank 0) / Response FIFO (R)
$1F801802CDROM_DATA/PARAMR/WData FIFO (R) / Parameter FIFO (W bank 0) / INT enable (W bank 1)
$1F801803CDROM_IRQR/WINT enable+flag (R) / INT flag ack (W): write $07/$1F to acknowledge
$1F801C00–$1F801DFFSPUR/W24 voice registers + global controls (see SPU section above)
$1F801DAASPUCNTR/WSPU control: bit15=master, bit7=reverb, bit6=IRQ9 enable, bits5-4=transfer mode, bit0=CD enable
$1F801DACSPUSTATRSPU status (read-only mirror of control + DMA/IRQ state)

x86-64 Dispatch Handler Stubs

// Conceptual dispatch for REFORGE PS1 I/O
void mmio_dispatch(uint32_t addr, uint32_t value, bool is_write) {
switch (addr) {
// Interrupts
case 0x1F801070:
if (is_write) i_stat_and_ack(value);  // new = old & written
else return i_stat_read();
break;
case 0x1F801074:
if (is_write) i_mask_write(value);
else return i_mask_read();
break;

// GPU
case 0x1F801810: gp0_write(value); break;
case 0x1F801814:
if (is_write) gp1_write(value);
else return gpustat_read();
break;

// DMA
case 0x1F8010F0: dpcr_write(value); break;
case 0x1F8010F4:
if (is_write) dicr_w1c(value);  // flags: current &= ~(written & flags_mask)
else return dicr_read();
break;

// Timers
case 0x1F801104: case 0x1F801114: case 0x1F801124:
timer_mode_write(addr, value);  // resets counter to 0
break;

// Joypad
case 0x1F801040:
if (is_write) joy_tx(value);
else return joy_rx();  // default $FFFF
break;

// SPU
case 0x1F801DAA: spucnt_write(value); break;

// CD-ROM
case 0x1F801803:
if (is_write) cdrom_irq_ack(value);  // write $07/$1F
break;

// MDEC
case 0x1F801820: mdec_cmd_write(value); break;
case 0x1F801824: return mdec_stat_read();
}
}

Verification Notes

Test approach (mednafen/DuckStation trace comparison):

  1. I_STAT AND-acknowledge — set flags via hardware IRQ, write partial mask, verify only masked bits remain
  2. DICR write-1-to-clear — set channel flags, write selective clear, verify bit 31 master recomputation
  3. Timer MODE write — verify counter resets to 0, target-reached flag clears
  4. GTE RTPS — compare all 32 output registers + FLAG against known test vectors
  5. DMA Ch2 linked-list — walk test OT, verify GP0 receives correct word count and data
  6. SPU ADSR — verify envelope volume progression against cycle-accurate traces

Expected trace match: ≥99.9% for all MMIO addresses, <0.1% deviation on cycle-timing-dependent reads (GPU FIFO status during heavy rendering).

Public sources

Production ledger

PRODUCTION VERIFICATION NOT STARTEDThe dossier is available as hardware research. No implementation result is recorded here yet.