Phasor

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

PHASOR is a space shooter game in which the player fires phasors at aliens moving across a 26-column play field, managing both a shield count and a phasor count across three difficulty levels. The player fires by pressing the key whose column code matches the alien’s position, detected via CODE INKEY$-38 compared to R6+1. Difficulty controls the inner loop count INP, calculated as (1/INT X)*25, tightening reaction time at higher levels; mid-game rank promotions (Falcon, Hawk, Eagle) are triggered at score thresholds 1050, 2100, and 2850. The fire-explosion sequence in the GOSUB 1000 routine uses layered PRINT AT statements with block graphics to animate an expanding blast, and FAST/SLOW toggling inside the loop creates a flash effect. Reaching zero shields triggers the game-over starfield routine at line 8000, which randomly scatters dot and block-graphic characters across a cleared screen.


Program Analysis

Program Structure

The program is divided into clearly separated functional blocks:

  1. Lines 1–18: Initialisation, difficulty selection, and rank-string assignment.
  2. Lines 20–180: Main screen setup — starfield rendering, score/status panel drawing.
  3. Lines 200–290: Main game loop — alien placement, firing detection, alien movement.
  4. Lines 300–380: Hit subroutine — score update and hit animation.
  5. Lines 500–600: Miss/alien-fire subroutine — shield deduction and hit reporting.
  6. Lines 1000–1240: Explosion graphics subroutine with FAST/SLOW flash effect.
  7. Lines 2010–2030: Game-over restart prompt.
  8. Lines 7000–7030: Rank promotion congratulations display.
  9. Lines 8000–8100: Game-over starfield clear and redraw routine.

Difficulty and Timing Mechanics

Difficulty level X (1, 2, or 3) drives the inner loop count INP via LET INP=(1/INT X)*25, yielding 25, 12, or 8 iterations respectively. Each iteration gives the player one polling opportunity, so higher difficulty dramatically shrinks reaction time. At line 205, once I reaches 150, INP is decremented by 1 each cycle (unless already at 1), providing an escalating challenge even within a chosen difficulty level.

Firing Detection Idiom

The core shooting mechanic at line 250 uses:

IF CODE INKEY$-38=R6+1 AND P<>0 THEN GOSUB 300

On the ZX81/TS1000 keyboard layout, the digit keys ‘0’–’9′ have character codes 28–37, and the letter keys begin at 38 (‘A’=38, ‘B’=39, …). Subtracting 38 maps key ‘A’ to 0, ‘B’ to 1, and so on across the 26-column display. Since R6 is an alien column 0–23 and the comparison is against R6+1, there is a consistent off-by-one offset built into the mapping, meaning the player must press the key one position to the right of the alien’s column.

Rank Promotion System

Three rank titles are assigned in lines 16–18 using cascading IF statements. The ranks escalate with both score and difficulty:

RankConditions
FalconX=1 (any score)
HawkX=2, or X=1 and S≥2100
EagleX=3, or X=2 and S≥2100, or X=1 and S≥2850

The congratulations subroutine at line 7000 is triggered at line 20 when the score equals exactly 1050, 2100, or 2850 — relying on score increments of exactly 10 per hit, so these thresholds are always reachable.

Screen Layout and Block Graphics

The play field occupies columns 0–25 across rows 0–20, while columns 26–31 form a status panel. The starfield is built in two passes: lines 45–90 scatter 80 inverse-space characters ("%.") as background stars, then lines 95–130 place 10 block-graphic "\:'" (▛) characters as larger star objects. The alien is displayed as "%(%0%)" (inverse parentheses around an inverse zero). The explosion subroutine (lines 1000–1240) prints expanding rings of block graphics across rows 10–20 at fixed columns, producing a symmetrical blast pattern centred at column 11.

FAST/SLOW Flash Effect

Inside the explosion loop (lines 1015–1240), FAST and SLOW are toggled on consecutive lines within a FOR L=1 TO 5 loop. This causes the display to flicker between the two rendering modes, producing a visible flash effect that accompanies the explosion animation without requiring any additional graphics work.

Alien Random Fire

A random value R8 = INT(RND*30)+1 is rolled each inner-loop iteration. If INKEY$="" (no key pressed) and R8=1, the alien fires via GOSUB 525. The 1-in-30 probability makes alien fire relatively rare but unpredictable. The alien-hit subroutine further rolls R7 = INT(RND*3)+1; only when R7=1 does the alien shot actually hit the player and reduce SH (shields).

Game-Over Starfield Routine

When shields reach zero, subroutine 8000 clears the screen row by row in FAST mode, then in SLOW mode randomly populates it with either a period (B$=".") or a block-graphic dot (B$="\. ", i.e. ▖) at 80 random positions, generating a sparse star-debris effect as the final display.

Notable Bugs and Anomalies

  • Line 241: IF I=150 THEN GOTO 11 — line 11 does not exist. This causes the program to jump to the next higher line, which is line 12 (LET P=20). This appears to be an intentional or accidental partial game reset when the escalation counter reaches 150, resetting phasors but not score or shields.
  • Line 580: IF SH<0 THEN GOTO 1000 — the condition is less than zero, but SH is decremented at line 570 after a shield check. If SH was 0 before decrement, it becomes -1, which correctly triggers the game-over path. However, the display at line 590 (PRINT AT 12,30;SH) is skipped in this case, leaving the shield count display unchanged.
  • Line 170: The shield and phasor count labels are printed character-by-character with individual AT clauses, and the initial counts (5 and 20) are hardcoded as string literals rather than read from SH and P. This means if the initial values were changed, the display would not reflect them.
  • Line 8: LET INP=(1/INT X)*25 — if X=0 were allowed, this would cause a division-by-zero error. The guard at line 7 uses X<0 rather than X<1, so entering 0 would pass the check and crash at line 8.

Content

Appears On

Assembled by Tim Ward from many sources. Contains programs 10176 – 10210.

Related Products

Related Articles

Remarkable graphics effects are the striking feature of Phasor for the 16K TS1000, ZX81. You are an infamous space pirate...

Related Content

Image Gallery

Phasor

Source Code

   1 SAVE "1018%4"
   2 CLS 
   3 PRINT "PHASOR";AT 1,0;"\''\''\''\''\''\''",,
   4 PRINT "WHAT LEVEL OF DIFFICULTY?",,,
   5 PRINT "(1,2,OR 3)"
   6 INPUT X
   7 IF X>3 OR X<0 THEN GOTO 6
   8 LET INP=(1/INT X)*25
   9 CLS 
  10 LET S=0
  11 LET SH=5
  12 LET P=20
  13 LET I=0
  15 CLS 
  16 IF X=1 THEN LET A$=" FALCON"
  17 IF X=2 OR X=1 AND S=2100 THEN LET A$=" HAWK"
  18 IF X=3 OR X=2 AND S=2100 OR X=1 AND S=2850 THEN LET A$=" EAGLE"
  20 IF S=1050 OR S=2100 OR S=2850 THEN GOSUB 7000
  25 FOR N=1 TO 21
  30 PRINT "% % % % % % % % % % % % % % % % % % % % % % % % % % "
  40 NEXT N
  45 FOR M=1 TO 80
  50 LET R1=INT (RND*20)
  60 LET R2=INT (RND*26)
  80 PRINT AT R1,R2;"%."
  90 NEXT M
  95 FOR K=1 TO 10
 100 LET R3=INT (RND*20)
 110 LET R4=INT (RND*26)
 120 PRINT AT R3,R4;"\:'"
 130 NEXT K
 135 LET Q=38
 140 LET Z=0
 145 PRINT AT 21,Z;CHR$ Q
 150 LET Q=Q+1
 155 LET Z=Z+1
 156 IF Z=26 THEN GOTO 165
 160 GOTO 145
 165 PRINT AT 2,26;"SCORE:";AT 3,26;S
 170 PRINT AT 6,28;"S";AT 7,28;"H";AT 8,28;"I";AT 9,28;"E";AT 10,28;"L";AT 11,28;"D";AT 12,28;"S";AT 12,29;"=";AT 12,30;"5"
 180 PRINT AT 14,28;"P";AT 15,28;"H";AT 16,28;"A";AT 17,28;"S";AT 18,28;"O";AT 19,28;"R";AT 20,28;"S";AT 20,29;"=";AT 20,30;"20"
 200 REM %W%A%R%P%-%I%N% % % % % % % % % % % % % % % % 
 205 IF I=150 AND INP<>1 THEN LET INP=INP-1
 210 LET R5=INT (RND*20)
 220 LET R6=INT (RND*24)
 230 FOR C=1 TO INP
 235 LET R8=INT (RND*30)+1
 240 PRINT AT R5,R6;"%(%0%)"
 241 IF I=150 THEN GOTO 11
 245 IF P=0 THEN GOSUB 500
 250 IF CODE INKEY$-38=R6+1 AND P<>0 THEN GOSUB 300
 260 IF INKEY$<>"" THEN GOSUB 500
 265 IF INKEY$="" AND R8=1 THEN GOSUB 525
 270 NEXT C
 280 PRINT AT R5,R6;"% %.% "
 290 GOTO 210
 300 REM %H%I%T% % % % % % % % % % % % % % % % % % % % 
 310 LET P=P-1
 320 LET S=S+10
 325 LET I=I+10
 330 PRINT AT 3,26;"      ";AT 3,26;S
 335 PRINT AT 20,30;"  ";AT 20,30;P
 340 FOR F=1 TO 5
 350 PRINT AT R5,R6;"% % % "
 360 PRINT AT R5,R6;"%(%0%)"
 370 NEXT F
 375 PRINT AT R5,R6;"% % %."
 380 GOTO 200
 500 REM %M%I%S%S% % % % % % % % % % % % % % % % % % % 
 510 IF P<>0 THEN LET P=P-1
 520 PRINT AT 20,30;"  ";AT 20,30;P
 525 FOR J=1 TO 5
 530 PRINT AT 0,0;"%A%L%I%E%N% %F%I%R%E%S"
 535 NEXT J
 540 LET R7=INT (RND*3)+1
 545 PRINT AT 0,0;"% %.% %.% % \:.%.% % % "
 546 GOSUB 1000
 550 IF R7<>1 THEN RETURN 
 555 FOR Y=1 TO 5
 560 PRINT AT 0,0;"%A%L%I%E%N% %H%I%T%S"
 565 PRINT AT 0,0;"% % % % % % \:.% % % "
 566 NEXT Y
 570 LET SH=SH-1
 580 IF SH<0 THEN GOTO 1000
 590 PRINT AT 12,30;SH
 600 RETURN 
\n1000 REM %F%I%R%E% %G%R%A%P%H%I%C%S% % % % % % % % % % 
\n1005 PRINT AT R5,R6;"% % % "
\n1010 PRINT AT 10,11;"%(%0%)"
\n1015 FOR L=1 TO 5
\n1020 PRINT AT 11,11;"\:.";TAB 13;"\.:"
\n1030 PRINT AT 11,11;"% ";TAB 13;"% "
\n1040 PRINT AT 12,10;" ";TAB 14;" "
\n1050 PRINT AT 12,10;"% ";TAB 14;"% "
\n1060 PRINT AT 13,8;"  ";TAB 15;"  ";AT 14,8;"  ";TAB 15;"  "
\n1070 PRINT AT 13,8;"% %.";TAB 15;"%.%.";AT 14,8;"\:'% ";TAB 15;"% % "
\n1080 PRINT AT 15,4;"    ";TAB 17;"    ";AT 16,4;"    ";TAB 17;"    ";AT 17,4;"    ";TAB 17;"    ";AT 18,4;"    ";TAB 17;"    "
\n1090 PRINT AT 15,4;"% %.% % ";TAB 17;"% % % % ";AT 16,4;"% % % % ";TAB 17;"% %.%.% ";AT 17,4;"% % % % ";TAB 17;"\:'% % % ";AT 18,4;"% % % % ";TAB 17;"% % % % "
\n1100 PRINT AT 19,0;"   ";TAB 21;"     ";AT 20,0;"   ";TAB 21;"     "
\n1110 PRINT AT 19,0;"% % %.% ";TAB 21;"% %.%.% % ";AT 20,0;"% % %.";TAB 21;"% %.% %.% "
\n1111 IF R7<>1 THEN PRINT AT 10,11;"%.%.% "
\n1115 IF R7<>1 THEN RETURN 
\n1200 FOR F=1 TO 10
\n1210 FAST 
\n1220 SLOW 
\n1230 NEXT F
\n1240 NEXT L
\n1242 PRINT AT 10,11;"% % %."
\n1245 IF SH<>0 THEN RETURN 
\n1247 GOSUB 8000
\n2010 PRINT AT 0,0;"HIT ""R"" FORNEW GAME."
\n2020 IF INKEY$="R" THEN RUN 2
\n2030 GOTO 2020
\n7000 PRINT AT 1,1;"CONGRATULATIONS";AT 2,1;"\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''";AT 4,1;"WE HEREBY AWARD YOU THE TITLE";AT 5,1;"OF: ""STAR";A$;""".";AT 8,1;"KEEP ON FIGHTING, COWBOY."
\n7010 PAUSE 300
\n7020 CLS 
\n7030 RETURN 
\n8000 REM %E%N%D% % % % % % % % % % % % % % % % % % % % 
\n8010 FAST 
\n8015 FOR U=0 TO 20
\n8020 PRINT AT U,0;"                          "
\n8025 NEXT U
\n8030 SLOW 
\n8035 FOR U=1 TO 80
\n8040 LET R9=INT (RND*4)+1
\n8050 IF R9>1 THEN LET B$="."
\n8060 IF R9=1 THEN LET B$="\. "
\n8070 PRINT AT INT (RND*20),INT (RND*26);B$
\n8080 NEXT U
\n8100 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