--- title: "ZX81 Home Computer Package" id: 56751 type: "computer_media" slug: "zx81-home-computer-package" url: "http://localhost/computer_media/zx81-home-computer-package/" markdown_url: "http://localhost/computer_media/zx81-home-computer-package.md" published_at: "2024-09-22T23:31:59+00:00" modified_at: "2026-04-03T07:58:54+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/09/menu-screen.jpeg" excerpt: "A four-module home utility suite from 1982 packs a scrolling billboard, drawing program, music composer, and checkbook balancer into Z80 machine code hidden inside REM statements." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "Lamo-Lem" slug: "lamo-lem" taxonomy: "post_tag" url: "http://localhost/tag/lamo-lem/" - name: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" genre: - name: "Art" slug: "art" taxonomy: "genre" url: "http://localhost/type/art/" - name: "Banner" slug: "banner" taxonomy: "genre" url: "http://localhost/type/banner/" - name: "Finance" slug: "finance" taxonomy: "genre" url: "http://localhost/type/finance/" - name: "Music" slug: "music" taxonomy: "genre" url: "http://localhost/type/music/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/ZX81%20Home%20Computer%20Package%20%281982%29%28Lamo-Lem%20Labs%29%28TS1000%29%28US%29%28Cassette%29.zip" mediadate: "1982" producer_company: - id: 11041 title: "Lamo-Lem" type: "company" url: "http://localhost/company/lamo-lem/" images: - url: "http://localhost/wp-content/uploads/2024/09/menu-screen.jpeg" - url: "http://localhost/wp-content/uploads/2024/09/ZX81-Home-Computer-Pkg.jpg" related_products: - id: 14797 title: "ZX81 Home Computer Package" type: "product" url: "http://localhost/product/zx81-home-computer-package/" media_type_tags: "Art, Banner, Finance, Music" --- # ZX81 Home Computer Package 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. | Program | Application | MC Entry Point | Key Lines | | --- | --- | --- | --- | | 1 | Menu Loader | None | 10–80: PRINT menu | | 2 | Billboard | `USR VAL "16525"` | 1: INPUT M$, 2: RUN USR, 3: GOTO 2 | | 3 | Etch-A-Screen | `GOTO USR U` | 2: GOTO USR U, 3: GOTO 2 | | 4 | Composer | `USR VAL "16637"` | 3: GOTO USR | | 5 | Checkbook Balancer | `USR 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 2` → `GOTO 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. ## 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 322A3838262C2AFCDFC2CD2AA11F6C53E68047CDF58AFD7C110F32AE40A7ED422249402A1040235E2356EB19223C40EB23223E40CDBB27C85FEFA2010CD2AA180118240CD6BB110C921290FEF828B0ED5B3E402A3C40A7ED5238C3EB1605E23223E4063CB23CB1210FA2101E191140403E84FEDB01266CCD3C412A4940E5D11B1C40EDB0DD214640112006636762BAFDDCB061F77A7ED52DD2B10EF61BCD3C41FD354868F20CCC3BA404E4E4E4E10FAD3FF2AC40CBFCCD922ED5F11193EF5CDB522BCD922DBFEC9 1 INPUT M$ 2 RUN USR VAL "16525" 3 GOTO VAL "2" 1 REM 39383D3E363A3F37FF110FFFF01FF611C562E4E10FDD3FF2AC40CBFCCD922ED5F11193EF5CDB522BCD922C1DBFE10DDCD292ED4B2540CDBD7FE30205CD69818C8FE2D20821117CDFC218BCFE2C208CDE28CD2AA18B0FE3C207213C403E71189FE3B209213E403E80AE771898CB7628AFDBE40324040208C185ED5B3C40197EFDB63ECB772833A3F40323F40ED4B4140CDF583A3F40D73A4040180218240EDB1C29340E793A414086E61F4F233A424086FE11385201AFE61047ED434140CDF587EFE76201AF323F403E17D7C39340 2 GOTO USR U 3 GOTO 2 0 REM E74159430567892221201FABCDE1D1C1B1A2C2D2E2F3049484746313233343544434241FCDECABDA996857DFF7D6F645D534A413E53E37312E2924201EFF1E1B18161412FE5E2397EE1FDCB3C46283CD7B41FD363CFF77233603420B35FE52862BCD7B4118EECD9B412B3077E2318E82A8240E5CDBB2E5C1AF2C2811CDBD72187401240EDB128B8FD363C0E1FE42847FE262848FE272847FE2281FFE1204120C9E5218640FE24286FE23284183343435E1CD994118B53E5BE389CD8A41BE38FACD7B417E23562BCD9D41389ECD7B4118E4CD8A41183CD7B417EA7288D23562BCD9D4118852323EB2A8440A7ED52EBD02A8240C92B2BEB2A824037ED52EBD82A8440C93EFF1613C5F2835663A8640835FD3FFCDB34110F91520EFC94B007E3E43D20FDD20F54B0AFDB0323D403E1DB0FD863DE63FFE3DD20EBC966CDB34110FB1520F6C9 1 REM FC5DE6CA7BD8A9996A8597DCFF57D96FB64E5DE53104A1141143E17FF43E143719311C2E1F2923242920291E33FF51E2B1B32183816371446123DF55E5EFF1056CFF83E204A225D1B7D146F56465D76F95D87D14FF3FF2FF3531A3E224A1F5D166F76455D653F4AC5320FF553A4A135373E1A4A75385D1BFF27D86FD5D66FD5D76F67D14FF27D85D124A953F7D5FF27D55DE4AC5310FF2FF14AC41E3E134AF5DC53157D95D1CFF75905315315335315335315325315315315315325315315325315325315325315315315315315325335315325315315315315315315315315315315315315315315315315315315315315315315315315315325315325325315315325315315315315315315315315315315315325315315315325315315325325D15D15D25D25D65CE 2 SAVE "%3" 3 GOTO USR VAL "16637" 0 REM 66000007900000444211604442B9B7A6B300A6B2B90DAAB7B7B4B735CD2AACDE2815011A040CD6BBCD292CD2AAED4B2540CDBD7329040FE52817CDE287B130FE20C8FE21C8CFE22C8FE9C8E6C9FD3540FCF541150119540CD6BB2A3C40CDA5AE5160119A40CD6BBE1CD1442223C40CD2042EFE534CD61B190C9CD11422323117140CD342EFE434CDA7EC9CD2AA3A9040FE9284FE222060CD1341C5CDF541C12A8E40FD3540FAA640CDEA928611601918EFE523CD1442D1ED539340160EDB0FD3540F255413A9040FE222811EFE518C4234CD942CD2542CDFD411812218940117140CD342CD2542118940CD04221924035AFFE2120DCD1341C5EFE518C5234C1187FE202033CD13412191407E2334BEDAA54078B1CAA5402A934070237123117640EBCD1842ED539340EFE5C4234CD942CD2542CDFD41AF218240ED5B10401C0EDB0FE120621742CDFC2180C9218E40113C40186118340217640150EDB0C921834011764018F22A104023117640140EDB0AF12C9EFA0C4234EFA2E4E5FA4A444C5330218E5F36A4A445C5234C9 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" ```