This program is a contact directory manager designed for church or congregational use, capable of storing up to 90 records with fields for name, street address, city, state, ZIP code, phone number, and up to four category codes per entry. Each record is packed into fixed-width string arrays: `n$` holds the name, `s$` holds address and phone data in a single packed string (characters 1–19 for street, 20–26 for area code and exchange, 27 onward for the local number), and `t$` holds city, codes, state, and ZIP in a similar packed layout. The menu dispatcher at line 30 uses the expression `GO SUB j*100` to branch directly to one of nine subroutine blocks based on the user’s numeric menu choice, a compact routing technique. Search routines support prefix-matching on names, two-letter state filtering (both inclusive and exclusive), ZIP code lookup, and category code lookup. Deletion is handled by swapping the target record with the last record and decrementing the count variable `d`, avoiding array compaction.
Program Analysis
Program Structure
The program is organized around a central menu dispatcher at lines 10–40. The user selects options 1–9, and line 30 routes execution via GO SUB j*100, mapping each choice to a subroutine block starting at a multiple of 100. The program appears twice in the listing (an artifact of the file), but both copies are functionally identical except that the SAVE at line 915 uses the filename "deacons" in the first copy and "directory" in the second.
| Menu Option | Subroutine | Function |
|---|---|---|
| 1 | 100 | Enter new names |
| 2 | 200 | Change a selected record |
| 3 | 300 | Check/verify all entries |
| 4 | 400 | Search by name prefix |
| 5 | 500 | List names in a state |
| 6 | 600 | List names not in a state |
| 7 | 700 | Search by ZIP code |
| 8 | 800 | Search by category code |
| 9 | 900 | Save directory |
Data Storage Layout
All contact data is stored in three string arrays, with fields packed into fixed character positions within each row. This avoids the overhead of separate arrays per field and keeps all data for one record accessible via a single index l.
| Array | Character Range | Field |
|---|---|---|
n$(l) | entire string | Full name (Last, First) |
s$(l) | 1–19 | Street address |
s$(l) | 20–22 | Area code |
s$(l) | 23 | Hyphen literal (“-“) |
s$(l) | 24–26 | Exchange |
s$(l) | 27 | Hyphen literal (“-“) |
s$(l) | 28– | Local phone number |
t$(l) | 1–19 | City |
t$(l) | 18–21 | Category codes (1 char each, positions p=18..21) |
t$(l) | 23–25 | State abbreviation |
t$(l) | 27–31 | ZIP code |
Note that city occupies positions 1–19 of t$ while category codes are placed at positions 18–21, meaning the last two characters of the city field and the first two category code slots overlap. This is a latent data corruption bug if both city and codes are fully populated.
Key BASIC Idioms and Techniques
- Computed GOSUB dispatch: Line 30 uses
GO SUB j*100to branch to any of the nine subroutines with a single statement, eliminating a chain ofIFtests. - Prefix search: Line 440 uses
w$=n$(l, TO LEN w$)to compare only the leading characters of a name, enabling initial-letter or partial-name lookups. - Paginated display: Lines 465–497 implement a simple 4-record-per-page pager. After displaying a record, variable
qis incremented andINT(q/4)=q/4is tested; every fourth record triggers aSTOPwith a “PRESS CONT” prompt. - Record deletion by swap: The subroutine at lines 660–695 replaces the deleted record with the last record in the array and decrements
d, avoiding the need to shift all subsequent records. - Dual use of variable
a: The flagais set to 1 when the edit subroutine at 330 is called from the single-record change routine (200) rather than from the bulk check loop (300), allowing line 324 to return early after one correction.
Notable Anomalies and Bugs
- Overlapping field definitions in
t$: City is stored in positions 1–19, but category codes begin at position 18. A city name filling all 19 characters will overwrite the first two code slots. - Line 395 loops back to 305 unconditionally: After any correction,
GO TO 305re-displays the current record and asks “Are name & address correct?” again. However, this loop does not advancel, so when called from the bulk-check loop at 300, it will check the same record indefinitely until the user chooses option 8 (“Nothing wrong”) to exit viaGO TO 35. - Lines 540 and 640 call
GO SUB 455: Line 455 is not labeled as a subroutine entry point; it is the mid-flow “NONE FOUND” check inside the name-search block. Jumping into it via GOSUB works because BASIC executes from that line forward, but it is an unconventional structure that could confuse maintenance. - State search stores state at positions 23–25 but compares only 23–24: Input at line 140 accepts characters into
t$(l,23 TO 25), but the search at lines 525 and 625 matches onlyt$(l,23 TO 24). A two-letter code will match correctly, but the extra character at position 25 is silently ignored during search. - Duplicate program listing: The entire program appears twice in the file, with the only difference being the SAVE filename at line 915 (
"deacons"vs."directory"). The interpreter will only see and run the first copy encountered in memory. - Empty code labels at lines 885–889: The category code menu shows entries 4 through 8 as blank, indicating placeholder slots left for the user to customize.
Content
Source Code
10 PRINT AT 2,1;"Please enter code for what is wanted:"
11 PRINT "1. Enter more names"
12 PRINT "2. Change selected name or other data"
13 PRINT "3. Check all entries"
14 PRINT "4. List all names beginning"," with a letter"
15 PRINT "5. List all names in state"
16 PRINT "6. List all names not in state"
17 PRINT "7. List all names by zip code"
18 PRINT "8. List all coded names"
19 PRINT "9. Save revised directory"
20 INPUT j
25 CLS
30 IF j<=9 THEN GO SUB j*100
35 CLS
40 GO TO 10
100 FOR l=d+1 TO 90
102 IF l=91 THEN GO TO 196
105 PRINT AT 4,0;"Type Name (Last, First)"
110 INPUT n$(l)
112 LET d=d+1
115 PRINT AT 6,0;"Street Address"
120 INPUT s$(l, TO 19)
125 PRINT AT 8,0;"City"
130 INPUT t$(l, TO 19)
135 PRINT AT 10,0;"State; Zip"
140 INPUT t$(l,23 TO 25)
141 INPUT t$(l,27 TO )
142 CLS
145 PRINT AT 4,0;"Area Code; Exchange; No."
150 INPUT s$(l,20 TO 22)
151 LET s$(l,23)="-"
152 INPUT s$(l,24 TO 26)
153 INPUT s$(l,28 TO )
154 LET s$(l,27)="-"
155 PRINT AT 6,0;"Any special codes? Y or N"
160 INPUT j$
165 CLS
170 IF j$="Y" THEN GO SUB 750
172 PRINT AT 0,0;l,,n$(l),s$(l),t$(l),,,
175 PRINT "All correct? Y or N"
178 INPUT j$
180 IF j$<>"N" THEN GO TO 184
181 LET a=1
182 GO SUB 330
183 LET a=0
184 CLS
185 PRINT AT 6,0;"Any more names? Y or N"
187 INPUT w$
190 CLS
192 IF w$<>"Y" THEN RETURN
195 NEXT l
196 PRINT "MEMORY FULL"
197 PRINT AT 20,0;"PRESS ""CONT"" TO REGAIN MENU"
198 STOP
199 RETURN
200 PRINT AT 3,0;"Enter register no. of name to be changed"
205 INPUT l
210 PRINT l,,n$(l),s$(l),t$(l),,,
215 LET a=1
220 GO SUB 330
230 RETURN
300 FOR l=1 TO d
301 LET a=0
305 PRINT AT 0,0;l,,n$(l),s$(l),t$(l),,,
310 PRINT "Are name & address correct? Y or N"
315 INPUT j$
320 IF j$="N" THEN GO TO 330
322 CLS
324 IF a=1 THEN RETURN
326 NEXT l
328 RETURN
330 PRINT ,,"What line is wrong?",,,"1. Name",,"2. Street address","3. City",,"4. State",,"5. Zip",,"6. Phone no.",,"7. Code"
331 PRINT "8. Nothing",,"9. Everything - Delete entry"
340 INPUT q
350 IF q=1 THEN INPUT n$(l)
355 IF q=2 THEN INPUT s$(l, TO 19)
360 IF q=3 THEN INPUT t$(l, TO 19)
365 IF q=4 THEN INPUT t$(l,23 TO 25)
370 IF q=5 THEN INPUT t$(l,27 TO 31)
375 IF q=6 THEN INPUT s$(l,20 TO )
380 IF q=7 THEN GO SUB 750
385 IF q=8 THEN GO TO 35
388 IF q=9 THEN GO SUB 660
389 CLS
395 GO TO 305
400 PRINT AT 4,0;"Enter letter(s) or name to be","located"
405 LET q=0
410 INPUT w$
420 CLS
430 FOR l=1 TO d
440 IF w$=n$(l, TO LEN w$) THEN GO SUB 465
450 NEXT l
455 IF q=0 THEN PRINT AT 7,10;"NONE FOUND"
457 PRINT AT 20,0;"PRESS ""CONT"" TO REGAIN MENU"
460 STOP
462 RETURN
465 PRINT l,,n$(l),s$(l),t$(l),,,
470 LET q=q+1
480 IF INT (q/4)=q/4 THEN GO TO 490
485 RETURN
490 PRINT AT 20,0;"PRESS ""CONT"" TO RESUME LISTING"
492 STOP
495 RETURN
497 GO TO 450
500 PRINT AT 5,0;"Enter two letter state code"
505 LET q=0
510 INPUT w$
515 CLS
520 FOR l=1 TO d
525 IF w$=t$(l,23 TO 24) THEN GO SUB 465
530 NEXT l
540 GO SUB 455
550 RETURN
600 PRINT AT 5,0;"Enter two letter state code"
605 LET q=0
610 INPUT w$
615 CLS
620 FOR l=1 TO d
625 IF w$<>t$(l,23 TO 24) THEN GO SUB 465
630 NEXT l
640 GO SUB 455
650 RETURN
660 LET n$(l)=n$(d)
665 LET s$(l)=s$(d)
670 LET t$(l)=t$(d)
675 LET n$(d)=" "
680 LET s$(d)=" "
685 LET t$(d)=" "
690 LET d=d-1
695 RETURN
700 PRINT AT 5,0;"Enter 5 number ZIP"
702 LET q=0
704 INPUT w$
706 CLS
708 FOR l=1 TO d
710 IF w$=t$(l,27 TO (26+LEN w$)) THEN GO SUB 465
712 NEXT l
714 GO SUB 455
716 RETURN
750 CLS
751 GO SUB 880
765 FOR p=18 TO 21
770 INPUT t$(l,p)
775 NEXT p
785 CLS
790 RETURN
800 LET q=0
801 CLS
805 GO SUB 881
810 INPUT a$
812 CLS
815 FOR l=1 TO d
820 FOR p=18 TO 21
825 IF t$(l,p)=a$ THEN GO SUB 465
830 NEXT p
833 NEXT l
845 GO SUB 455
850 RETURN
880 PRINT l,,n$(l),s$(l),t$(l),,,
881 PRINT AT 4,10;"Code Choice",,,
882 PRINT "1. Congregational Services"
883 PRINT "2. Membership Concerns"
884 PRINT "3. Mission & Ministry"
885 PRINT "4. "
886 PRINT "5. "
887 PRINT "6. "
888 PRINT "7. "
889 PRINT "8. "
890 RETURN
900 PRINT ,,"IF ""SAVE"" IS WANTED, ENTER ""1"""
910 INPUT e
915 IF e=1 THEN SAVE "deacons"
917 CLS
920 GO TO 10
10 PRINT AT 2,1;"Please enter code for what is wanted:"
11 PRINT "1. Enter more names"
12 PRINT "2. Change selected name or other data"
13 PRINT "3. Check all entries"
14 PRINT "4. List all names beginning"," with a letter"
15 PRINT "5. List all names in state"
16 PRINT "6. List all names not in state"
17 PRINT "7. List all names by zip code"
18 PRINT "8. List all coded names"
19 PRINT "9. Save revised directory"
20 INPUT j
25 CLS
30 IF j<=9 THEN GO SUB j*100
35 CLS
40 GO TO 10
100 FOR l=d+1 TO 90
102 IF l=91 THEN GO TO 196
105 PRINT AT 4,0;"Type Name (Last, First)"
110 INPUT n$(l)
112 LET d=d+1
115 PRINT AT 6,0;"Street Address"
120 INPUT s$(l, TO 19)
125 PRINT AT 8,0;"City"
130 INPUT t$(l, TO 19)
135 PRINT AT 10,0;"State; Zip"
140 INPUT t$(l,23 TO 25)
141 INPUT t$(l,27 TO )
142 CLS
145 PRINT AT 4,0;"Area Code; Exchange; No."
150 INPUT s$(l,20 TO 22)
151 LET s$(l,23)="-"
152 INPUT s$(l,24 TO 26)
153 INPUT s$(l,28 TO )
154 LET s$(l,27)="-"
155 PRINT AT 6,0;"Any special codes? Y or N"
160 INPUT j$
165 CLS
170 IF j$="Y" THEN GO SUB 750
172 PRINT AT 0,0;l,,n$(l),s$(l),t$(l),,,
175 PRINT "All correct? Y or N"
178 INPUT j$
180 IF j$<>"N" THEN GO TO 184
181 LET a=1
182 GO SUB 330
183 LET a=0
184 CLS
185 PRINT AT 6,0;"Any more names? Y or N"
187 INPUT w$
190 CLS
192 IF w$<>"Y" THEN RETURN
195 NEXT l
196 PRINT "MEMORY FULL"
197 PRINT AT 20,0;"PRESS ""CONT"" TO REGAIN MENU"
198 STOP
199 RETURN
200 PRINT AT 3,0;"Enter register no. of name to be changed"
205 INPUT l
210 PRINT l,,n$(l),s$(l),t$(l),,,
215 LET a=1
220 GO SUB 330
230 RETURN
300 FOR l=1 TO d
301 LET a=0
305 PRINT AT 0,0;l,,n$(l),s$(l),t$(l),,,
310 PRINT "Are name & address correct? Y or N"
315 INPUT j$
320 IF j$="N" THEN GO TO 330
322 CLS
324 IF a=1 THEN RETURN
326 NEXT l
328 RETURN
330 PRINT ,,"What line is wrong?",,,"1. Name",,"2. Street address","3. City",,"4. State",,"5. Zip",,"6. Phone no.",,"7. Code"
331 PRINT "8. Nothing",,"9. Everything - Delete entry"
340 INPUT q
350 IF q=1 THEN INPUT n$(l)
355 IF q=2 THEN INPUT s$(l, TO 19)
360 IF q=3 THEN INPUT t$(l, TO 19)
365 IF q=4 THEN INPUT t$(l,23 TO 25)
370 IF q=5 THEN INPUT t$(l,27 TO 31)
375 IF q=6 THEN INPUT s$(l,20 TO )
380 IF q=7 THEN GO SUB 750
385 IF q=8 THEN GO TO 35
388 IF q=9 THEN GO SUB 660
389 CLS
395 GO TO 305
400 PRINT AT 4,0;"Enter letter(s) or name to be","located"
405 LET q=0
410 INPUT w$
420 CLS
430 FOR l=1 TO d
440 IF w$=n$(l, TO LEN w$) THEN GO SUB 465
450 NEXT l
455 IF q=0 THEN PRINT AT 7,10;"NONE FOUND"
457 PRINT AT 20,0;"PRESS ""CONT"" TO REGAIN MENU"
460 STOP
462 RETURN
465 PRINT l,,n$(l),s$(l),t$(l),,,
470 LET q=q+1
480 IF INT (q/4)=q/4 THEN GO TO 490
485 RETURN
490 PRINT AT 20,0;"PRESS ""CONT"" TO RESUME LISTING"
492 STOP
495 RETURN
497 GO TO 450
500 PRINT AT 5,0;"Enter two letter state code"
505 LET q=0
510 INPUT w$
515 CLS
520 FOR l=1 TO d
525 IF w$=t$(l,23 TO 24) THEN GO SUB 465
530 NEXT l
540 GO SUB 455
550 RETURN
600 PRINT AT 5,0;"Enter two letter state code"
605 LET q=0
610 INPUT w$
615 CLS
620 FOR l=1 TO d
625 IF w$<>t$(l,23 TO 24) THEN GO SUB 465
630 NEXT l
640 GO SUB 455
650 RETURN
660 LET n$(l)=n$(d)
665 LET s$(l)=s$(d)
670 LET t$(l)=t$(d)
675 LET n$(d)=" "
680 LET s$(d)=" "
685 LET t$(d)=" "
690 LET d=d-1
695 RETURN
700 PRINT AT 5,0;"Enter 5 number ZIP"
702 LET q=0
704 INPUT w$
706 CLS
708 FOR l=1 TO d
710 IF w$=t$(l,27 TO (26+LEN w$)) THEN GO SUB 465
712 NEXT l
714 GO SUB 455
716 RETURN
750 CLS
751 GO SUB 880
765 FOR p=18 TO 21
770 INPUT t$(l,p)
775 NEXT p
785 CLS
790 RETURN
800 LET q=0
801 CLS
805 GO SUB 881
810 INPUT a$
812 CLS
815 FOR l=1 TO d
820 FOR p=18 TO 21
825 IF t$(l,p)=a$ THEN GO SUB 465
830 NEXT p
833 NEXT l
845 GO SUB 455
850 RETURN
880 PRINT l,,n$(l),s$(l),t$(l),,,
881 PRINT AT 4,10;"Code Choice",,,
882 PRINT "1. Congregational Services"
883 PRINT "2. Membership Concerns"
884 PRINT "3. Mission & Ministry"
885 PRINT "4. "
886 PRINT "5. "
887 PRINT "6. "
888 PRINT "7. "
889 PRINT "8. "
890 RETURN
900 PRINT ,,"IF ""SAVE"" IS WANTED, ENTER ""1"""
910 INPUT e
915 IF e=1 THEN SAVE "directory"
917 CLS
920 GO TO 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
