This program is a ham radio contact log (QSO logbook) for amateur radio operators, allowing up to 195 contacts to be recorded with fields for date, time, callsign, frequency, mode, RST sent/received, contact name, and QTH (location). It provides a five-option menu covering data entry, printer output via LPRINT, callsign or QTH search, starting a new log, and saving to cassette tape. Data is stored in eight parallel string arrays (D$, T$, S$, F$, M$, V$, R$, H$) each dimensioned 195 elements wide. The search routines use FAST/SLOW mode switching to speed up linear array scanning, pausing every three results with a GOSUB scroll-break subroutine at line 6000.
Program Analysis
Program Structure
The program is divided into clearly separated functional blocks, each anchored at a round line-number boundary:
| Line range | Function |
|---|---|
| 0–155 | Title animation and main menu |
| 1000–1265 | Array initialisation and data entry loop |
| 2000–2105 | Printer (LPRINT) output |
| 3000–3070 | Search sub-menu |
| 5000–5050 | Cassette SAVE |
| 5100–5190 | Search by callsign |
| 5200–5345 | Search by QTH |
| 6000–6050 | Scroll-pause subroutine |
Data Storage
All log data is held in eight parallel fixed-width string arrays, each dimensioned to 195 rows:
D$(195,6)— date (DDMMYY)T$(195,4)— time (HHMM)S$(195,10)— station callsignF$(195,6)— frequencyM$(195,4)— mode (CW, SSB, RTTY, etc.)V$(195,3)— RST sentR$(195,3)— RST receivedH$(195,10)— QTH (location)
The contact name is stored in N$(195,6). The index variable X is used as the current write pointer and is incremented after each logged contact at line 1232. The remaining capacity is displayed to the user as 195-(X-1).
Key BASIC Idioms
Several recurring patterns appear throughout:
- “Same as previous” shortcut: For date, frequency, mode, RST, and QTH, the user can type
Sto copy the previous entry: e.g.,IF K$="S" THEN LET D$(X)=D$(X-1)followed immediately byIF K$<>"S" THEN LET D$(X)=K$. This avoids an ELSE clause, which is unavailable in this BASIC dialect. - FAST/SLOW bracketing: The search loops at lines 5100–5165 and 5200–5270 switch to
FASTmode before iterating and restoreSLOWafterwards, significantly reducing scan time at the cost of display stability during the loop. - Scroll-break via GOSUB: Subroutine 6000 fires when
K=3(three results shown), pausing for a keypress, clearing the screen, resettingKto 0, and returning inFASTmode.
Search Implementation
Both search routines (callsign at 5100, QTH at 5200) reuse the last slot of the respective array (S$(X) or H$(X)) as a temporary holding variable for the search term, then compare it against all previous entries in a FOR J=1 TO X-1 loop. This is an economical technique that avoids declaring an extra string variable, though it means the search term occupies a real array slot and must be cleared or overwritten before the next log entry is made.
Printer Output
The LPRINT section (lines 2000–2075) uses inverse-video characters (e.g., %D%A%T%E) for column headers, creating a visually distinct printed format. Block graphic characters form separator lines above and below each record. The user selects which QSO number to start printing from, and the loop runs from that point to X-1. A variable N is both the INPUT target and the loop counter, which is incremented manually inside the loop with LET N=N+1 in addition to the FOR J counter — N is used only for the “QSO NUMBER” label on the printout.
Title Screen Animation
Lines 25–70 produce a simple animation: a banner of alternating block graphics (▖▝ pattern) is printed at row 10, the logbook title at row 12, a short delay loop runs (FOR N=1 TO 20), then the title is blanked with spaces, and a second border line is added at row 14. This repeats 10 times (FOR L=1 TO 10), giving a flicker effect before the menu appears.
Bugs and Anomalies
- Inverted menu validation logic (line 120):
IF L$<"1" AND L$>"5" THEN GOTO 75uses AND where OR is needed. No string can simultaneously be less than “1” and greater than “5”, so this condition is always false and invalid input is never caught here. The fallthroughGOTO 155at line 155 provides a safety net. - Same logic flaw at line 1255:
IF Z$<"1" AND Z$>"2" THEN GOTO 1230— the AND should be OR. - Same logic flaw at line 3060:
IF B<1 AND B>2 THEN GOTO 3000— impossible condition for a numeric variable. - SAVE target (line 5035):
SAVE "LO%G"— the%Gis an inverse-G character in the filename, which acts as an auto-run flag. - GOTO 5 (line 5050): Targets a non-existent line; execution will fall through to the next available line (line 10), effectively restarting the program from the title input — a deliberate restart technique.
- Typo at line 1180: “RECIEVED” should be “RECEIVED” — a spelling error in the prompt text.
- “Continue old log” (option 1, line 130): Jumps to line 1060, bypassing array initialisation (lines 1005–1055). If the arrays have not been previously dimensioned (e.g., after a fresh load without a prior NEW LOG), this will cause an error. The intent is that a previously SAVEd and reloaded program would retain the array data, but only if
Xis also preserved, which requires the SAVE at line 5035 to capture the variable state.
Content
Source Code
0 REM (C) 1983 BY KENTRONICS
10 PRINT AT 10,0;"ENTER YOUR CALL SIGN"
15 INPUT C$
20 CLS
25 FOR L=1 TO 10
30 PRINT AT 10,0;".'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.''.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'."
35 PRINT AT 12,7;"LOG BOOK OF ";C$
40 FOR N=1 TO 20
45 NEXT N
50 FOR F=1 TO 2
55 PRINT AT 12,18;" "
60 NEXT F
65 PRINT AT 14,0;"'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'..'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'"
70 NEXT L
75 CLS
80 PRINT AT 2,13;"MENU"
85 PRINT ,,,,"(1) CONTINUE OLD LOG"
90 PRINT ,,"(2) COPY LOG CONTENTS TO PRINTER"
95 PRINT ,,"(3) SEARCH LOG BY CALLSIGN/QTH"
100 PRINT ,,"(4) START A NEW LOG"
105 PRINT ,,"(5) SAVE ""LOG"" WITH DATA"
110 PRINT AT 20,0;"ENTER NUMBER OF YOUR CHOICE"
115 INPUT L$
120 IF L$<"1" AND L$>"5" THEN GOTO 75
125 CLS
130 IF L$="1" THEN GOTO 1060
135 IF L$="2" THEN GOTO 2000
140 IF L$="3" THEN GOTO 3000
145 IF L$="4" THEN GOTO 1000
150 IF L$="5" THEN GOTO 5000
155 GOTO 75
1000 CLS
1005 DIM D$(195,6)
1010 DIM T$(195,4)
1015 DIM S$(195,10)
1020 DIM F$(195,6)
1025 DIM M$(195,4)
1030 DIM V$(195,3)
1035 DIM R$(195,3)
1040 DIM N$(195,6)
1045 DIM H$(195,10)
1050 LET X=1
1055 LET K=0
1060 PRINT AT 0,0;"DATE ? (DDMMYY)";AT 20,2;"ENTER (S) IF SAME DATE"
1065 INPUT K$
1070 IF K$="S" THEN LET D$(X)=D$(X-1)
1072 IF K$<>"S" THEN LET D$(X)=K$
1075 CLS
1080 PRINT "TIME ?"
1085 INPUT T$(X)
1090 CLS
1095 PRINT AT 0,0;"STATION ?"
1100 INPUT S$(X)
1110 CLS
1115 PRINT AT 0,0;"FREQUENCY ?";AT 20,2;"ENTER (S) IF SAME FREQUENCY"
1120 INPUT W$
1130 IF W$="S" THEN LET F$(X)=F$(X-1)
1132 IF W$<>"S" THEN LET F$(X)=W$
1135 CLS
1140 PRINT AT 0,0;"MODE ? (CW,SSB,RTTY,ETC.)";AT 20,2;"ENTER (S) IF SAME MODE"
1145 INPUT E$
1150 IF E$="S" THEN LET M$(X)=M$(X-1)
1152 IF E$<>"S" THEN LET M$(X)=E$
1155 CLS
1160 PRINT AT 0,0;"RS/T SENT ?";AT 20,2;"ENTER (S) IF SAME REPORT"
1165 INPUT I$
1170 IF I$="S" THEN LET V$(X)=V$(X-1)
1172 IF I$<>"S" THEN LET V$(X)=I$
1175 CLS
1180 PRINT AT 0,0;"RS/T RECIEVED ?";AT 20,2;"ENTER (S) IF SAME REPORT"
1185 INPUT Y$
1190 IF Y$="S" THEN LET R$(X)=R$(X-1)
1192 IF Y$<>"S" THEN LET R$(X)=Y$
1195 CLS
1200 PRINT "CONTACTS NAME ?"
1205 INPUT N$(X)
1210 CLS
1215 PRINT AT 0,0;"HIS QTH ?";AT 20,2;"ENTER (S) IF SAME QTH"
1220 INPUT G$
1225 IF G$="S" THEN LET H$(X)=H$(X-1)
1227 IF G$<>"S" THEN LET H$(X)=G$
1230 CLS
1232 LET X=X+1
1233 PRINT "YOU CAN LOG ";195-(X-1);" MORE CONTACTS"
1235 PRINT AT 10,0;"(1) LOG MORE CONTACTS"
1240 PRINT ,,"(2) RETURN TO MENU"
1245 PRINT ,,,,,,"ENTER NUMBER OF YOUR CHOICE"
1250 INPUT Z$
1252 CLS
1255 IF Z$<"1" AND Z$>"2" THEN GOTO 1230
1260 IF Z$="1" THEN GOTO 1060
1265 IF Z$="2" THEN GOTO 75
2000 CLS
2001 PRINT "LAST LOG ENTRY WAS NUMBER ";X-1
2005 PRINT ,,"WHICH QSO NUMBER TO START PRINT?"
2010 INPUT N
2015 LPRINT "LOG OF RADIO STATION ";C$
2020 LPRINT
2025 FOR J=N TO X-1
2030 LPRINT " ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '"
2035 LPRINT "%Q%S%O% %N%U%M%B%E%R ";N
2040 LPRINT ,,"%D%A%T%E %T%I%M%E %S%T%A%T%I%O%N %F%R%E%Q%U%E%N%C%Y"
2045 LPRINT D$(J);" ";T$(J);" ";S$(J);" ";F$(J)
2050 LPRINT ,,"%M%O%D%E %S%E%N%T %R%C%V%D %N%A%M%E %Q%T%H"
2055 LPRINT M$(J);" ";V$(J);" ";R$(J);" ";N$(J);" ";H$(J)
2060 LPRINT ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "
2065 LET N=N+1
2070 NEXT J
2075 LPRINT ,,"TOTAL LOG ENTRIES ; ";X-1
2080 CLS
2085 PRINT ,,,,"ENTER (C) TO LOG MORE CONTACTS"
2090 PRINT ,,"ENTER (M) TO RETURN TO MENU"
2095 INPUT O$
2100 IF O$="C" THEN GOTO 1060
2105 GOTO 75
3000 CLS
3010 PRINT ,,,,"(1) SEARCH BY CALLSIGN"
3020 PRINT ,,"(2) SEARCH BY QTH"
3030 INPUT B
3035 CLS
3040 IF B=1 THEN GOTO 5100
3050 IF B=2 THEN GOTO 5200
3060 IF B<1 AND B>2 THEN GOTO 3000
3070 GOTO 3000
5000 CLS
5010 PRINT AT 8,5;"SET CASSETTE TO RECORD"
5020 PRINT ,,"PRESS ENTER TO SAVE ""LOG"""
5030 INPUT L$
5035 IF L$="" THEN SAVE "LO%G"
5040 CLS
5050 GOTO 5
5100 PRINT ,,,,"ENTER CALLSIGN TO SEARCH FOR"
5105 INPUT S$(X)
5110 CLS
5112 FAST
5115 PRINT " ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '"
5120 LET K=0
5125 FOR J=1 TO X-1
5130 IF S$(J)=S$(X) THEN PRINT "%D%A%T%E %T%I%M%E %S%T%A%T%I%O%N %F%R%E%Q%U%E%N%C%Y"
5135 IF S$(J)=S$(X) THEN PRINT D$(J);" ";T$(J);" ";S$(J);" ";F$(J)
5140 IF S$(J)=S$(X) THEN PRINT ,,"%M%O%D%E %S%E%N%T %R%C%V%D %N%A%M%E %Q%T%H"
5145 IF S$(J)=S$(X) THEN PRINT M$(J);" ";V$(J);" ";R$(J);" ";N$(J);" ";H$(J)
5150 IF S$(J)=S$(X) THEN PRINT " ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '"
5155 IF S$(J)=S$(X) THEN LET K=K+1
5160 IF K=3 THEN GOSUB 6000
5165 NEXT J
5167 SLOW
5170 PRINT ,,"DATA SEARCH COMPLETE"
5180 PRINT "ENTER (M) TO RETURN TO MENU"
5185 INPUT X$
5190 GOTO 75
5200 CLS
5205 PRINT ,,"ENTER QTH TO SEARCH FOR"
5210 INPUT H$(X)
5215 CLS
5217 FAST
5220 PRINT " ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '"
5225 LET K=0
5230 FOR J=1 TO X-1
5235 IF H$(J)=H$(X) THEN PRINT "%D%A%T%E %T%I%M%E %S%T%A%T%I%O%N %F%R%E%Q%U%E%N%C%Y"
5240 IF H$(J)=H$(X) THEN PRINT D$(J);" ";T$(J);" ";S$(J);" ";F$(J)
5245 IF H$(J)=H$(X) THEN PRINT ,,"%M%O%D%E %S%E%N%T %R%C%V%D %N%A%M%E %Q%T%H"
5250 IF H$(J)=H$(X) THEN PRINT M$(J);" ";V$(J);" ";R$(J);" ";N$(J);" ";H$(J)
5255 IF H$(J)=H$(X) THEN PRINT " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ."
5260 IF H$(J)=H$(X) THEN LET K=K+1
5265 IF K=3 THEN GOSUB 6000
5270 NEXT J
5275 SLOW
5330 PRINT ,,"DATA SEARCH COMPLETE"
5335 PRINT ,,"ENTER (M) TO RETURN TO MENU"
5340 INPUT X$
5345 GOTO 75
6000 SLOW
6010 PRINT "PRESS ENTER TO CONTINUE"
6020 INPUT G$
6030 CLS
6040 LET K=0
6045 FAST
6050 RETURN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

