Skip to content

Latest commit

 

History

History
305 lines (235 loc) · 13 KB

File metadata and controls

305 lines (235 loc) · 13 KB

DESKTOP source guide

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:

  1. reproduce the preserved machine-code and data images exactly;
  2. 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.

Source map

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:

The stable cross-subsystem overview is ../documentation/SOURCE-TREE.md.

Principal image roots

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/.

How to read this source

1. Start from a root, then change to conceptual order

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.

2. Treat comments as part of the reconstruction

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.

3. Recognize code-resident state

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.

4. Distinguish published and transient state

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.

5. Follow nonstandard control flow literally

The reconstructed code retains historical techniques such as:

  • synthetic calls made by pushing a target and executing RET;
  • threaded inline strings that consume a CALL return 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.

Source and data boundary

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.

Naming conventions

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.

Recommended reading paths

Installer and installation mechanics

  1. desktop/installer/images/loaded.asm
  2. desktop/installer/stage1/entry.asm
  3. desktop/installer/stage1/decoder.asm
  4. desktop/installer/images/decoded.asm
  5. desktop/installer/stage2/relocation.asm
  6. desktop/installer/images/menu.asm
  7. desktop/installer/menu/dispatch.asm
  8. desktop/installer/menu/finalize-installed-image.asm
  9. one producer under desktop/installer/stored-frontends/producers/
  10. the matching installed image under desktop/editor/images/

See desktop/installer/README.md.

Resident editor

  1. desktop/editor/images/epson/interface1.asm
  2. desktop/editor/image-layout/installed-prefix.inc
  3. desktop/editor/core/document/document-picture-heap.asm
  4. desktop/editor/core/abi/entry-vectors.asm
  5. desktop/editor/core/startup/editor-lifecycle.asm
  6. desktop/editor/core/document/current-line-storage.asm
  7. desktop/editor/core/layout/reflow-engine.asm
  8. desktop/editor/core/rendering/raster-renderer.asm
  9. desktop/editor/core/tape/load-and-merge.asm

See desktop/editor/core/README.md.

Output subsystem

  1. choose an image root, for example desktop/editor/images/epson/interface1.asm;
  2. read its transport profile;
  3. read the device installed-frontend.inc composition;
  4. read the device parameter UI and raster front end;
  5. read the selected physical transport driver;
  6. finish with desktop/editor/image-layout/installed-output-tail.inc.

See desktop/editor/output/README.md.

Standalone utilities

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.

Building and verification

Run commands from the repository root, not from inside src/.

python3 tools/build.py --clean
python3 tools/verify.py

Equivalent Make targets are:

make build
make verify

The 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 runnable

See ../documentation/RUNNABLE-TAP-IMAGES.md.

Change-safety rules

Before editing assembler, identify which of these categories applies:

  1. Comment/name-only improvement — emitted bytes must remain identical.
  2. Exact reconstruction correction — bytes may change only when stronger historical evidence proves the previous source wrong.
  3. 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.py before considering the change complete.

Further documentation