--- title: "Morse" id: 56174 type: "computer_media" slug: "morse" url: "http://localhost/computer_media/morse/" markdown_url: "http://localhost/computer_media/morse.md" published_at: "2024-07-21T02:00:33+00:00" modified_at: "2026-03-30T21:44:09+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/07/SCR-20240720-tahe.png" excerpt: "A three-mode Morse code trainer that plays dots and dashes as tones, teaches the full alphabet, encodes typed messages, and quizzes you with a scored test." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Amateur radio" slug: "amateur-radio" taxonomy: "post_tag" url: "http://localhost/tag/amateur-radio/" - 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/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" genre: - name: "Ham Radio" slug: "ham-radio" taxonomy: "genre" url: "http://localhost/type/ham-radio/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Morse%20%28198x%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/07/SCR-20240720-tahe.png" media_type_tags: "Ham Radio" --- This program is a Morse code trainer that teaches, transmits, and tests the user’s knowledge of the international Morse alphabet. It stores all 26 letter codes as a single DATA string at line 1000, using “.” for dots and “-” for dashes, then plays them audibly via BEEP with dashes sounding three times longer than dots (BEEP speed vs. BEEP speed/3). Three modes are offered: an alphabet review that steps through A–Z one letter at a time with visual and audio output, a message sender that encodes arbitrary text input character by character, and a multiple-choice test that randomly selects letters using RND and scores the user’s typed responses. The menu uses PRINT OVER 1 with underscore characters to animate underlines beneath the menu options as a decorative effect. *** ## Program Analysis ### Program Structure The program is organized into four distinct functional blocks, entered via `GO TO` from a central menu at line `2000`: 1. **Menu / initialization** — lines `2000`–`2110`: resets score, sets speed, draws the menu, and polls `INKEY$` in a tight loop. 2. **Alphabet review** — lines `8`–`70`: iterates `FOR a=1 TO 26`, reads each Morse code string, prints and plays it, and waits for a keypress before advancing. 3. **Send message** — lines `90`–`320`: accepts an `INPUT` string, encodes each character by scanning the DATA list, and plays the corresponding Morse tones. 4. **Test** — lines `399`–`840`: prompts for a question count, randomly selects letters via `RND`, plays their Morse tones, and scores typed answers. ### DATA Layout and Access All 26 Morse code strings are stored in a single `DATA` statement at line `1000`, ordered A–Z. Each routine calls `RESTORE` before reading so the data pointer is always reset to the beginning. The message-sender at line `130` locates a letter by iterating `FOR e=1 TO 26` and comparing `e=d-64` (where `d` is the ASCII code of the input character), then jumps to line `300`. However, line `300` does not exist — the jump target is `301`, which is a well-known technique relying on the interpreter finding the next available line. ### Morse Timing The speed variable is initialized at `LET speed=.2` (line `2005`). Dashes are played as `BEEP speed,20` and dots as `BEEP speed/3,20`, correctly maintaining the standard 3:1 dash-to-dot duration ratio. Both use the same pitch (note value 20). The speed value is never exposed to user adjustment in the menu, though the variable name suggests it was intended to be configurable. ### Key BASIC Idioms - `PAUSE 0` at line `56` and `800` halts execution until any key is pressed — the standard Sinclair-family keypress-wait idiom. - `RESTORE` is called at the top of each mode to reset the `DATA` pointer, since all three modes share the same single `DATA` line. - Menu animation at lines `2091`–`2096` uses `PRINT OVER 1` with underscore characters to draw and redraw underlines beneath menu items, creating a simple visual effect without clearing the screen. - `PRINT OVER 1;AT 3,10;"__________"` at line `2012` underlines the title “MORSE CODE” using OVER mode so it overlays without erasing the text above. ### Test Mode Logic The test mode at line `400` randomly selects a Morse code string by reading past `INT(RND*26)+1` entries from the DATA list (`FOR a=1 TO INT(RND*26)+1 / READ a$ / NEXT a`). After playing the tones, the expected answer is computed as `LET ans=a+63` — since after the loop `a` has been incremented one past the selected index by `NEXT a`, this actually computes `CHR$(selected_index + 64)`, which is the correct uppercase letter. The comparison at line `560` uses `CODE n$=ans`, meaning only exact uppercase or lowercase matching is accepted depending on the shift state. ### Bugs and Anomalies | Line | Issue | | --- | --- | | `2060` | The instruction message contains a typographical run-on: `"caps shift isin the ON ERR"` — the word “is” and “in” are merged, and `ON ERR` (the `{` keyword) appears where the word “CAPS LOCK” was probably intended. | | `840` | `PRINT 300` appears to be a stray line; it likely should be `PAUSE 300` to give the player time to read the score before returning to the menu. | | `121` | `IF d=32 THEN NEXT l` skips spaces in the message, which works correctly but relies on jumping to the `NEXT` statement directly — a somewhat unconventional flow-control approach. | | `2087` | `GO TO 99` targets a non-existent line; the interpreter will proceed to line `100`, the start of the Send Message section — intentional and functional. | | `560` | Case sensitivity: `CODE n$=ans` compares the raw character code against the uppercase letter code, so lowercase input will fail. The menu warning about caps lock (garbled as it is) addresses this. | ## Source Code ``` 5 GO TO 2000 8 CLS 9 RESTORE 10 FOR a=1 TO 26 14 PRINT AT 17,0;"Press [M] to return to menu" 15 PRINT AT 19,0;"Press any other key to continue" 16 IF INKEY$="m" OR INKEY$="M" THEN GO TO 2000 20 PRINT AT 0,0;CHR$ (a+64);" "; 30 READ b$ 35 FOR d=1 TO LEN b$ 36 PRINT b$(d); 41 IF b$(d)="-" THEN BEEP speed,20 42 IF b$(d)="." THEN BEEP speed/3,20 50 NEXT d 56 PAUSE 0 57 CLS 60 NEXT a 70 GO TO 2000 90 CLS 100 PRINT AT 3,9;"Send message" 101 PRINT AT 6,2;"What message would you like to send?" 105 INPUT a$ 106 CLS 107 RESTORE 110 FOR l=1 TO LEN a$ 120 LET d=CODE a$(l) 121 IF d=32 THEN NEXT l 130 FOR e=1 TO 26 135 READ w$ 140 IF e=d-64 THEN GO TO 300 150 NEXT e 301 FOR q=1 TO LEN w$ 302 PRINT AT 10,0;w$;" " 305 IF w$(q)="-" THEN BEEP speed,20 306 IF w$(q)="." THEN BEEP speed/3,20 307 NEXT q 309 PRINT AT 19,0;a$( TO l) 310 RESTORE : NEXT l 315 PAUSE 400 320 GO TO 2000 399 CLS 400 PRINT AT 3,12;"Test" 410 INPUT "How many questions?";qu 490 FOR t=1 TO qu 495 RESTORE 500 FOR a=1 TO INT (RND*26)+1 501 READ a$ 502 NEXT a 503 FOR d=1 TO LEN a$ 504 IF a$(d)="-" THEN BEEP speed,20 505 IF a$(d)="." THEN BEEP speed/3,20 506 NEXT d 508 PRINT AT 8,2;"What letter is represented by:" 509 PRINT AT 10,0;" " 530 PRINT AT 10,(31-LEN a$)/2;a$ 540 LET ans=a+63 550 INPUT n$ 555 PRINT AT 14,0;"Your answer was ";n$ 560 IF CODE n$=ans THEN GO TO 700 565 BEEP .4,-25 570 PRINT AT 12,0;" Wrong, the letter is ";CHR$ ANS 575 PAUSE 200: CLS 580 NEXT t 590 GO TO 800 700 BEEP .1,10: BEEP .1,0: BEEP .1,40 702 PRINT AT 12,0;"Correct, the letter is ";n$ 705 LET cor=cor+1 706 PAUSE 200 710 NEXT t 800 PRINT AT 21,0;"PRESS A KEY TO SEE YOUR SCORE": PAUSE 0: CLS 820 PRINT "You scored ";cor;" right" 830 PRINT "out of ";qu;". That is ";INT ((cor/qu)*100);"%." 840 PRINT 300: GO TO 2000 1000 DATA ".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.." 2000 CLS 2001 LET cor=0 2005 LET speed=.2 2010 PRINT AT 3,10;"MORSE CODE" 2012 PRINT OVER 1;AT 3,10;"__________" 2015 PRINT AT 5,2;"Choose one of the following:" 2020 PRINT AT 9,5;"1) Review alphabet/code";AT 10,5;"2) Send code";AT 11,5;"3) Test" 2060 PRINT AT 19,0;"Make sure the caps shift isin the ON ERRCBEEP Mode,or the computer will not understand you answer" 2080 LET a$=INKEY$ 2081 OVER 0 2085 IF a$="1" THEN GO TO 8 2087 IF a$="2" THEN GO TO 99 2090 IF a$="3" THEN GO TO 399 2091 FOR t=8 TO 27: PRINT OVER 1;AT 9,t;"_": NEXT t 2092 FOR t=8 TO 27: PRINT OVER 1;AT 9,t;"_": NEXT t 2093 FOR t=8 TO 16: PRINT OVER 1;AT 10,t;"_": NEXT t 2094 FOR t=8 TO 16: PRINT OVER 1;AT 10,t;"_": NEXT t 2095 FOR t=8 TO 11: PRINT OVER 1;AT 11,t;"_": NEXT t 2096 FOR t=8 TO 11: PRINT OVER 1;AT 11,t;"_": NEXT t 2110 GO TO 2080 ```