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:
- Input and validation (lines 20–40): Accepts a phone number via
LINEinput, then iterates character by character, rejecting any character that is not a digit, hyphen, or space. - Dial trigger (lines 50–60): Waits for the user to press
dusing a computedGO TOidiom. - Tone generation loop (lines 70–230): Iterates over each character of the number, skipping separators and dispatching to a per-digit subroutine.
- Digit subroutines (lines 120–210): Ten subroutines, one per digit (0–9), each issuing a
SOUNDcommand 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.
| Digit | Subroutine | Reg 0 (row tone) | Reg 2 (col tone) |
|---|---|---|---|
| 0 | 120 | 116 | 82 |
| 1 | 130 | 156 | 90 |
| 2 | 140 | 156 | 82 |
| 3 | 150 | 156 | 74 |
| 4 | 160 | 142 | 90 |
| 5 | 170 | 142 | 82 |
| 6 | 180 | 142 | 74 |
| 7 | 190 | 128 | 90 |
| 8 | 200 | 128 | 82 |
| 9 | 210 | 128 | 74 |
Notable Techniques
- Computed dispatch: Line 100 uses
GO SUB 120+n*10to jump directly to the correct digit subroutine without a chain ofIFstatements orON ... GO SUB. This is an elegant and efficient BASIC idiom. - Computed GO TO for keypress wait: Line 60 uses
GO TO 60+(INKEY$="d"). WhenINKEY$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 ... LINEcaptures 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,60before 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,0and inserts a shortPAUSE 1gap 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
0has 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.