Tape File

This file is part of and Synchro-Sette June 1983. Download the collection to get this file.
Date: June 1983
Type: Program
Platform(s): TS 1000
Tags: Utility

This program is a cassette tape cataloguing system that stores metadata for up to 100 programs in a 10×32 string array. Each record in the array holds a program name (columns 1–8), subject (10–15), counter location (17–22), tape number/side (24–27), and miscellaneous info (29–32). The main menu dispatches to six routines via a computed GOTO using GOTO 1000*VAL B$, covering data entry, viewing, tape save, clear, print, and sort. A Shell sort (gap-halving) at line 6200 allows sorting records by any of the five fields. Data is persisted to tape using the SAVE command at line 3050.


Program Analysis

Program Structure

The program is organised as a menu-driven application with a central dispatch loop and separate numbered subroutine blocks. The main menu lives at lines 20–260; six functional modules begin at multiples of 1000 (1000, 2000, 3000, 4000, 5000, 6000). A second sub-menu for viewing/editing begins at line 2000, itself dispatching via GOTO (VAL B$*200)+2100 to lines 2300, 2500, 2700, and 2900. Utility subroutines are at lines 9000 (scroll 10 lines) and 9800 (press-enter pause).

Data Model

All records are held in the string array A$, dimensioned at line 10 as DIM A$(10,32). Note that the first dimension is 10, yet the entry loop runs up to N=100 — this is a clear bug; the array can only hold 10 records before an index-out-of-range error occurs. The counter R1 tracks how many records have been entered and is preserved across menu returns.

Each 32-character row is laid out as a fixed-width record:

ColumnsFieldMax Length
1–8Program name8
9Separator (space)
10–15Subject6
16Separator
17–22Counter location6
23Separator
24–27Tape no./side4
28Separator
29–32Miscellaneous info4

Menu Dispatch Technique

The main menu reads a single keypress and validates it by checking CODE B$ against the range 29–34 (ZX81 character codes for digits 1–6). The computed jump at line 260, GOTO 1000*VAL B$, routes directly to the correct module in a single statement — a classic and efficient ZX81 BASIC idiom. The secondary menu at line 2260 uses GOTO (VAL B$*200)+2100 with valid range 29–32 (digits 1–4), landing at lines 2300, 2500, 2700, and 2900. VAL B$ here works because B$ holds a single digit character.

Inverse Video Title Screen

The screen background effect at lines 40–60 fills the display by PRINTing "% % % % % % % % " in a loop 96 times — each % is an inverse space, alternating with normal spaces to produce a checkerboard pattern. The title text and menu options are then written using PRINT AT over this background. A similar 192-iteration loop appears in the sub-menu screen at line 2000. POKE 16418,0 sets the border colour and POKE 16418,2 changes it when entering a module.

Shell Sort Implementation

Lines 6200–6370 implement a Shell sort on the array. The gap N starts at INT(R1/2) and is halved each outer pass (line 6220). The inner loop compares A$(I, A TO B) with A$(L, A TO B), where A and B are set by the earlier field-selection block (lines 6070–6160) to the appropriate column slice for the chosen sort key. Swaps exchange the full 32-character row via the temporary B$. Note that B$ is reused for both menu input and sort temporary storage throughout the program.

Key BASIC Idioms

  • POKE 16418,N — direct memory write to the system variable controlling the display file border (TV colour register on ZX81).
  • SCROLL used extensively to advance the display without clearing it, providing a rolling-log entry style.
  • FAST/SLOW mode switching around INPUT statements — SLOW is required for the display to work during input; FAST is used otherwise to speed up computations and screen fills.
  • Left-padding of the miscellaneous field in lines 1376–1385 using a prepend loop: LET B$=" "+B$ repeated 4-LEN B$ times.
  • The ruler string Z$ at line 12 is a 32-character row of inverse dashes used as a visual separator wherever data is displayed.

Bugs and Anomalies

  • Array size mismatch: DIM A$(10,32) at line 10 allocates only 10 rows, but the entry loop at line 1000 iterates up to N=100. Entering more than 10 programs will cause a subscript error.
  • Dead code at lines 8000/8100: Lines 8842 and 8844 call GOSUB 8000 and GOSUB 8100, but neither subroutine exists in the listing. Editing the counter field will produce an error.
  • Unreachable STOP at line 1999: Line 1999 contains STOP but can only be reached by falling through from line 1420’s NEXT N loop completing at N=100; in practice execution goes to line 1500 when the user enters an empty name.
  • Line 2560 is missing: The search loop at line 2530 branches to GOTO 2560 on a name match, but line 2560 does not exist — execution falls through to line 2660, which works correctly as the next defined line, making this a deliberate gap-jump technique.
  • Typo in label at line 8700: The prompt reads "WHAT IS THE NEW STUBJECT?" — “STUBJECT” instead of “SUBJECT”.
  • Print format mismatch at line 8660: The header printed reads "NAME PART NO. COST IT/UN IN/S", suggesting a parts-inventory header was copied from another program rather than the tape-catalogue header used elsewhere.
  • Module 4 (line 4000): The “clear all data” option simply executes RUN, which re-initialises all variables and arrays — a functional but destructive implementation with no confirmation prompt.

Content

Appears On

Cassette to accompany the June 1983 issue of Synchro-Sette.

Related Products

Related Articles

Related Content

Image Gallery

Tape File

Source Code

  10 DIM A$(10,32)
  11 LET R1=0
  12 LET Z$="%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-"
  20 FAST 
  25 CLS 
  30 POKE 16418,0
  40 FOR N=1 TO 96
  50 PRINT "% % % % % % % % ";
  60 NEXT N
  70 PRINT AT 2,5;" PROGRAM TAPE FILE "
  80 PRINT AT 5,1;"%T%O% %E%N%T%E%R% %P%R%O%G%R%A%M%S";TAB 26;"%-% %1"
  90 PRINT AT 7,1;"%T%O% %S%E%E% %P%R%O%G%R%A%M%S";TAB 26;"%-% %2"
 100 PRINT AT 9,1;"%T%O% %S%A%V%E% %D%A%T%A% %O%N% %T%A%P%E";TAB 26;"%-% %3"
 110 PRINT AT 11,1;"%T%O% %C%L%E%A%R% %A%L%L% %D%A%T%A";AT 11,26;"%-% %4"
 120 PRINT AT 13,1;"%T%O% %P%R%I%N%T% %D%A%T%A% ";TAB 26;"%-% %5"
 130 PRINT AT 15,1;"%T%O% %S%O%R%T% %D%A%T%A% ";TAB 26;"%-% %6"
 180 PRINT AT 22,4;"%E%N%T%E%R% %O%N%E% %O%F% %A%B%O%V%E% %:%:%:";AT 22,4;"ENTER ONE OF ABOVE :::";AT 22,4;"%E%N%T%E%R% %O%N%E% %O%F% %A%B%O%V%E% %:%:%:"
 190 SLOW 
 200 LET B$=INKEY$
 210 IF B$="" THEN GOTO 180
 220 IF CODE B$<29 OR CODE B$>34 THEN GOTO 180
 230 FAST 
 240 POKE 16418,2
 250 CLS 
 260 GOTO 1000*VAL B$
 1000 FOR N=R1+1 TO 100
 1010 GOSUB 9000
 1020 PRINT "WHAT IS THE PROGRAM NAME?"
 1030 SCROLL 
 1040 PRINT "PROGRAM NO. ";N;" (8 CHAR. MAX.)"
 1050 SCROLL 
 1055 SLOW 
 1060 INPUT B$
 1065 FAST 
 1070 IF B$="" THEN GOTO 1500
 1080 LET A$(N, TO 8)=B$
 1090 PRINT A$(N)
 1100 GOSUB 9000
 1110 SCROLL 
 1120 PRINT "WHAT IS THE PROGRAM SUBJECT?"
 1125 SCROLL 
 1126 PRINT "(6 CHAR MAX)"
 1130 SCROLL 
 1135 SLOW 
 1140 INPUT B$
 1142 FAST 
 1145 IF LEN B$>6 THEN GOTO 1135
 1150 LET A$(N,10 TO 15)=B$
 1160 PRINT A$(N)
 1170 GOSUB 9000
 1190 PRINT "WHAT IS THE COUNTER LOCATION?"
 1195 SCROLL 
 1196 PRINT "(6 CHAR MAX)"
 1200 SCROLL 
 1205 SLOW 
 1210 INPUT B$
 1212 FAST 
 1214 IF LEN B$>6 THEN GOTO 1205
 1220 SCROLL 
 1230 LET A$(N,17 TO 22)=B$
 1240 PRINT A$(N)
 1250 GOSUB 9000
 1260 PRINT "TAPE NO./SIDE? ";N;" (4 CHAR. MAX.)"
 1270 SCROLL 
 1275 SLOW 
 1280 INPUT B$
 1285 FAST 
 1290 IF LEN B$>4 THEN GOTO 1275
 1300 SCROLL 
 1320 LET A$(N,24 TO 27)=B$
 1330 PRINT A$(N)
 1340 GOSUB 9000
 1350 PRINT "MISC. INFO. OR CODE ?"
 1351 SCROLL 
 1352 PRINT "(4 CHAR MAX)"
 1355 SLOW 
 1360 INPUT B$
 1365 FAST 
 1370 IF LEN B$>4 THEN GOTO 1355
 1374 IF LEN B$=4 THEN GOTO 1390
 1376 FOR I=1 TO 4-LEN B$
 1380 LET B$=" "+B$
 1385 NEXT I
 1390 SCROLL 
 1400 LET A$(N,29 TO 32)=B$
 1410 PRINT A$(N)
 1420 NEXT N
 1500 FAST 
 1510 CLS 
 1520 LET R1=N-1
 1530 SLOW 
 1540 GOTO 20
 1999 STOP 
 2000 FAST 
 2010 CLS 
 2020 POKE 16418,0
 2030 FOR N=1 TO 192
 2040 PRINT "% % % % ";
 2050 NEXT N
 2060 PRINT AT 2,8;" PROGRAM DATA "
 2070 PRINT AT 5,1;"%T%O% %S%E%E% %A%L%L% %P%R%O%G%R%A%M% %D%A%T%A";TAB 28;"%-% %1"
 2080 PRINT AT 7,1;"%T%O% %C%H%A%N%G%E% %P%R%O%G%R%A%M% %N%A%M%E";TAB 28;"%-% %2"
 2090 PRINT AT 9,1;"%T%O% %S%E%E% %I%T%E%M% %D%A%T%A";TAB 28;"%-% %3"
 2100 PRINT AT 11,1;"%T%O% %E%D%I%T% %D%A%T%A% %I%T%E%M%S";TAB 28;"%-% %4"
 2180 PRINT AT 22,4;"%E%N%T%E%R% %O%N%E% %O%F% %A%B%O%V%E% %:%:%:";AT 22,4;"ENTER ONE OF ABOVE :::";AT 22,4;"%E%N%T%E%R% %O%N%E% %O%F% %A%B%O%V%E% %:%:%:"
 2190 SLOW 
 2200 LET B$=INKEY$
 2210 IF B$="" THEN GOTO 2180
 2220 IF CODE B$<29 OR CODE B$>32 THEN GOTO 2180
 2230 FAST 
 2240 POKE 16418,2
 2250 CLS 
 2260 GOTO (VAL B$*200)+2100
 2300 SLOW 
 2310 FOR N=1 TO R1
 2320 SCROLL 
 2340 SCROLL 
 2350 PRINT "NAME    SUBJECT    C/L T/NO MISC" 
 2360 SCROLL 
 2365 PRINT Z$
 2370 SCROLL 
 2380 PRINT A$(N)
 2382 SCROLL 
 2384 SCROLL 
 2386 SCROLL 
 2388 NEXT N
 2390 PRINT "PRESS ENTER TO CONTINUE :::"
 2392 INPUT B$
 2395 GOTO 20
 2500 PRINT AT 10,0;"WHAT IS THE PROGRAM NAME?"
 2505 SLOW 
 2510 INPUT B$
 2515 FAST 
 2520 FOR N=1 TO R1
 2525 FAST 
 2530 IF A$(N, TO LEN B$)=B$ THEN GOTO 2560
 2540 NEXT N
 2542 CLS 
 2544 GOSUB 9000
 2546 PRINT "PROGRAM NAME NOT IN FILE :::"
 2547 GOSUB 9000
 2548 GOSUB 9800
 2550 GOTO 20
 2660 FAST 
 2662 CLS 
 2664 GOSUB 9000
 2666 PRINT "NAME    SUBJECT  C/L  T/NO. MISC" 
 2668 SCROLL 
 2670 PRINT Z$
 2672 SCROLL 
 2674 PRINT A$(N)
 2676 GOSUB 9000
 2678 PRINT AT 20,0;"IS THIS THE CORRECT PROGRAM     NAME?"
 2679 SLOW 
 2680 INPUT Y$
 2682 FAST 
 2683 IF Y$(1)="N" THEN GOTO 2540
 2684 SCROLL 
 2685 SCROLL 
 2686 PRINT "WHAT IS THE CORRECT NAME?"
 2687 SLOW 
 2688 INPUT B$
 2689 FAST 
 2690 LET A$(N, TO 8)=B$
 2691 SCROLL 
 2692 SCROLL 
 2693 PRINT Z$
 2694 SCROLL 
 2695 PRINT A$(N)
 2696 SCROLL 
 2697 SCROLL 
 2698 GOSUB 9800
 2699 GOTO 20
 2700 CLS 
 2705 PRINT AT 10,1;"WHAT IS THE PROGRAM NAME?"
 2710 SLOW 
 2715 INPUT B$
 2720 FAST 
 2725 IF LEN B$>8 THEN GOTO 2710
 2730 FOR N=1 TO R1
 2735 IF A$(N, TO LEN B$)=B$ THEN GOTO 2760
 2740 NEXT N
 2745 SCROLL 
 2750 PRINT TAB 16-((LEN B$)/2);B$
 2755 GOTO 2544
 2760 CLS 
 2765 PRINT ,,,,"PROGRAM   -";TAB 24;A$(N, TO 8)
 2770 PRINT ,,"SUBJECT   -";TAB 24;A$(N,10 TO 15)
 2775 PRINT ,,"CTR. LOC. -";TAB 24;A$(N,17 TO 22)
 2780 PRINT ,,"TP. NO/SD -";TAB 24;A$(N,24 TO 27)
 2785 PRINT ,,"MISC.     -";TAB 24;A$(N,29 TO 32)
 2815 GOSUB 9800
 2820 GOTO 20
 2900 CLS 
 2905 PRINT AT 10,1;"WHAT IS THE PROGRAM NAME?"
 2910 SLOW 
 2915 INPUT B$
 2920 FAST 
 2925 IF LEN B$>6 THEN GOTO 2910
 2930 FOR N=1 TO R1
 2935 IF A$(N, TO LEN B$)=B$ THEN GOTO 2950
 2940 NEXT N
 2945 GOTO 2745
 2950 CLS 
 2955 PRINT "NAME    SUBJECT  C/L  T/NO. MISC" 
 2960 PRINT Z$;A$(N)
 2965 PRINT ,,,,"<1> MISC","<3> CTR LOC","<2> SUBJECT","<4> TP NUM/SD",,,,"CHOOSE ONE?"
 2967 SLOW 
 2970 INPUT B$
 2972 FAST 
 2974 IF CODE B$<29 OR CODE B$>32 THEN GOTO 2967
 2975 GOTO 8500+(100*VAL B$)
 2999 GOTO 2999
 3000 FAST 
 3002 CLS 
 3006 PRINT AT 10,10;"FILE NAME?"
 3010 SLOW 
 3020 INPUT C$
 3030 PRINT AT 12,0;"PREPARE THE RECORDER AND THEN   PRESS ENTER :::"
 3040 INPUT B$
 3050 SAVE C$
 3060 FAST 
 3070 CLS 
 3080 GOTO 20
 4000 FAST 
 4010 CLS 
 4020 RUN 
 5000 PRINT AT 10,0;"SET UP PRINTER AND PRESS ENTER."
 5010 INPUT B$
 5020 FOR N=1 TO R1
 5030 LPRINT 
 5040 LPRINT "NAME    SUBJECT  C/L  T/NO. MISC" 
 5050 LPRINT "--------------------------------"
 5060 LPRINT A$(N)
 5070 NEXT N
 5080 GOTO 20
 6000 PRINT AT 8,0;"SORT BY?"
 6010 PRINT ,"NAME        (1)"
 6020 PRINT ,"SUBJECT     (2)"
 6030 PRINT ,"CTR. LOC.   (3)"
 6040 PRINT ,"TP NUM/SD   (4)"
 6050 PRINT ,"MISC.       (5)"
 6055 SLOW 
 6060 LET B$=INKEY$
 6065 IF CODE B$<29 OR CODE B$>33 THEN GOTO 6060
 6066 FAST 
 6070 IF B$="1" THEN LET A=1
 6080 IF B$="1" THEN LET B=8
 6090 IF B$="2" THEN LET A=10
 6100 IF B$="2" THEN LET B=15
 6110 IF B$="3" THEN LET A=17
 6120 IF B$="3" THEN LET B=22
 6130 IF B$="4" THEN LET A=24
 6140 IF B$="4" THEN LET B=27
 6150 IF B$="5" THEN LET A=29
 6160 IF B$="5" THEN LET B=32
 6200 CLS 
 6210 LET N=R1
 6220 LET N=INT (N/2)
 6230 IF N=0 THEN GOTO 20
 6240 LET J=1
 6250 LET K=R1-N
 6260 LET I=J
 6270 LET L=I+N
 6280 IF A$(I,A TO B)<A$(L,A TO B) THEN GOTO 6350
 6290 LET B$=A$(I)
 6300 LET A$(I)=A$(L)
 6310 LET A$(L)=B$
 6320 LET I=I-N
 6330 IF I<1 THEN GOTO 6350
 6340 GOTO 6270
 6350 LET J=J+1
 6360 IF J>K THEN GOTO 6220
 6370 GOTO 6260
 8600 PRINT ,,"WHAT IS THE NEW <MISC> INFO?"
 8610 SLOW 
 8620 INPUT B$
 8630 FAST 
 8640 IF LEN B$>4 THEN GOTO 8610
 8650 LET A$(N,29 TO 32)=B$
 8660 PRINT ,,"NAME    PART NO. COST IT/UN IN/S";Z$;A$(N) 
 8670 GOSUB 9800
 8680 GOTO 20
 8700 PRINT ,,"WHAT IS THE NEW STUBJECT?"
 8710 SLOW 
 8720 INPUT B$
 8730 FAST 
 8740 IF LEN B$>6 THEN GOTO 8710
 8750 LET A$(N,10 TO 15)=B$
 8760 GOTO 8660
 8800 PRINT ,,"WHAT IS THE NEW COUNTER?"
 8810 SLOW 
 8820 INPUT B$
 8830 FAST 
 8840 IF LEN B$>6 THEN GOTO 8810
 8842 GOSUB 8000
 8844 IF LEN B$<6 THEN GOSUB 8100
 8850 LET A$(N,17 TO 22)=B$
 8860 GOTO 8660
 8900 PRINT ,,"WHAT IS THE NEW TAPE NO./SIDE?"
 8910 SLOW 
 8920 INPUT B$
 8930 FAST 
 8940 IF LEN B$>4 THEN GOTO 8910
 8950 LET A$(N,24 TO 27)=B$
 8960 GOTO 8660
 9000 FOR I=1 TO 10
 9010 SCROLL 
 9020 NEXT I
 9030 RETURN 
 9800 PRINT AT 21,0;"PRESS ENTER TO CONTINUE :::"
 9810 INPUT B$
 9820 CLS 
 9830 RETURN 
 9998 SAVE "TAPE FIL%E"
 9999 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