The Address Book

Date: 198x
Type: Program
Platform(s): TS 2068
Tags: Database

Keeps an address file of up to 250 entries, each holding a name, street, city and state, zip code and phone number. From the menu you can add entries, edit any field of an entry found by name, show one entry or the whole file on screen, and print either address labels or a full list. The phone number is typed digit by digit and the program inserts the slash and dash itself. The whole file is saved to and loaded from tape as one string array, and a help screen explains each option.

The program carries no author credit; its REM title is “THE ADDRESS BOOK”. It was found on a public-domain disk in an Oliger-equipped TS2068 owner’s collection.

Program Analysis

Structure

  • Lines 1–13: colours, the printer flag prntr, and the arrays: a$(250,5,20) for the file, t$(12) for phone entry and c$(3,20) for the search name and the two forms of “all”.
  • Lines 15–38: the menu, polled with a chain of INKEY$ tests that accept upper or lower case.
  • Lines 44–94: input. Line 45 skips to the first empty record, and lines 69–86 build the phone number from single keypresses.
  • Lines 140–169: display, print list and label routines, all walking the array from the start and matching a name or A/a for all.
  • Lines 170–195: the editor, which finds a record by exact name and replaces one field at a time.
  • Lines 200–219: SAVE z$ DATA a$() and LOAD z$ DATA a$(); lines 250–276: help; lines 290–292: printer width switch.

Data Layout

Each record is five 20-character strings in one three-dimensional string array, so the file takes about 25 KB whether it is full or empty. An empty record is detected by comparing the name with 20 spaces, which is also how the display and print loops know they have reached the end of the file.

Notable Techniques

  • The phone field is pre-filled with & markers; PAUSE 0 and INKEY$ read each digit, and positions 4 and 8 are filled with / and - automatically.
  • Search accepts either a full name or A/a, held in c$(2) and c$(3), so one comparison line serves single and all-records output.
  • The array is saved with its contents, so a data tape is simply a DATA file of the whole address book.

Potential Issues

  • Names must match exactly, including trailing spaces, so a search only finds an entry typed the same way.
  • Phone entry accepts any key, including ENTER or letters, and has no way to correct a mistake other than editing the field afterwards.
  • The label routine stops after the first label when a single name is given, but when printing all it relies on the next empty record to end.
  • Option C only changes the “40/80 Column Printer Enabled” note; the output itself is the same.

This program came from an Oliger (JLO SAFE) disk and was converted to load from tape. The Oliger printer-selection statements (LET /P=O/B, LET /P=T) were removed, the slashes were dropped from the data SAVE and LOAD, the “to JLO Disc” messages now say tape, and the empty saved array was left out because the program creates it at start. It was tested in ZEsarUX.

Image Gallery

Source Code

    1 REM ** THE ADDRESS BOOK **
    2 BORDER 0: PAPER 0: INK 7
    3 CLS 
    4 LET prntr=80
    5 LET a=0
    7 LET f=0
    8 LET t=12
    9 DIM t$(t)
   10 DIM a$(250,5,20)
   11 DIM c$(3,20)
   12 LET c$(2)="A"
   13 LET c$(3)="a"
   15 CLS : LET f=0
   16 PRINT AT 3,13;"MENU";TAB 0;"  "
   17 PRINT "A: Print Address Labels"
   18 PRINT "C: Change Print Device"
   19 PRINT "D: Display Address List"
   20 PRINT "E: Edit Address Data";TAB 0;"H: Help"
   22 PRINT "I: Input Address Data";TAB 0;"L: Load Data Tape"
   23 PRINT "P: Print Address List";TAB 0;"Q: Quit"
   24 PRINT "S: Save Data Tape";TAB 0;" "
   25 PRINT "SELECT YOUR DESIRED FUNCTION";TAB 0;" "
   26 IF prntr=80 THEN PRINT "80 Column Printer Enabled"
   27 IF prntr=40 THEN PRINT "40 Column Printer Enabled"
   28 IF INKEY$="A" OR INKEY$="a" THEN GO TO 160
   29 IF INKEY$="D" OR INKEY$="d" THEN GO TO 140
   30 IF INKEY$="E" OR INKEY$="e" THEN GO TO 170
   31 IF INKEY$="H" OR INKEY$="h" THEN GO TO 250
   32 IF INKEY$="I" OR INKEY$="i" THEN GO TO 44
   33 IF INKEY$="L" OR INKEY$="l" THEN GO TO 210
   34 IF INKEY$="P" OR INKEY$="p" THEN GO TO 150
   35 IF INKEY$="Q" OR INKEY$="q" THEN GO TO 300
   36 IF INKEY$="S" OR INKEY$="s" THEN GO TO 200
   37 IF INKEY$="C" OR INKEY$="c" THEN GO TO 290
   38 GO TO 28
   44 REM * Input Data Routine *
   45 CLS : IF a$(a+1,1)<>"                    " AND a<250 THEN LET a=a+1: GO TO 45
   46 IF a>=250 THEN PRINT AT 10,0;"The address file is full. It    contains 250 persons, places or things!": GO TO 15
   50 INPUT "Enter Name";a$(a+1,1)
   51 PRINT AT 0,0;"NAME:       ";a$(a+1,1)
   60 INPUT "Enter Street Address";a$(a+1,2)
   61 PRINT "STREET NO:  ";a$(a+1,2)
   65 INPUT "Enter City, State";a$(a+1,3)
   66 PRINT "CITY/STATE: ";a$(a+1,3)
   67 INPUT "Enter Zip Code";a$(a+1,4)
   68 PRINT "ZIP CODE:   ";a$(a+1,4)
   69 LET t=1
   70 LET t$(t)="&": LET t=t+1: IF t<>12 THEN GO TO 70
   74 PRINT "PHONE NO:   "
   75 PRINT AT 21,0;"Enter Telephone Number": LET t=1
   76 PAUSE 0
   77 LET t$(t)=INKEY$
   78 IF t$(t)<>"&" THEN GO TO 83
   79 GO TO 76
   83 PRINT AT 4,11+t;t$(t): LET t=t+1
   84 IF t=4 THEN PRINT AT 4,15;"/": LET t$(t)="/": LET t=5
   85 IF t=8 THEN PRINT AT 4,19;"-": LET t$(t)="-": LET t=9
   86 IF t<13 THEN GO TO 76
   87 PRINT AT 21,0;"                       "
   90 LET a$(a+1,5)=t$
   92 PRINT "PRESS SPACE-BAR FOR MENU"
   93 IF INKEY$=" " THEN GO TO 15
   94 GO TO 93
  140 REM * Display Routine *
  141 LET z$="y": LET cnt=3: CLS : LET a=0: INPUT "Enter Name Desired Or A(ll)";c$(1)
  142 IF (c$(1)=c$(2) OR c$(1)=c$(3) OR c$(1)=a$(a+1,1)) THEN PRINT a$(a+1,1);TAB 0;a$(a+1,2);TAB 0;a$(a+1,3);TAB 0;a$(a+1,4);TAB 0;a$(a+1,5);TAB 0;" "
  143 LET cnt=cnt-1: IF cnt<=0 THEN LET cnt=3: INPUT "[more? Y or N]";z$: IF z$="Y" OR z$="y" THEN CLS 
  144 IF z$="n" OR z$="N" THEN PAUSE 100: GO TO 15
  145 IF INKEY$=" " THEN GO TO 15
  146 IF a$(a+1,1)="                    " THEN PRINT AT 17,0;"No Other Names Are Currently On File";TAB 0;" ";TAB 0;"PRESS SPACE-BAR FOR MENU": GO TO 145
  147 LET a=a+1: IF INKEY$=" " THEN GO TO 15
  148 IF a>=250 THEN LET a=0: PRINT AT 10,0;"The file for "; c$(1);TAB 0;"cannot be located.";TAB 0;" ";TAB 0;"PRESS SPACE-BAR FOR MENU": GO TO 147
  149 GO TO 142
  150 REM  * Print Routine *
  151 CLS : LET a=0: INPUT "Enter Name Desired Or A(ll)";c$(1)
  152 IF (c$(1)=c$(2) OR c$(1)=c$(3) OR c$(1)=a$(a+1,1)) THEN LPRINT a$(a+1,1): LPRINT a$(a+1,2): LPRINT a$(a+1,3): LPRINT "          ";a$(a+1,4): LPRINT a$(a+1,5): LPRINT " ": LET f=1
  154 LET a=a+1
  155 IF a$(a,1)="                    " THEN LPRINT "  This Concludes The List  ": GO TO 15
  156 IF INKEY$=" " THEN GO TO 15
  157 IF a>=250 THEN LET a=0: PRINT AT 10,0;"The file for "; c$(1);TAB 0;"cannot be located.";TAB 0;" ";TAB 0;"PRESS SPACE-BAR FOR MENU": GO TO 156
  159 GO TO 152
  160 REM  * Label Routine *
  161 CLS : LET a=0: INPUT "Enter Name Desired Or A(ll)";c$(1)
  162 IF (c$(1)=c$(2) OR c$(1)=c$(3) OR c$(1)=a$(a+1,1)) THEN LPRINT a$(a+1,1): LPRINT a$(a+1,2): LPRINT a$(a+1,3): LPRINT "          ";a$(a+1,4): LPRINT "": LPRINT ""
  164 IF (c$(1)<>c$(2) AND c$(1)<>c$(3)) OR a$(a+1,1)="                    " THEN GO TO 15
  165 LET a=a+1
  166 IF INKEY$=" " THEN GO TO 15
  167 IF a>=250 THEN LET a=0: PRINT AT 10,0;"The file for "; c$(1);TAB 0;"cannot be located.";TAB 0;" ";TAB 0;"PRESS SPACE-BAR FOR MENU": GO TO 166
  169 GO TO 162
  170 REM  * Editor Routine *
  171 CLS : INPUT "Enter Name Desired For Editing";c$(1)
  172 PRINT c$(1): LET a=0
  175 IF a$(a+1,1)=c$(1) THEN PRINT AT 2,0;"THIS FILE CONTAINS:";TAB 0;"1. NAME:       ";a$(a+1,1);TAB 0;"2. STREET NO:  ";a$(a+1,2);TAB 0;"3. CITY/STATE: ";a$(a+1,3);TAB 0;"4. ZIP CODE:   ";a$(a+1,4);TAB 0;"5. PHONE NO:   ";a$(a+1,5);TAB 0;"6. PRESS TO RETURN TO MENU": GO TO 180
  176 LET a=a+1
  177 IF a>=250 THEN LET a=0: PRINT AT 10,0;"The file for "; c$(1);TAB 0;"cannot be located.";TAB 0;" ";TAB 0;"PRESS SPACE-BAR FOR MENU"
  178 IF INKEY$=" " THEN GO TO 15
  179 GO TO 175
  180 INPUT "ENTER THE NUMBER FOR THE DATA THAT YOU WISH TO EDIT";D$
  181 IF d$<>"1" AND d$<>"2" AND d$<>"3" AND d$<>"4" AND d$<>"5" AND d$<>"6" THEN PRINT AT 14,0;"IMPROPER ENTRY! PLEASE RESELECT": GO TO 180
  182 IF d$="1" THEN INPUT "Enter The New Name";a$(a+1,1)
  184 IF d$="2" THEN INPUT "Enter The New Street Number";a$(a+1,2)
  186 IF d$="3" THEN INPUT "Enter The New City, State";a$(a+1,3)
  188 IF d$="4" THEN INPUT "Enter The New Zip Code";a$(a+1,4)
  190 IF d$="5" THEN GO SUB 310
  191 IF d$="6" THEN GO TO 15
  192 CLS 
  193 PRINT "NEW ADDRESS DATA FOR ";c$(1)
  195 PRINT AT 2,0;"THIS FILE NOW CONTAINS:";TAB 0;"1. NAME:       ";a$(a+1,1);TAB 0;"2. STREET NO:  ";a$(a+1,2);TAB 0;"3. CITY/STATE: ";a$(a+1,3);TAB 0;"4. ZIP CODE:   ";a$(a+1,4);TAB 0;"5. PHONE NO:   ";a$(a+1,5);TAB 0;"6. PRESS TO RETURN TO MENU": GO TO 180
  200 REM  * Save Data Routine *
  201 CLS : PRINT AT 10,0;"Enter a name for this address   file: "
  202 INPUT z$
  203 PRINT '"Saving ";z$;" to tape"
  208 SAVE z$ DATA a$()
  209 GO TO 15
  210 REM * Load Data Routine *
  211 CLS : PRINT AT 10,0;"Enter the name of the desired   address file: "
  212 INPUT z$
  213 PRINT '"Loading ";z$;" from tape"
  215 LOAD z$ DATA a$()
  219 GO TO 15
  250 REM * HELP FILE *
  252 CLS : PRINT AT 0,3;"ADDRESS BOOK INSTRUCTIONS";TAB 0;" "
  253 PRINT "A: PRINT ADDRESS LABELS"
  254 PRINT "   This allows for the printing    of address labels on a          tractor-feed, 80 character      printer. The printer must be    set up with labels and          selected when using this        option.";TAB 0;" "
  255 PRINT "C: CHANGE PRINT DEVICE"
  256 PRINT "   This option will enable a 40    character or 80 character       printer when selected. The      printer enabled is announced    at the bottom of the MENU.";TAB 0;" "
  257 PRINT "D: DISPLAY ADDRESS LIST"
  258 PRINT "   This option will dislay on      the screen any address record   on file or the entire address   file.";TAB 0;" "
  259 PRINT "E: EDIT ADDRESS DATA"
  260 PRINT "   This editor allows any          address record to be updated.";TAB 0;" "
  261 PRINT "H: HELP"
  262 PRINT "   This is the Address Book        Instructions file.";TAB 0;" "
  263 PRINT "I: INPUT ADDRESS DATA"
  264 PRINT "   This option permits address     records to be manually added    to the file.";TAB 0;" "
  265 PRINT "L: LOAD DATA TAPE"
  266 PRINT "   This option provides loading    instructions for the data       tape. The data tape load is     required for accessing          previously established          address records.";TAB 0;" "
  267 PRINT "P: PRINT ADDRESS LIST"
  268 PRINT "   This option will provide a      hard copy of either             individual address records      or all address records.";TAB 0;" "
  269 PRINT "Q: QUIT"
  270 PRINT "   This option will stop the       program.";TAB 0;" "
  271 PRINT "S: SAVE DATA TAPE"
  272 PRINT "   When selected, this option      provides instructions and       enables for saving and          verifying the address data.";TAB 0;" "
  273 PRINT "   PRESS SPACE-BAR FOR MENU.";TAB 0;"    ";TAB 3;"PRESS THE R BUTTON TO REPEAT    THE ADDRESS BOOK INSTRUCTION    LISTING."
  274 IF INKEY$=" " THEN GO TO 15
  275 IF INKEY$="R" OR INKEY$="r" THEN GO TO 250
  276 GO TO 274
  290 REM * Change Printer *
  291 IF prntr=40 THEN LET prntr=80: GO TO 16
  292 IF prntr=80 THEN LET prntr=40: GO TO 16
  300 STOP 
  310 REM * CHANGE PHONE ROUTINE *
  315 LET t=1
  370 LET t$(t)="&": LET t=t+1: IF t<>12 THEN GO TO 370
  375 PRINT AT 20,0;"Enter New Phone Number": LET t=1
  376 PAUSE 0
  377 LET t$(t)=INKEY$
  378 IF t$(t)<>"&" THEN GO TO 383
  379 GO TO 376
  383 PRINT AT 21,11+t;t$(t): LET t=t+1
  384 IF t=4 THEN PRINT AT 21,15;"/": LET t$(t)="/": LET t=5
  385 IF t=8 THEN PRINT AT 21,19;"-": LET t$(t)="-": LET t=9
  386 IF t<13 THEN GO TO 376
  387 PRINT AT 21,0;"                             ";TAB 0;"                            "
  390 LET a$(a+1,5)=t$
  400 RETURN 
 9999 SAVE "ADDRESSBK" LINE 1

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.