Space Docking

This file is part of and Timex Sinclair Public Domain Library Tape 1006. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Game

This is a space docking arcade game in which the player manoeuvres a ship (displayed as inverse “< >” characters) upward toward a randomly positioned fuel satellite, earning points for each successful docking. The program opens with a RAND USR 16514 call in FAST mode, executing a machine-code routine before the game logic runs. Scoring uses a running total stored in G, initialised to a random offset of up to 349 points, with 210 added per successful dock. A blinking “SAVED” animation subroutine at line 702 is implemented with a software delay loop rather than PAUSE, and star-field decoration is scattered via four random PRINT AT statements in the GOSUB 650 subroutine. An in-game instruction screen is accessible via GOTO 9000, which is referenced in the status bar but requires the user to navigate there manually since the line is never called programmatically during normal play.


Program Analysis

Program Structure

The program is divided into several functional blocks:

  1. Initialisation (lines 1–7): Machine-code call, variable setup, random score seed, and initial star-field draw.
  2. Game setup (lines 10–90): Constants established, cockpit border printed, satellite positioned randomly.
  3. Main game loop (lines 100–230): Draws satellite and ship, reads keyboard, enforces bounds, tests win/loss conditions.
  4. Dock success (lines 300–361): Moves satellite up five rows, updates score, triggers “SAVED” animation, restarts loop.
  5. Fuel exhausted / game over (lines 500–645): Displays result screen with ships saved and total points, then restarts.
  6. Star-field subroutine (lines 650–701): Prints four random inverse-pixel stars and resets the POKE 16418 scroll counter.
  7. “SAVED” flash subroutine (lines 702–730): Blinks the word three times using a software delay inner loop.
  8. Instructions (lines 9000–9010): Printed but never called from within the game; accessed only via the status bar hint.
  9. Save/auto-run block (lines 9100–9120): Clears memory and SAVEs the program with an auto-run flag in the filename.

Machine Code Usage

Line 3 executes RAND USR 16514 in FAST mode (line 2). Address 16514 lies inside the ZX81/TS1000 system variables / ROM area and is used here as a common trick to invoke a ROM routine or patch memory before the BASIC game begins. The exact effect depends on whatever routine resides there, but the FAST/SLOW sandwich (lines 2 and 4) is the standard idiom for a quick machine-code call with minimal screen flicker.

Key Variables

VariableRole
AConstant 1 (PI/PI), used as the increment unit throughout
BConstant 0 (PI-PI), used as the zero-boundary sentinel
SShip row (starts at 18, decrements toward 0)
TShip column (starts at 15, keyboard-controlled)
XSatellite column (random each round)
YSatellite row (starts at 15, moves up 5 on each dock)
VFuel/timer countdown (starts at 600, decremented by 1 each iteration)
RShips saved counter (incremented at line 350)
GRunning score (random seed 0–349 plus 210 per dock)
PReused: delay loop counter in game-over screen AND flash counter in subroutine 702

BASIC Idioms

  • PI arithmetic for constants: LET A=PI/PI (=1) and LET B=PI-PI (=0) avoids storing integer literals and is a classic ZX81 memory-saving trick. These are then used everywhere instead of literal 0 and 1.
  • POKE 16418,0 (line 654): Resets the system variable DF_SZ or a related scroll register to prevent the lower display area from auto-scrolling during PRINT AT operations — a standard ZX81 display-control idiom.
  • Inverse-video characters: The ship is rendered as % %<%O%>% (inverse space, inverse <, inverse O, inverse >, inverse space), and the satellite as % %<\..%>% (with a block-graphic body). The score bar and borders use solid inverse-space blocks.
  • Erasing sprites: The previous ship position is overwritten at line 120 with a blank inverse-space string, using S+A (one row below) — a simple erase-by-overwrite scheme with no attribute complications.

Game Loop Logic

Each iteration of the main loop (lines 110–230) draws the ship, decrements the fuel counter V, reads one key from INKEY$ for Z (left), M (right), and A (up), clamps T between 0 and 25, then checks three conditions in order: fuel empty → game over (line 190); ship reached row 0 without docking → next round with score (line 200); ship column matches satellite column at the correct row → dock success (line 210). If the ship has risen to the satellite row but missed horizontally, it resets to the starting position (line 220).

“SAVED” Flash Animation (lines 702–730)

The subroutine at line 702 implements a three-cycle blink by alternately printing %S%A%V%E%D (inverse) and blanks. Each display state is held for a short software delay: lines 724–730 form a tight loop counting T from 0 to 3. Because P is the outer counter and T the inner, and both variables are shared with the main game, callers must not rely on their values afterward — which the code handles correctly by reinitialising T at line 65 and V at line 40 on each game-loop restart.

Bugs and Anomalies

  • Variable P reuse: P is used both as the game-over delay loop counter (lines 550–575) and as the blink counter inside subroutine 702. Since subroutine 702 is only called from the dock-success path (line 357) and never from the game-over path, there is no actual conflict, but the shared name is potentially confusing.
  • Instructions line never called: Line 655 prints a status bar message referencing GOTO 9000 for instructions, but no code path in the game ever jumps there. The player must manually type GOTO 9000 or the game reaches STOP only if they somehow navigate there outside normal play.
  • Ship erase row offset: The erase print at line 120 uses AT S+A,T+A (one row below and one column right of the ship), which does not exactly overwrite the ship’s position at AT S,T. This means a ghost trail of the previous position at S,T is not always cleanly erased, potentially leaving artefacts — though the frequent full-screen redraws at lines 80–81 and 351–352 mitigate this.
  • Random score seed: G is initialised to a random value 0–349 at line 6, before being overwritten at line 5 to 0 — but line 6 immediately follows line 5 and re-randomises it. The initial LET G=0 at line 5 is therefore redundant.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10252 – 10293.

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   1 REM Y% .'. :%KNOT $TAB @@RND: TAB '.RNDTAN 
   2 FAST 
   3 RAND USR 16514
   4 SLOW 
   5 LET G=0
   6 LET G=INT (RND*350)
   7 GOSUB 650
  10 LET A=PI/PI
  20 LET B=PI-PI
  21 PRINT AT 20,15;"':.:% :.:'"
  22 PRINT AT 21,14;".:% % % % % :."
  30 LET R=B
  40 LET V=600
  50 LET S=18
  60 LET T=15
  65 LET Y=15
  80 PRINT AT 0,0;"% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % "
  81 PRINT AT 1,0;"% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % "
  82 GOSUB 650
  90 LET X=INT (RND*25)
 100 PRINT AT Y,X;"% %<%O%>% "
 110 PRINT AT S,T;"% %<..%>% "
 112 PRINT AT 19,15;"% % ''% % "
 120 PRINT AT S+A,T+A;"% % % % % "
 130 LET V=V-A
 140 IF INKEY$="Z" THEN LET T=T-A
 150 IF INKEY$="M" THEN LET T=T+A
 160 IF INKEY$="A" THEN LET S=S-A
 170 IF T<B THEN LET T=B
 180 IF T>25 THEN LET T=25
 190 IF V=B THEN GOTO 500
 200 IF S=B THEN GOTO 350
 210 IF T=X AND S=Y-A THEN GOTO 300
 220 IF S=Y-A AND T<>X THEN GOTO 50
 230 GOTO 110
 300 LET Y=Y-5
 310 GOTO 80
 350 LET R=R+A
 351 PRINT AT 0,0;"% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % "
 352 PRINT AT 1,0;"% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % "
 355 LET G=G+110+100
 356 PRINT AT 20,1;"%P%O%I%N%T%S% ";G
 357 GOSUB 702
 361 GOTO 50
 500 CLS 
 510 PRINT AT 10,11;"%G%A%M%E% %O%V%E%R"
 520 PRINT AT 12,5;"**YOU SAVED ";R;" SHIPS**"
 530 PRINT AT 14,8;"TOTAL POINTS ";G
 550 FOR P=1 TO 100
 575 NEXT P
 642 CLS 
 645 GOTO 1
 650 PRINT AT RND*15,RND*31;"%."
 651 PRINT AT RND*15,RND*31;"%."
 652 PRINT AT RND*15,RND*31;"%."
 653 PRINT AT RND*15,RND*31;"%."
 654 POKE 16418,0
 655 PRINT AT 22,0;"% SPACE DOCKING---INST.GOTO 9000% "
 656 PRINT AT 23,0;"% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % "
 701 RETURN 
 702 PRINT AT 3,13;"%S%A%V%E%D"
 704 LET P=0
 706 GOSUB 724
 708 PRINT AT 3,13;"%S%A%V%E%D"
 710 GOSUB 724
 712 PRINT AT 3,13;"% % % % % "
 714 GOSUB 724
 716 LET P=P+1
 718 IF P=3 THEN RETURN 
 720 GOTO 708
 724 LET T=0
 726 LET T=T+1
 728 IF T=3 THEN RETURN 
 730 GOTO 726
 9000 PRINT AT 2,0;"PRESS(A)TO MAKE YOUR SHIP GO UP"
 9002 PRINT AT 4,0;"PRESS(Z)TO GO LEFT"
 9004 PRINT AT 6,0;"PRESS(M)TO GO RIGHT" 
 9006 PRINT AT 8,0;"YOU MUST BE DIRECTLY UNDER THE"
 9008 PRINT AT 9,0;"FUEL SATELLITE TO CONTINUE."
 9010 STOP 
 9100 CLEAR 
 9110 SAVE "1025%8"
 9120 RUN 

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

People

No people associated with this content.

Scroll to Top