Trap

Products: Trap
Date: 1983
Type: Cassette
Platform(s): TS 1000
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 1REM containing the entire machine code payload (and apparent title-screen data).
  2. Line 10LET K=USR 17606: jumps into the machine code.
  3. Line 20SAVE "TRAP": saves the complete program, including the REM payload, to tape.
  4. Line 25STOP: halts execution after saving.
  5. Line 30GOTO 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

VariableRole
KReceives the return value of the USR call (result discarded in practice)

Content

Appears On

Related Products

A high speed arcade-type game in which you can test your reflexes and see how many bouncing balls you can...

Related Articles

Related Content

Image Gallery

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

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

People

No people associated with this content.

Scroll to Top