--- title: "Log Book" id: 56693 type: "computer_media" slug: "log" url: "http://localhost/computer_media/log/" markdown_url: "http://localhost/computer_media/log.md" published_at: "2024-09-22T23:31:42+00:00" modified_at: "2026-04-03T07:59:00+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/09/LOG.jpeg" excerpt: "A full-featured ham radio QSO logbook with menu-driven entry, printer output, callsign/QTH search, and cassette save — storing up to 195 contacts in parallel string arrays." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "Kentronics" slug: "kentronics" taxonomy: "post_tag" url: "http://localhost/tag/kentronics/" - name: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" genre: - name: "Ham Radio" slug: "ham-radio" taxonomy: "genre" url: "http://localhost/type/ham-radio/" media_type: "Cassette" download_url: "https://archive.org/download/timex-sinclair-software-archive/LOG%20%281983%29%28Kentronics%29%28TS1000%29%28US%29%28Program%29.zip" mediadate: "1983" producer_company: - id: 11017 title: "Kentronics" type: "company" url: "http://localhost/company/kentronics/" images: - url: "http://localhost/wp-content/uploads/2024/09/LOG.jpeg" - url: "http://localhost/wp-content/uploads/2024/09/Tape-13.jpg" related_products: - id: 13123 title: "Log Book" type: "product" url: "http://localhost/product/log-book/" media_type_tags: "Ham Radio" --- # Log Book 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 callsign - `F$(195,6)` — frequency - `M$(195,4)` — mode (CW, SSB, RTTY, etc.) - `V$(195,3)` — RST sent - `R$(195,3)` — RST received - `H$(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 `S` to copy the previous entry: e.g., `IF K$="S" THEN LET D$(X)=D$(X-1)` followed immediately by `IF 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 `FAST` mode before iterating and restore `SLOW` afterwards, 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, resetting `K` to 0, and returning in `FAST` mode. ### 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 75` uses 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 fallthrough `GOTO 155` at 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 `%G` is 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 `X` is also preserved, which requires the SAVE at line 5035 to capture the variable state. ## 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 ```