--- title: "Deacons" id: 50609 type: "computer_media" slug: "deacons" url: "http://localhost/computer_media/deacons/" markdown_url: "http://localhost/computer_media/deacons.md" published_at: "2023-06-23T11:26:00+00:00" modified_at: "2026-03-30T21:41:39+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2019/02/20230809-041332.jpg" excerpt: "A full-featured contact directory manager for up to 90 entries supports name, address, phone, state, ZIP, and church committee code searches from a single numeric menu." 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 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" genre: - name: "Database" slug: "database" taxonomy: "genre" url: "http://localhost/type/database/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Deacons%20%28198x%29%28Swoger%2C%20Bob%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2023/06/SCR-20260329-ptpd.png" media_type_tags: "Database" --- # Deacons 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*100` to branch to any of the nine subroutines with a single statement, eliminating a chain of `IF` tests. - **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 `q` is incremented and `INT(q/4)=q/4` is tested; every fourth record triggers a `STOP` with 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 flag `a` is 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 305` re-displays the current record and asks “Are name & address correct?” again. However, this loop does not advance `l`, 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 via `GO 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 only `t$(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. ## 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 ```