This program implements a simple flat-file database for cataloguing projects with associated magazine references, storing up to five records each containing a project name (25 chars), magazine (16 chars), month/year (6 chars), page number (4 chars), and remarks (30 chars). The main menu uses `GOTO 1000*VAL I$` to dispatch between four options — data entry, viewing/editing, file clear, and tape save — using arithmetic on the menu choice character. Record entry uses five parallel string arrays (`P$`, `M$`, `D$`, `R$`, `N$`) dimensioned with a common variable `T=5`, and a counter `R1` tracks how many records have been entered. The editing sub-menu at line 2700 uses `GOTO 2800+(VAL Y$*10)` to jump to field-specific edit routines via computed branching. The display alternates between `FAST` and `SLOW` modes throughout to balance rendering speed with input responsiveness.
Program Analysis
Program Structure
The program is organised around a main menu (lines 100–230) that dispatches to four functional sections using a computed GOTO. Lines 1000–1920 handle data entry, lines 2000–2999 cover viewing and editing, line 3000 performs a RUN (file clear by restart), and lines 4000–4080 manage tape saving.
| Line Range | Function |
|---|---|
| 4–90 | Initialisation: array dimensions, counter reset |
| 100–230 | Main menu display and dispatch |
| 1000–1920 | Data entry loop |
| 2000–2999 | View, search, and edit records |
| 3000 | “Clear file” via RUN |
| 4000–4080 | Tape save routine |
Data Model
Five parallel string arrays hold the database fields, all dimensioned to T=5 rows at startup:
P$(T,25)— Project name (25 characters)M$(T,16)— Magazine name (16 characters)D$(T,6)— Month/Year (6 characters)N$(T,4)— Page number (4 characters)R$(T,30)— Remarks (30 characters)
The variable R1 tracks how many records have been populated. Entry begins at N=R1+1, so re-entering the entry routine appends rather than overwrites. Pressing Enter on an empty project field at line 1055 exits the loop and sets R1=N-1.
Computed GOTO Dispatch
The main menu validates that CODE I$ falls between 29 and 32 (the ZX81 key codes for digits 1–4) then executes GOTO 1000*VAL I$ at line 230. This cleanly maps menu choices to section start lines without an IF-chain. A similar technique appears in the edit sub-menu at line 2750: GOTO 2800+(VAL Y$*10) routes choices 1–5 to lines 2810, 2820, 2830, 2840, and 2880 respectively — note that 2850–2870 are absent, so choice 5 (Remarks) lands at 2880 rather than 2850, which is intentional.
FAST/SLOW Mode Alternation
The program switches between FAST and SLOW modes frequently. FAST is used for screen-clearing and rendering to avoid flicker, while SLOW is engaged immediately before INPUT or INKEY$ polling loops to allow the display to remain stable during user interaction. This pattern repeats throughout all four functional sections.
Key BASIC Idioms
- Inverse-video banner: Lines 110–115 use block graphic escapes to draw a bordered title box with a solid top bar, inverse-video text, and a bottom border made of
▄characters. - INKEY$ polling loop: Lines 200–210 and 2020–2060 implement a spin-wait on
INKEY$with validation against allowed key codes, a standard ZX81 idiom for menu selection. - SCROLL for output management: The entry routine (lines 1010–1800) uses repeated
SCROLLcalls rather thanCLSto create a rolling display of field prompts and entered values. - Substring comparison for search: Line 2170 uses
X$( TO LEN I$)to match only the leading characters of a stored project name against the search string, providing a simple prefix search. - File clear via RUN: Option 3 jumps to line 3000 which contains only
RUN, restarting the program and thus reinitialising all arrays — a common minimal “clear” technique.
Notable Anomalies and Observations
- Line 155 prints a warning in inverse video: “NEVER ENTER RUN-ENTER GOTO 102”, instructing the user to use
GOTO 102instead ofRUNto return to the menu without losing data — sinceRUNwould reinitialise all arrays. - Line 180 immediately overwrites the normal text printed at line 170 with an inverse-video version of the same string (“ENTER ONE OF ABOVE”), creating an inverse prompt effect without clearing the screen.
- The edit field dispatch via
GOTO 2800+(VAL Y$*10)accepts codes 29–36 (digits 1–8) but only defines handlers at 2810–2880 for five fields. Choices 6, 7, or 8 would jump to non-existent lines 2860, 2870, or 2880 — where 2880 happens to be the Remarks handler. Choices 6 and 7 would cause an error. - Lines 4060–4080 appear after the tape save routine and are unreachable in normal execution:
CLEARfollowed bySAVE "1032%9"(saving under an inverse-character filename) andRUN. These lines appear to be a bootstrap or master save remnant left in the listing. - The database capacity is fixed at
T=5records. IncreasingTat line 5 is the only way to expand capacity, constrained by available RAM.
Content
Source Code
4 FAST
5 LET T=5
10 DIM P$(T,25)
20 DIM M$(T,16)
30 DIM D$(T,6)
40 DIM N$(T,4)
80 DIM R$(T,30)
90 LET R1=0
100 FAST
102 CLS
105 PRINT " \:'\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\':"
110 PRINT " \: %N%A%M%E% %A%N%D% %A%D%D%R%E%S%S% %P%R%O%G%R%A%M\ :"
115 PRINT " \:.\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\.:"
120 PRINT ,,,,,,,,,," TO ENTER OR ADD DATA - 1"
130 PRINT " TO SEE OR CHANGE DATA - 2"
140 PRINT " TO CLEAR FILE - 3"
150 PRINT " TO SAVE FILE ON TAPE - 4"
155 PRINT AT 15,1;"%N%E%V%E%R% %E%N%T%E%R% %R%U%N%-%E%N%T%E%R% %G%O%T%O% %1%0%2"
160 PRINT AT 19,6;"\:'\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\':";AT 20,6;"\: ";AT 20,25;"\ :";AT 21,6;"\:.\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\.:"
170 PRINT AT 20,7;"ENTER ONE OF ABOVE"
180 PRINT AT 20,7;"%E%N%T%E%R% %O%N%E% %O%F% %A%B%O%V%E"
190 SLOW
200 LET I$=INKEY$
210 IF CODE I$<29 OR CODE I$>32 THEN GOTO 170
215 FAST
220 CLS
230 GOTO 1000*VAL I$
\n1000 FOR N=R1+1 TO T
\n1010 SCROLL
\n1020 PRINT "NO.";N;" PROJECT ? (25)"
\n1030 SLOW
\n1040 INPUT X$
\n1050 FAST
\n1055 IF X$="" THEN GOTO 1900
\n1057 LET P$(N)=X$
\n1060 SCROLL
\n1070 PRINT P$(N)
\n1080 SCROLL
\n1090 SCROLL
\n1100 SCROLL
\n1110 PRINT "MAGAZINE ? (16)"
\n1120 SLOW
\n1130 INPUT M$(N)
\n1140 FAST
\n1150 SCROLL
\n1160 PRINT M$(N)
\n1170 SCROLL
\n1180 SCROLL
\n1200 SCROLL
\n1210 PRINT "MONTH/YR ? (6)"
\n1220 SLOW
\n1230 INPUT D$(N)
\n1240 FAST
\n1250 SCROLL
\n1260 PRINT D$(N)
\n1270 SCROLL
\n1280 SCROLL
\n1300 SCROLL
\n1310 PRINT "PAGE NO.? (4)"
\n1320 SLOW
\n1330 INPUT N$(N)
\n1340 FAST
\n1350 SCROLL
\n1360 PRINT N$(N)
\n1370 SCROLL
\n1380 SCROLL
\n1400 SCROLL
\n1710 PRINT "REMARKS ? (30)"
\n1720 SLOW
\n1730 INPUT R$(N)
\n1740 FAST
\n1750 SCROLL
\n1760 PRINT R$(N)
\n1770 SCROLL
\n1780 SCROLL
\n1800 NEXT N
\n1810 GOTO 100
\n1900 LET R1=N-1
\n1910 SLOW
\n1920 GOTO 100
\n2000 CLS
\n2005 SLOW
\n2010 PRINT AT 11,2;"DO YOU WANT TO SEE THE WHOLE";AT 12,14;"FILE?"
\n2020 LET I$=INKEY$
\n2030 IF I$="" THEN GOTO 2020
\n2040 IF I$="Y" THEN GOTO 2500
\n2050 IF I$="N" THEN GOTO 2100
\n2060 GOTO 2020
\n2100 FAST
\n2110 CLS
\n2120 PRINT AT 11,5;"WHAT IS THE PROJECT ?"
\n2130 SLOW
\n2140 INPUT I$
\n2145 FAST
\n2150 FOR N=1 TO R1
\n2160 LET X$=P$(N)
\n2170 IF I$=X$( TO LEN I$) THEN GOTO 2300
\n2180 NEXT N
\n2185 CLS
\n2190 PRINT AT 11,6;"PROJECT NOT IN FILE?";AT 21,0;"PRESS ENTER TO CONTINUE :::::"
\n2195 SLOW
\n2200 INPUT I$
\n2210 GOTO 100
\n2300 FAST
\n2310 CLS
\n2320 PRINT M$(N);TAB 32;P$(N);TAB 32;D$(N);TAB 32;N$(N);TAB 32;,,R$(N)
\n2330 PRINT AT 21,0;"IS THIS THE CORRECT PROJECT ?"
\n2335 SLOW
\n2340 LET Y$=INKEY$
\n2350 IF Y$="" THEN GOTO 2340
\n2360 IF Y$="Y" THEN GOTO 2600
\n2370 IF Y$="N" THEN GOTO 2180
\n2380 GOTO 2340
\n2500 FAST
\n2510 CLS
\n2520 FOR N=1 TO R1
\n2530 FAST
\n2535 CLS
\n2540 PRINT "PROJECT NO.";N;" OF ";R1,,,,,
\n2550 PRINT M$(N);TAB 32;P$(N);TAB 32;D$(N);TAB 32;N$(N);TAB 32;,,R$(N);AT 21,0;"PRESS ENTER TO CONTINUE :::"
\n2560 SLOW
\n2570 INPUT I$
\n2580 NEXT N
\n2590 GOTO 100
\n2600 FAST
\n2610 PRINT AT 21,0;"DO YOU WANT TO EDIT? "
\n2620 SLOW
\n2630 LET Y$=INKEY$
\n2640 IF Y$="" THEN GOTO 2630
\n2650 IF Y$="N" THEN GOTO 100
\n2660 IF Y$="Y" THEN GOTO 2700
\n2670 GOTO 2630
\n2700 PRINT AT 11,0;"1 - PROJECT","2 - MAGAZINE","3 - MONTH/YR","4 - PAGE NO.","5 - REMARKS"
\n2710 PRINT AT 21,0;"WHICH ONE DO YOU WISH TO EDIT?"
\n2720 LET Y$=INKEY$
\n2730 IF Y$="" THEN GOTO 2720
\n2740 IF CODE Y$<29 OR CODE Y$>36 THEN GOTO 2720
\n2750 GOTO 2800+(VAL Y$*10)
\n2810 PRINT AT 19,0;"OLD PROJECT IS";TAB 32;P$(N);TAB 32;"INPUT NEW INFO ::: "
\n2815 INPUT P$(N)
\n2817 GOTO 2900
\n2820 PRINT AT 19,0;"OLD MAGAZINE IS";TAB 32;M$(N);TAB 32;"INPUT NEW INFO ::: "
\n2825 INPUT M$(N)
\n2827 GOTO 2900
\n2830 PRINT AT 19,0;"OLD MONTH/YR IS";TAB 32;D$(N);TAB 32;"INPUT NEW INFO ::: "
\n2835 INPUT D$(N)
\n2837 GOTO 2900
\n2840 PRINT AT 19,0;"OLD PAGE NO. IS";TAB 32;N$(N);TAB 32;"INPUT NEW INFO ::: "
\n2845 INPUT N$(N)
\n2847 GOTO 2900
\n2880 PRINT AT 19,0;"OLD REMARKS ARE";TAB 32;R$(N);TAB 32;"INPUT NEW INFO ::: "
\n2885 INPUT R$(N)
\n2900 FAST
\n2910 CLS
\n2920 PRINT M$(N);TAB 32;P$(N);TAB 32;D$(N);TAB 32;N$(N);TAB 32;,,R$(N)
\n2930 GOTO 2610
\n2999 GOTO 2999
\n3000 RUN
\n4000 FAST
\n4010 PRINT "WHAT IS THE NAME OF THE FILE?"
\n4015 SLOW
\n4020 INPUT B$
\n4030 PRINT ,,,,"PREPARE THE RECORDER AND THEN","PRESS ENTER ::::"
\n4035 INPUT X$
\n4040 SAVE B$
\n4050 GOTO 100
\n4060 CLEAR
\n4070 SAVE "1032%9"
\n4080 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
