Sound Approach is a Morse code trainer. It starts by sounding its tone so you can set the pitch with h and l (H and L for bigger steps), then offers three exercises: a typewriter mode that sends each key you press as dots and dashes, a text drill that sends a line you type, and a random drill that sends endless five-character groups drawn from the letters, figures and the punctuation marks , – . / and ?. For the drills you choose a speed from 2 to 15 words per minute and whether each character is shown on screen as it is sent.
The program is John (Basil) Wentworth’s, from the SyncWare News article “Sound Approach” (January/February 1988), one of a trilogy of programs by three authors introduced in “Pounding Brass and Blinking Symbols”. The article’s feature list matches it exactly. This copy came from the AERCO disk of SyncWare News’ second annual programmers’ competition, where it was saved under the name “M*5”.
Program Analysis
Sending a character
Each character is looked up by line number: GO SUB (500+CODE l$) jumps to one of the lines 544 to 590, each of which sets d$ to the character’s dots and dashes followed by the character itself (for example LET d$=".-A"). The routine at 200 then plays d$ a symbol at a time, a dot as BEEP .05,freq and a dash as BEEP .15,freq, stopping at the first character that is neither. Characters with no code, such as the space, land on a bare RETURN line and are silent.
Speed
The pause between characters comes from LET pause=-1+66*LN (15/(w-1.5)), which gives a pause of about 220 frames (over four seconds) at 2 words per minute and about 6 frames at 15. The random drill pauses twice as long between groups.
Notable Techniques
- Using the character code as part of a line number turns the Morse table into a jump table with no arrays or searching.
- Storing the character after its code in each
d$lets one string serve both for sounding and for display. - Capitals are switched on with
POKE 23658,8for the drills and off withPOKE 23658,0for the menu. - The tuning routine shows the final pitch and lists line 40 so you can make it the new default.
Potential Issues
- Line 9330 jumps to line 9500, which does not exist, so the program carries on at line 9530; this is harmless.
- Choosing p (print text) from the menu before any drill has been run stops with “Variable not found”, because
m$is only set by the drills. - The typewriter mode runs until you BREAK; the menu tells you to use
GO TO 1to get back.
This copy came from an AERCO DOS-64 disk image that was only partly read. The program lines are complete; the saved variables were not, so the tape holds the program alone, saved as “code” to start at line 9200 like the author’s own SAVE line. It was tested in ZEsarUX on a stock TS2068: tuning, the menu and the random drill.
Source Code
10 REM initialize
20 LET z$=",-./0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZ"
30 POKE 23658,0: REM lower case letters
40 LET freq=16
50 LET w=10
60 GO TO 1000: REM menu
80 PRINT '"OK? ";
90 PRINT "y- n-": REM VERIFY
100 REM INKEY$
110 PAUSE 0
120 LET c=CODE INKEY$
130 LET ok=(c=89)+(c=121)
140 RETURN
200 REM dit/dah
210 LET d$=""
220 GO SUB (500+CODE l$)
230 IF d$="" THEN RETURN
250 FOR d=1 TO LEN d$
260 IF d$(d)<>"." AND d$(d)<>"-" THEN RETURN
270 IF d$(d)="." THEN BEEP .05,freq
280 IF d$(d)="-" THEN BEEP .15,freq
290 NEXT d
300 RETURN
530 REM CHR$
543 RETURN
544 LET d$="--..-->,": RETURN
545 LET d$="-...->-": RETURN
546 LET d$=".-.-.->.": RETURN
547 LET d$="-..-./": RETURN
548 LET d$="-----0": RETURN
549 LET d$=".----1": RETURN
550 LET d$="..---2": RETURN
551 LET d$="...--3": RETURN
552 LET d$="....-4": RETURN
553 LET d$=".....5": RETURN
554 LET d$="-....6": RETURN
555 LET d$="--...7": RETURN
556 LET d$="---..8": RETURN
557 LET d$="----.9": RETURN
562 RETURN
563 LET d$="..--..?": RETURN
564 RETURN
565 LET d$=".-A": RETURN
566 LET d$="-...B": RETURN
567 LET d$="-.-.C": RETURN
568 LET d$="-..D": RETURN
569 LET d$=".E": RETURN
570 LET d$="..-.F": RETURN
571 LET d$="--.G": RETURN
572 LET d$="....H": RETURN
573 LET d$="..I": RETURN
574 LET d$=".---J": RETURN
575 LET d$="-.-K": RETURN
576 LET d$=".-..L": RETURN
577 LET d$="--M": RETURN
578 LET d$="-.N": RETURN
579 LET d$="---O": RETURN
580 LET d$=".--.P": RETURN
581 LET d$="--.-Q": RETURN
582 LET d$=".-.R": RETURN
583 LET d$="...S": RETURN
584 LET d$="-T": RETURN
585 LET d$="..-U": RETURN
586 LET d$="...-V": RETURN
587 LET d$=".--W": RETURN
588 LET d$="-..-X": RETURN
589 LET d$="-.--Y": RETURN
590 LET d$="--..Z": RETURN
656 RETURN
1000 REM menu
1010 CLS
1020 PRINT '" PRESS TO "
1030 PRINT '" c Continue with exercise"
1040 PRINT '" p Print text"
1050 PRINT '" s SAVE program"
1060 PRINT ''"You can return to menu at any"
1070 PRINT "time by BREAK:GO TO 1"
1080 PRINT ''"To reset the frequency of the"
1090 PRINT "audio tone, BREAK:GO TO 9200"
1200 GO SUB 100
1210 IF c=83 OR c=115 THEN GO TO 9000: REM SAVE
1220 IF c=80 OR c=112 THEN CLS : PRINT m$: STOP : REM PRINT
1290 IF c<>67 AND c<>99 THEN GO TO 1200: REM invalid entry
1500 REM INPUT
1510 CLS
1520 PRINT '"PRESS FOR "
1530 PRINT ''" l Letter-by-letter input"
1540 PRINT " (typewriter)"
1550 PRINT '" t Text drill"
1560 PRINT '" r Random letter drill"
1570 LET ra=0
1600 GO SUB 100
1610 POKE 23658,8: REM capitals
1620 IF c=76 OR c=108 THEN GO TO 2000: REM typewriter
1630 IF c=84 OR c=116 THEN GO TO 2500: REM text
1640 IF c=82 OR c=114 THEN GO TO 3000
1650 GO TO 1600: REM invalid entry
1999 STOP
2000 REM typewriter
2010 CLS
2020 POKE 23658,8: REM capitals
2030 PRINT "Enter text, letter by letter"
2040 LET m$=""
2050 GO SUB 100
2060 LET l$=CHR$ c
2070 GO SUB 200
2080 PRINT l$;
2090 LET m$=m$+l$
2100 GO TO 2050
2500 REM text drill
2510 CLS
2520 GO SUB 5000: REM display?
2530 GO SUB 8000: REM speed
2590 POKE 23658,8
2610 CLS
2620 INPUT "Input text ";m$
2630 PRINT m$
2640 GO SUB 80
2650 IF NOT ok THEN GO TO 2610
2660 CLS
2670 PRINT "Press ""ENTER"" to start drill"
2680 GO SUB 100
2690 GO TO 4000
3000 REM random CHR$
3010 LET ra=1
3020 CLS
3030 GO SUB 5000: REM display?
3040 GO SUB 8000: REM speed
3050 CLS
3060 PRINT '"Press ""ENTER"" to start drill"
3090 GO SUB 100
3100 POKE 23658,8
3110 CLS
3120 LET m$=""
3130 FOR f=1 TO 5
3140 LET n=INT (41*RND)+1
3160 LET l$=z$(n)
3170 LET m$=m$+l$
3210 GO SUB 200
3240 IF disp THEN PRINT l$;
3250 PAUSE pause
3260 NEXT F
3270 PRINT " ";
3280 LET m$=m$+" "
3290 PAUSE 2*pause
3300 GO TO 3130
3999 STOP
4000 REM READ text
4010 CLS : PRINT
4020 FOR m=1 TO LEN m$
4030 LET l$=m$(m)
4040 GO SUB 200
4050 PAUSE pause
4060 IF disp THEN PRINT l$;
4070 NEXT m
4090 IF ra THEN RETURN
4999 STOP
5000 REM display?
5010 PRINT '"Do you want each letter dis-"
5020 PRINT "played as it is ""transmitted""?"
5030 PRINT '" ";
5040 GO SUB 90
5050 LET disp=ok
5060 RETURN
8000 REM speed
8010 CLS
8020 PRINT '"How many words per minute do"
8030 PRINT "you want (2-15)?"
8040 INPUT w
8050 IF W<2 OR W>15 THEN GO TO 8040
8080 LET pause=-1+66*LN (15/(w-1.5))
8090 RETURN
8999 STOP
9000 REM SAVE
9010 CLEAR
9020 CLS : SAVE "code" LINE 9200
9030 BEEP .3,16: BEEP 1,16
9040 PRINT '"re-play tape to VERIFY "
9050 VERIFY "code"
9060 PRINT AT 10,10;" VERIFY OK "
9070 BEEP .3,12: BEEP 1,12
9080 STOP
9200 REM tune BEEP
9210 CLS
9220 POKE 23658,0: REM lower case letters
9230 PRINT ''"First, tune the audio tone to"
9240 PRINT "suit your taste."
9250 PRINT '"The present pitch is as follows:"
9260 PRINT '"Press ""ENTER"" if OK"
9270 PRINT ''"Press ""h"" for higher pitch;"
9280 PRINT """l"" for lower (""H"" and ""L"" for"
9290 PRINT " much lower)"
9300 LET freq=16
9310 BEEP 1,freq
9320 GO SUB 100
9330 IF c=13 THEN GO TO 9500
9340 LET freq=freq+(c=104)-(c=108)+4*((c=72)-(c=76))
9350 GO TO 9310
9530 CLS
9540 PRINT '"The frequency index of the tone"
9550 PRINT "is now set at ";freq;". You may"
9560 PRINT "wish to record this setting in"
9570 PRINT "line 40."
9580 PRINT '"Then GO TO 1 to continue."
9590 PRINT
9600 LIST 40Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.


