Playground

Tools that run on your own data

The Lab teaches concepts with synthetic inputs. This page is the other half: drop in artifacts your build actually produced — a module from a game you dumped, a command-buffer dump, your _kyty.txt — and read them with the same constants the emulator uses. The artifact readers cite their source files and state their supported subset, and every one has a demo button so you can watch it work before you supply anything.

Nothing you load here leaves your browser. There is no upload, no server, no analytics — the parsing all happens in this tab.

Inspection limits: 64 MiB per module, 2 MiB per text file, and 16,384 words per PM4 or shader stream. Extract a relevant block or use offline tools for larger artifacts.

PM4 command decoder GPU

The CPU records work for the PS5 GPU — it fills a ring buffer with PM4 packets and the command processor eats them. Every draw, every register write, every fence is one of these. Paste dwords from a command-buffer dump, or encode a packet from scratch and watch the bit layout fall out.

Predict the packet boundary

Related lesson →

Load the annotated draw. Predict its total length, then remove the last payload word.

Check your explanation

One header plus two payload words is three dwords. Removing one produces a truncated-packet warning. Valid packet boundaries alone do not validate draw state.

Module inspector Guest

Sony modules are ELF files that a normal ELF reader refuses to load: the type is ET_SCE_* and the import/export machinery lives in a proprietary PT_OS_DYNLIBDATA segment instead of the standard place. Drop one of your own modules in and see exactly what the runtime linker sees.

Separate bytes on disk from bytes in memory

Related lesson →

Load the synthetic module and compare filesz and memsz for the writable PT_LOAD segment.

Check your explanation

Its larger memory size includes zero-filled storage. Sum of segment memory sizes and reserved address span are different quantities. SELF inspection reports headers only.

Log triage Host

A failing run produces thousands of lines and maybe five that matter. This groups them by what they mean for you — unresolved imports are work you could pick up, unknown packets point at the GPU decoder, errors read best from the bottom. Point it at the log from a title that does not boot and you have a to-do list.

Check a classification against its evidence

Related lesson →

Load a missing file and a missing symbol. Predict which category each belongs to, then open the original evidence.

Check your explanation

The file error is an error, not an unresolved import. The symbol line is a resolution lead. Neither proves an implementation is missing; investigate the module, lookup and surrounding events.

Module & library id encoder Guest

Symbol names in a PS5 module look like pt2fEBBpEJk#A#A. Those trailing tokens are 16-bit module and library ids squeezed into a 64-symbol alphabet. This is the emulator's encoder, transcribed exactly — drag the slider and watch which branch the value takes.

Cross an encoding boundary

Related lesson →

Start at 63, then enter 64 and 4096. Predict how many characters each needs.

Check your explanation

63 is “-”, 64 is “BA”, and 4096 is “BAA”. This encodes a 16-bit module/library ID, not the function NID. Out-of-range and noncanonical tokens are rejected.

Appendix · C++ primer tools

The three ideas the C++ appendix keeps returning to, as tools: what the compiler does to a struct, what the JIT writes into a machine-code stub, and what a crash log is actually telling you. No artifacts needed — each one demos itself.

Struct layout lab C++

Padding is the difference between the size you guess and the size the compiler produces. Build a struct, watch the alignment padding appear byte by byte, flip #pragma pack(1) and watch it vanish — then assert the exact size the way static_assert(sizeof(...)) does in memory.h.

Predict padding before packing

Related lesson →

With the padding-trap preset, calculate offsets for u8, u64, u32, u8. Then enable pack(1).

Check your explanation

The unpacked offsets are 0, 8, 16, 20 and sizeof is 24. Packed offsets are 0, 1, 9, 13 and sizeof is 14. This selected x64 layout model does not cover every C++ ABI, bitfield rule or object-lifetime requirement.

Machine-code patch calculator C++

The emulator writes its own import stubs, and every relative jump or call needs a displacement computed by hand: target − rip, stored little-endian. Give it a rip and a target and watch the exact bytes jit.h would write — including when the target is too far away.

Check a signed displacement

Related lesson →

Load the far-target example. Predict why a positive displacement of 2147483648 cannot fit rel32.

Check your explanation

Signed rel32 spans −2147483648 through 2147483647. The reference address is the next instruction, after the displacement. Truncating to four bytes does not make an unreachable target reachable.

Crash-log reader C++

Guest code runs natively, so a game crash is a real host exception — and the emulator writes a forensic dump about it. Paste one in and it becomes a page: what faulted, on which register, called from where. The faulting address is a symptom; the stack trace at the bottom is the cause.

Distinguish fault evidence from cause

Related lesson →

Load the sample fault. Identify the instruction address, accessed address and access type. Decide what additional evidence would test a cause.

Check your explanation

The dump records where execution failed and how memory was accessed. Inspect instruction semantics, registers, module mappings and prior data flow. Candidate stack words or a resolved stack trace do not establish root cause by themselves.

Appendix · shaders

Inspect supported input-ISA encodings, summarize compiler artifacts, and unpack buffer and sampler descriptors. These readers expose evidence; they do not compile or execute shaders.

RDNA2 ISA word decoder GPU

A shader is just 32-bit words until something decodes them. Inspect base scalar/vector ALU encodings and their literal words using fields from ShaderDecoder.cpp. Extended, modifier and memory families stop with a scope message. This is a field inspector, not a complete disassembler.

Find the literal word

Related lesson →

Load the three words. Predict whether they encode two instructions or three.

Check your explanation

They encode s_mov_b32 with a following literal, then s_endpgm at byte 8. The literal is data owned by the first instruction. Unsupported extended families stop explicitly so later words are not misidentified.

Shader artifact reader GPU

With --graphics-debug-dump true, the pinned renderer saves input ISA as _Shaders/original/*.bin and generated SPIR-V as _Shaders/*.spv. Shader logging adds decoded ISA and IR to the run log. Import a decoded excerpt, binary artifact, or externally produced .spvasm to inspect its structure.

Read compiler output without executing it

Related lesson →

Load the SPIR-V text sample. Find its entry point, function and block label. Compare with the input-ISA sample.

Check your explanation

The artifact reader summarizes compiler output; it does not compile or execute it. Binary SPIR-V stores word count in the high 16 bits and opcode in the low 16. A structurally readable module can still fail semantic or Vulkan validation.

Buffer & sampler descriptor decoder GPU

Every buffer_load and every image_sample reads its parameters from a descriptor in the shader resource table. Give a V# (buffer) or an S# (sampler) its four dwords and read back the address, stride, count, format — or the filtering rules — using shaderBindings.h. A T# is an eight-dword image descriptor and is outside this tool’s scope.

Decode a full address and byte range

Related lesson →

Load the buffer sample. Predict its 48-bit base and size from its four words, then try the sampler sample.

Check your explanation

The buffer base is 0x000180000000. A 32-byte stride and 300 records cover 9600 bytes. Zero stride uses the record count as bytes. Sampler filters come from WORD2; a sampler has no texture address.

Don't have artifacts yet?

From your KytyPS5 checkout, use a title configured for your build. Substitute your executable path if it differs from this example; see Building, linking & debugging:

.\_Build\windows-prod\kyty_emulator.exe --game "<your title>" `
  --printf-direction File --printf-output-file _kyty.txt `
  --redzone --command-buffer-dump true --graphics-debug-dump true `
  --shader-log-direction File --shader-log-folder _Shaders

Paths are relative to the emulator’s working directory. Shaders are saved when those paths execute; a failed or cached run may not produce every artifact. Command-buffer dumps and _kyty.txt can be inspected above. Use spirv-dis input.spv -o output.spvasm if SPIRV-Tools is installed. Each reader states its limits; files remain local to your browser.