Invaders

Products: Invaders
Date: 1982
Type: Cassette
Platform(s): TS 1000
Tags: Arcade, Game

Invaders is a Space Invaders-style arcade game that uses direct memory PEEK and POKE operations to manipulate the display file for smooth character-cell animation. The player sprite and alien formations are positioned using absolute memory addresses calculated from the system variable at address 16398/16399 (the display file pointer, stored in E1), allowing the gun to move left and right along the bottom row while waves of aliens scroll downward. Five alien types are cycled through using a pattern-index variable D, each rendered with a different block-graphic character combination, and each worth a different point value (20–50 points). The game includes a high-score tracker, a multi-wave progression system, a bonus jet escape sequence, and a “DANGER” warning when aliens reach a critical row.


Program Analysis

Program Structure

The program is organized into several functional regions, loosely separated by line number ranges:

  • Lines 1–10: Initialization, high-score reset, title block, jump to setup.
  • Lines 80–99: Per-wave setup — reset score display, draw play field, branch to alien shape selector via GOTO 100*D.
  • Lines 100–510: Alien shape definitions (five variants) and animation frame cycling.
  • Lines 600–630: Subroutine to fill the play area rows with solid inverse blocks.
  • Lines 1500–1840: Keyboard input handler and player gun movement via POKE.
  • Lines 1900–2900: Main game loop — alien scroll, collision, bonus jet sequence, scoring.
  • Lines 7000–7100: Game-over handler with flashing death animation and score display.
  • Lines 7397–7450: Title/attract screen with animated “GET YOURSELF READY” text.
  • Lines 7500–7695: Wave-start subroutine — animates player gun appearing from top of screen.
  • Lines 8020–8600: Fire (laser) subroutine — traces bullet upward using POKEs, tests for hit.
  • Lines 9005–9950: Screen setup subroutine — reads display file base address into E1, draws border and title banner.

Display File Addressing

The core technique throughout is computing absolute display-file addresses to animate characters without using PRINT AT. The subroutine at line 9005 reads the display file start address from system variables 16398–16399 and stores it in E1. All subsequent POKE/PEEK operations use offsets from E1; for example, each row is 33 bytes wide (32 character columns plus one attribute/newline byte in the ZX81 file format), so adding 33 advances one row. The player gun position is tracked in Y1, initialized at E1+705 (row 21, roughly column 12), and incremented or decremented by 1.5 per keypress — an unusual fractional step that still produces integer POKE targets due to how BASIC truncates addresses.

Alien Shape Cycling

Five alien shapes are defined in A$ at lines 100, 200, 300, 400, and 500, each using different block graphic characters to simulate animation frames. The variable D (1–5) selects the current frame, and GOTO 100*D at line 99 is a computed branch — a classic BASIC optimization avoiding a chain of IF statements. After printing, line 510 advances D with wrap-around: LET D=D+1-5*(D=5), cycling D through 1→2→3→4→5→1.

Main Game Loop and Alien Scroll

The alien formation is drawn using PLOT/PRINT pairs. PLOT col,row positions the cursor, then PRINT A$ renders the alien string. Ten columns of aliens are drawn per pass (lines 2001–2091), with the loop variable S counting down from a difficulty-dependent starting row Q (10, 22, 22, 18, or 14 depending on D) toward row 4 in steps of 4. After each alien print, GOSUB 1500 checks for key input, giving the player opportunities to move and fire during the alien descent.

When aliens reach row 6 (S=6), a “DANGER” warning is printed and T1 is incremented. After three such warnings (T1=3, line 2091), the game jumps to the bomb-hit sequence at line 2900.

Laser Fire Mechanism

Firing is handled at line 8020. The subroutine traces a bullet upward from the gun position Y1 by POKEing character codes at successive addresses 66 bytes apart (two rows up per step), creating a moving dot effect. Hit detection at line 8125 checks whether the bullet’s column position falls within the alien string bounds by comparing (Y1-U) against a range derived from PEEK 16438 (the print position register). Line 8150 then checks whether the character at that position in A$ equals CHR$ 52 (the character “4”, used as the alien center pixel “O”) to confirm a hit rather than striking empty space.

Bonus Jet Sequence

When the aliens are defeated (scroll completes without collision), the game triggers a bonus sequence (line 2200 onward). A jet icon (▝X▘) appears randomly at the left or right edge of row 20. The player must guide their gun to intercept it: the code traces a path across the display file from W+33 downward, animating movement with POKEs (characters 189, 190, 128), then checks alignment with the gun. A successful intercept awards 100 points and triggers an explosion animation (lines 2355–2365) using +, *, =, and inverse-block characters in a loop.

Scoring and High Score

Points are accumulated in S1. Each alien hit scores D*10 points (line 8500), so wave 1 aliens are worth 10 pts and wave 5 aliens worth 50 pts — matching the score table displayed on the attract screen (lines 7400–7404). The bonus jet awards a flat 100 pts. The high score is stored in HI (initialized to 500) and HS flags a new high score. When a new high score is achieved, lines 7057–7070 POKE a flashing “NEW HIGH SCORE” message directly into the display file using alternating normal and inverse character codes (toggled by 128*(INT(J/2)=J/2)).

Notable Techniques

  • GOTO 100*D — computed GOTO used as a jump table for five alien sprite variants.
  • LET D=D+1-5*(D=5) — Boolean arithmetic for modular cycling without IF.
  • Fractional gun step (Y1±1.5) — unusual but functionally equivalent to ±1 for POKE addressing due to integer truncation in the memory address context.
  • Display file manipulation via PEEK 16398/16399 — portable within the platform, since the display file can move depending on program size.
  • Row width of 33 bytes — correctly accounts for the ZX81 display file format where each row is 32 character bytes plus a NEWLINE token.
  • Attract screen animation (lines 7406–7414) — builds “GET YOURSELF READY” one character at a time across successive PRINT statements for a typewriter effect.
  • POKE 16442,4 at line 9123 — sets the system variable MARGIN, adjusting the left margin of the display.

Bugs and Anomalies

  • Line 1700 is referenced by line 1510 (GOTO 1700) but the actual movement code starts at line 1710. Line 1700 does not exist, so the branch falls through to 1710 — a well-known technique that works correctly here.
  • The empty loops at lines 7565–7570, 7595–7596, and 7645–7646 (FOR J=1 TO 5: NEXT J with no body) serve as deliberate timing delays.
  • B$ is set at line 98 but its length (13 characters) and the hit-detection comparison at line 8590 check for 14 characters ("██████████████") — a possible off-by-one that may prevent the all-clear condition from triggering reliably.
  • Line 2200 computes B=33*((42-S)/2)+(Y1-U); the factor (42-S)/2 depends on the last value of S from the scroll loop, which may not always be a clean integer, potentially misaligning the jet target address.

Content

Appears On

Related Products

Shoot down the marching aliens with your rapid fire laser cannon before they take over the planet forever. Shields are...

Related Articles

Related Content

Image Gallery

Source Code

   1 REM █[I][N][V][A][D][E][R][S]█
   2 GOTO 5
   3 SAVE "INVADER[S]"
   4 REM █[P][R][O][G][R][A][M]█[L][O][A][D][E][D]█
   5 LET S1=0
   6 LET HS=0
   7 LET HI=500
  10 GOSUB 9000
  20 GOTO 7400
  80 LET D=1
  81 LET S1=0
  82 PRINT AT 1,16;S1;"...."
  90 GOSUB 600
  93 LET T1=0
  98 LET B$="█████████████"
  99 GOTO 100*D
 100 LET A$="██[H]O[H]██[H]O[H]█[H]O[H]"
 101 GOTO 510
 200 LET A$="██▗O▖██▗O▖█▗O▖"
 201 GOTO 510
 300 LET A$="██▚O▞██▚O▞█▚O▞"
 301 GOTO 510
 400 LET A$="██▛O▜██▛O▜█▛O▜"
 401 GOTO 510
 500 LET A$="██▀O▀██▀O▀█▀O▀"
 510 LET D=D+1-5*(D=5)
 512 GOSUB 7500
 514 GOTO 1900
 600 FOR J=8 TO 21
 610 PRINT AT J,0;"████████████████████████████████"
 620 NEXT J
 630 RETURN
 1500 IF INKEY$ ="P" THEN GOTO 1800
 1510 IF INKEY$ ="O" THEN GOTO 1700
 1520 IF INKEY$ ="A" THEN GOTO 8000
 1530 RETURN
 1710 POKE Y1,128
 1720 LET Y1=Y1-1.5
 1730 IF PEEK Y1<>128 THEN LET Y1=E1+694
 1740 POKE Y1,19
 1750 RETURN
 1800 POKE Y1,128
 1810 LET Y1=Y1+1.5
 1820 IF PEEK Y1<>128 THEN LET Y1=E1+723
 1830 POKE Y1,18
 1840 RETURN
 1900 LET Q=10
 1910 IF D=1 THEN LET Q=26
 1920 IF D=2 THEN LET Q=22
 1930 IF D=3 THEN LET Q=18
 1940 IF D=4 THEN LET Q=14
 2000 FOR S=Q TO 4 STEP -4
 2001 PLOT 0,S
 2003 PRINT A$
 2004 GOSUB 1500
 2007 PLOT 4,S
 2009 PRINT A$
 2011 GOSUB 1500
 2014 PLOT 8,S
 2016 PRINT A$
 2018 GOSUB 1500
 2026 PLOT 12,S
 2028 PRINT A$
 2030 GOSUB 1500
 2038 PLOT 16,S
 2040 PRINT A$
 2042 GOSUB 1500
 2048 PLOT 20,S
 2050 PRINT A$
 2051 GOSUB 1500
 2056 PLOT 24,S
 2058 PRINT A$
 2059 GOSUB 1500
 2060 PLOT 28,S
 2067 PRINT A$
 2068 GOSUB 1500
 2076 PLOT 32,S
 2078 PRINT A$
 2080 GOSUB 1500
 2088 PLOT 34,S
 2090 PRINT A$
 2091 IF T1=3 THEN GOTO 2900
 2097 IF S=6 THEN PRINT AT 14,10;"[D][A][N][G][E][R]"
 2098 IF S=6 THEN LET T1=T1+1
 2099 IF S=6 THEN GOTO 2001
 2100 NEXT S
 2200 LET B=33*((42-S)/2)+(Y1-U)
 2201 LET W=E1+B
 2202 PRINT AT 14,10;"[1][0][0][P][T][S]"
 2203 PRINT AT 10,10;"[R][U][N]█[T][O]█[T][H][E]█[J][E][T][.][.][.]"
 2206 LET O=INT (RND*2)
 2207 IF O=1 THEN GOTO 2210
 2208 PRINT AT 20,1;"▝X▘"
 2209 GOTO 2225
 2210 PRINT AT 20,28;"▝X▘"
 2225 POKE W+33,148
 2226 GOSUB 1500
 2227 POKE W+66,148
 2228 GOSUB 1500
 2229 IF PEEK (W+99)<>128 THEN GOTO 7000
 2230 IF Y1>(W+99) THEN LET I=1
 2235 IF Y1<(W+99) THEN LET I=-1
 2236 PRINT AT 14,10;"██████"
 2238 FOR J=I TO I*30 STEP I
 2239 IF PEEK (W+99+J)<>128 THEN GOTO 7000
 2240 POKE W+99+J,189
 2245 POKE W+99+J,190
 2250 POKE W+99+J,128
 2255 GOSUB 1500
 2256 IF PEEK (Y1-33)=61 THEN GOTO 2300
 2260 NEXT J
 2300 LET R=2
 2301 IF O=1 THEN LET R=29
 2305 POKE W+99+J,190
 2310 POKE W+R,128
 2320 FOR J=20 TO 9 STEP -1
 2330 PRINT AT J,R-1;"▝X▘"
 2335 PRINT AT J,R-1;"███"
 2340 NEXT J
 2350 PRINT AT J,R-1;"███"
 2355 FOR N=1 TO 4
 2360 PRINT AT J,R;" "
 2361 PRINT AT J,R;"[+]"
 2362 PRINT AT J,R;"[*]"
 2363 PRINT AT J,R;"[=]"
 2364 PRINT AT J,R;"█"
 2365 NEXT N
 2370 LET S1=S1+100
 2380 PRINT AT 1,16;S1;"."
 2390 GOTO 90
 2900 POKE Y1-100,173
 2910 POKE Y1-99,52
 2920 POKE Y1-98,173
 2930 GOTO 2200
 7000 PRINT AT 10,10;"████[D][A][M][N][E][D]█[.][.][.]█"
 7001 FOR J=1 TO 30
 7002 POKE Y1,0
 7003 POKE Y1,149
 7004 POKE E1,103
 7005 POKE Y1,128
 7007 POKE E1,128
 7010 NEXT J
 7020 PRINT AT 1,16;S1
 7040 IF S1>HI THEN LET HS=1
 7050 IF HS THEN LET HI=S1
 7054 PRINT AT 1,0;"████[*][*][*]█[H][I][G][H]█[S][C][O][R][E]█.....█[*][*][*]████"
 7055 PRINT AT 1,19;HI
 7056 IF HS=0 THEN GOTO 7080
 7057 FOR J=1 TO 10
 7058 LET I=0+128*(INT (J/2)=J/2)
 7060 POKE E1+41,45+I
 7061 POKE E1+42,46+I
 7062 POKE E1+43,44+I
 7063 POKE E1+44,45+I
 7064 POKE E1+45,0+I
 7065 POKE E1+46,56+I
 7066 POKE E1+47,40+I
 7067 POKE E1+48,52+I
 7068 POKE E1+49,55+I
 7069 POKE E1+50,42+I
 7070 NEXT J
 7080 FOR J=1 TO 21
 7090 PRINT AT 20,J;"█[G][A][M][E]█[O][V][E][R]"
 7100 NEXT J
 7397 LET HS=0
 7398 PRINT AT 0,0;
 7399 GOSUB 9000
 7400 PRINT AT 10,10;"[H]O[H][.][.][.][2][0][P][T][S]"
 7401 PRINT AT 12,10;"▗O▖[.][.][.][3][0][P][T][S]"
 7402 PRINT AT 14,10;"▚O▞[.][.][.][4][0][P][T][S]"
 7403 PRINT AT 16,10;"▛O▜[.][.][.][5][0][P][T][S]"
 7404 PRINT AT 18,10;"▀O▀[.][.][.][1][0][P][T][S]"
 7405 PRINT AT 1,16;S1
 7406 PRINT AT 20,15;"[G][Y]"
 7407 PRINT AT 20,14;"[G][E][D][Y]"
 7408 PRINT AT 20,13;"[G][E][T][A][D][Y]"
 7409 PRINT AT 20,12;"[G][E][T]█[E][A][D][Y]"
 7410 PRINT AT 20,11;"[G][E][T]█[Y][R][E][A][D][Y]"
 7411 PRINT AT 20,10;"[G][E][T]█[Y][O]█[R][E][A][D][Y]"
 7412 PRINT AT 20,9;"[G][E][T]█[Y][O][U][F]█[R][E][A][D][Y]"
 7413 PRINT AT 20,8;"[G][E][T]█[Y][O][U][R][L][F]█[R][E][A][D][Y]"
 7414 PRINT AT 20,7;"[G][E][T]█[Y][O][U][R][S][E][L][F]█[R][E][A][D][Y]"
 7415 GOSUB 600
 7420 PRINT AT 12,11;"[P][.][.][.][L][E][F][T]"
 7421 PRINT AT 15,11;"[O][.][.][.][R][I][G][H][T]"
 7422 PRINT AT 18,11;"[A][.][.][.][F][I][R][E]"
 7423 FOR J=20 TO 1 STEP -1
 7424 PRINT AT 20,J;"[G][A][M][E]█[B][E][G][I][N][S]█"
 7425 NEXT J
 7450 GOTO 80
 7500 PRINT AT 1,16;S1;"."
 7501 LET Y1=E1+705
 7505 LET X=E1+248
 7510 POKE X,0
 7511 POKE X,149
 7512 POKE X,189
 7513 POKE X,155
 7514 POKE X,128
 7520 IF X-E1=578 THEN GOTO 7550
 7530 LET X=X+33
 7540 GOTO 7510
 7550 PRINT AT 17,16;"▝X▘"
 7565 FOR J=1 TO 5
 7570 NEXT J
 7580 POKE X+33,148
 7585 POKE X+66,148
 7586 POKE X+99,148
 7587 POKE X+132,148
 7595 FOR J=1 TO 5
 7596 NEXT J
 7600 POKE X+33,189
 7605 POKE X+33,148
 7610 POKE X+66,189
 7615 POKE X+66,148
 7620 POKE X+99,189
 7625 POKE X+99,148
 7630 POKE X+132,189
 7635 POKE X+132,148
 7640 POKE X+131,189
 7641 POKE X+131,128
 7642 POKE X+127,189
 7643 POKE X+127,190
 7644 POKE X+127,61
 7645 FOR J=1 TO 5
 7646 NEXT J
 7650 POKE X+132,128
 7655 POKE X+99,128
 7660 POKE X+66,128
 7665 POKE X+33,128
 7670 POKE X-1,128
 7675 POKE X+1,128
 7680 FOR J=1 TO 6
 7685 POKE X,189
 7686 POKE X,148
 7687 POKE X,149
 7688 POKE X,128
 7689 NEXT J
 7695 RETURN
 8020 LET Y=Y1
 8050 POKE Y-66,173
 8055 POKE Y-132,173
 8060 POKE Y-66,128
 8065 POKE Y-132,128
 8070 POKE Y-198,173
 8075 POKE Y-264,173
 8080 POKE Y-198,128
 8085 POKE Y-264,128
 8090 POKE Y-330,173
 8095 POKE Y-396,173
 8100 POKE Y-330,128
 8105 POKE Y-396,128
 8110 POKE Y-462,173
 8115 POKE Y-462,128
 8120 LET T=(PEEK 16438)/2
 8125 IF (Y1-U)<(T+2) OR (Y1-U)>(T+13) THEN RETURN
 8130 LET A=(Y1-U)-T
 8150 IF A$(A)<>CHR$ 52 THEN RETURN
 8160 IF S<7 THEN GOTO 2200
 8500 LET S1=S1+(D*10)
 8515 POKE E1,103
 8580 LET A$(A-1 TO A+1)="███"
 8585 POKE E1,128
 8590 IF A$="██████████████" THEN GOTO 90
 8600 RETURN
 9005 LET E1=PEEK 16398+256*PEEK 16399
 9006 LET U=E1+693
 9100 PRINT "████████████████████████████████"
 9101 PRINT "██████[*][*][*]█[S][C][O][R][E]█.....█[*][*][*]███████"
 9102 PRINT "████████████████████████████████"
 9103 PRINT "████████████████████████████████"
 9104 PRINT "█████▌▐ ▐▐ █▌▐ ▖▐ ▝▌▗▟▗ ▌ ▟█████"
 9105 PRINT "█████▌▐ ▞▐▌▐ █ ▘▐▐▌▌ █ ▄▙▖▐█████"
 9106 PRINT "█████▌▐ ▌▐█ ▐█ ▖▐ ▗▌▝▜▐ ▌ ▐█████"
 9107 FOR J=7 TO 21
 9108 PRINT AT J,0;"████████████████████████████████"
 9109 NEXT J
 9123 POKE 16442,4
 9124 PRINT "▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒"
 9950 RETURN

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

People

No people associated with this content.

Scroll to Top