--- title: "Trap" id: 51805 type: "computer_media" slug: "trap" url: "http://localhost/computer_media/trap/" markdown_url: "http://localhost/computer_media/trap.md" published_at: "2023-08-13T23:14:33+00:00" modified_at: "2026-04-03T13:10:48+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2019/02/20230809-041332.jpg" excerpt: "A machine code game hidden inside a REM statement launches via a USR call, complete with a block-graphic title screen spelling out \"TRAP.\"" 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: "Timex Computer Corporation" slug: "timex-computer-corporation" taxonomy: "post_tag" url: "http://localhost/tag/timex-computer-corporation/" - 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: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_type: "Cassette" download_url: "https://archive.org/download/timex-sinclair-software-archive/Trap (1983)(Timex)(US)(TS1000)(Cassette).zip" mediadate: "1983" producer_company: - id: 11401 title: "Timex Computer Corporation" type: "company" url: "http://localhost/company/timex-computer-corporation/" related_products: - id: 14434 title: "Trap" type: "product" url: "http://localhost/product/trap/" media_type_tags: "Game" --- Trap is a machine code game that loads and executes a routine stored in the REM statement at line 1. The program uses the common ZX81/TS1000 technique of embedding machine code bytes directly inside a REM statement, then jumping into it with LET K=USR 17606, where 17606 is the memory address of the first byte of that REM’s data area. Line 20 saves the program (including the machine code payload in the REM) to tape under the name “TRAP”. Lines 25 and 30 provide a simple stop/restart loop so the USR call can be re-entered. The title screen text visible in the REM data — “T I M E X” and “T R A P” surrounded by block graphics — suggests a branded title display is rendered by the machine code routine. *** ## Program Analysis ### Program Structure The BASIC portion of this program is minimal — just five lines — but the real content is the large machine code payload embedded in the `REM` statement at line 1. The BASIC lines serve purely as a loader and tape-save utility: 1. **Line 1** — `REM` containing the entire machine code payload (and apparent title-screen data). 2. **Line 10** — `LET K=USR 17606`: jumps into the machine code. 3. **Line 20** — `SAVE "TRAP"`: saves the complete program, including the REM payload, to tape. 4. **Line 25** — `STOP`: halts execution after saving. 5. **Line 30** — `GOTO 10`: provides a restart path back to the USR call. ### Machine Code Delivery via REM Storing machine code inside a `REM` statement is a classic technique. The tokenizer ignores everything after the `REM` keyword, so arbitrary byte values can be placed there without interference from the BASIC interpreter. The address `17606` (decimal) corresponds to the first data byte of line 1’s `REM` body in the system’s memory map, assuming the program starts at the standard BASIC area base address. When `USR 17606` is evaluated, the Z80 CPU executes a `CALL` to that address, transferring control directly to the machine code. ### Title Screen Evidence in REM Data Portions of the REM data, when interpreted as character codes, produce recognizable display strings. The sequences render as: - A row of `▀` block graphics forming a top border. - The text `T I M E X` flanked by `▝` and `▌` graphics. - A row of `█` block graphics forming a separator. - The text `T R A P` flanked by `▙` and `▌` graphics. - A closing row of block graphics. These are almost certainly printed by the machine code routine as a title/splash screen when the game starts. ### Save and Restart Logic The sequence at lines 20–30 is a deliberate distribution pattern. Running the program from line 10 launches the game. If the user instead runs from line 20, the `SAVE` command writes the entire program — including the machine code REM — to tape, producing a distributable copy. `STOP` at line 25 prevents accidental fall-through to `GOTO 10` after a save. `GOTO 10` at line 30 is reachable by `CONTINUE` or direct `GOTO` to re-launch the game without reloading. ### Notable Techniques - **USR as game launcher:** Using `LET K=USR addr` rather than just `RAND USR addr` is functionally equivalent for launching machine code but stores the return value in `K`, which is harmless. - **Self-contained distribution:** Because the machine code lives in the REM and the SAVE is part of the same program, a single tape file contains both loader and game payload. - **Address calculation:** The address `17606` is hard-coded, meaning the program must always reside at a fixed location in RAM. Moving the program (e.g., by adding lines before line 1) would shift the REM body and break the USR address — a known fragility of this technique. ### Potential Anomalies The hard-coded `USR 17606` address is the most notable fragility. If the program is loaded after other programs have altered the system variable state, or if additional BASIC lines are inserted before line 1, the REM body will no longer start at address 17606 and the machine code will not execute correctly. No error-checking or dynamic address calculation (such as `USR (PEEK 16396 + 256*PEEK 16397 + offset)`) is employed. ### Key Variables | Variable | Role | | --- | --- | | `K` | Receives the return value of the `USR` call (result discarded in practice) | ## Source Code ``` 1 REM ▗ 2[R]#[R]#[R]#[R]#[R]#V#[A]#########▙### RETURN PLOT LOAD LET PAUSE SLOWB PRINT RETURN\~~N\,, POKE PAUSE ) PRINT 67777777 ▘0ACS SK\~~ACS TK▀Y▗TAN Y▖TAN ACS TK▀Y▝TAN Y▘TAN #█- #▞▌ACS 7ACS >( IF E[.]RND;- #;TAN ▖#E[.]RND\,,TAN GOSUB #[▒]RND# RETURNTCOS £ GOSUB #[▒]RNDE[;]RNDACS TSP76[;]RNDF/. GOSUB #[▒]RND# RETURN▘COS $ GOSUB #[▒]RNDE[;]RNDACS TK*F6[;]RND FAST)5 ACS S▘▐▖S▖Y▐/5Y▗/F)5 ACS S▘█▖K▖Y▄/▛#[I]#;( IF TAN LN #INKEY$ Y▀[I]#TAN LN #INKEY$ Y▌ LPRINT 7▘▌▖LN #INKEY$ TAN LN #INKEY$ Y▝[I]#Y▖ LPRINT LN #INKEY$ Y▘[I]#TAN #[I]#)▞ ;#[I]#TAN GOSUB #▙RND# RETURN▘COS $ GOSUB #▙RNDE[<]RNDACS TK(F6[<]RNDACS SS▖Y▝/USR Y▗/SQR ACS SS▖Y▘/COS Y▖/CODE GOSUB #▙RND# RETURNICOS £ GOSUB #▙RNDE[<]RNDACS TS THEN76[<]RNDF/ACS 6B666677777777778888888888999 GOSUB #[▒]RND# RETURN▘COS ▌ GOSUB #[▒]RNDE[;]RNDACS SK+)5 [B] GOSUB #6[;]RNDACS TS▖Y▖/LY▗/HACS TS▖Y▘/9Y▝/5 GOSUB #[▒]RND# RETURN3COS ▖ GOSUB #[▒]RNDE[;]RNDACS SS STEP )5 ;6[;]RND[B] GOSUB #/COS ##[I]#)▜ ;#[I]#TAN GOSUB #▙RND# RETURN▘COS ▌ GOSUB #▙RNDE[<]RNDACS SKP)5 [B] GOSUB #6[<]RND;/. GOSUB #▙RND# RETURNACOS ▖ GOSUB #▙RNDE[<]RNDACS SS+)5 ;6[<]RND▞▞ACS TS▖Y▀/XY▝/2▞▞ACS TK▖Y▐/\~~Y█##[I]#7( IF TAN :█LN [W]PIY▌[I]#TAN FAST:▀LN [W]PIY▘[I]# LPRINT [B] GOSUB #Y▗▘▄▞LN [W]PIY▖[I]#TAN FASTLN [U]PI LPRINT [B] GOSUB #Y▄▞▞/VAL [J]▘ ▖[J]▘ \~~[S]CODE ##LN [V]▝# RETURN COPYCOS RETURN RUN C# RETURN LOAD C# RETURN CLS4\,,5▙RND)[<]RND#EXP # RETURN#4\,,5▜RND)[+]RND#EXP # RETURN CLEAR4\,,5▚RND)[*]RND#,# RETURN[Z]4\,,5[▒]RND)[;]RND#,#)COS RND RETURN TO 4▛, RETURN0COS X/▒ RETURN RETURN"", RETURNZCOS W#E[.]RND,[I][C]##>CHR$ 0MH#TAN ( CLEARTAN # RETURN TO 4;#[*]INKEY$ # RETURN TO 4▀#▐PI RETURN LOAD 4▀##PI RETURN RUN 4(#TAN INKEY$ RETURN CLEAR""U"# RETURN[)]COS W#/£ RETURN CLEAR""U"# RETURN[~~]C)X#USIN RND RETURN COS [J]MSIN RND#M"#TAN USIN RND RETURN COS LPRINT 5▙RND▞▒[J][Y]4▖7( IF TAN #LEN # 6[;]INKEY$ 6[6]INKEY$ 6ACS INKEY$ 6USR INKEY$ 6#PI6#PI6▗PI6[(]PI FOR 6[9]INKEY$ 6[H]INKEY$ 6NOT INKEY$ 6 TO INKEY$ 6#PI6█PI6[<]PI6[2]PIYTAN M[,,]#Y[*]M##Y#M▙#Y▐M##Y▘MSIN RNDTAN 65INKEY$ 6EINKEY$ 6▀INKEY$ 6£INKEY$ 6▀PI6£PI6SPI6INKEY$ PI FOR 6HINKEY$ 6PINKEY$ 6?INKEY$ 6*INKEY$ 6?PI60PI6#PI6#PIY▘M[,,]#Y3M##Y▘M▙#YQM##Y▘MSIN RNDTAN ▛▀▀▀▀▀▀▀▀▀▘T I M E X▝▀▀▀▀▀▀▀▀▀▀▌█████████████████████████████▌▌▙▄▄▄▄▄▄▄▄▄▄▖T R A P▗▄▄▄▄▄▄▄▄▄▄▄▌ LN 7?LN E\~~)##▘4 LN #"▞=)▜#VAL ▘4 LN #"AT ( NEXT )[8]#▘4 LN #"E£RND)7 ;6[.]RNDLN F?/▛WM##▘/=▘/= GOSUB #▙RND GOSUB #▜RND▘£\~~LN LLIST RND6[<]RND6[+]RND▘2( GOSUB #[▒]RND GOSUB #▚RND▘?▒LN LLIST RND6[*]RND6[;]RND[J]5[~~]RND▞▒#7( UNPLOT 5[H]RND▞▒[J]#7#W7( RAND Y[~~]M"#YAMCOS RNDE[.]RNDYA#Y\~~MH#### AT # GOSUB ##/▌AT # GOSUB ##5LEN RND#W# RETURN 4; LPRINT LN ▘#[J]MLEN RND OR 5[1]RND▘[~~]RND OR 5[H]RND#G# FAST▖£VAL #[B] PAUSE [.]#J RETURNCABS ####[B] PAUSE [B]#J RETURNVABS ###U▄RND[S]4$U▙RNDX[T]K▞LEN $[T]ABS ##U▐RND[S]4$U▜RNDX[T]K▞LEN $[T]ABS ##U▚RND[T]4$U▗RNDX[S]K▞LEN \,,[S]ABS ##U[▒]RND[T]4$U[,,]RNDX[S]K▞LEN \,,[S]ABS ##LN TAN RND PRINT LN LLIST RND FAST OR #7# FOR \~~[I]# LPRINT Y[~~][T]K▀ LET [J] PRINT LET ▝[I]# FOR #F#£GG OR AT LPRINT #H#GGY[W][X] AND ##▘= [J][S]C▒#X RETURN 4 CLS( SAVE #[:]##OO5D#OO5/\~~OO59#OO▘█ LLIST [J][S]ASN [=]##X RETURN C CLS( SAVE #[=]# 000000001111111111222222222233333333334444444444555555555566666666667777777777888888888899999999990000000000 10 LET K=USR 17606 20 SAVE "TRA[P]" 25 STOP 30 GOTO 10 ```