Rocket

Date: 198x
Type: Program
Platform(s): TS 1000
Tags: Game

Program for creating a directory of programs on a tape.

This program is a cassette tape catalogue manager for the ZX81/TS1000, allowing users to store, view, revise, delete, and print records of up to ten cassette files, each holding up to ten named programs with tape counter start and end positions. Data is held in parallel arrays: C$(10,4) for load-mode strings, N$(10,15) for cassette names, P$(10,10,15) for program names, and T(10,10,2) for tape counter values. The print-label routine uses block-graphic border strings (X$, Y$, Z$) sent to the printer via LPRINT to produce formatted cassette inlay cards. The program saves itself with its data arrays using SAVE S$ and warns users via a start-up screen not to RUN it (which would reinitialise variables) but instead to GOTO 1.


Program Structure

The program is organised as a dispatcher with a main menu loop and a set of subroutines, each entered via GOSUB from lines 501507. The overall flow is:

  1. GOTO 280 at line 1 skips the variable initialisation block on a cold start; the warning screen at lines 200270 explains why RUN must not be used.
  2. Lines 10170: global variable and array initialisation.
  3. Lines 280540: main menu loop. FAST mode is set at line 320 for display speed.
  4. Lines 550970: Create File subroutine.
  5. Lines 10001360: View File subroutine.
  6. Lines 13701860: Revise File subroutine.
  7. Lines 19002330: Delete File subroutine.
  8. Lines 23402640: Print Label subroutine.
  9. Lines 26802900: Save Files / Erase All subroutine.
  10. Lines 29303080: Auto-run save routine (shared with Save Files path).

Data Structures

VariableDimensionsPurpose
C$(10,4)10 files × 4 charsLoad mode (“NORM” or “%F%/%L”)
N$(10,15)10 files × 15 charsCassette name
P$(10,10,15)10 files × 10 programs × 15 charsProgram names
T(10,10,2)10 files × 10 programs × 2Tape counter FROM / TO values
TFscalarTotal files created so far
FscalarCurrent file index
XscalarFlag: 1 = reinitialise arrays after erase
S$stringProgram save name on tape

Notable Techniques

  • Self-saving with data: The SAVE S$ at line 3060 saves the entire program including all populated arrays, so the catalogue persists across sessions without a separate data file.
  • Blank-entry field revision: The Revise subroutine (lines 13701860) tests IF M$="" after each INPUT; pressing ENTER with no text leaves the field unchanged, a clean idiom for in-place editing.
  • Block-graphic borders for printer labels: X$ (line 170) is a full-width row of // characters, Y$ (line 180) a dotted separator, and Z$ (line 190) a blank interior row, all used with LPRINT to frame the cassette label output.
  • Deletion by array shifting: When a file is deleted (lines 20302110), all higher-numbered entries are shifted down by one index in all four arrays, maintaining contiguous file numbering without gaps.
  • Erasure padding: After shifting, the vacated top slot is overwritten with spaces from E$ (a 32-space string) and zeros, preventing stale data from appearing as a ghost record.
  • FAST/SLOW idiom: FAST is set at line 320 for the menu, and SLOW at line 3030 before SAVE, which requires the normal video timing to operate correctly.
  • Key-wait for printer: Lines 24602470 use PAUSE 3200 followed by an INKEY$ busy-wait loop — a common ZX81 idiom for “press any key to continue” that survives a PAUSE timeout.

Bugs and Anomalies

  • Dead code after GOTO at line 1920: Line 1920 reads IF F<=TF AND F>=1 THEN GOTO 4070. Line 4070 does not exist in the listing, so a valid file number causes a 4070 error or jump to undefined behaviour. The intended target is probably line 1960, which displays the file details before confirming deletion. Lines 19601950 are therefore unreachable as written.
  • Erase-all flag logic: The “Erase All” subroutine (line 2860) calls CLEAR and then sets X=1 (line 2890). Back in the main loop, line 530 checks IF X=1 THEN GOTO 30, which re-runs the DIM statements, effectively reinitialising the arrays. However, because CLEAR has already wiped all variables including X, the check at line 530 will always see X=0 — meaning the arrays are never re-dimensioned after an erase. The flag X is set at line 2890 after CLEAR, so it does survive to line 530; this does in fact work as intended on closer inspection, since X=1 is set after the CLEAR.
  • Line 3050 jump target: IF INKEY$="" THEN GOTO 9999 — line 9999 does not exist; this is presumably intended as an infinite wait loop but would cause an error if triggered while no key is pressed (though in practice PAUSE 3200 preceding it means the user has had time to press a key).
  • Missing SLOW at save: SLOW appears at line 3030 before the key-wait, but the INKEY$ loop at 3050 means the program never actually falls through to 3060 when a key is not pressed — see the anomaly above.
  • Line 29102920 dead code: PRINT and REM at lines 29102920 are unreachable; the Save subroutine falls through to line 2930 directly from line 2780 or 2760.

Content

Appears On

Related Products

Related Articles

Related Content

Image Gallery

Rocket

Source Code

   1 GOTO 280
  10 LET S$="CASSFILE*1"
  20 REM "CASSFILE"
  30 DIM C$(10,4)
  40 DIM N$(10,15)
  50 DIM P$(10,10,15)
  60 DIM T(10,10,2)
  70 LET X=0
  80 LET F=0
  90 LET E$="                                "
 100 LET A$="LOADING MODE:"
 110 LET B$="CASSETTE NAME"
 120 LET F$="FILE NO."
 130 LET G$="PROGRAM NAME"
 140 LET H$="TAPE COUNT"
 150 LET I$="FROM TO"
 160 LET TF=0
 170 LET X$=":'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''':"
 180 LET Y$=":..............................................................:"
 190 LET Z$=":                                :"
 200 PRINT AT 8,11;"""NOTE"""
 210 PRINT AT 8,0;"DONOT ""RUN""THE PROGRAM","""USE GOTO 1"""
 220 PRINT 
 230 PRINT "IF YOU DO,IT WILL CLEAR ALL THE VARIABLES.",,,,
 240 PRINT "THAT MEANS YOU HAVE TO START    OVER WITH EVERTHING."
 250 PRINT 
 260 PRINT TAB 16;"11-16-84 ";"""RGS"""
 270 PAUSE 480
 280 CLS 
 290 REM ********
 300 REM **MENU**
 310 REM ********
 320 FAST 
 330 PRINT S$
 340 PRINT TAB 12;"MENU."
 350 PRINT "--------------------------------"
 360 PRINT 
 370 PRINT "1. CREATE FILE"
 380 PRINT ,,"2. VIEW/PRINT FILE"
 390 PRINT ,,"3. REVISE FILE"
 400 PRINT ,,"4. DELETE FILE"
 410 PRINT ,,"5. PRINT CASSETTE FILE"
 420 PRINT ,,"6. SAVE FILES"
 430 PRINT ,,"7. ERASE ALL FILES"
 440 PRINT AT 19,5;"""INPUT YOUR CHOICE"""
 450 PRINT 
 460 PRINT "--------------------------------"
 470 INPUT M
 480 IF M<1 OR M>7 THEN GOTO 440
 500 CLS 
 501 IF M=1 THEN GOSUB 550
 502 IF M=2 THEN GOSUB 1E3
 503 IF M=3 THEN GOSUB 1370
 504 IF M=4 THEN GOSUB 1900
 505 IF M=5 THEN GOSUB 2340
 506 IF M=6 THEN GOSUB 2680
 507 IF M=7 THEN GOSUB 2820
 520 CLS 
 530 IF X=1 THEN GOTO 30
 540 GOTO 340
 550 REM <<<<%C%R%E%A%T%E% %F%I%L%E% %S%U%B>>>>
 560 LET F=TF+1
 570 IF F<=10 THEN GOTO 610
 580 PRINT "**NO SPACE FOR ANOTHER FILE**",,,"ON RETURN TO MENU CHOOSE SAVE","OPTION TO KEEP CURRENT FILES","THEN ERASE FILES AND START NEW","FILE ARRAY."
 590 PAUSE 300
 600 RETURN 
 610 PRINT "READY TO CREATE FILE NO.";F
 620 PRINT AT 2,0;"INPUT SAVE/LOAD MODE: ",,,;"""NORM"" FOR NORMAL LOADING","""%F%/%L"" FOR ZXLR8 FASTLOADING ","ROUTINE."
 630 INPUT C$(F)
 640 CLS 
 650 PRINT TAB 18;F$;F
 660 PRINT AT 2,0;E$;AT 2,0;B$;"?(15 CHRS MAX)"
 670 INPUT N$(F)
 680 PRINT AT 2,0;E$;AT 2,0;"INPUT PROG.NAMES AND TAPE COUNTS"
 690 FOR N=1 TO 10
 700 PRINT AT 4,0;"PROGRAM ";N
 710 PRINT G$;" ? (15 CHRS MAX)"
 720 INPUT P$(F,N)
 730 PRINT AT 5,0;E$;AT 5,0;H$; " FROM ?"
 740 INPUT T(F,N,1)
 750 PRINT AT 5,11;"TO ?  "
 760 INPUT T(F,N,2)
 770 PRINT AT 5,0;E$;AT 5,0;"ANOTHER PROGRAM ?(Y/N)"
 780 INPUT M$
 790 IF M$="N" THEN GOTO 820
 800 IF M$<>"N" AND M$<>"Y" THEN GOTO 770
 810 NEXT N
 820 CLS 
 830 LET TF=TF+1
 840 PRINT AT 8,2;"(C)REATE ANOTHER FILE."
 850 PRINT 
 860 PRINT TAB 2;"(V)IEW CREATED FILE."
 870 PRINT 
 880 PRINT TAB 2;"(M)ENU."
 890 PRINT AT 18,5;"INPUT C,V OR M."
 900 INPUT M$
 910 IF M$<>"C" THEN GOTO 950
 920 LET F=F+1
 930 CLS 
 940 GOSUB 610
 950 CLS 
 960 IF M$="V" THEN GOSUB 1040
 970 RETURN 
 980 REM **********************
 990 REM ***VIEW FILE SUB*** 
 1000 REM **********************
 1010 PRINT AT 12,5;"WHICH FILE NUMBER ?"
 1020 INPUT F
 1030 REM **ENTRY FROM OTHER SUBS**
 1040 CLS 
 1050 IF TF<>0 AND F<=TF AND F>=1 THEN GOTO 1130
 1060 PRINT """NO FILE WITH THAT NUMBER."""
 1070 PRINT "MENU (M) OR OTHER FILE (V)"
 1080 INPUT M$
 1090 IF M$="V" THEN GOTO 1010
 1100 IF M$="M" THEN RETURN 
 1110 PRINT "FOLLOW INSTRUCTIONS PLEASE"
 1120 GOTO 1070
 1130 CLS 
 1140 PRINT F$;F
 1150 PRINT ,,A$;C$(F)
 1160 PRINT "********************************"
 1170 PRINT G$;TAB 20;H$;TAB 20;I$
 1180 PRINT "--------------------------------"
 1190 FOR N=1 TO 10
 1200 PRINT N;".";P$(F,N);TAB 20;T(F,N,1);TAB 26;T(F,N,2)
 1210 NEXT N
 1220 PRINT AT 21,0;"(P)PRINT,(N)NEXT FILE,OR (M)MENU"
 1230 INPUT M$
 1240 PRINT AT 21,0;E$
 1250 IF M$="P" THEN COPY 
 1260 IF M$<>"N" THEN GOTO 1350
 1270 LET F=F+1
 1280 IF F<=TF THEN GOTO 1340
 1290 CLS 
 1300 PRINT AT 11,1;"**NO FILE OF HIGHER NUMBER**"
 1310 PAUSE 150
 1320 CLS 
 1330 GOTO 1350
 1340 GOSUB 1040
 1350 RETURN 
 1360 STOP 
 1370 REM ***%R%E%V%I%S%E% %F%I%L%E% %S%U%B***"
 1380 PRINT AT 10,1;"WHICH FILE TO REVISE? (1-10)"
 1390 PRINT 
 1400 PRINT TAB 4;"FILE NO.REQUESTED. ";
 1410 INPUT F
 1420 PRINT F
 1430 PAUSE 180
 1440 IF F<=TF THEN GOTO 1490
 1450 PRINT 
 1460 PRINT TAB 6;"**NO SUCH FILE**"
 1470 PAUSE 150
 1480 RETURN 
 1490 CLS 
 1500 PRINT AT 8,0;"FILE ";F;" DETAILS WILL BE PRINTED.",,,"PRESS ENTER IF CORRECT.","INPUT NEW DETAILS IF REQUIRED."
 1510 PAUSE 150
 1520 SCROLL 
 1530 PRINT A$;C$(F)
 1540 INPUT M$
 1550 IF M$="" THEN GOTO 1600
 1560 LET C$(F)=M$
 1570 CLS 
 1580 SCROLL 
 1590 PRINT "NEW ";A$;C$(F)
 1600 SCROLL 
 1610 PRINT B$;" ";N$(F)
 1620 INPUT M$
 1630 IF M$="" THEN GOTO 1700
 1640 LET N$(F)=M$
 1650 CLS 
 1660 SCROLL 
 1670 PRINT A$;C$(F)
 1680 SCROLL 
 1690 PRINT "NEW CASS.NAME ";N$(F)
 1700 SCROLL 
 1710 FOR N=1 TO 10
 1720 PRINT "PROG.";N;" NAME ";P$(F,N)
 1730 INPUT M$
 1740 IF M$<>"" THEN LET P$(F,N)=M$
 1750 PRINT AT 21,0;"PROG.";N;" NAME ";P$(F,N)
 1760 SCROLL 
 1770 PRINT AT 21,0;"TAPE FROM:";T(F,N,1)
 1780 INPUT M$
 1790 IF M$<>"" THEN LET T(F,N,1)=VAL M$
 1800 PRINT AT 21,0;"TAPE FROM:";T(F,N,1);"   TO:";T(F,N,2)
 1810 INPUT M$
 1820 IF M$<>"" THEN LET T(F,N,2)=VAL M$
 1830 PRINT AT 21,0;"TAPE FROM:";T(F,N,1);"   TO:";T(F,N,2)
 1840 SCROLL 
 1850 NEXT N
 1860 RETURN 
 1870 REM **********************
 1880 REM **DELETE FILE SUB**
 1890 REM **********************
 1900 PRINT "WHICH FILE DO YOU WISH TO DELETE ? (1 TO 10)"
 1910 INPUT F
 1920 IF F<=TF AND F>=1 THEN GOTO    4070
 1930 PRINT "**NO FILE OF THAT NUMBER**"
 1940 PAUSE 150
 1950 GOTO 2330
 1960 PRINT F$;F,,A$;C$(F)
 1970 PRINT B$;" ";N$(F)
 1980 PRINT AT 10,0;"INPUT D TO CONFIRM DELETION",,,"OR M FOR MENU."
 1990 INPUT M$
 2000 IF M$<>"D" THEN GOTO 2330
 2010 PRINT AT 14,0;"ALL FILES WITH NUMBERS >";F,"WILL HAVE THEIR FILE NUMBERS","REDUCED BY ONE."
 2020 IF F=TF THEN GOTO 2120
 2030 FOR N=F TO TF-1
 2040 LET N$(N)=N$(N+1)
 2050 LET C$(N)=C$(N+1)
 2060 FOR L=1 TO 10
 2070 LET P$(N,L)=P$(N+1,L)
 2080 LET T(N,L,1)=T(N+1,L,1)
 2090 LET T(N,L,2)=T(N+1,L,2)
 2100 NEXT L
 2110 NEXT N
 2120 LET C$(TF)=E$
 2130 LET N$(TF)=E$
 2140 FOR N=1 TO 10
 2150 LET P$(TF,N)=E$
 2160 LET T(TF,N,1)=0
 2170 LET T(TF,N,2)=0
 2180 NEXT N
 2190 LET TF=TF-1
 2200 CLS 
 2210 PRINT "FILE DELETED"
 2220 PRINT ,,"NEW FILE LISTING:"
 2230 PRINT 
 2240 FOR N=1 TO TF
 2250 PRINT F$;N;" ";A$;C$(N)
 2260 NEXT N
 2270 PRINT AT 21,0;"COPY NEW LIST (C) OR MENU (M)"
 2280 INPUT M$
 2290 IF M$<> "C" THEN GOTO 2330
 2300 PRINT AT 21,0;E$
 2310 COPY 
 2320 CLS 
 2330 RETURN 
 2340 REM **********************
 2350 REM ** PRINT LABEL SUB *** 
 2360 REM **********************
 2370 PRINT AT 8,0;"WHICH FILE DO YOU WANT TO PRINT",,,"AS A CASSETTE LABEL?(1 TO 10)"
 2380 PRINT 
 2390 INPUT F
 2400 IF F>=1 AND F<=TF THEN GOTO 2450
 2410 PRINT "**NO FILE OF THAT NUMBER**"
 2420 PAUSE 150
 2430 CLS 
 2440 GOTO 2640
 2450 PRINT ,,"FILE ";F;" WILL NOW BE PRINTED.",,,"CHECK PRINTER,HIT A KEY TO START"
 2460 PAUSE 3200
 2470 IF INKEY$="" THEN GOTO 2470
 2480 LPRINT X$;": ";A$;C$(F);TAB 20;F$;F; TAB 31;" :"
 2490 LPRINT Z$;": ";B$;" ";N$(F); TAB 31;" :"
 2500 LPRINT Z$;X$;": ";G$; TAB 20;": ";H$; TAB 31;" :"
 2510 LPRINT ": ";TAB 20;": ";I$;TAB 31;" :"
 2520 LPRINT X$
 2530 FOR N=1 TO 6
 2540 LPRINT ": ";N;" ";P$(F,N); TAB 21;T(F,N,1);TAB 25;T(F,N,2); TAB 31;" :";Z$
 2550 NEXT N
 2560 LPRINT Y$;X$
 2570 LPRINT ": ";A$;C$(F); TAB 20;F$;F; TAB 31;" :"
 2580 LPRINT Z$;": ";B$;" ";N$(F); TAB 31;" :"
 2590 LPRINT Y$;X$
 2600 FOR N=7 TO 10
 2610 LPRINT ": ";N;" ";P$(F,N);   TAB 21;T(F,N,1);TAB 25;T(F,N,2);TAB 31;" :";Z$
 2620 NEXT N
 2630 LPRINT Y$
 2640 RETURN 
 2650 REM **********************
 2660 REM ** SAVE FILES PROC **
 2670 REM **********************
 2680 CLS 
 2690 PRINT AT 6,0;"SAVE FILES ON TAPE ROUTINE"
 2700 PRINT ,,"CURRENT PROGRAM NAME IS"
 2710 PRINT ,," "" ";S$;" "" "
 2720 PRINT ,,"INPUT A NEW NAME FOR THIS ","PROGRAM FILE OR PRESS ENTER","ONLY TO SAVE WITH CURRENT NAME."
 2730 PRINT ,,"INPUT M FOR MENU"
 2740 INPUT M$
 2750 IF M$="M" THEN RETURN 
 2760 IF M$="" THEN GOTO 2930
 2770 LET S$=M$
 2780 GOTO 2930
 2790 REM **********************
 2800 REM *DELETE ALL FILES SUB*
 2810 REM **********************
 2820 PRINT "INPUT D TO CONFIRM ALL FILES","ARE TO BE DELETED."
 2830 PRINT ,,"INPUT M TO RETURN TO MENU."
 2840 INPUT M$
 2850 IF M$<>"D" THEN GOTO 2890
 2860 CLEAR 
 2870 PRINT ,,"INPUT NEW NAME FOR THIS FILE"
 2880 INPUT S$
 2890 LET X=1
 2900 RETURN 
 2910 PRINT 
 2920 REM **********************
 2930 REM ** AUTO-RUN ROUTINE.**
 2940 REM **********************
 2950 CLS 
 2960 PRINT AT 6,0;"PROGRAM NAME IS ";
 2970 PRINT """ ";S$;" """
 2980 PRINT 
 2990 PRINT TAB 6;"**NOTE IT DOWN**"
 3000 PRINT 
 3010 PRINT ,,"SET CASSETTE TO RECORD,AND THEN","PRESS A KEY TO SAVE."
 3020 PAUSE 3200
 3030 SLOW 
 3050 IF INKEY$="" THEN GOTO 9999
 3060 SAVE S$
 3070 CLS 
 3080 GOTO 200

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

People

No people associated with this content.

Scroll to Top