ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM 



ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
C

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
F\CD\FC

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\CD

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"F\C5E\CD\F5\AF\D7\C1\F3

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
E\A7\ED

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
AE\EBC\EBE\CD\BB

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
C\FE\FA\CD

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\CDB

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
B itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\C9

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\FE\F8\B0\EDBE

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
AC\A7\ED\C3\EB

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
EE\CB\CB\FA

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"EEF\ED\B0C\CDC

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A\E5\D1 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"B itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"\C4

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\ED\B0\DD

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
B\AF\DD\CB

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"F\A7\ED\DD

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
B\EF itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"B\CDC\FDF\CC\C3\BAEEEE\FA\D3\FF

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
C\CB\FC\CD

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\EDF itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"E\F5\CD\B5

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
B\CD

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\DB\FE\C9 1 INPUT M$ 2 RUN USR VAL "16525" 3 GOTO VAL "2" 1 REM DEAF\FF itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\FF\FF

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"\FF\C5

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
EE\FD\D3\FF

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
C\CB\FC\CD

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\EDF itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"E\F5\CD\B5

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
B\CD

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\C1\DB\FE\DD\CD

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\EDB\CD\BD\FE\CD\C8\FE

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
D\CD\FC

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\BC\FE

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
C\CD\E2\CD

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A\B0\FECCE\FEBEE\AE\CB

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A\FD\BEC\EDBCE\FD\B6E\CBAFF\EDB\CD\F5AF\D7A itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\ED\B1\C2

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
EA\E6 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"FFA\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"\AF\E6\ED\CD\F5E\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"\AFFE\D7\C3 2 GOTO USR U 3 GOTO 2 0 REM \E7

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"F

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
B

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
C

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
D

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
E itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"D itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"C itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"B itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"A

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
C

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
D

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
E

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
F\FC\DE\CA\BD\A9D\FFDFDAEE

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
E itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"E\FF itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"E itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"B

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
F

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
E

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
EE\E1\FD\CBC\CDB\FDC\FF

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
B\FE

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
B\CDB\EE\CDB

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
BE\E8

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A\E5\CD\BB

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\E5\C1\AF

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
C\CD\BD itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\ED\B1\B8\FDC

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\E1\FE\FE\FE\FE

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"F\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\C9\E5\FE\FE\E1\CD\B5E\BE\CDA\BE\FA\CDBE

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
B\CDDE\CDB\E4\CDA\CDBE\A7D

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
B\CDD\EB

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A\A7\ED\EB\D0

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A\C9

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
B

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
B\EB

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A\ED\EB\D8

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A\C9E\FF itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"CFAF\D3\FF\CD\B3\F9\EF\C9B

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
EED\FD

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
D\F5B

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\AF\DB

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
DE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"\DB

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\FDD\E6F\FED

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
D\EB\C9\CD\B3\FB\F6\C9 1 REM \FC\DE\CA\BD\A9

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
AD

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
C\FFDF

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
B

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
ED

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
EAE\FFE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"C

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
E itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"F itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"E\FF itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"E

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
B itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"BD

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
F

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
EE\FFC\FFEAD itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"BDFDFDD\FF\FF

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\FF itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"AEA itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"FDFD

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
FA

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
C\FF

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
AAE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"AAD itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"B\FF

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
DF

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
DDF

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
DDFD\FF

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
DDA

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
FD\FF

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
DD

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
EA

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
C\FF

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\FF itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"A

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
C

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
EEA

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
FD

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
CDD itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"C\FF itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4" itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
D itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"D itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"D

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
D

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
D\CE 2 SAVE "%3" 3 GOTO USR VAL "16637" 0 REM

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\B9\B7\A6\B3

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\A6\B2\B9

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
D\AA\B7\B7\B4\B7\CD

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A\CD\E2 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\A0\CDB

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
B\CD

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\CD

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A\EDB\CD\BD\FE\CD\E2B itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\FE\C8\FE\C8

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
C\FE\C8\FE\C8

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
E\C9\FD\FC\F5 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\CDB

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
B

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
AC\CD\A5

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A\E5 itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A\CDB

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
B\E1\CDC\CD\EF\E5\CD

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
B itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\C9\CD\CD\EF\E4\CD\A7

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
E\C9\CD

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
AA\FE\FE\CD\C5\CD\F5\C1

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
AE\FD\FA\A6\CD\EA

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\EF\E5\CD\D1\ED itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\ED\B0\FD\F2A\FE\EF\E5\C4

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\CD\CD\CD\FD\CD\CD\CD

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\AF\FE

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
D\CD\C5\EF\E5\C5

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\C1\FE\CDE\BE\DA\A5\B1\CA\A5

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A\EB\CD\ED\EF\E5\C4

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\CD\CD\CD\FD\AF\EDB itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
C

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\ED\B0\FE itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\CD\FC

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\C9EC itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\ED\B0\C9\F2

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
A itemtype='https://schema.org/Blog' itemscope='itemscope' class="wp-singular computer_media-template-default single single-computer_media postid-56751 wp-custom-logo wp-embed-responsive wp-theme-astra wp-child-theme-astra-child ast-desktop ast-separate-container ast-left-sidebar astra-4.12.6 group-blog ast-blog-single-style-1 ast-custom-post-type ast-single-post ast-inherit-site-logo-transparent ast-hfb-header ast-full-width-primary-header ast-box-layout ast-normal-title-enabled astra-addon-4.12.4"

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\ED\B0\AF\C9\EF\A0\C4

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\EF\A2\E4\E5

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
F\A4\A4\C5

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\E5

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
F\A4\A4\C5

ZX81 Home Computer Package

Date: 1982
Type: Program
Platform(s): TS 1000

This is a four-program ZX81/TS1000 home computer package by Lamo-Lem Labs, consisting of a menu loader plus three applications: Billboard (a scrolling marquee display), Etch-A-Screen (a freehand drawing program), and Composer (a music composition tool), with a Checkbook Balancer as the fourth module. Each application stores substantial Z80 machine code in REM statements at line 0 or line 1, invoked via USR calls — a standard technique for embedding native code in ZX81 BASIC programs. The machine code routines handle hardware-level tasks such as direct port I/O (OUT FFh), keyboard scanning, and display manipulation that would be impractical in BASIC alone. The Checkbook Balancer uses BASIC expressions like AT PI,NOT PI (evaluating to AT 3,0) as a compact way to specify print positions without numeric literals.


Program Analysis

Program Structure

The package is organized as five separate BASIC programs intended to be loaded in sequence from tape. The first program is a menu loader that presents the four application choices. The remaining four programs implement Billboard, Etch-A-Screen, Composer, and Checkbook Balancer respectively. Each application program uses SAVE at an early line to allow re-saving, then immediately transfers control to machine code.

ProgramApplicationMC Entry PointKey Lines
1Menu LoaderNone10–80: PRINT menu
2BillboardUSR VAL "16525"1: INPUT M$, 2: RUN USR, 3: GOTO 2
3Etch-A-ScreenGOTO USR U2: GOTO USR U, 3: GOTO 2
4ComposerUSR VAL "16637"3: GOTO USR
5Checkbook BalancerUSR VAL "16677" / USR VAL "16565"3–9: INPUT/PRINT/GOTO

Machine Code in REM Statements

Each application embeds its Z80 machine code payload in REM statements at line 0 or line 1. On the ZX81, the body of a REM line is stored verbatim in memory at a predictable address, making it an ideal container for binary data. The USR keyword transfers BASIC execution to the Z80 routine at the computed address. Address 16525 (0x408D) corresponds to the ZX81 RAM area just above system variables, consistent with the REM payload starting near the default RAMTOP position.

Notable Z80 instructions visible in the hex payloads include OUT (FF),A (port FFh — the ZX81 NMI/display port), ED B0 (LDIR block copy), DB FE (IN A,(FE) — keyboard port), and various CD (CALL) sequences targeting ZX81 ROM routines such as CD 2A 0A and CD 92 02.

Billboard Program

The Billboard program accepts a message via INPUT M$ at line 1, then calls the machine code at USR VAL "16525" to scroll the text across the display. Line 3 loops back to line 2 with GOTO VAL "2", which re-executes the USR call. The use of VAL "2" and VAL "16525" rather than bare literals saves a small number of bytes by storing the number as a string rather than as a five-byte floating-point constant.

Etch-A-Screen Program

The Etch-A-Screen program uses the variable U (uninitialised, defaulting to 0 on the ZX81) as the USR target in GOTO USR U. However, the true entry point is computed by the machine code itself, loaded into a register on entry; the BASIC line merely serves as the jump-off point after the REM machine code is in place in memory. The tight loop GOTO 2 / GOTO USR U keeps re-entering the driver. The machine code payload in line 1 REM includes keyboard scanning via DB FE and character plotting routines.

Composer Program

The Composer’s line 0 REM contains a large table of note frequency and duration data (the structured byte sequences with values such as FC DE CA BD A9 96 85 7D are a descending frequency table for the tone generator). Line 1 REM holds what appears to be encoded musical score data followed by a long sequence of 53 xx 5D xx pairs — likely (note, duration) pairs for playback. The tone output is driven through port FF (D3 FF), which toggles the ZX81’s speaker line.

Checkbook Balancer

The Checkbook Balancer is the only module with meaningful BASIC logic visible. Line 8 uses the expression AT PI, NOT PI to specify print coordinates. PI evaluates to approximately 3.14159, which truncates to 3 for the row, and NOT PI evaluates to 0 (since PI is non-zero, NOT returns 0) for the column. Similarly, AT PI+PI, NOT PI gives row 6, column 0. This is a space-saving trick: the keyword PI occupies one byte as a token, whereas the literal 3 stored as a floating-point number occupies six bytes in a BASIC line.

Key BASIC Idioms

  • VAL "number" in GO TO and USR — saves bytes versus a floating-point numeric literal.
  • RUN USR VAL "16525" — combines RUN (which clears variables) with the USR call; unusual but valid on ZX81.
  • GOTO USR U — uses an uninitialized variable as an indirect jump, relying on machine code already being in memory.
  • AT PI, NOT PI — encodes print coordinates using mathematical constants to minimize token storage.
  • Tight two-line loops (GOTO 2GOTO USR ...) keep the machine code driver re-entrant from BASIC.

Notable Techniques and Observations

  • All heavy work (scrolling, drawing, sound, I/O) is handled in Z80 machine code; BASIC lines serve only as scaffolding and re-entry points.
  • The Composer’s REM at line 1 encodes both the playback engine and what appears to be a pre-composed tune as inline data, making the program entirely self-contained.
  • ROM routine addresses called from machine code (e.g., 0x022A, 0x0292, 0x0BD2) correspond to known ZX81 ROM entry points for display, keyboard, and utility functions.
  • The Checkbook Balancer’s machine code (line 0 REM, ~300 bytes) implements what appears to be a simple data-entry and arithmetic engine, with the BASIC layer handling only prompts and display formatting.

Content

Appears On

Related Products

Four programs: Billboard: Scrolls a giant banner across the screen. Etch-a- Screen: Draws text and graphics in any direction. Checkbook...

Related Articles

Related Content

Image Gallery

ZX81 Home Computer Package

Source Code

   0 REM COPYRIGHT 1982 LAMO-LEM LABS
   1 SAVE "%0"
  10 PRINT AT 3,11;"THE ZX81"
  20 PRINT AT 5,5;"HOME COMPUTER PACKAGE"
  30 PRINT AT 8,0;"1)  BILLBOARD"
  40 PRINT AT 10,0;"2)  ETCH-A-SCREEN"
  50 PRINT AT 12,0;"3)  COMPOSER"
  60 PRINT AT 14,0;"4)  CHECKBOOK BALANCER"
  70 PRINT AT 20,1;"COPYRIGHT 1982 LAMO-LEM LABS"
  80 PRINT " BOX 2382, LA JOLLA, CA 92038"

   0 REM \32\2A\38\38\26\2C\2A\0F\CD\FC\02\CD\2A\0A\01\1F\06\C5\3E\06\80\47\CD\F5\08\AF\D7\C1\10\F3\2A\0E\40\A7\ED\42\22\49\40\2A\10\40\23\5E\23\56\EB\19\22\3C\40\EB\23\22\3E\40\CD\BB\02\7C\85\FE\FA\20\10\CD\2A\0A\01\08\00\11\82\40\CD\6B\0B\01\01\00\C9\21\29\00\FE\F8\28\B0\ED\5B\3E\40\2A\3C\40\A7\ED\52\38\C3\EB\16\00\5E\23\22\3E\40\06\03\CB\23\CB\12\10\FA\21\00\1E\19\11\40\40\3E\08\4F\ED\B0\12\06\6C\CD\3C\41\2A\49\40\E5\D1\1B\01\C4\00\ED\B0\DD\21\46\40\11\20\00\06\06\36\76\2B\AF\DD\CB\00\06\1F\77\A7\ED\52\DD\2B\10\EF\06\1B\CD\3C\41\FD\35\48\06\8F\20\CC\C3\BA\40\4E\4E\4E\4E\10\FA\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\DB\FE\C9
   1 INPUT M$
   2 RUN USR VAL "16525"
   3 GOTO VAL "2"

   1 REM \39\38\3D\3E\36\3A\3F\37\FF\01\01\00\FF\FF\00\01\FF\06\11\C5\06\2E\4E\10\FD\D3\FF\2A\0C\40\CB\FC\CD\92\02\ED\5F\01\01\19\3E\F5\CD\B5\02\2B\CD\92\02\C1\DB\FE\10\DD\CD\29\02\ED\4B\25\40\CD\BD\07\FE\30\20\05\CD\69\08\18\C8\FE\2D\20\08\21\11\07\CD\FC\02\18\BC\FE\2C\20\08\CD\E2\08\CD\2A\0A\18\B0\FE\3C\20\07\21\3C\40\3E\71\18\09\FE\3B\20\09\21\3E\40\3E\80\AE\77\18\98\CB\76\28\0A\FD\BE\40\32\40\40\20\8C\18\05\ED\5B\3C\40\19\7E\FD\B6\3E\CB\77\28\03\3A\3F\40\32\3F\40\ED\4B\41\40\CD\F5\08\3A\3F\40\D7\3A\40\40\01\08\00\21\82\40\ED\B1\C2\93\40\0E\07\09\3A\41\40\86\E6\1F\4F\23\3A\42\40\86\FE\11\38\05\20\01\AF\E6\10\47\ED\43\41\40\CD\F5\08\7E\FE\76\20\01\AF\32\3F\40\3E\17\D7\C3\93\40
   2 GOTO USR U
   3 GOTO 2

   0 REM \E7\41\59\43\00\05\06\07\08\09\22\21\20\1F\0A\0B\0C\0D\0E\1D\1C\1B\1A\2C\2D\2E\2F\30\49\48\47\46\31\32\33\34\35\44\43\42\41\FC\DE\CA\BD\A9\96\85\7D\FF\7D\6F\64\5D\53\4A\41\3E\05\3E\37\31\2E\29\24\20\1E\FF\1E\1B\18\16\14\12\0F\0E\05\0E\23\09\7E\E1\FD\CB\3C\46\28\03\CD\7B\41\FD\36\3C\FF\77\23\36\00\34\20\0B\35\FE\05\28\06\2B\CD\7B\41\18\EE\CD\9B\41\2B\30\07\7E\23\18\E8\2A\82\40\E5\CD\BB\02\E5\C1\AF\2C\28\11\CD\BD\07\21\87\40\01\24\00\ED\B1\28\B8\FD\36\3C\00\E1\FE\04\28\47\FE\26\28\48\FE\27\28\47\FE\02\28\1F\FE\01\20\04\01\02\00\C9\E5\21\86\40\FE\24\28\06\FE\23\28\04\18\03\34\34\35\E1\CD\99\41\18\B5\3E\05\BE\38\09\CD\8A\41\BE\38\FA\CD\7B\41\7E\23\56\2B\CD\9D\41\38\9E\CD\7B\41\18\E4\CD\8A\41\18\03\CD\7B\41\7E\A7\28\8D\23\56\2B\CD\9D\41\18\85\23\23\EB\2A\84\40\A7\ED\52\EB\D0\2A\82\40\C9\2B\2B\EB\2A\82\40\37\ED\52\EB\D8\2A\84\40\C9\3E\FF\16\01\3C\5F\28\35\06\06\3A\86\40\83\5F\D3\FF\CD\B3\41\10\F9\15\20\EF\C9\4B\00\00\7E\3E\04\3D\20\FD\0D\20\F5\4B\00\AF\DB\00\32\3D\40\3E\01\DB\00\FD\86\3D\E6\3F\FE\3D\0D\20\EB\C9\06\06\CD\B3\41\10\FB\15\20\F6\C9
   1 REM \FC\05\DE\06\CA\07\BD\08\A9\09\96\0A\85\09\7D\0C\FF\05\7D\09\6F\0B\64\0E\5D\0E\53\10\4A\11\41\14\3E\17\FF\04\3E\14\37\19\31\1C\2E\1F\29\23\24\29\20\29\1E\33\FF\05\1E\2B\1B\32\18\38\16\37\14\46\12\3D\0F\55\0E\5E\FF\10\05\6C\FF\08\3E\20\4A\22\5D\1B\7D\14\6F\05\64\06\5D\07\6F\09\5D\08\7D\14\FF\03\FF\02\FF\03\53\1A\3E\22\4A\1F\5D\16\6F\07\64\05\5D\06\53\0F\4A\0C\53\20\FF\05\53\0A\4A\13\53\07\3E\1A\4A\07\53\08\5D\1B\FF\02\7D\08\6F\0D\5D\06\6F\0D\5D\07\6F\06\7D\14\FF\02\7D\08\5D\12\4A\09\53\0F\7D\05\FF\02\7D\05\5D\0E\4A\0C\53\10\FF\02\FF\01\4A\0C\41\0E\3E\13\4A\0F\5D\0C\53\15\7D\09\5D\1C\FF\07\05\90\53\01\53\01\53\03\53\01\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\01\53\02\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\02\53\03\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\02\53\02\53\01\53\01\53\02\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\01\53\02\53\01\53\01\53\01\53\02\53\01\53\01\53\02\53\02\5D\01\5D\01\5D\02\5D\02\5D\06\05\CE
   2 SAVE "%3"
   3 GOTO USR VAL "16637"

   0 REM \66\00\00\00\00\00\79\00\00\00\00\00\44\42\01\16\00\44\42\B9\B7\A6\B3\00\00\A6\B2\B9\00\0D\AA\B7\B7\B4\B7\35\CD\2A\0A\CD\E2\08\01\05\00\11\A0\40\CD\6B\0B\CD\29\02\CD\2A\0A\ED\4B\25\40\CD\BD\07\32\90\40\FE\05\28\17\CD\E2\08\7B\01\03\00\FE\20\C8\FE\21\C8\0C\FE\22\C8\FE\09\C8\0E\06\C9\FD\35\40\FC\F5\41\01\05\00\11\95\40\CD\6B\0B\2A\3C\40\CD\A5\0A\E5\01\06\00\11\9A\40\CD\6B\0B\E1\CD\14\42\22\3C\40\CD\20\42\EF\E5\34\CD\61\0B\01\09\00\C9\CD\11\42\23\23\11\71\40\CD\03\42\EF\E4\34\CD\A7\0E\C9\CD\2A\0A\3A\90\40\FE\09\28\04\FE\22\20\60\CD\13\41\C5\CD\F5\41\C1\2A\8E\40\FD\35\40\FA\A6\40\CD\EA\09\28\06\11\06\00\19\18\EF\E5\23\CD\14\42\D1\ED\53\93\40\01\06\00\ED\B0\FD\35\40\F2\55\41\3A\90\40\FE\22\28\11\EF\E5\18\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\18\12\21\89\40\11\71\40\CD\03\42\CD\25\42\11\89\40\CD\00\42\21\92\40\35\AF\FE\21\20\0D\CD\13\41\C5\EF\E5\18\C5\02\34\C1\18\07\FE\20\20\33\CD\13\41\21\91\40\7E\23\34\BE\DA\A5\40\78\B1\CA\A5\40\2A\93\40\70\23\71\23\11\76\40\EB\CD\18\42\ED\53\93\40\EF\E5\C4\02\34\CD\09\42\CD\25\42\CD\FD\41\AF\21\82\40\ED\5B\10\40\01\0C\00\ED\B0\FE\01\20\06\21\74\02\CD\FC\02\01\08\00\C9\21\8E\40\11\3C\40\18\06\11\83\40\21\76\40\01\05\00\ED\B0\C9\21\83\40\11\76\40\18\F2\2A\10\40\23\11\76\40\01\04\00\ED\B0\AF\12\C9\EF\A0\C4\02\34\EF\A2\E4\E5\0F\A4\A4\04\04\C5\33\00\02\18\E5\0F\36\A4\A4\04\05\C5\02\34\C9
   1 REM                                                                                                                                           
   3 INPUT A
   4 PRINT "%T"
   5 INPUT T
   7 GOTO USR VAL "16677"
   8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A
   9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top
\C9 1 REM 3 INPUT A 4 PRINT "%T" 5 INPUT T 7 GOTO USR VAL "16677" 8 PRINT "%B%A%L%A%N%C%E";AT PI,NOT PI;"BANK $";T;AT PI+PI,NOT PI;"CHECKBOOK $";A 9 GOTO USR VAL "16565"

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

People

No people associated with this content.

Scroll to Top