Tone Phone 2068

Developer(s): J. Kevin Paulsen
Date: 1986
Type: Program
Platform(s): TS 2068
Tags: Home

Tone Phone 2068 simulates DTMF (dual-tone multi-frequency) telephone dialing by generating two-tone audio signals for each digit using the SOUND command. The program accepts a phone number string (including hyphens and spaces as separators), validates that only digits and separators are present, then plays the corresponding tone pair for each digit. Each digit 0–9 is assigned a dedicated subroutine at lines 120–210, with the subroutine address computed dynamically via `GO SUB 120+n*10`, avoiding a lookup table. The SOUND commands set two independent tone channels simultaneously to approximate the standard DTMF frequency pairs used by telephone switching equipment.


Program Structure

The program is organized into four logical phases:

  1. Input and validation (lines 20–40): Accepts a phone number via LINE input, then iterates character by character, rejecting any character that is not a digit, hyphen, or space.
  2. Dial trigger (lines 50–60): Waits for the user to press d using a computed GO TO idiom.
  3. Tone generation loop (lines 70–230): Iterates over each character of the number, skipping separators and dispatching to a per-digit subroutine.
  4. Digit subroutines (lines 120–210): Ten subroutines, one per digit (0–9), each issuing a SOUND command and returning.

DTMF Tone Encoding

Standard DTMF uses a matrix of four row frequencies (697, 770, 852, 941 Hz) and three column frequencies (1209, 1336, 1477 Hz). The SOUND register values used here encode two simultaneous tones per digit. Registers 0 and 2 control the pitch of two independent channels; registers 1 and 3 are set to 0 (no attenuation or fine-tune offset). Register 8 and 9 are set to 15 (full volume) at the start of each digit and reset to 0 at line 220 to silence the tone between digits.

DigitSubroutineReg 0 (row tone)Reg 2 (col tone)
012011682
113015690
214015682
315015674
416014290
517014282
618014274
719012890
820012882
921012874

Notable Techniques

  • Computed dispatch: Line 100 uses GO SUB 120+n*10 to jump directly to the correct digit subroutine without a chain of IF statements or ON ... GO SUB. This is an elegant and efficient BASIC idiom.
  • Computed GO TO for keypress wait: Line 60 uses GO TO 60+(INKEY$="d"). When INKEY$ is not "d", the Boolean expression evaluates to 0 and the program loops on line 60; when "d" is pressed it evaluates to 1, advancing to line 61 — which does not exist, so execution falls through to line 70. This is a well-known technique for non-blocking key detection.
  • LINE input: Using INPUT ... LINE captures the entire typed string including spaces, which is necessary since phone numbers often contain spaces and hyphens.
  • Separator handling: Lines 80–90 detect hyphens and spaces and jump to NEXT d (line 230), cleanly skipping non-digit characters without producing a tone.
  • Dial tone: Line 70 issues SOUND 7,60 before the loop begins, simulating a brief dial tone burst before dialing commences.
  • Inter-digit silence: Line 220 resets volume registers 8 and 9 to 0 with SOUND 8,0;9,0 and inserts a short PAUSE 1 gap between digits to prevent tones from blurring together.

Validation Logic

The validation in line 30 uses a compound Boolean condition: a character is rejected if it falls outside the range "0""9" AND it is not a hyphen AND it is not a space. Any invalid character causes an immediate GO TO 20, re-prompting the user. This loop runs before dialing, so the entire number is validated upfront rather than during playback.

Potential Anomalies

  • The digit 0 has register values (116, 82) that differ in pattern from digits 1–9, which use a descending set of row values (156, 142, 128) grouped in threes. This is consistent with the DTMF standard, where 0 shares the 941 Hz row with * and #, neither of which is supported here.
  • The * and # keys common on telephone keypads are not handled; entering them would trigger the validation rejection at line 30.
  • After dialing completes, the program unconditionally returns to line 20 to prompt for another number, with no option to quit gracefully.

Source Code

  10 REM \{20}\{1}>>  Tone/Phone 2068  <<\{20}\{0}                                by J. Kevin Paulsen                       \* Time Designs  N/D 86 
  20 CLS :INPUT "Enter phone number: "; LINE d$:IF d$="" THEN GO TO 20
  30 FOR d=1 TO LEN d$:IF (d$(d)<"0" OR d$(d)>"9") AND d$(d) <>"-" AND d$(d) <>" " THEN GO TO 20
  40 NEXT d:CLS 
  50 PRINT "Press D to dial"
  60 GO TO 60+(INKEY$="d")
  70 SOUND 7,60:FOR d=1 TO LEN d$
  80 IF d$(d)="-" THEN GO TO 230
  90 IF d$(d)=" " THEN GO TO 230
 100 LET n= VAL (d$(d)):PRINT n;:GO SUB 120+n*10
 110 GO TO 220
 120 SOUND 8,15;9,15;0,116;1,0;2,82;3,0:RETURN 
 130 SOUND 8,15;9,15;0,156;1,0;2,90;3,0:RETURN 
 140 SOUND 8,15;9,15;0,156;1,0;2,82;3,0:RETURN 
 150 SOUND 8,15;9,15;0,156;1,0;2,74;3,0:RETURN 
 160 SOUND 8,15;9,15;0,142;1,0;2,90;3,0:RETURN 
 170 SOUND 8,15;9,15;0,142;1,0;2,82;3,0:RETURN 
 180 SOUND 8,15;9,15;0,142;1,0;2,74;3,0:RETURN 
 190 SOUND 8,15;9,15;0,128;1,0;2,90;3,0:RETURN 
 200 SOUND 8,15;9,15;0,128;1,0;2,82;3,0:RETURN 
 210 SOUND 8,15;9,15;0,128;1,0;2,74;3,0:RETURN 
 220 PAUSE 10:SOUND 8,0;9,0:PAUSE 1
 230 NEXT d
 240 GO TO 20

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