KITAQ SERIES • REFERENCE EDITION
KUROSAKI
NES and FDS execution and analysis
Source snapshot: September 14, 2026 · English edition: September 14, 2026
Prebuilt Windows CLI
The repository now includes kurosaki.exe at its root. Download the repository ZIP and keep the license notices with the executable. This Windows x64 CLI needs no Rust, Python or .NET installation to run. The build steps below are for rebuilding from source. The independent project code is licensed by DAISUKE OBA under MIT; dependency terms are preserved in BINARY_NOTICES.md and licenses/.
1. What KUROSAKI does
KUROSAKI is an NES/Famicom/FDS observation emulator that reads KITAQFC information. Its CLI inspects ROMs, executes software, records audio, diagnoses behavior, saves snapshots, replays input, disassembles instructions and decompiles candidate functions. Mapper implementations differ in scope, so inspect the ROM and support information first.
2. Build and start
Push-Location .\kurosaki
.\scripts\build.ps1
.\kurosaki.exe --help
Pop-LocationShort kurosaki commands below assume the executable directory is on PATH. Otherwise replace the command name with & "full executable path".
kurosaki inspect-rom .\out\hello.nes --json .\out\rom.json
kurosaki run .\out\hello.nes --frames 120 --png .\out\hello.png --json .\out\run.jsonUse Volume 4's hello ROM to verify text display. inspect-rom examines a header; run advances CPU and PPU execution. Successful inspection does not guarantee successful execution.
3. Check the mapper and board
Nametable RAM mapping
PPU reads, writes and rendering use AxROM’s lower/upper single-screen selection, FME7’s vertical/horizontal/lower/upper selection and all sixteen CIRAM-only MMC5 layouts. MMC5 ExRAM and fill rendering are not supported. See the KITAQFC board-specific examples for the tested behavior.
Mode values and executed examples
mapper-list lists registered mapper types, mapper-info describes one type, and audit-board checks board constraints. The mapper number connects the ROM header to assumptions about physical wiring. A name alone does not establish capacity, CHR-RAM or fixed-bank behavior.
kurosaki mapper-list
kurosaki mapper-info 4
kurosaki audit-board .\out\surom.nes --expected-board surom512 --json .\out\board.json--allow-unimplemented permits observation to continue past unsupported elements. A run using it is not proof that those elements are supported.
4. Controller input
run --pad1 and --pad2 use raw NES button masks: A=1, B=2, SELECT=4, START=8, UP=16, DOWN=32, LEFT=64 and RIGHT=128. Add the values for simultaneous buttons.
kurosaki run .\out\game.nes --frames 120 --pad1 1 --png .\out\held_a.png --json .\out\held_a.jsonThis holds A for 120 frames. Use replay for ordered actions such as title, start and confirm. The CLI replay-record example records a baseline run without interactive input; it is different from recording a person operating a GUI.
5. Snapshots and replay
kurosaki snapshot-save .\out\game.nes --frames 120 --out .\out\title.kss.json
kurosaki snapshot-load .\out\title.kss.json
kurosaki replay-record .\out\game.nes --frames 120 --out .\out\baseline.replay.json
kurosaki replay-run .\out\game.nes .\out\baseline.replay.json --json .\out\replay.jsonResumable state uses version 2 snapshots. Keep the ROM SHA-256 matched to its state. snapshot-resume continues from a saved point. snapshot-rebase explicitly transfers state to a compatible different ROM under a supplied contract. Unconditionally reusing old state after changing code or RAM placement is unsafe; normally reproduce the same actions from startup.
Snapshot JSON preserves fractional audio timing values with full f64 precision. Do not round or rewrite these numbers: unchanged ROM and input are not enough for an exact continuation comparison if saved timing values have changed.
6. Traces, diagnostics and profiles
kurosaki trace .\out\game.nes --frames 2 --cpu --ppu --apu --mapper --nmi --dma --out .\out\trace.jsonl
kurosaki diagnose .\out\game.nes --frames 120 --out .\out\diagnostics.json --md .\out\diagnostics.md
kurosaki profile .\out\game.nes --frames 120 --out .\out\profile.jsonA trace records what happened over time; diagnostics identify rule-matching observations; a profile shows where execution concentrated. A few frames around an anomaly are usually easier to inspect than a long full trace.
Pass matching build-debug JSON with --kitaqfc-debug. An observation without source-line information should not be interpreted as a complete source-line trace.
7. Save sound and pictures
kurosaki audio-export .\out\sound.nes --frames 180 --wav .\out\sound.wav --json .\out\audio.json
kurosaki run .\out\game.nes --frames 120 --png .\out\frame.png --snapshot .\out\frame.kss.json --json .\out\frame.jsonRegister changes, generated PCM and correctly sounding audio are separate checks. Record the mapper when testing built-in or expansion sound. A single PNG cannot establish movement or input behavior; retain the preceding and following state and input as well.
8. Disassembly and decompilation
kurosaki disasm .\out\game.nes --bytes 256 --text .\out\reset.txt
kurosaki decompile .\out\game.nes --format markdown --out .\out\decompile.mddisasm emits instruction sequences. decompile emits function-boundary candidates, CFGs, references and pseudocode. With switchable banks, a CPU address alone does not identify a physical ROM position. Provide mapper state through --snapshot where needed and use execution traces or annotations as supporting evidence. This is not perfect recovery of original source.
Reset, Nmi and Irq are identified from their vectors in the captured mapper context. A different snapshot PC is a current_pc candidate with an automatic sub_B... name, not evidence of reset or a confirmed function boundary.
9. Connect to SARAKURA
kurosaki run .\out\game.nes --frames 300 --emit-diagnostics .\out\kurosaki_events.jsonl --json .\out\run.json
sarakura fc analyze --metadata .\out\build.json --events .\out\kurosaki_events.jsonl --out .\out\fc_report --fail-on errorKUROSAKI --emit-diagnostics takes a JSONL file path, just like KOKURA. Keep CPU traces and diagnostic-event files distinct.
10. Publication scope
This manual covers the CLI and its integration APIs.
11. FDS and save RAM
fds-inspect examines disk structure; export-assets exports assets. Test FDS separately from NES cartridges because startup, BIOS and disk-access requirements differ. Battery .sav files and .kss.json snapshots serve different purposes; use a save layout supported by the implementation.
kurosaki battery-export .\out\game.nes .\out\title.kss.json --out .\out\save.sav
kurosaki battery-run .\out\game.nes --sav .\out\save.sav --frames 120 --save-out .\out\next.sav --png .\out\battery.pngbattery-export extracts raw save RAM from a matching ROM and snapshot. battery-run loads that RAM and starts from power-on; it does not restore the CPU or PPU's interrupted execution state. Specify output with --save-out. These operations require a supported ROM with save RAM and do not apply to every lesson ROM.
Command syntax reference
The following help was captured for the source edition. Consult it for optional arguments, defaults and accepted values. Replace the illustrative input filenames with your own outputs. Captured tool responses retain their original wording.
kurosaki
KITAQFC-aware clean-room NES observation emulator CLI
Usage: kurosaki.exe <COMMAND>
Commands:
battery-export Export raw battery RAM from a matching snapshot (not a snapshot file)
battery-run Cold boot with an explicit battery file; no implicit save-file writes
inspect-rom
audit-board
run
trace
audio-export
profile
diagnose
replay-record
replay-run
snapshot-save
snapshot-load
snapshot-rebase Rebind a reviewed v2 snapshot to an explicitly allowlisted compatible ROM
snapshot-resume
diff
decompile Recover bounded function CFGs and readable pseudocode from a mapper context
disasm
mapper-test
fds-inspect
export-assets
report
mapper-list
mapper-info
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help
-V, --version Print versionkurosaki battery-export — Export raw battery RAM from a saved state
kurosaki battery-export out/game.nes out/state.kss.json --out out/save.savExport raw battery RAM from a matching snapshot (not a snapshot file)
Usage: kurosaki.exe battery-export --out <OUT> <ROM> <SNAPSHOT>
Arguments:
<ROM>
<SNAPSHOT>
Options:
--out <OUT>
-h, --help Print helpkurosaki battery-run — Boot with saved RAM
kurosaki battery-run out/game.nes --sav out/save.sav --frames 120 --png out/loaded.png --save-out out/next.savCold boot with an explicit battery file; no implicit save-file writes
Usage: kurosaki.exe battery-run [OPTIONS] --sav <SAV> <ROM>
Arguments:
<ROM>
Options:
--sav <SAV>
--frames <FRAMES> [default: 600]
--replay <REPLAY>
--json <JSON>
--snapshot <SNAPSHOT>
--png <PNG>
--save-out <SAVE_OUT>
-h, --help Print helpkurosaki inspect-rom — Inspect the ROM header
kurosaki inspect-rom out/game.nes --json out/rom.jsonUsage: kurosaki.exe inspect-rom [OPTIONS] <ROM>
Arguments:
<ROM>
Options:
--json <JSON>
--md <MD>
-h, --help Print helpkurosaki audit-board — Check board requirements
kurosaki audit-board out/game.nes --expected-board surom512 --json out/board.jsonUsage: kurosaki.exe audit-board [OPTIONS] <ROM>
Arguments:
<ROM>
Options:
--expected-board <EXPECTED_BOARD> [default: surom512]
--metadata <METADATA>
--json <JSON>
-h, --help Print helpkurosaki run — Run for a fixed number of frames
kurosaki run out/game.nes --frames 120 --png out/game.png --json out/run.jsonUsage: kurosaki.exe run [OPTIONS] <ROM>
Arguments:
<ROM>
Options:
--frames <FRAMES> [default: 1]
--max-instructions <MAX_INSTRUCTIONS>
--headless
--state-hash <STATE_HASH>
--json <JSON>
--md <MD>
--png <PNG>
--snapshot <SNAPSHOT>
--observe-json <OBSERVE_JSON>
--trace-jsonl <TRACE_JSONL>
--emit-diagnostics <EMIT_DIAGNOSTICS>
--repro-bundle <REPRO_BUNDLE>
--break-on-diagnostic <BREAK_ON_DIAGNOSTIC>
--png-on-diagnostic <PNG_ON_DIAGNOSTIC>
--snapshot-on-diagnostic <SNAPSHOT_ON_DIAGNOSTIC>
--kitaqfc-debug <KITAQFC_DEBUG>
--allow-unimplemented
--pad1 <PAD1> [default: 0]
--pad2 <PAD2> [default: 0]
-h, --help Print helpkurosaki trace — Record a chronological event trace
kurosaki trace out/game.nes --frames 2 --cpu --ppu --out out/trace.jsonlUsage: kurosaki.exe trace [OPTIONS] --out <OUT> <ROM>
Arguments:
<ROM>
Options:
--frames <FRAMES> [default: 1]
--out <OUT>
--cpu
--mem-read
--mem-write
--ppu
--apu
--mapper
--nmi
--dma
--full
--kitaqfc-debug <KITAQFC_DEBUG>
--allow-unimplemented
--pad1 <PAD1> [default: 0]
--pad2 <PAD2> [default: 0]
-h, --help Print helpkurosaki audio-export — Write PCM audio to WAV
kurosaki audio-export out/game.nes --frames 120 --wav out/audio.wavUsage: kurosaki.exe audio-export [OPTIONS] --wav <WAV> <ROM>
Arguments:
<ROM>
Options:
--frames <FRAMES> [default: 60]
--wav <WAV>
--json <JSON>
--allow-unimplemented
--trace-audio
--pad1 <PAD1> [default: 0]
--pad2 <PAD2> [default: 0]
-h, --help Print helpkurosaki profile — Locate execution hotspots
kurosaki profile out/game.nes --frames 120 --out out/profile.jsonUsage: kurosaki.exe profile [OPTIONS] <ROM>
Arguments:
<ROM>
Options:
--frames <FRAMES> [default: 60]
--out <OUT>
--md <MD>
--kitaqfc-debug <KITAQFC_DEBUG>
--allow-unimplemented
-h, --help Print helpkurosaki diagnose — Produce static and runtime diagnostics
kurosaki diagnose out/game.nes --frames 120 --out out/diagnostics.jsonUsage: kurosaki.exe diagnose [OPTIONS] <ROM>
Arguments:
<ROM>
Options:
--frames <FRAMES>
[default: 0]
--out <OUT>
--md <MD>
--emit-diagnostics <EMIT_DIAGNOSTICS>
--check <CHECK>
[possible values: ppu, nmi, mapper, apu, abi, input, fds, asset]
--kitaqfc-debug <KITAQFC_DEBUG>
--allow-unimplemented
--pad1 <PAD1>
[default: 0]
--pad2 <PAD2>
[default: 0]
-h, --help
Print helpkurosaki replay-record — Record a reference replay
kurosaki replay-record out/game.nes --frames 120 --out out/replay.jsonUsage: kurosaki.exe replay-record [OPTIONS] --out <OUT> <ROM>
Arguments:
<ROM>
Options:
--frames <FRAMES> [default: 60]
--out <OUT>
--allow-unimplemented
-h, --help Print helpkurosaki replay-run — Execute a recorded input sequence
kurosaki replay-run out/game.nes out/replay.json --json out/replay-result.jsonUsage: kurosaki.exe replay-run [OPTIONS] <ROM> <REPLAY>
Arguments:
<ROM>
<REPLAY>
Options:
--load-snapshot <LOAD_SNAPSHOT>
Restore this version-2 snapshot before applying the replay timeline. With this option, --frames and trace bounds are absolute emulator frames
--frames <FRAMES>
--verify
--json <JSON>
--png <PNG>
--snapshot <SNAPSHOT>
--observe-json <OBSERVE_JSON>
--wav <WAV>
--trace-jsonl <TRACE_JSONL>
--trace-start-frame <TRACE_START_FRAME>
--trace-end-frame-exclusive <TRACE_END_FRAME_EXCLUSIVE>
--cpu
--mem-read
--mem-write
--ppu
--apu
--mapper
--nmi
--dma
--full
--allow-unimplemented
-h, --help
Print helpkurosaki snapshot-save — Save machine state
kurosaki snapshot-save out/game.nes --frames 120 --out out/state.kss.jsonUsage: kurosaki.exe snapshot-save [OPTIONS] --out <OUT> <ROM>
Arguments:
<ROM>
Options:
--frames <FRAMES> [default: 1]
--out <OUT>
--allow-unimplemented
--pad1 <PAD1> [default: 0]
--pad2 <PAD2> [default: 0]
-h, --help Print helpkurosaki snapshot-load — Inspect a state file
kurosaki snapshot-load out/state.kss.json --json out/state-summary.jsonUsage: kurosaki.exe snapshot-load [OPTIONS] <SNAPSHOT>
Arguments:
<SNAPSHOT>
Options:
--json <JSON>
-h, --help Print helpkurosaki snapshot-rebase — Transfer state to a ROM permitted by a compatibility contract
kurosaki snapshot-rebase out/before.nes out/after.nes out/state.kss.json --contract out/compatibility.json --out out/rebased.kss.jsonRebind a reviewed v2 snapshot to an explicitly allowlisted compatible ROM
Usage: kurosaki.exe snapshot-rebase [OPTIONS] --contract <CONTRACT> --out <OUT> <SOURCE_ROM> <TARGET_ROM> <SNAPSHOT>
Arguments:
<SOURCE_ROM>
<TARGET_ROM>
<SNAPSHOT>
Options:
--contract <CONTRACT>
--prg-ram-patch <ADDRESS=FILE>
--cpu-ram-patch <ADDRESS=HEXBYTES>
--out <OUT>
--json <JSON>
-h, --help Print helpkurosaki snapshot-resume — Continue from saved state
kurosaki snapshot-resume out/game.nes out/state.kss.json --frames 60 --json out/resumed.jsonUsage: kurosaki.exe snapshot-resume [OPTIONS] <ROM> <SNAPSHOT>
Arguments:
<ROM>
<SNAPSHOT>
Options:
--reset-at-start Reset the CPU after restoring the snapshot while retaining mapper RAM
--frames <FRAMES> [default: 1]
--out <OUT>
--json <JSON>
--png <PNG>
--observe-json <OBSERVE_JSON>
--trace-jsonl <TRACE_JSONL>
--cpu
--mem-read
--mem-write
--ppu
--apu
--mapper
--nmi
--dma
--full
--allow-unimplemented
--pad1 <PAD1> [default: 0]
--pad2 <PAD2> [default: 0]
-h, --help Print helpkurosaki diff — Compare saved results
kurosaki diff --before out/before.kss.json --after out/after.kss.json --json out/diff.jsonUsage: kurosaki.exe diff [OPTIONS] --before <BEFORE> --after <AFTER>
Options:
--before <BEFORE>
--after <AFTER>
--json <JSON>
--md <MD>
-h, --help Print helpkurosaki decompile — Recover functions, control-flow graphs and pseudocode
kurosaki decompile out/game.nes --format markdown --out out/decompile.mdRecover bounded function CFGs and readable pseudocode from a mapper context
Usage: kurosaki.exe decompile [OPTIONS] <ROM>
Arguments:
<ROM>
Options:
--out <OUT>
Write the rendered report here; stdout is used when omitted
--format <FORMAT>
[default: json] [possible values: json, markdown, text]
--function <FUNCTIONS>
Function name or Bnnn:$AAAA physical PRG-bank selector. Repeatable
--all
Also start a bounded candidate analysis at $8000 in every physical 8 KiB PRG bank
--annotations <ANNOTATIONS>
JSON annotation sidecar. ROM.decompile.json is loaded automatically when present
--snapshot <SNAPSHOT>
Restore a version-2 snapshot before capturing the PRG-bank windows
--trace-jsonl <TRACE_JSONL>
KUROSAKI trace JSONL to overlay exact physical-bank/PC hit counts
--max-instructions <MAX_INSTRUCTIONS>
Per-function static-analysis cap, preventing data from causing unbounded output [default: 2048]
-h, --help
Print helpkurosaki disasm — Display CPU instructions
kurosaki disasm out/game.nes --bytes 256 --text out/disasm.txtUsage: kurosaki.exe disasm [OPTIONS] <ROM>
Arguments:
<ROM>
Options:
--bytes <BYTES> [default: 256]
--start <START> CPU address in decimal or with a 0x/$ hexadecimal prefix
--snapshot <SNAPSHOT> Restore a version 2 snapshot before reading mapped CPU bytes
--prg-bank-8k <PRG_BANK_8K> Read one exact physical 8 KiB PRG-ROM bank, independent of mapper state
--json <JSON>
--text <TEXT>
-h, --help Print helpkurosaki mapper-test — Observe mapper behavior
kurosaki mapper-test out/game.nes --json out/mapper-test.jsonUsage: kurosaki.exe mapper-test [OPTIONS] <ROM>
Arguments:
<ROM>
Options:
--json <JSON>
-h, --help Print helpkurosaki fds-inspect — Inspect disk structure
kurosaki fds-inspect out/game.fdsUsage: kurosaki.exe fds-inspect [OPTIONS] <DISK>
Arguments:
<DISK>
Options:
--json <JSON>
-h, --help Print helpkurosaki export-assets — Export assets from a ROM
kurosaki export-assets out/game.nes --out out/assetsUsage: kurosaki.exe export-assets --out <OUT> <ROM>
Arguments:
<ROM>
Options:
--out <OUT>
-h, --help Print helpkurosaki report — Create a report from saved observations
kurosaki report out/run.json --md out/report.mdUsage: kurosaki.exe report --md <MD> <INPUT>
Arguments:
<INPUT>
Options:
--md <MD>
-h, --help Print helpkurosaki mapper-list — List registered mappers
kurosaki mapper-listUsage: kurosaki.exe mapper-list [OPTIONS]
Options:
--all
--json <JSON>
--md <MD>
-h, --help Print helpkurosaki mapper-info — Describe a mapper
kurosaki mapper-info 4Usage: kurosaki.exe mapper-info [OPTIONS] <MAPPER>
Arguments:
<MAPPER>
Options:
--json <JSON>
-h, --help Print help