--- title: "Address" id: 57160 type: "computer_media" slug: "address" url: "http://localhost/computer_media/address/" markdown_url: "http://localhost/computer_media/address.md" published_at: "2024-10-04T01:04:13+00:00" modified_at: "2026-04-03T07:58:42+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/109_Addr.png" excerpt: "A compact address-book utility that routes between Add, Change, Review, and Save modes using a single calculated GOTO driven by ASCII arithmetic." 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/" genre: - name: "Database" slug: "database" taxonomy: "genre" url: "http://localhost/type/database/" media_contents: - id: 56733 title: "Timex Sinclair Public Domain Library Tape 1002" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1002/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/10/109_Addr.png" media_type_tags: "Database" --- # Address This program implements a simple address-book manager using a two-dimensional string array to store up to ten 25-character records. Navigation between the Add, Change, Review, and Save functions is achieved with a calculated GOTO using CODE B$*100, which jumps to line 3800 (Add), 4000 (Change), 5500 (Review), or 5600 (Save) based on the ASCII value of the first letter typed. Records are indexed by a counter variable K for adding and by a user-supplied entry number for editing. The SAVE command stores the program to tape with a filename that includes inverse characters acting as an auto-run trigger. *** ## Program Analysis ### Program Structure The program is organised into five functional blocks, each beginning at a line number that is a multiple of the ASCII code of the mode’s initial letter multiplied by 100: | Line range | Mode | Initial letter | CODE × 100 | | --- | --- | --- | --- | | 3800–3840 | Add | A (65) | 6500 — see note | | 4000–4030 | Change | C (67) | 6700 — see note | | 5500–5550 | Review | R (82) | 8200 — see note | | 5600–5610 | Save | S (83) | 8300 — see note | | 6000–6020 | Entry edit | — | shared subroutine | **Note:** The dispatch expression `GOTO CODE B$*100` does *not* actually reach the intended blocks. The ASCII values of ‘A’, ‘C’, ‘R’, and ‘S’ are 65, 67, 82, and 83 respectively, giving target lines 6500, 6700, 8200, and 8300 — none of which exist. The intended targets (3800, 4000, 5500, 5600) would require dividing by 100 and then using the result differently, or the line numbers should have been 6500, 6700, 8200, and 8300. As written, line 60 causes a “Variable not found” or “No such line” error for any valid input, making the dispatch mechanism non-functional. ### Data Storage Line 10 declares `A$(10,25)`, a two-dimensional string array holding ten records of 25 characters each. Line 20 declares `B$(1)` as a one-character string used to capture the mode selector at the main menu. The counter `K` (initialised at line 5) tracks how many entries have been added and is incremented at line 3800 before each new addition. ### Notable Techniques - **Computed GOTO dispatch:** Line 60 uses `GOTO CODE B$*100` to branch based on the ASCII value of the first character of input. This is a classic BASIC trick for building menu-driven programs without a chain of IF statements, though the arithmetic here produces incorrect target line numbers (see bug note above). - **Shared entry-edit block:** Both Add (line 3840) and Change (line 4020) jump to line 6000 with `E` set to the target record index, effectively using it as a simple subroutine without `GO SUB`/`RETURN`. - **Linear search in Review:** Lines 5520–5540 loop through all `K` entries comparing the first character of each record (`A$(X,1)`) against the search key `B$`, printing matching rows with their index number. - **Bounds checking:** Line 3820 prevents overflow beyond ten records by redirecting to the main menu if `K>10`. Line 4020 validates the entered entry number to the range 1–10. ### Bugs and Anomalies - **Fatal dispatch error:** The core dispatch at line 60 (`GOTO CODE B$*100`) always targets non-existent lines. The program as listed cannot successfully navigate to any mode. The line numbers of the mode blocks would need to be 6500, 6700, 8200, and 8300 (or the formula corrected) to function. - **One-character menu input:**`B$(1)` is declared as length 1, so only the first character of any input is retained. This is intentional for the dispatch mechanism but is fragile if the user enters a lowercase letter, since `CODE "a"` (97) differs from `CODE "A"` (65). - **K initialised only at line 5:**`K` is set to 0 once at startup. If SAVE is used and the program reloaded, `K` will restart from 0 even though `A$` may contain existing data, potentially overwriting records. - **Review overwrites B$:** Line 5510 inputs into `B$`, which also serves as the mode selector. This is harmless given the flow, but could confuse anyone modifying the code. - **Add counter off-by-one risk:**`K` is incremented *before* the bounds check at line 3820, so when K reaches 11 the overflow check triggers correctly, but K is left at 11 rather than being reset or clamped. ## Source Code ``` 1 REM ADDRESS 2 REM DONT ENTER ANYTHING BESIDES %A%,%C%,%R%,%S%, SINCE PROGRAM WILL CRASH. TO REVIEW, PROGRAM WILL ASK FOR A"KEY". THEN TYPE IN FIRST LETTER OR NUMBER OF DATA. TO CHANGE PROGRAM WILL ASK FOR ENTRY NUMBER" YOU MUST USE REVIEW TO IND THE ENTRY NO.TO ALTER DATA ETERED. 5 LET K=0 10 DIM A$(10,25) 20 DIM B$(1) 30 PRINT "ADD,CHANGE,REVIEW,SAVE" 40 INPUT B$ 50 CLS 60 GOTO CODE B$*100 3800 LET K=K+1 3820 IF K>10 THEN GOTO 30 3830 LET E=K 3840 GOTO 6000 4000 PRINT "ENTRY NUMBER" 4010 INPUT E 4020 IF E>0 AND E<11 THEN GOTO 6000 4030 GOTO 30 5500 PRINT "KEY" 5510 INPUT B$ 5520 FOR X=1 TO K 5530 IF A$(X,1)=B$ THEN PRINT X;"";A$(X) 5540 NEXT X 5550 GOTO 30 5600 SAVE "1010%9" 5610 GOTO 30 6000 PRINT "NEW ENTRY" 6010 INPUT A$(E) 6020 GOTO 30 ```