Creative Coding

10,287 Bytes, Ten Months, No Random Number Generator: Writing a Cracktro for a Stock 128K Spectrum

Mark Dastmalchi-Round's starfield stores each star as a screen byte plus a bit mask with a separate occupancy table, and the scrolltext works by chaining rl instructions so pixels fall out of one character cell into the carry flag.

In the late 1980s, Mark Dastmalchi-Round spent an embarrassing number of hours at a ZX Spectrum typing in Sinclair BASIC and copied assembler routines, trying to recreate the Amiga crack intros he had seen at a friend’s house. They never came close.

Last December he started again in Z80 assembly. The finished production — TNFStro — runs on a stock 128K Spectrum and carries the full set of late-80s tropes: a smooth scrolltext in custom fonts, a three-channel AY soundtrack, bouncing VU meters and the obligatory parallax starfield.

It is 10,287 bytes of code, or 19,552 bytes as a complete tape image. He began on 13 December last year, which works out to an average production rate of about 455 bytes per week.

Why a cracktro, in 2026

The genre is specific. Crack intros were made by the piracy groups that broke copy protection on floppy-disk games, and they shared a design language: an edgy logo at the top, boastful text over an effect — usually a parallax starfield or a rotating 3D object — and a scrolltext full of greetings to rival crackers and adverts for illegal BBS systems. The demoscene grew directly out of them once the cracking faded into the background.

Dastmalchi-Round’s version is a BBStro: an intro built to promote a BBS. The BBS in question is his own TNFS site, an old-school interactive service for the Spectrum that grew out of seeing how far he could push Sinclair BASIC, and which runs over a modern network card fitted to the machine.

That is also where the project came from. Through TNFS he met Desertkun, another protocol enthusiast who is producing a new WiFi network card for the Spectrum and sent over prototypes to test. On a video call comparing development setups, Desertkun asked why Mark didn’t write any Z80 assembly himself. The challenge stuck.

The scrolltext: letting pixels fall into the carry flag

Smooth horizontal scrolling on a Spectrum is hard because the screen is organised in character cells, and the obvious approach — redrawing shifted copies of the text — is far too slow.

The trick is the rl instruction. Rotating a byte left through carry pushes the top bit out into the carry flag, and pulls whatever was in carry into the bottom. Chain rl across a row of adjacent screen bytes and the pixel that falls off the right edge of one character cell reappears at the left edge of the next, for free, as a property of the instruction rather than as something the program has to arrange.

The starfield: no RNG, no coordinates

The parallax starfield uses no random number generator and stores no X/Y coordinates.

Each star is held as a screen byte plus a bit mask — that is, directly as the address it will be written to and the pixel within it. There is no transformation from world space to screen space, because there is no world space. A separate occupancy table tracks which cells are in use, so stars skip the cells that hold text rather than drawing over them.

This is the kind of representation that only makes sense under hard constraints, and it is why the effect runs at all on a 3.5 MHz CPU.

The music: a 1989 Amiga tune, squeezed by one channel

The soundtrack is a conversion of “Milkman” from the 1989 Amiga music disk “Sounds Of Gnome” — appropriate, given that the whole project is a Spectrum tribute to Amiga culture.

The Amiga original has four channels. The Spectrum’s AY sound chip has three. The missing channel was recovered using Vortex Tracker ornaments to play arpeggio chords, trading a simultaneous voice for a fast sequence that the ear reads as harmony. It is the standard chiptune solution to the problem, applied here in the direction people rarely go: porting down from the machine that won.

The toolchain, and the debugging tools that mattered

The build is Makefile-driven: the Pasmo assembler, his own fork of zmakebas for the BASIC loader, and the FUSE emulator for testing, with final verification on real hardware — .tap files uploaded to his local TNFS server and run on a +3.

He also credits a web-based Z80 asm-editor that doubles as an instruction reference and a step-through debugger, letting you watch registers and memory change one instruction at a time. Its syntax differs from Pasmo’s, so code could not be pasted straight in, but for manually tracing what a djnz loop or an add carry actually does, it earned its place.

And the tools he names as most significant are a notepad and pen, and his two dogs, Biscuit and Pebble. Coming from decades of high-level languages, he found he only understood most of his Z80 code after drawing the bytes and bitmasks by hand, keeping a written table of register flags, and sketching chunks of screen memory on paper. The evening dog walks were where the problems got solved.

He rates it simultaneously one of his favourite side projects and the one that most often nearly put his foot through a monitor.

Sources