--- title: "File" id: 57644 type: "computer_media" slug: "file" url: "http://localhost/computer_media/file/" markdown_url: "http://localhost/computer_media/file.md" published_at: "2024-10-06T01:16:42+00:00" modified_at: "2026-03-30T21:16:39+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/file.png" excerpt: "An address book storing 100 contacts across eight parallel string arrays, with partial-name search and field-by-field editing dispatched via computed GOTO." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" indiv: - name: "Gene G. Buza" slug: "gene-g-buza" taxonomy: "indiv" url: "http://localhost/indiv/gene-g-buza/" genre: - name: "Database" slug: "database" taxonomy: "genre" url: "http://localhost/type/database/" media_contents: - id: 56727 title: "Synchro-Sette October 1982" type: "computer_media" url: "http://localhost/computer_media/synchro-sette-october-1982/" media_type: "Program" programmers: - name: "Gene G. Buza" slug: "gene-g-buza" taxonomy: "indiv" url: "http://localhost/indiv/gene-g-buza/" mediadate: "October 1982" images: - url: "http://localhost/wp-content/uploads/2024/10/file.png" media_type_tags: "Database, Software" --- # File 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`: 1. **Initialisation (lines 4–100):** Arrays are dimensioned, the record counter `R1` is set to zero, and the main menu is drawn. 2. **Data entry (lines 1000–1920):** A `FOR N=R1+1 TO T` loop collects eight fields per record using alternating `SLOW`/`FAST` and `SCROLL` to page through the limited display. 3. **View / search / edit (lines 2000–2999):** The user chooses whole-file browse or name search; an edit sub-menu at line `2700` allows individual field correction. 4. **Clear file (line 3000):** A bare `RUN` resets everything by restarting the program. 5. **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 line `230` multiplies 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 line `2750` dispatches to lines 2810, 2820 … 2880 depending on which field number (1–8) was entered. - **Partial-name matching:** Line `2170` uses `X$(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 `210` and `2740` test `CODE 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 `INPUT` is bracketed by `SLOW` before and `FAST` after 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 in `R1` at line `1900`. ### 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 `FOR` loop at line `1000` exhausts naturally and falls through to `GOTO 100` at line `1810` without updating `R1`, leaving it at its previous value. Only the blank-entry exit path at line `1900` correctly records the count. - **Line 2999 infinite loop:**`GOTO 2999` is an intentional dead-end guard after the edit section, presumably to prevent fall-through into the clear routine at line `3000`. ## 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 ```