HLE is how PS5PCEM answers the firmware calls a title imports. Each numeric NID becomes a Zig function on a host stack, with the guest System V calling convention preserved on Windows.
How it worksImplementation
How PS5PCEM works
Each page is one mechanism the emulator actually runs: what the console does, what the Zig code does, and what is still missing.
Repository notes through October 17, 2026
Firmware and HLE
AMPR counters
PartialAMPR in PS5PCEM is a process-local software model of the console's counter and completion commands. One hundred and twenty-eight counters accept stores, atomic field updates, paired reads and masked waits, in submission order.
How it worksAPR resolves a title file once and then carries a process-local identifier in later command buffers. Deferred AMPR reads reopen that same read-only /app0 file without keeping a host descriptor forever.
How it worksGuest addresses are real host addresses. Direct memory is a sparse shared physical pool mapped into that space, and MemoryPool adds reserve, commit and batch operations on top of the same backing.
How it worksSavedata
WorkingA mounted save slot becomes a writable /savedata0. The title uses the ordinary file API, and the next launch finds the same files under the product code the title publishes.
How it worksFont rendering
PartiallibSceFont rasterizes title-supplied TrueType and OpenType faces with FreeType. System-font requests use the bundled Noto Sans substitute for Latin, Greek and Cyrillic.
How it worksPNG encode and decode
PartialThe PNG encoder writes 8-bit RGB or RGBA files from pitched RGBA or BGRA pixels. The decoder reads non-interlaced grayscale, palette, RGB and RGBA images into a checked guest buffer.
How it worksReal-time clock
PartialRTC checks calendar fields, converts Windows FILETIME, and does checked arithmetic on ticks. The guest sees a coherent clock without the host's daylight-saving conversion.
How it worksOn Windows, each libSceFiber fiber is a real Windows fiber, so a switch keeps the guest registers and the guest stack. User-level threads start through the same pthread path.
How it worksThe kernel AIO API accepts a batch of reads and returns an identifier. PS5PCEM performs the batch at submission, which the interface allows, and the title collects a finished result.
How it worksGraphics
A PS5 title builds GPU packets in its own memory and submits the buffer. PS5PCEM decodes that PM4 stream, keeps the register state, and executes draws and dispatches in order.
How it worksRDNA2 shaders to SPIR-V
PartialPlayStation 5 shaders are RDNA2 machine code. PS5PCEM decodes the GFX10 families, builds a control-flow graph, and lowers the supported operations to SPIR-V 1.5 for Vulkan.
How it worksNGG vertex shaders
PartialMerged NGG vertex programs, including a fetch shader that continues with S_SETPC_B64, translate as one graphics stage. The export program keeps its own user-data window.
How it worksMulti-texel image loads
PartialIMAGE_LOAD_BY2, BY4, PCK2 and PCK4, including the explicit-mip forms, execute for the measured native 2D formats. A BY load returns consecutive texels. A PCK load packs their raw bits into one register.
How it worksHorizontal gathers
PartialIMAGE_GATHER4H and IMAGE_GATHER4H_PCK gather one channel across a horizontal group of texels. The measured direct 1D and 2D subset is covered by 1,242 GPU dispatches.
How it worksScalar shader calls
PartialS_SWAPPC_B64 and S_CALL_B64 save a full return address and run a bounded local subroutine, including a callee that sits after ENDPGM. A verified AGC fetch shader can be linked the same way.
How it worksVulkan renderer
WorkingThe Vulkan backend loads the driver at runtime, requires Vulkan 1.2, and presents guest frames through a swapchain. Render targets, storage images and pipelines stay resident across draws.
How it worksDirect3D 12 backend
PartialAn experimental native Windows renderer added after 0.3.5. It shares the PM4 decoder and the RDNA2 shader translation with Vulkan, then executes and presents through D3D12 and DXGI. Vulkan stays the default, and games do not run through this path yet.
How it worksMSAA
PartialMatching 2×, 4× and 8× color and depth sample counts stay on the host image through a later resolve. Asterix uses that path for MSAA depth and stencil, which removed a large accidental readback.
How it worksHTILE, DCC, CMASK and FMASK
PartialHTILE, DCC, CMASK and FMASK are the console's compressed depth and color metadata. PS5PCEM tracks the pointers, clears HTILE in the cases it understands, and refuses a layout it would otherwise detile incorrectly.
How it worksTexture detiling
PartialPS5 textures are stored in GFX10 swizzle patterns, not in linear rows. PS5PCEM applies the address equations on the CPU, and on the GPU for the large 4, 8 and 16-byte surfaces that qualify.
How it worksGPU page tracker
PartialThe opt-in page tracker watches 16 KiB guest pages. The first native CPU store faults, advances a generation, and invalidates the GPU copy so unchanged pages do not get hashed and uploaded every frame.
How it worksVideoOut
WorkingVideoOut registers the guest's display buffers and completes a flip only after the presentation callback has accepted the frame. The host window is a Vulkan swapchain at 1080p SDR.
How it worksAudio and video
AudioOut
WorkingAudioOut plays guest PCM on a Windows device at 48 kHz. Legacy ports have their own streams and queues, so music and effects run together, and an underrun keeps sample order.
How it worksACM convolution
PartialACM convolution runs FMOD's partitioned reverb on the CPU. Shared-input batches transform one dry signal, apply float or half-float impulse partitions, and overlap-add the wet result.
How it worksAJM codecs
PartialAJM decodes ATRAC9, MP3, MPEG-4 AAC and Opus. Each codec instance keeps its own state, and an unknown codec is rejected instead of being reported as silent success.
How it worksNGS2
PartialNGS2 keeps system, rack and voice handles, parses ordinary RIFF/WAVE data, and paces a silent 48 kHz grain so a software-DSP worker cannot spin. Voice synthesis itself is incomplete.
How it worksAvPlayer
WorkingSceAvPlayer decodes movie containers with FFmpeg into title-owned NV12 frames and 48 kHz stereo PCM. Playback ends when the source duration passes, even if the title never reads one of the streams.
How it worksCPU, loader and tools
Native guest execution
WorkingOn Windows x86-64 the guest's machine code runs directly. One host worker carries each guest pthread, and the FS base is restored after every blocking call because Windows does not keep it.
How it worksELF and SELF loading
WorkingThe loader maps decrypted PS5 SELF and bare ELF64 modules, applies relocations, and resolves imports against the HLE registry. The title then receives stable handles for modules it starts itself.
How it worksControllers and keyboard
WorkingDualSense, DualSense Edge and DualShock 4 are read over HID, on USB and Bluetooth. Xbox-compatible pads use XInput. The keyboard maps to the sticks through a launcher profile.
How it worksPKG extractor
Partialpkgextractor unpacks the debug FPKG layouts observed in development: the outer package, inner PFS, NAPS name maps and Kraken-compressed payloads. Encrypted retail packages are out of scope.
How it worksWhat these pages are