Z-AID

Products: Z-AID
Date: 1982
Type: Program
Platform(s): TS 1000
Tags: Tape

Z-AID is a utility that extends cassette tape operations by adding verify, chain, and block memory save/load capabilities through an embedded machine code routine. The program self-installs by decoding a hex string stored in Z$ (line 60) into raw Z80 machine code bytes at memory address 29000, using a FOR loop that processes the string two characters at a time. Each byte value is reconstructed by subtracting 28 from each character code and combining the two nibbles — an encoding scheme that keeps all characters printable on the ZX81 character set. After decoding, control is transferred to the routine via RAND USR 29000. The startup sequence uses SLOW mode, displays a title screen, and prompts the user to position the tape before the load sequence begins at line 9.


Program Analysis

Program Structure

The program has two distinct execution paths controlled by the entry point. Line 5 jumps immediately to line 18, which runs the interactive title/setup sequence. Lines 9–17 form the tape-load completion handler, reached via GOTO 9 at line 80 after the machine code has been POKEd into memory. The overall flow is:

  1. Line 5: GOTO 18 — skip the load-complete handler on first run.
  2. Lines 18–55: Display title screen in SLOW mode, prompt user to stop the tape latch.
  3. Lines 55–80: Initialize target address T=29000, set up hex string Z$, CLEAR 3000 to protect RAM from 3000 upward, then GOTO 9.
  4. Lines 9–17: CLS, print restart-tape prompt, PAUSE 100, RAND USR 29000 to execute the installed routine, then display load-complete message and STOP.
  5. Lines 3000–8000: Subroutine that decodes Z$ two characters at a time and POKEs bytes to address T.
  6. Lines 9000–9010: SAVE then RUN — the distribution/re-save block.

Note that the decode subroutine at lines 3000–8000 is never explicitly called with GO SUB in the visible listing; CLEAR 3000 at line 62 protects the subroutine area, and the flow from line 80 goes to line 9 rather than into the subroutine directly. The subroutine ends with RETURN at line 8000, suggesting it was designed to be called via GO SUB 3000 from a line that may have been removed or is reached differently in the saved version.

Machine Code Encoding Scheme

The hex payload in Z$ (line 60) is not stored as ASCII hex digits. Instead, each nibble is offset by 28 added to its value, placing all characters in the printable ZX81 range. The decode loop at lines 3000–8000 reverses this:

  • Take two consecutive characters from Z$.
  • High nibble: (CODE Z$(X) - 28) * 16
  • Low nibble: CODE Z$(X+1) - 28
  • Sum the two to reconstruct the full byte, then POKE T, V.

This encoding ensures the string contains no characters with codes below 28, avoiding control characters that would be illegal or ambiguous inside a ZX81 string literal.

Z80 Payload Analysis

The hex string in Z$ decodes to approximately 50 bytes of Z80 machine code installed at address 29000 (0x7148). Key opcodes visible in the raw hex include CD (CALL), C9 (RET), DB FE (IN A,(254) — keyboard read), D3 FF (OUT (255),A — likely display or border), and loop constructs using 10 (DJNZ) and 20 (JR NZ). The routine is invoked via RAND USR 29000, which is the standard ZX81 idiom for calling machine code from BASIC.

Memory Layout

AddressPurpose
3000CLEAR boundary — BASIC decode subroutine starts here (protected from BASIC memory manager)
29000 (0x7148)Target address for decoded Z80 machine code; initial value of T

Key BASIC Idioms

  • RAND USR 29000 — standard ZX81 technique to call a machine code address from BASIC without using USR in an expression context.
  • CLEAR 3000 — reserves high memory for the machine code while also resetting the stack; used here to protect the subroutine lines from being overwritten.
  • FOR X=1 TO LEN Z$ STEP 2 — iterates over pairs of characters in the encoded string without hardcoding the byte count, making the routine length-agnostic.
  • The SAVE "[B]" at line 9000 followed immediately by RUN at line 9010 is the standard self-replicating distribution pattern for ZX81 utilities.

Anomalies and Notable Points

  • The decode subroutine (lines 3000–8000) ends with RETURN, implying a GO SUB 3000 call that is not present in the listed code between lines 62 and 80. It is likely that a GO SUB 3000 was intended between lines 62 and 80 and is missing from the listing, or the GOTO 9 at line 80 was meant to be GO SUB 3000: GOTO 9.
  • Lines 25, 38, and 48 contain copyright and publisher text printed in plain (non-inverse) characters, consistent with a commercial product splash screen.
  • The PAUSE 100 at line 11 gives the user roughly 5 seconds to act on the “PLEASE RESTART THE TAPE NOW” prompt before RAND USR 29000 executes the installed utility.

Content

Appears On

Related Products

VERIFY confirms whether a program has been recorded properly on tape. The program in memory is unaffected, and a further...

Related Articles

Related Content

Image Gallery

Source Code

   5 GOTO 18
   9 CLS
  10 PRINT AT 10,1;"[P][L][E][A][S][E]█[R][E][S][T][A][R][T]█[T][H][E]█[T][A][P][E]█[N][O][W]"
  11 PAUSE 100
  12 RAND USR 29000
  15 CLS
  16 PRINT AT 10,3;"[Z][-][A][I][D]█[L][O][A][D]█[I][S]█[N][O][W]█[C][O][M][P][L][E][T][E]"
  17 STOP
  18 SLOW
  19 CLS
  20 PRINT AT 4,7;"[Z][-][A][I][D]█[1][.][0]"
  25 PRINT AT 6,0;"COPYRIGHT 1982 BY"
  38 PRINT AT 7,0;"INTERNATIONAL PUBLISHING ";AT 8,0;"AND SOFTWARE INC."
  48 PRINT AT 10,0;"[*][*]██[P][R][E][S][S]█[T][H][E]█[S][T][O][P]█[L][A][T][C][H]██████[*][*][*][*]████[O][N]█[T][H][E]█[T][A][P][E]█[D][E][C][K]████████[*][*]"
  55 LET T=29000
  60 LET Z$="CD[3]30#260FCD72712520FACD727169CD727161CD7271C5CD727179C147C5CD72717123C10B78B120F4C90E0106003E7FDBFED3FF1FD2A2031717380510F0C372711E94061A1DDBFE17CB7B7B38F510F52004FE5630D63FCB1130D1C9"
  62 CLEAR3000
  80 GOTO 9
 3000 FOR X=1 TO LEN Z$ STEP 2
 4000 LET V=(CODE Z$(X)-28)*16+CODE Z$(X+1)-28
 5000 POKE T,V
 6000 LET T=T+1
 7000 NEXT X
 8000 RETURN
 9000 SAVE "[B]"
 9010 RUN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top