This program implements a name-and-address database manager capable of storing up to 100 records, each consisting of eight fields: last name, first name, address, city/town, state, ZIP code, telephone number, and remarks. Data is held in eight parallel string arrays dimensioned at line 10–80, with field widths ranging from 2 to 16 characters. The menu system uses key-code comparison (CODE I$ checked against values 29–32 for keys 1–4) and a computed GOTO via GOTO 1000*VAL I$ to dispatch to the four main routines. A partial-name search at line 2170 uses a string slice X$(TO LEN I$) to match leading characters rather than requiring an exact entry; editing is dispatched with GOTO 2800+(VAL Y$*10), jumping directly to the handler for whichever field number was pressed.
Program Structure
The program is divided into five logical sections, entered via a computed dispatch at line 230:
- Initialisation (lines 4–100): Arrays are dimensioned, the record counter
R1is set to zero, and the main menu is drawn. - Data entry (lines 1000–1920): A
FOR N=R1+1 TO Tloop collects eight fields per record using alternatingSLOW/FASTandSCROLLto page through the limited display. - View / search / edit (lines 2000–2999): The user chooses whole-file browse or name search; an edit sub-menu at line
2700allows individual field correction. - Clear file (line 3000): A bare
RUNresets everything by restarting the program. - Save to tape (lines 4000–4050): Prompts for a filename and issues
SAVE B$.
Array Layout
| Array | Field | Width (chars) |
|---|---|---|
L$ | Last name | 16 |
F$ | First name | 12 |
A$ | Address | 16 |
C$ | City/Town | 16 |
S$ | State | 2 |
Z$ | ZIP code | 5 |
T$ | Telephone | 12 |
R$ | Remarks | 12 |
All arrays share the same first dimension T=100, declared at line 5. Total string storage is 100 × (16+12+16+16+2+5+12+12) = 9,100 bytes.
Key BASIC Idioms
- Computed GOTO for menu dispatch:
GOTO 1000*VAL I$at line230multiplies the digit pressed (1–4) to jump directly to the routine at 1000, 2000, 3000, or 4000. - Computed GOTO for field editing:
GOTO 2800+(VAL Y$*10)at line2750dispatches to lines 2810, 2820 … 2880 depending on which field number (1–8) was entered. - Partial-name matching: Line
2170usesX$(TO LEN I$)— a leading-substring slice — so the user can search by typing only the start of a last name. - Key-code gating: Lines
210and2740testCODE I$rather than the character itself; ZX81 key codes 29–32 correspond to digits 1–4, and 29–36 to digits 1–8. - SLOW/FAST toggling: Every
INPUTis bracketed bySLOWbefore andFASTafter to enable keyboard scanning without sacrificing display speed during processing. - Blank-entry sentinel: At line
1055, an empty last-name input (X$="") terminates the entry loop and stores the count inR1at line1900.
Display Techniques
The title banner at lines 105–115 uses ZX81 block-graphic escape sequences to draw a bordered box with ▌, ▀, and ▟ characters. A second smaller box is drawn inline at line 160 using AT co-ordinates to frame the “ENTER ONE OF ABOVE” prompt. The flashing-text effect at line 180 is achieved by reprinting the same prompt with each character surrounded by % signs, which on the ZX81 selects inverse video, creating an alternating highlight when the line is rewritten over line 170.
Record display at lines 2320 and 2550 uses TAB 32 to force each field onto a new line (since the ZX81 display is 32 columns wide, TAB 32 wraps to the next line), giving a clean multi-line card layout without explicit AT positioning for each field.
Bugs and Anomalies
- R1 not updated on normal loop completion: If all 100 slots are filled, the
FORloop at line1000exhausts naturally and falls through toGOTO 100at line1810without updatingR1, leaving it at its previous value. Only the blank-entry exit path at line1900correctly records the count. - Line 2999 infinite loop:
GOTO 2999is an intentional dead-end guard after the edit section, presumably to prevent fall-through into the clear routine at line3000.
Content
Source Code
4 FAST
5 LET T=100
10 DIM L$(T,16)
20 DIM F$(T,12)
30 DIM A$(T,16)
40 DIM C$(T,16)
50 DIM S$(T,2)
60 DIM Z$(T,5)
70 DIM T$(T,12)
80 DIM R$(T,12)
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"
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$
1000 FOR N=R1+1 TO T
1010 SCROLL
1020 PRINT "NO.";N;" LAST NAME?"
1030 SLOW
1040 INPUT X$
1050 FAST
1055 IF X$="" THEN GOTO 1900
1057 LET L$(N)=X$
1060 SCROLL
1070 PRINT L$(N)
1080 SCROLL
1090 SCROLL
1100 SCROLL
1110 PRINT "FIRST NAME?"
1120 SLOW
1130 INPUT F$(N)
1140 FAST
1150 SCROLL
1160 PRINT F$(N)
1170 SCROLL
1180 SCROLL
1200 SCROLL
1210 PRINT "ADDRESS?"
1220 SLOW
1230 INPUT A$(N)
1240 FAST
1250 SCROLL
1260 PRINT A$(N)
1270 SCROLL
1280 SCROLL
1300 SCROLL
1310 PRINT "CITY/TOWN?"
1320 SLOW
1330 INPUT C$(N)
1340 FAST
1350 SCROLL
1360 PRINT C$(N)
1370 SCROLL
1380 SCROLL
1400 SCROLL
1410 PRINT "STATE?"
1420 SLOW
1430 INPUT S$(N)
1440 FAST
1450 SCROLL
1460 PRINT S$(N)
1470 SCROLL
1480 SCROLL
1500 SCROLL
1510 PRINT "ZIP CODE?"
1520 SLOW
1530 INPUT Z$(N)
1540 FAST
1550 SCROLL
1560 PRINT Z$(N)
1570 SCROLL
1580 SCROLL
1600 SCROLL
1610 PRINT "TELEPHONE NO.?"
1620 SLOW
1630 INPUT T$(N)
1640 FAST
1650 SCROLL
1660 PRINT T$(N)
1670 SCROLL
1680 SCROLL
1700 SCROLL
1710 PRINT "REMARKS?"
1720 SLOW
1730 INPUT R$(N)
1740 FAST
1750 SCROLL
1760 PRINT R$(N)
1770 SCROLL
1780 SCROLL
1800 NEXT N
1810 GOTO 100
1900 LET R1=N-1
1910 SLOW
1920 GOTO 100
2000 CLS
2005 SLOW
2010 PRINT AT 11,2;"DO YOU WANT TO SEE THE WHOLE";AT 12,14;"FILE?"
2020 LET I$=INKEY$
2030 IF I$="" THEN GOTO 2020
2040 IF I$="Y" THEN GOTO 2500
2050 IF I$="N" THEN GOTO 2100
2060 GOTO 2020
2100 FAST
2110 CLS
2120 PRINT AT 11,5;"WHAT IS THE LAST NAME?"
2130 SLOW
2140 INPUT I$
2145 FAST
2150 FOR N=1 TO R1
2160 LET X$=L$(N)
2170 IF I$=X$( TO LEN I$) THEN GOTO 2300
2180 NEXT N
2185 CLS
2190 PRINT AT 11,6;"NAME NOT IN FILE?";AT 21,0;"PRESS ENTER TO CONTINUE :::::"
2195 SLOW
2200 INPUT I$
2210 GOTO 100
2300 FAST
2310 CLS
2320 PRINT F$(N);TAB 32;L$(N);TAB 32;A$(N);TAB 32;C$(N);TAB 32;S$(N);" ";Z$(N);" ";T$(N);TAB 32;,,R$(N)
2330 PRINT AT 21,0;"IS THIS THE CORRECT NAME?"
2335 SLOW
2340 LET Y$=INKEY$
2350 IF Y$="" THEN GOTO 2340
2360 IF Y$="Y" THEN GOTO 2600
2370 IF Y$="N" THEN GOTO 2180
2380 GOTO 2340
2500 FAST
2510 CLS
2520 FOR N=1 TO R1
2530 FAST
2535 CLS
2540 PRINT "CUSTOMER NO.";N;" OF ";R1,,,,,
2550 PRINT F$(N);TAB 32;L$(N);TAB 32;A$(N);TAB 32;C$(N);TAB 32;S$(N);" ";Z$(N);" ";T$(N);TAB 32;,,R$(N);AT 21,0;"PRESS ENTER TO CONTINUE :::"
2560 SLOW
2570 INPUT I$
2580 NEXT N
2590 GOTO 100
2600 FAST
2610 PRINT AT 21,0;"DO YOU WANT TO EDIT? "
2620 SLOW
2630 LET Y$=INKEY$
2640 IF Y$="" THEN GOTO 2630
2650 IF Y$="N" THEN GOTO 100
2660 IF Y$="Y" THEN GOTO 2700
2670 GOTO 2630
2700 PRINT AT 11,0;"1 - LAST NAME","5 - STATE","2 - FIRST NAME","6 - ZIP CODE","3 - ADDRESS","7 - PHONE NO.","4 - CITY/TOWN","8 - REMARKS"
2710 PRINT AT 21,0;"WHICH ONE DO YOU WISH TO EDIT?"
2720 LET Y$=INKEY$
2730 IF Y$="" THEN GOTO 2720
2740 IF CODE Y$<29 OR CODE Y$>36 THEN GOTO 2720
2750 GOTO 2800+(VAL Y$*10)
2810 PRINT AT 19,0;"OLD LAST NAME IS";TAB 32;L$(N);TAB 32;"INPUT NEW INFO ::: "
2815 INPUT L$(N)
2817 GOTO 2900
2820 PRINT AT 19,0;"OLD FIRST NAME IS";TAB 32;F$(N);TAB 32;"INPUT NEW INFO ::: "
2825 INPUT F$(N)
2827 GOTO 2900
2830 PRINT AT 19,0;"OLD ADDRESS IS";TAB 32;A$(N);TAB 32;"INPUT NEW INFO ::: "
2835 INPUT A$(N)
2837 GOTO 2900
2840 PRINT AT 19,0;"OLD CITY/TOWN IS";TAB 32;C$(N);TAB 32;"INPUT NEW INFO ::: "
2845 INPUT C$(N)
2847 GOTO 2900
2850 PRINT AT 19,0;"OLD STATE IS";TAB 32;S$(N);TAB 32;"INPUT NEW INFO ::: "
2855 INPUT S$(N)
2857 GOTO 2900
2860 PRINT AT 19,0;"OLD ZIP CODE IS";TAB 32;Z$(N);TAB 32;"INPUT NEW INFO ::: "
2865 INPUT Z$(N)
2867 GOTO 2900
2870 PRINT AT 19,0;"OLD PHONE NO. IS";TAB 32;T$(N);TAB 32;"INPUT NEW INFO ::: "
2875 INPUT T$(N)
2877 GOTO 2900
2880 PRINT AT 19,0;"OLD REMARKS ARE";TAB 32;R$(N);TAB 32;"INPUT NEW INFO ::: "
2885 INPUT R$(N)
2900 FAST
2910 CLS
2920 PRINT F$(N);TAB 32;L$(N);TAB 32;A$(N);TAB 32;C$(N);TAB 32;S$(N);" ";Z$(N);" ";T$(N);TAB 32;,,R$(N)
2930 GOTO 2610
2999 GOTO 2999
3000 RUN
4000 FAST
4010 PRINT "WHAT IS THE NAME OF THE FILE?"
4015 SLOW
4020 INPUT B$
4030 PRINT ,,,,"PREPARE THE RECORDER AND THEN","PRESS ENTER ::::"
4035 INPUT X$
4040 SAVE B$
4050 GOTO 100
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
