This directory is the authoritative reconstructed source for Proxima DESKTOP on the ZX Spectrum. It is a clean-room decompilation of the preserved binaries, not the original historical source tree. The source has two simultaneous goals:
- reproduce the preserved machine-code and data images exactly;
- make the program understandable as a set of cooperating subsystems.
Those goals explain the central organization rule:
Directories express responsibility; top-level image roots express physical address order.
A module may therefore live beside related code even when the image root must
include it earlier or later for byte identity. Never infer binary order from an
alphabetical directory listing. Follow the include sequence in the relevant
image root.
src/
├── platform/
│ └── zx-spectrum/ Spectrum ROM aliases and platform notes
├── desktop/
│ ├── installer/ protected loader, two decode stages and menu
│ └── editor/
│ ├── core/ device-independent resident editor
│ ├── extensions/ installer-selected editor extensions
│ ├── image-layout/ canonical physical composition fragments
│ ├── images/ complete installed-image roots
│ └── output/ printer and plotter front ends/transports
└── utilities/
├── fonteditor/ standalone font, title and screen editor
├── convertor/ foreign-editor to DESKTOP document converter
└── screentop/ large-canvas graphics editor and tape packer
Subsystem entry guides:
desktop/installer/README.mddesktop/editor/README.mddesktop/editor/core/README.mddesktop/editor/output/README.mddesktop/editor/images/README.mdutilities/README.mdutilities/fonteditor/README.mdutilities/convertor/README.mdutilities/screentop/README.md
The stable cross-subsystem overview is
../documentation/SOURCE-TREE.md.
Each root below is directly assembled by the public build. It is intentionally thin: constants and modules are selected here, while the implementation remains in the owning subsystem.
| Image | Root source | Address range | Meaning |
|---|---|---|---|
| Packed installer | desktop/installer/images/loaded.asm |
$5E88-$CB18 |
bytes loaded from the original installer tape block |
| First decoded installer | desktop/installer/images/decoded.asm |
$5E88-$D2F7 |
state after the first protection layer |
| Universal installer menu | desktop/installer/images/menu.asm |
$5E88-$E667 |
transient menu before an output configuration is installed |
| Installed editor variants | desktop/editor/images/**/*.asm |
$5E88-$E667 |
25 output configurations plus installed FONTEDITOR |
| Packed FONTEDITOR | utilities/fonteditor/standalone_fonteditor_packed.asm |
$5E88-$C618 |
historical protected CODE payload |
| Expanded FONTEDITOR | utilities/fonteditor/standalone_fonteditor_unpacked.asm |
$5E88-$FFFF |
complete post-expansion runtime image |
| Protected CONVERTOR | utilities/convertor/convertor_protected_basic.asm |
$5CCB-$7936 |
protected type-0 BASIC payload |
| Expanded CONVERTOR | utilities/convertor/standalone_convertor_runtime.asm |
$5DC0-$FFFF |
complete conversion runtime and template |
| Expanded SCREENTOP | utilities/screentop/standalone_screentop_unpacked.asm |
$5E88-$FFFF |
complete post-expansion graphics utility |
The installer also assembles each stored output producer independently under
desktop/installer/stored-frontends/producers/. These logical-origin images
are then embedded by matching record wrappers under records/.
The root tells you which bytes exist and where. Once that is clear, use the subsystem README to follow the program by lifecycle rather than address. For the resident editor, for example, the most useful order is:
image composition
-> lifecycle and restart model
-> persistent document/picture arena
-> current-line transaction
-> command dispatch
-> proportional layout and reflow
-> raster projection
-> tape load/save and recovery
This differs from the exact $BC55-$E667 include order, which is preserved in
desktop/editor/image-layout/core-body.inc.
The assembly uses a literate style. Large comment blocks establish:
- the representation currently held in memory;
- entry and exit contracts;
- stack shape at nonstandard control transfers;
- ownership of mutable instruction operands;
- publication order for persistent state;
- known historical defects or masked failure states.
End-of-line comments are used selectively for local mechanism. They should not replace a routine contract or repeat the mnemonic in prose.
DESKTOP frequently stores mutable state in instruction bytes. Names ending in
_operand, _instruction or _opcode identify those sites. They are not
incidental self-modification: they are fields of the runtime data model.
Typical examples include:
- current record and heap-front pointers;
- renderer glyph base, raster pointer, phase and clip limits;
- output-driver ports, masks and initializer bytes;
- window geometry and transfer operators;
- codec lengths, decoder addresses and selected wrappers.
When changing one of these fields, find both its writers and readers. The nearby commentary normally provides a small ownership ledger.
The resident editor is easiest to understand when memory is divided into:
- published state — packed text records, picture objects, fonts and public heap boundaries;
- transient projection — expanded current row, canonical raster, cursor and visible-page walkers;
- lifetime-overlaid scratch — workspaces reused by mutually exclusive operations such as editing, loading or font rollback.
A restart may discard and rebuild the transient projection without changing the published document. The utility programs use the same general economy: a buffer is often relocated before a transformation so the next phase can expand in place.
The reconstructed code retains historical techniques such as:
- synthetic calls made by pushing a target and executing
RET; - threaded inline strings that consume a
CALLreturn address; - tail dispatch through
JP (HL); - shared fall-through entries;
- nonlocal aborts that restore a saved stack pointer;
- relocated or copied executable templates;
- alternate-register preservation across ROM calls.
Comments document the stack and register narrative at these points. Do not normalize them into conventional calls unless a separate alternative build is being designed; doing so changes size, flags, timing or overlapping data.
Executable intervals are represented as assembler. Binary assets are retained only where the bytes are genuinely immutable data or protected streams, for example:
- compressed installer or utility streams;
- font corpus evidence;
- Spectrum screen images;
- initial bitmap seeds;
- terminal reserve bytes whose exact value is part of an expanded image.
An INCBIN is therefore a preservation boundary, not an invitation to hide
unexplained code. The public verification rejects external reconstruction-only
assets and requires the publication tree to be self-contained.
| Form | Meaning |
|---|---|
descriptive_global_label |
callable routine, public datum or cross-module state |
.local_label |
control-flow point meaningful only inside the current routine/chapter |
*_operand |
mutable immediate/address bytes inside an instruction |
*_instruction |
the instruction that owns a mutable operand or opcode |
*_pointer / *_front / *_end |
a published address value, not necessarily the address of the field itself |
*_workspace / *_buffer |
an actual memory interval |
*_bias |
base adjusted so a character/index may be added directly |
*_template |
bytes copied or emitted before later execution/use |
Addresses in comments are half-open only when explicitly written that way.
Otherwise $A-$B means inclusive historical addresses.
desktop/installer/images/loaded.asmdesktop/installer/stage1/entry.asmdesktop/installer/stage1/decoder.asmdesktop/installer/images/decoded.asmdesktop/installer/stage2/relocation.asmdesktop/installer/images/menu.asmdesktop/installer/menu/dispatch.asmdesktop/installer/menu/finalize-installed-image.asm- one producer under
desktop/installer/stored-frontends/producers/ - the matching installed image under
desktop/editor/images/
See desktop/installer/README.md.
desktop/editor/images/epson/interface1.asmdesktop/editor/image-layout/installed-prefix.incdesktop/editor/core/document/document-picture-heap.asmdesktop/editor/core/abi/entry-vectors.asmdesktop/editor/core/startup/editor-lifecycle.asmdesktop/editor/core/document/current-line-storage.asmdesktop/editor/core/layout/reflow-engine.asmdesktop/editor/core/rendering/raster-renderer.asmdesktop/editor/core/tape/load-and-merge.asm
See desktop/editor/core/README.md.
- choose an image root, for example
desktop/editor/images/epson/interface1.asm; - read its transport profile;
- read the device
installed-frontend.inccomposition; - read the device parameter UI and raster front end;
- read the selected physical transport driver;
- finish with
desktop/editor/image-layout/installed-output-tail.inc.
See desktop/editor/output/README.md.
Begin with utilities/README.md, then use the local
README. Each utility guide separates the historical packed representation, the
expanded runtime and the recommended semantic reading order.
Run commands from the repository root, not from inside src/.
python3 tools/build.py --clean
python3 tools/verify.pyEquivalent Make targets are:
make build
make verifyThe build assembles all installer states, every stored producer, 26 installed
editor layouts and all utility images. Verification additionally checks exact
lengths and hashes, rebuilds the complete 43-pair tape, and proves that the
freshly assembled installer yields the preserved Desktop.tap byte for byte.
To build direct emulator/hardware convenience tapes for all Czech and Slovak installed layouts:
python3 tools/build.py --clean --runnable
# or
make runnableSee ../documentation/RUNNABLE-TAP-IMAGES.md.
Before editing assembler, identify which of these categories applies:
- Comment/name-only improvement — emitted bytes must remain identical.
- Exact reconstruction correction — bytes may change only when stronger historical evidence proves the previous source wrong.
- Alternative build — behavior or size may intentionally change, but the exact roots and preserved tape must remain available.
For exact-source work:
- do not reorder includes in an image root;
- do not replace intentional padding with guessed variables;
- do not “fix” a documented historical defect in the canonical target;
- do not convert operand-backed state to RAM merely for stylistic reasons;
- do not duplicate the generic editor core in a device image;
- do not edit a stored producer record when the owning logical producer or shared device module is the real source of the bytes;
- preserve register, flag, stack and fall-through contracts at every entry;
- run
python3 tools/verify.pybefore considering the change complete.
../documentation/EDITOR-LIFECYCLE.md../documentation/EDITOR-COMMANDS.md../documentation/EDITOR-RENDERING.md../documentation/OUTPUT-DRIVERS.md../documentation/OUTPUT-VARIANTS.md../documentation/FONTEDITOR.md../documentation/CONVERTOR.md../documentation/SCREENTOP.md../documentation/DISTRIBUTION-BUILD.md