--- title: "Tone Phone 2068" id: 71472 type: "computer_media" slug: "tone-phone-2068" url: "http://localhost/computer_media/tone-phone-2068/" markdown_url: "http://localhost/computer_media/tone-phone-2068.md" published_at: "2026-09-09T09:03:18+00:00" modified_at: "2026-09-09T09:03:19+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2022/04/20230809-041332.jpg" excerpt: "Type in any phone number and hear each digit dialed as a pair of synthesized tones — a software DTMF dialer built entirely in BASIC." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "1986" slug: "year-1986" taxonomy: "post_tag" url: "http://localhost/tag/year-1986/" - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" basic: - name: "SOUND" slug: "sound" taxonomy: "basic" url: "http://localhost/basic/sound/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" indiv: - name: "J. Kevin Paulsen" slug: "j-kevin-paulsen" taxonomy: "indiv" url: "http://localhost/indiv/j-kevin-paulsen/" genre: - name: "Home" slug: "home" taxonomy: "genre" url: "http://localhost/type/home/" media_type: "Program" programmers: - name: "J. Kevin Paulsen" slug: "j-kevin-paulsen" taxonomy: "indiv" url: "http://localhost/indiv/j-kevin-paulsen/" download_url: "https://archive.org/download/timex-sinclair-software-archive/Tone%20Phone%202068%20(1986)(Paulsen%2C%20J.%20Kevin)(TS2068)(US)(Program).zip" tsrun_member: "Tone Phone 2068 (1986)(Paulsen, J. Kevin)(TS2068)(US)(Program).tap" mediadate: "1986" media_type_tags: "Home" --- # Tone Phone 2068 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. | 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*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 ```