An annotated reconstruction of Flicky for the Sega Mega Drive, plus the tooling that rebuilds the ROM and compares it byte for byte against the original cartridge dump.
The source assembles with the AS Macro Assembler, which is vendored in bin/.
Approaches are shared with the sibling
alien_soldier_src project.
The build reproduces the reference ROM exactly, verified against the dump
itself. src/main.s is no longer a source file: it is an index of 36
address-ordered modules, and every symbol in them says what it is for -- there
are no disassembler-generated names left anywhere in the source.
Source Reconstruction 1.0 remains complete and immutable. Source 2.0 is a
tag-ready release candidate on top of it, with isolated Level, Graphics, and
Sound studios. The
data formats have codecs, the symbol map is exported for debuggers, twelve scenarios
replay under the emulator and are checked against 68 declared facts about work
RAM, and make release-check audits the whole release contract. See
docs/source_reconstruction_1_0.md for
what the release claims and what it does not.
The gate for every change is make verify. Annotating, renaming and
reformatting must never alter the assembled bytes, so any difference means the
edit was wrong.
git clone <repo>
cd flicky_src
# Place a legally obtained original ROM in the project root:
# Flicky (UE) [!].bin SHA-1 83d8bbf0a9b38c42a0bf492d105cc3abe9644a96
make init # Validate the ROM, extract data, build and verify
make verify # The permanent gateA successful verify prints:
[OK] Byte-identical ROM reproduced (SHA1 83d8bbf0a9b38c42a0bf492d105cc3abe9644a96)
The ROM is never tracked by this repository and is not distributed with it. Neither is anything extracted from it.
flicky_src/
|-- assets/
| `-- manifest.json # Reference ROM identity and per-segment SHA-1
|-- bin/ # Vendored AS toolchain, one folder per platform
| |-- windows_i386/ # asw.exe, p2bin.exe, message catalogs
| |-- linux_x86_64/ # asl, p2bin, message catalogs
| `-- README.md # Provenance, hashes, why -p=FF matters
|-- config/ # Build, authoring, runtime, and release contracts
| |-- authoring/ # Studio inventory and editable data formats
| |-- debugger/ # Symbol-resolved breakpoints and watches
| |-- linker/ # ROM map, landmarks, padding gap, module ranges
| |-- reconstruction/ # 300-700-line source policy and exceptions
| |-- runtime/ # Emulator capture configuration
| |-- toolchain.json # Toolchain hashes, pins, and supported hosts
| |-- source_reconstruction_1_0.json
| `-- source_reconstruction_2_0.json
|-- data/ # Extracted binary segments (ignored, from make split)
|-- docs/ # Task-oriented guides; see docs/index.md
|-- movies/ # Gens input recordings and their scene indexes
|-- scenarios/ # Runtime scenarios and their state expectations
|-- scripts/ # Categorized tooling, dispatched by run.py
| |-- authoring/ # Content models, studios, and native preview support
| |-- build/ # Assembly, extraction and housekeeping
| |-- formats/ # Shared Nemesis and Enigma Python codecs
| |-- runtime/ # Emulator capture and state validation
| |-- validation/ # Static, binary and release gates
| `-- workflow/ # Reverse-engineering maintenance tools
|-- tests/ # Tests mirroring authoring/runtime/validation
|-- src/
| |-- compression/ # Nemesis and Enigma decompressors
| |-- data/ # Binary includes and the large data tables
| |-- game/ # World/rules plus actors, enemies, rounds, screens
| |-- macros/ # Alignment pseudo-instructions
| |-- memory/ # Hardware ports, constants, work RAM map
| |-- rendering/ # VDP, tilemaps, text, HUD, level drawing
| |-- sound/ # 68000 host plus modular Z80 driver and sound data
| |-- system/ # Boot, entry point, interrupts, DMA, input
| `-- main.s # Address-ordered include index, the entrypoint
|-- mk/ # Authoring, runtime, validation, workflow recipes
`-- Makefile # Public interface and build primitives
make init # Validate the ROM, extract data, build and verify
make build # Assemble; a mismatch is reported as a warning
make verify # Assemble; a mismatch fails the build (the gate)
make compare # Compare an existing build without reassembling
make check-assets # Validate data/ against assets/manifest.json
make split # Re-extract data segments (the only writer of data/)
make lint # Style, naming, documentation and evidence checks
make format # Apply the deterministic fixes, then lint
make unpack-data # Decompress the Nemesis and Enigma segments
make clean # Remove build artifacts; extracted data is kept
make help # Everything, including the analysis workflow
make test # Unit tests for the Python tooling
make roundtrip-formats # Decode and re-encode the authored data
make symbols # Export build/main.sym for debuggers
make verify-toolchain # Hash-check the selected build tools before they run
make verify-emulator # Check the selected Gens executable and source revision
make verify-layout # Check the ROM layout against config/linker/rom_layout.json
make check-source-structure # Enforce 300-700 lines, justified exceptions, paths
make release-check # The complete acceptance gate
make init-content # Initialize the ignored editor workspace
make build-content # Build an isolated editable ROM
make check-content-zero-edit # Prove editable baseline byte identity
make level-studio # Open the visual level editor
make graphics-studio # Open the visual graphics editor
make sound-studio # Open the music and SFX editor
make preview-sound SOUND=zMusic81Header # Render standalone VGM and WAV audio
make verify-sound-sequencer # Compare Python YM2612 writes with the real Z80 driver
make check-studios # Validate Studio models without opening GUI
make smoke-studios-workstation # Exercise real Tk windows and public Studio actions
make source-2-audit # Check the Source 2.0 manifest
make source-2-check # Complete 1.0 + 2.0 acceptance gate
make source-2-pre-tag-check # Clean-tree check before creating the tag
make source-2-tag-check # Verify the annotated tag at HEADThe toolchain folder is chosen from the host platform; override it with
make PLATFORM=linux_x86_64.
make split is deliberately explicit and destructive, and make build never
touches data/. That asymmetry means locally modified assets survive a
rebuild.
- Find the owning module with
docs/source_layout.mdand its callers withdocs/subsystems.md. - Make the change, then run
make format,make lintandmake verify. - If something cannot be named with confidence, give it a neutral name and
open an entry in
docs/unknowns.md.
Full workflow in CONTRIBUTING.md.
Automated procedure analysis stubs a routine with an early return, rebuilds and
diffs emulator screenshots against a reference capture. It needs the
instrumented Gens build from
gens_automation as a sibling
checkout; make build-gens cross-compiles it in Docker, so Visual Studio is
optional. The command reads the exact source revision from
config/toolchain.json: it checks out that revision for a new clone and rejects
an existing checkout at any other revision before compiling. Every public
capture and playtest also verifies the resolved GENS_EXE against the approved
binary hash before launch.
The same sibling build contains a Z80 sound-port tracer. make trace-sound
captures the title music into build/sound_trace/, using an isolated sound-on
configuration rather than modifying the user's Gens.cfg.
make build-gens # Check out the pinned revision and cross-build in Docker
make reference MOVIE=longplay # Capture the reference frames
make find-unanalyzed # List procedures still to analyze
make analyze MOVIE=longplay # Stub and diff
make report MOVIE=longplay # Build the reportMOVIE is longplay or demos; see movies/README.md.
| Title | FLICKY |
| Platform | Sega Mega Drive / Genesis |
| Release | February 1991 |
| Product code | GM 00001022-00 |
| ROM size | 128 KB |
| Regions | Japan, USA, Europe |
Bit 7 of the version register selects the domestic revision, so the ROM carries
two sets of on-screen text: Japanese for Japan and English elsewhere. Symbols
for the Japanese variants carry a JP suffix.
- Nemesis does not re-encode byte for byte. Nine of the seventeen segments
round-trip exactly, including Enigma; the six Nemesis streams round-trip
semantically with smaller valid encodings. Tracked as DATA-002; see
docs/data_formats.md. - The runtime layer checks state, not pixels. The twelve replays assert
declared values of work RAM, which catches a game that diverges; comparing
screenshots needs a reference capture, and none is tracked. See
docs/runtime_evidence.md. - Four further open questions are listed in
docs/unknowns.md.
The former fixed-address sound limitation is resolved on source-2.0:
make verify-relocation packs the ROM without its layout gaps and checks the
recomputed Z80 data sources. See DATA-001 in
docs/unknowns.md.
- Approaches shared with alien_soldier_src
- AS Macro Assembler by Alfred Arnold
- Original game by Sega
Reverse engineering for educational and preservation purposes. No original ROM data is distributed with this repository. The original game is copyright Sega.