--- title: "Life" id: 64648 type: "computer_media" slug: "life" url: "http://localhost/computer_media/life/" markdown_url: "http://localhost/computer_media/life.md" published_at: "2026-03-05T20:58:43+00:00" modified_at: "2026-03-30T21:43:28+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/03/Life-3.png" excerpt: "A full Conway's Life implementation with a cursor-driven cell editor and machine-code evolution engine, loaded from tape and driven by a BASIC menu shell." 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: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" genre: - name: "Education" slug: "education" taxonomy: "genre" url: "http://localhost/type/education/" - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_contents: - id: 64613 title: "CATS Library Tape 10" type: "computer_media" url: "http://localhost/computer_media/cats-library-tape-10/" - id: 54964 title: "ISTUG Public Domain Library 6" type: "computer_media" url: "http://localhost/computer_media/istug-public-domain-library-6/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Life%20%28198x%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2026/03/Life-3.png" - url: "http://localhost/wp-content/uploads/2026/03/Life-2.png" - url: "http://localhost/wp-content/uploads/2026/03/Life.png" media_type_tags: "Education, Game" --- This program implements [Conway’s Game of Life](https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life) cellular automaton, using a machine-code routine loaded from tape (via LOAD “”CODE at line 2) stored from address 30000 onward and occupying 410 bytes. The BASIC shell provides a menu for random or programmed colony starts, with a cursor-driven cell editor that allows placing or erasing cells using numeric keys mapped to directions and actions. Screen memory is directly manipulated via POKEs to address 22527+(32*r)+c for cursor display, and system variable 23659 (REPDEL) is toggled to control keyboard repeat behaviour. The machine-code entry points at USR 30088, USR 30139, and USR 30351 handle the random initialisation, Life evolution loop, and a third function respectively. Line 9998 saves both the BASIC and machine-code segments back to tape with LINE 1 autostart. *** ## Program Structure The program is divided into clearly demarcated sections: 1. **Lines 1–80:** Initialisation — clears memory to 29999, loads machine code from tape, sets colours, and shows an introduction screen. 2. **Lines 90–180:** Main menu — offers random start, programmed start, or end. 3. **Lines 190–320:** Cursor-driven cell editor for programmed starts, using numeric keypad-style input. 4. **Lines 400–610:** Action handlers for returning to menu (400), placing a live cell (500), and erasing a cell (600). 5. **Line 700:** Clean exit restoring REPDEL and stopping. 6. **Lines 1000–1020:** Subroutines for screen/system setup and status-bar printing. 7. **Lines 9998–9999:** Save/verify routines for both BASIC and machine-code segments. ## Machine Code Usage The machine-code block is loaded to address 30000 and is 410 bytes long. Three distinct entry points are used: | Address | Call site | Inferred function | | --- | --- | --- | | `USR 30088` | Line 170 | Random colony initialisation | | `USR 30139` | Line 410 | Life evolution loop (run simulation) | | `USR 30351` | Line 190 | Programmed-start evolution / entry point | The result of each `USR` call is assigned to a variable (`l` or `x`) but the return values are unused; the calls are purely for their side effects on the display. ## Screen and System Variable Manipulation The cursor is tracked with row `r` and column `c` variables. The display-file address is computed with a DEF FN at line 210: `DEF FN p()=22527+(32*r)+c` This gives the address of character cell (r,c) in the Spectrum display file. The cursor character is written as POKE 30 (char code 18, a Spectrum block graphic), and the original cell value `z` is saved and restored on cursor movement. System variable 23659 (`REPDEL`) is set to 2 during menus to enable key repeat, and to 0 during the cell editor to suppress it. System variables 23684–23687 are poked in subroutine 1000; these correspond to `ATTR_P`, `MASK_P`, `P_FLAG`, and the start of the print buffer area — effectively resetting permanent paper/ink attributes and cursor state. ## Cell Editor Key Mapping The editor reads `INKEY$` and converts to a numeric digit with `CODE INKEY$-48`, valid range 1–9: | Key | Action | | --- | --- | | `5` | Move cursor left | | `8` | Move cursor right | | `6` | Move cursor down | | `7` | Move cursor up | | `4` | Place live cell (POKE p,170; z=48) | | `9` | Erase cell (POKE p,170; z=54) | | `3` | Return to menu | Movement uses the idiom `c+(d=8)-(d=5)`, exploiting Boolean expressions evaluating to 1 or 0 to add or subtract without IF statements. Wrap-around at screen edges is handled by lines 310–313, providing a toroidal grid in the editor. ## Notable Techniques and Anomalies - The cursor display writes char code 18 (`POKE p,18`) directly to display RAM — a fast but attribute-ignorant method. - Lines 500 and 600 branch back to line 245 (`GO TO 245`), but line 245 does not exist; the interpreter will fall through to line 250. This is a minor anomaly that works correctly in practice because Spectrum BASIC performs a sequential search and executes the next available line. - The `OVER 1` print at lines 20 and 100 draws underscores over the title text to simulate an underline effect. - `POKE 23659,2` sets REPDEL to 2 frames (very fast repeat) at menus; `POKE 23659,0` disables repeat in the editor — a deliberate and correct use. - The save routine at line 9998 uses `SAVE "Life" LINE 1` to autostart the program, and saves the machine code separately as a CODE file starting at 30000, length 410. - `CLEAR 29999` at line 1 sets RAMTOP just below the machine-code load address, protecting the routine from being overwritten by BASIC’s memory management. ## Source Code ``` 1 CLEAR 29999 2 PRINT AT 10,2;"Leave recorder running"," life data now loading": BEEP .4,15: LOAD ""CODE 3 INK 9: PAPER 3: BORDER 4: CLS 10 PRINT AT 2,8;"CONWAY'S LIFE" 20 PRINT OVER 1;AT 2,8;"_____________" 30 PRINT AT 4,3;"THIS PROGRAM WILL SIMULATE"';"THE EVOLUTION OF A COLONY OF"';" ""BUGS""" 40 PRINT AT 8,3;"THE INITIAL COLONY "'"MAY BE RANDOM OR PROGRAMMED" 50 PRINT AT 11,3;"YOU MAY STOP AT ANY TIME TO"'"CHANGE THE DISPLAY OR RETURN"'" TO THE MENU" 60 PRINT PAPER 2; INK 9;AT 17,3;"PRESS ANY KEY TO CONTINUE" 70 IF INKEY$="" THEN GO TO 70 80 BEEP .2,15: POKE 23659,2: CLS 90 PRINT AT 2,13;"MENU" 100 PRINT OVER 1;AT 2,13;"____" 110 PRINT AT 5,3;"1:RANDOM START" 120 PRINT AT 7,3;"2:PROGRAMMED START" 125 PRINT AT 9,3;"3:END" 130 PRINT AT 12,2;"WHEN THE PROGRAM IS RUNNING, KEY ""1"" WILL RETURN TO THE MENU AND KEY ""2"" WILL ALLOW CHANGES TO BE MADE TO THE SCREEN" 140 PRINT FLASH 1; INK 1; PAPER 9;AT 21,7;"ENTER YOUR CHOICE" 150 LET a$=INKEY$ 160 IF CODE a$<49 OR CODE a$>51 THEN GO TO 150 170 IF a$="1" THEN GO SUB 1000: GO SUB 1010: LET l=USR 30088 180 IF a$="3" THEN GO TO 700 190 LET l=USR 30351 200 BEEP .2,15: LET c=16: LET r=11 205 GO SUB 1000: POKE 23659,0: PRINT PAPER 4; INK 9;AT 22,0;"use cursors to move,3 to return, 4 to enter,9 to erase" 210 DEF FN p()=22527+(32*r)+c 220 LET p=FN p() 230 LET z=PEEK p 240 POKE p,18 250 LET d=CODE INKEY$-48: IF d<1 OR d>9 THEN GO TO 250 260 IF d=3 THEN GO TO 400 270 IF d=4 THEN GO TO 500 280 IF d=9 THEN GO TO 600 285 POKE p,z 286 BEEP .1,10 290 LET c=c+(d=8)-(d=5): LET r=r+(d=6)-(d=7) 310 IF c=33 THEN LET c=1 311 IF c=0 THEN LET c=32 312 IF r=22 THEN LET r=0 313 IF r=-1 THEN LET r=21 320 GO TO 220 400 POKE 23659,2: POKE p,z 405 GO SUB 1000: GO SUB 1010 410 LET x=USR 30139 500 LET z=48 505 BEEP .2,20 510 POKE p,170: GO TO 245 600 LET z=54 605 BEEP .2,0 610 POKE p,170: GO TO 245 700 POKE 23659,2: STOP 1000 POKE 23684,128: POKE 23685,80: POKE 23686,33: POKE 23687,2: POKE 23659,0: RETURN 1010 PRINT PAPER 4; INK 9;AT 22,0;" enter 1 for menu,2 to alter " 1020 RETURN 9998 SAVE "Life" LINE 1: BEEP .4,15: SAVE "Life M/C"CODE 30000,410 9999 VERIFY "Life": BEEP .4,15: VERIFY "Life M/C"CODE 30000,410: GO TO 1 ```