Telephone Directory

This file is part of and CATS Library Tape 8. Download the collection to get this file.
Developer(s): Tim Hartnell
Date: 198x
Type: Program
Platform(s): TS 2068
Tags: Database, Home

This program implements a telephone directory application that stores up to 200 name-and-number entries in a two-dimensional string array dimensioned at 200 rows of 32 characters each. Entries are input interactively with a confirmation step, then concatenated with a space separator into the DIM D$ array. After data entry, a bubble sort routine (lines 220–350) arranges records alphabetically using string comparison, printing each sorted entry as it is placed. A substring search (lines 500–560) uses BASIC’s slice notation — D$(A)(TO F) — to match the user’s query against the leading characters of each stored record, then prints the remainder of the record (the phone number portion) upon a match. An LPRINT loop at line 465 provides hardcopy output of the directory in reverse order.


Program Analysis

Program Structure

The program opens with a GO TO 360 at line 15, jumping immediately to the main menu, bypassing the data-entry and sort routines. The logical flow divides into five distinct functional blocks:

  1. Lines 20–210: Array initialization and interactive data entry loop
  2. Lines 220–350: Bubble sort routine, triggered when the user exits the entry loop
  3. Lines 360–480: Main menu dispatcher
  4. Lines 500–570: Name search routine
  5. Line 9998: SAVE with auto-run

Data Storage

DIM D$(200,32) at line 20 allocates a fixed 6,400-byte block for up to 200 records, each padded to exactly 32 characters. Name and telephone number are concatenated with a single space separator via LET D$(D)=B$+" "+C$ at line 170. Because the array is fixed-width, all rows are space-padded to 32 characters automatically, which is important for the sort comparisons. The variable D doubles as both the FOR loop counter and the record count, so after the entry loop exits (via GO TO 210 rather than running off the end of NEXT D), D holds the index of the last entry added.

Sorting Algorithm

The sort (lines 220–350) is a selection sort, not a bubble sort despite the structure superficially resembling one. Variable G starts at D (the last filled index) and decrements each pass. Z walks from 1 upward; when D$(B) > D$(Z), the two entries are swapped using Q$ as a temporary. After each swap the inner walk continues from the same Z. The result of each pass places the lexicographically largest remaining record at position G, which is then printed (line 330) and the window shrinks. This means sorted entries are printed to screen as they are finalized, giving the user visual feedback during sorting.

POKE 23692,0 at line 216 resets the scroll counter so the screen does not pause with “scroll?” during the sort output — a standard Spectrum/2068 idiom.

Search Routine

The search at lines 500–570 uses BASIC string slicing: D$(A)(TO F) extracts the first F characters of each record (where F=LEN A$), performing a prefix match against the user’s input. On a match, D$(A)(F+1 TO ) prints the remainder of the record — ideally the space-separated phone number — and returns to the menu. Only the first match is reported; the loop does not continue after a hit.

Menu and Navigation

The menu at lines 360–480 uses a numeric INPUT B and a chain of IF statements rather than ON ... GO TO. Option 2 (“add new names”) executes NEXT D directly, resuming the FOR D=1 TO 200 loop that was left suspended — a clever reuse of BASIC’s loop state. Option 4 saves the array with SAVE "DIRECTORY" but does not reload it on startup, so there is no LOAD option in the menu. Option 5 prints the directory via LPRINT iterating from D down to 1, producing reverse-entry order on the printer rather than sorted order.

Notable Techniques

  • Reuse of the suspended FOR loop variable D as both counter and record-count sentinel.
  • Prefix-match search using open-ended slice notation D$(A)(TO F) and D$(A)(F+1 TO ).
  • POKE 23692,0 to suppress scroll prompts during bulk screen output.
  • INVERSE 1 and FLASH 1 used inline within PRINT statements for user-interface emphasis without custom UDGs.
  • Confirmation loop at lines 150–160: if E$ is non-empty (user typed something before ENTER), entry restarts; an empty ENTER accepts the record.

Bugs and Anomalies

  • The LPRINT loop at line 465 iterates from D TO 1 STEP -1, printing in reverse entry order rather than the sorted order the sort routine produces. If sorting has been run, the sorted data is in D$() but the printout walks it backwards.
  • There is no LOAD option in the menu, so a previously saved “DIRECTORY” file cannot be retrieved within the running program.
  • The entry loop uses FOR D=1 TO 200 but the array is dimensioned to 200; if all 200 slots are filled and the user presses ENTER to continue, NEXT D will exceed the loop bound and fall through, leaving the program in an undefined state rather than exiting gracefully.
  • After sorting, the screen displays sorted entries but the program falls through to the menu at line 360 without clearing the screen first, potentially leaving sort output visible behind menu text.

Variable Summary

VariablePurpose
D$(200,32)Main directory array, 200 × 32 characters
DFOR loop counter / current record index
B$Name input buffer
C$Phone number input buffer
E$Confirmation / menu-branch input
BNumeric menu choice; also sort inner pointer
GSort outer boundary (shrinks each pass)
ZSort inner walk pointer
Q$Swap temporary for sort
A$Search query string
FLength of search query for slice bounds
ASearch loop counter; also LPRINT loop counter

Content

Appears On

The power-user's tape. Assemble and disassemble Z80 code, manage databases with Quicksort, trace BASIC program flow, or decode resistor color codes — Tape 8 is an essential toolkit for the serious TS 2068 programmer.

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   10 REM TELEPHONE DIRECTORY
   12 REM From Timex Sinclair 2068 explored entered by Izzy Goldsmith LIST Group
   15 GO TO 360
   20 DIM D$(200,32)
   30 FOR D=1 TO 200
   40 INPUT "Enter Name ";B$
   90 PRINT AT 0,0;"Name: ";B$
  110 INPUT "Enter telephone number ";C$
  120 CLS 
  130 PRINT AT 0,0;B$;"  ";C$
  140 PRINT ''"If this is correct, press "; INVERSE 1;"ENTER"; INVERSE 0,"If incorrect, press "; FLASH 1;"'E'"; FLASH 0,"then ENTER"
  150 INPUT E$: CLS 
  160 IF E$<>"" THEN GO TO 40
  170 LET D$(D)=B$+" "+C$
  180 PRINT ''"Press "; INVERSE 1;"ENTER"; INVERSE 0;" to enter next item,","or any letter, then ENTER, to","sort directory"
  190 INPUT E$: CLS 
  200 IF E$="" THEN NEXT D
  210 PRINT PAPER 2; FLASH 1;"sorting..."
  216 POKE 23692,0
  220 LET B=0
  230 LET G=D
  240 LET Z=1
  250 LET B=Z+1
  260 IF B>G THEN GO TO 330
  270 IF D$(B)>D$(Z) THEN GO TO 290
  280 LET Z=Z+1: GO TO 250
  290 LET Q$=D$(Z)
  300 LET D$(Z)=D$(B)
  310 LET D$(B)=Q$
  320 GO TO 280
  330 PRINT D$(G)
  340 LET G=G-1
  350 IF G>0 THEN GO TO 240
  360 PRINT ''"Enter one number:"
  370 PRINT '"1 - To start new directory"
  380 PRINT '"2 - To add new names"
  390 PRINT '"3 - To search for number"
  400 PRINT '"4 - To save directory"
  405 PRINT '"5 - To print directory"
  410 PRINT '"6 - To stop"
  420 INPUT B: CLS 
  430 IF B=1 THEN GO TO 20
  440 IF B =2 THEN NEXT D
  450 IF B=3 THEN GO TO 500
  460 IF B=4 THEN SAVE "DIRECTORY"
  465 IF B=5 THEN FOR A=D TO 1 STEP -1: LPRINT D$(A): NEXT A
  470 IF B=6 THEN STOP 
  480 GO TO 360
  500 PRINT ''"ENTER NAME REQUIRED"
  510 INPUT A$: LET F=LEN A$
  520 PRINT FLASH 1; INK 1;"Searching for  ";A$
  530 FOR A=1 TO D
  540 IF D$(A)( TO F)=A$ THEN PRINT ''D$(A)(F+1 TO ): GO TO 360
  550 NEXT A
  560 PRINT '"Name not found"
  570 GO TO 360
 9998 SAVE "Phonedir" LINE 1

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

Scroll to Top