--- title: "Type DXCC" id: 56742 type: "computer_media" slug: "type-dxcc" url: "http://localhost/computer_media/type-dxcc/" markdown_url: "http://localhost/computer_media/type-dxcc.md" published_at: "2024-09-22T23:31:59+00:00" modified_at: "2026-04-03T07:58:53+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/09/SCR-20241102-llif.png" excerpt: "Two utilities in one listing: a 340-entry amateur radio DXCC log with search and totals, plus a column-tracking full-screen typewriter with cursor positioning." 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 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/" indiv: - name: "Robert J. Lees (W3ZQN)" slug: "robert-j-lees" taxonomy: "indiv" url: "http://localhost/indiv/robert-j-lees/" genre: - name: "Ham Radio" slug: "ham-radio" taxonomy: "genre" url: "http://localhost/type/ham-radio/" media_type: "Program" programmers: - name: "Robert J. Lees (W3ZQN)" slug: "robert-j-lees" taxonomy: "indiv" url: "http://localhost/indiv/robert-j-lees/" download_url: "https://archive.org/download/timex-sinclair-software-archive/Type%20DXCC%20%28198x%29%28Lees%2C%20R.%20J.%29%28TS1000%29%28US%29%28Cassette%29.zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/09/SCR-20241102-llif.png" - url: "http://localhost/wp-content/uploads/2024/09/SCR-20241102-llfp.png" - url: "http://localhost/wp-content/uploads/2024/09/Type_DXCC.jpg" media_type_tags: "Ham Radio" --- # Type DXCC The first program is a [DXCC (DX Century Club)](https://www.arrl.org/dxcc-rules) countries log for amateur radio operators, storing up to 340 country records in a single large string array D$(340,32), where each 32-character row holds country number, callsign prefix, country name, and QSL card data. It provides search by number, prefix, or name; a paged review mode; and a totals screen showing worked, credited, and QSL-sent/received counts. The second program is a full-screen typewriter utility that tracks cursor position column-by-column across a 32-column display, uses SCROLL to handle page overflow, and supports backspace, newline, and direct cursor positioning by line and column number. Both programs use the SLOW/FAST idiom around PAUSE and POKE 16437,255 to debounce keyboard input reliably on the ZX81. *** ## Program Analysis ### Program 1: DXCC Countries List This amateur radio utility, written by R. J. Lees (W3ZQN) in September 1982, maintains a database of up to 340 DXCC (DX Century Club) country entities. The entire database is stored in a single two-dimensional string array `D$(340,32)`, where each row is exactly 32 characters wide and encodes structured fields at fixed byte offsets. ### Record Layout | Columns | Field | Length | | --- | --- | --- | | 1–3 | Country number | 3 | | 4 | Separator (space) | 1 | | 5–15 | Callsign prefix | 11 | | 16 | Separator | 1 | | 17–26 | Country name | 10 | | 27 | Separator | 1 | | 28–32 | QSL data (MMYY + S/R/C) | 5 | Searching by prefix uses `D$(C,5 TO 15)=P$` and by name uses `D$(C,17 TO 26)=N$`. The final character at position 32 encodes QSL status: `S` = sent/no return, `R` = sent and returned, `C` = DXCC credited. The TOTALS routine (lines 4000–4240) iterates all 340 records, testing individual character positions to accumulate five counters. ### Program Structure - Lines 11–15: Array declarations (`C$`, `P$`, `N$`, `I$`, `D$`) - Lines 100–200: Main menu loop - Lines 1000–1050: Search sub-menu - Lines 1100–1260: Search by country number - Lines 1500–1710: Search by prefix - Lines 2000–2210: Search by name - Lines 3000–3120: Paged review mode - Lines 4000–4240: Totals computation and display - Lines 5000–5210: Data input routine - Lines 6000–6520: Shared display/change/another subroutines - Lines 7000–7020: Exit with warning message - Lines 8000–8120: Keypress wait and “not found” subroutines - Lines 9000–9010: SAVE and restart ### Key BASIC Idioms and Techniques The keypress-wait subroutine at line 8000 uses `SLOW`, `PAUSE 20`, `POKE 16437,255`, and a busy-wait loop on `INKEY$`. The POKE to address 16437 resets the ZX81’s internal frame counter, preventing a system BREAK. After returning, the calling code checks `INKEY$` directly for the expected key — this is safe because `SLOW` mode retains the keyboard state long enough for the test. The input routine at lines 5000–5190 stores the country number as a string in `C$`, then uses `VAL C$` at line 5012 to obtain the numeric index `C`. The country number string is also written directly into the first three columns of the record via `D$(C, TO 3)=C$`. The review routine (line 3030) steps by 21 with `FOR B=PS TO 340 STEP 21` and prints a page of 22 records with an inner loop, using a guard at line 3050 to stop at record 341. The “B” key advances pages; any other key returns to the main menu — though the logic at lines 3090–3100 has a minor anomaly: line 3100 tests `INKEY$<>"B"` which is always true right after a non-B key exits line 3090, but the intent is simply to branch to 130 on any non-B input. ### Notable Anomalies - Line 4050 is missing from the listing (skips from 4040 to 4060), suggesting a deleted line. - Lines 4100 and 4120–4130 are also absent, indicating further deletions in the totals section. - Line 1120 tests `D$(C,1)=" "` to detect an empty record, then calls subroutine 8100; however, execution falls through to line 1130 regardless, because there is no explicit RETURN path after the GOSUB — the program then checks `INKEY$` for Y/N navigation, which works correctly in practice. - The SAVE line (9000) saves the file with an inverse-video character embedded in the name. *** ### Program 2: TYPE — Full-Screen Typewriter Written by R. J. Lees (revision 1, May 1983), this utility turns the display into a typewriter, printing characters at a tracked cursor position `(N,C)` and displaying a block-graphic cursor character (`\##`, inverse hash) at the current position. It supports 22 lines of 32 columns. ### Program Structure - Lines 1–5: REMs and initialization (`L=0` line count) - Lines 10–210: Main character-input loop; cursor display and movement - Lines 300–320: Space (character 118 = newline/enter on ZX81 — actually this handles ENTER as space+advance) - Lines 400–450: Newline/carriage return handling with SCROLL at row 21 - Lines 500–530: Backspace (character 119) - Lines 600–630: Cursor jump by line and column (triggered by character 117 at column 0) - Lines 700–800: End-of-screen (22 lines filled) — waits for keypress, optionally prints/copies - Lines 900–930: Cursor repositioning after end-of-screen - Line 9000–9010: SAVE and restart ### Cursor and Column Tracking The variable `C` tracks the current column (0–31) and `N` tracks the current row. After each character is printed, `C` is incremented. When `C` reaches 27–31, the code at lines 160–200 places inverse digit characters (`%5` through `%1`) as a visual countdown to the end of the line, alerting the typist that the margin is near. At `C=32`, a newline is forced. ### Control Key Mapping | CHR$ code | Action | | --- | --- | | 118 | Print space and advance (treated as spacebar or ENTER) | | 114 | Carriage return / newline | | 119 | Backspace (move cursor left) | | 117 at C=0 | Jump to specific line and column | | 117 (end-of-screen) | Jump to specific line and column after full page | | 14 (end-of-screen) | COPY screen to printer, then scroll and continue | ### Notable Techniques The main input loop uses the classic double-wait idiom: lines 50–60 first flush any held key (`INKEY$<>""` busy-wait), then wait for a new keypress (`INKEY$=""` busy-wait), bracketed by `SLOW`/`FAST` for display stability. The cursor is a block-graphic inverse character printed with `PRINT AT N,C;"\##"`. The line counter `L` is reset to 0 at line 5 (not line 10), and `L=L-1` appears in the cursor-jump routines to compensate for the increment that will occur when execution resumes normally — this prevents double-counting of lines when repositioning. The revision note in line 2 documents that lines 630 and 930 were changed from `GOTO 20` to `GOTO 30`, which skips the `LET N=21` reset, allowing the cursor jump to land at an arbitrary row rather than always resetting to row 21. ## Source Code ``` 11 DIM C$(3) 12 DIM P$(11) 13 DIM N$(10) 14 DIM I$(5) 15 DIM D$(340,32) 100 PRINT TAB 5;"DXCC COUNTRIES LIST" 101 PRINT "PROG. BY W3ZQN, R J LEES, 09/82" 105 PRINT "%T%O% %R%U%N% %U%S%E% %"%G%O%T%O% %1%0%0%"% % % % % % % % % % % %T%O% %S%A%V%E% %U%S%E% %"%G%O%T%O% %9%0%0%0%"% % % % % % % % % %I%F% %"%R%U%N%"% %U%S%E%D%,% %A%L%L% %D%A%T%A% %I%S% %L%O%S%T% " 110 PRINT ,,"EACH DATA LINE HAS:",TAB 2;"COUNTRY NUMBER- 3 SPACES",TAB 10;"PREFIX-11",TAB 10;"NAME -10",TAB 10;"DATA - 5" 120 PRINT ,," DATA IS MO, YR, AND DXCC CODE: (S)ENT/(R)ECEIVED/(C)REDITED" 130 PRINT ,,,,"%E%N%T%E%R% %R%O%U%T%I%N%E% %D%E%S%I%R%E%D%:"," S-SEARCH (LOCATE/CHANGE DATA)"," R-REVIEW (BY PAGES)"," T-TOTALS (WORKED,CREDITED,ETC) I-INPUT (CHANGE DATA BASE)"," E-EXIT (STOP THE PROGRAM)" 140 GOSUB 8000 150 IF INKEY$="S" THEN GOTO 1000 160 IF INKEY$="R" THEN GOTO 3000 170 IF INKEY$="T" THEN GOTO 4000 180 IF INKEY$="I" THEN GOTO 5000 190 IF INKEY$="E" THEN GOTO 7000 200 GOTO 130 1000 PRINT "%S%E%L%E%C%T% %S%E%A%R%C%H% %R%O%U%T%I%N%E%:",TAB 3;"C-BY NUMBER",,TAB 3;"P-BY PREFIX",,TAB 3;"N-BY NAME" 1010 GOSUB 8000 1020 IF INKEY$="C" THEN GOTO 1100 1030 IF INKEY$="P" THEN GOTO 1500 1040 IF INKEY$="N" THEN GOTO 2000 1050 GOTO 1000 1100 PRINT "%E%N%T%E%R% %C%O%U%N%T%R%Y% %N%O%.%:" 1110 INPUT C 1120 IF D$(C,1)=" " THEN GOSUB 8100 1130 IF INKEY$="Y" THEN GOTO 1100 1140 IF INKEY$="N" THEN GOTO 130 1150 CLS 1160 PRINT D$(C) 1170 GOSUB 6000 1180 IF INKEY$="N" THEN GOTO 1250 1190 IF INKEY$="Y" THEN GOSUB 6100 1195 IF INKEY$="Y" THEN GOTO 1100 1200 GOTO 130 1250 GOSUB 6500 1260 GOTO 1195 1500 PRINT "%E%N%T%E%R% %P%R%E%F%I%X" 1510 INPUT P$ 1520 FOR C=1 TO 340 1530 IF D$(C,5 TO 15)=P$ THEN GOTO 1600 1540 NEXT C 1550 GOSUB 8100 1560 IF INKEY$="Y" THEN GOTO 1500 1570 IF INKEY$="N" THEN GOTO 130 1580 GOTO 1550 1600 CLS 1610 PRINT D$(C) 1620 GOSUB 6000 1630 IF INKEY$="N" THEN GOTO 1700 1640 IF INKEY$="Y" THEN GOSUB 6100 1650 IF INKEY$="Y" THEN GOTO 1500 1660 GOTO 130 1700 GOSUB 6500 1710 GOTO 1650 2000 PRINT "%E%N%T%E%R% %C%O%U%N%T%R%Y% %N%A%M%E" 2010 INPUT N$ 2020 FOR C=1 TO 340 2030 IF D$(C,17 TO 26)=N$ THEN GOTO 2100 2040 NEXT C 2050 GOSUB 8100 2060 IF INKEY$="Y" THEN GOTO 2000 2070 IF INKEY$="N" THEN GOTO 130 2080 GOTO 2050 2100 CLS 2110 PRINT D$(C) 2120 GOSUB 6000 2130 IF INKEY$="N" THEN GOTO 2200 2140 IF INKEY$="Y" THEN GOSUB 6100 2150 IF INKEY$="Y" THEN GOTO 2000 2160 GOTO 130 2200 GOSUB 6500 2210 GOTO 2150 3000 PRINT "USE ""B"" (SCROLL) TO PAGE FORWARDHIT ANY KEY TO EXIT ROUTINE" 3010 PRINT ,,"%S%T%A%R%T% %P%A%G%E% %A%T% %W%H%A%T% %C%O%U%N%T%R%Y% %N%O%.%?" 3020 INPUT PS 3025 CLS 3030 FOR B=PS TO 340 STEP 21 3040 FOR C=B TO B+21 3050 IF C=341 THEN GOTO 3080 3060 PRINT D$(C) 3070 NEXT C 3080 GOSUB 8000 3090 IF INKEY$="B" THEN GOTO 3110 3100 IF INKEY$<>"B" THEN GOTO 130 3110 NEXT B 3120 GOTO 130 4000 LET CL=0 4010 LET CW=0 4020 LET CS=0 4030 LET CR=0 4040 LET CC=0 4060 FOR C=1 TO 340 4070 IF D$(C,5)<>" " THEN LET CL=CL+1 4080 IF D$(C,28)<>" " THEN LET CW=CW+1 4090 IF D$(C,32)="S" THEN LET CS=CS+1 4110 IF D$(C,32)="R" THEN LET CR=CR+1 4140 IF D$(C,32)="C" THEN LET CC=CC+1 4150 NEXT C 4160 PRINT CL,"COUNTRIES LISTED" 4170 PRINT ,,CW,"WORKED" 4180 PRINT ,,CL-CW,"NOT WORKED" 4190 PRINT ,,CS,"QSL SENT,NO RET" 4200 PRINT ,,CR,"QSL SENT AND RET" 4210 PRINT ,,CC,"DXCC CREDITED" 4220 PRINT ,,,,"%H%I%T% %A%N%Y% %K%E%Y% %T%O% %R%E%T%U%R%N" 4230 GOSUB 8000 4240 GOTO 130 5000 PRINT "%C%O%U%N%T%R%Y% %N%O%.%?% %(%0% %T%O% %E%X%I%T%)" 5010 INPUT C$ 5012 LET C=VAL C$ 5015 IF C<1 OR C>340 THEN GOTO 5200 5020 CLS 5025 LET D$(C, TO 3)=C$ 5030 PRINT "COUNTRY NUMBER: ";C;" " 5040 PRINT AT 2,0;"%P%R%E%F%I%X%?% %(%1%1% %M%A%X%)" 5050 INPUT P$ 5060 LET D$(C,5 TO 15)=P$ 5070 PRINT AT 2,0;" PREFIX: ";P$ 5080 PRINT AT 4,0;"%N%A%M%E%?% %(%1%0% %M%A%X%)" 5090 INPUT N$ 5100 LET D$(C,17 TO 26)=N$ 5110 PRINT AT 4,0;" NAME: ";N$ 5120 PRINT AT 6,0;"%D%A%T%A%?% %(%M%M%Y%Y%S%/%R%/%C%)" 5130 INPUT I$ 5140 LET D$(C,28 TO 32)=I$ 5150 PRINT AT 6,0;" DATA: ";I$ 5160 PRINT AT 9,0;D$(C) 5170 PRINT AT 13,0;"%H%I%T% %A%N%Y% %K%E%Y% %T%O% %C%O%N%T%I%N%U%E" 5180 GOSUB 8000 5190 GOTO 5000 5200 CLS 5210 GOTO 130 6000 PRINT ,,"CHANGE DATA? %Y%/%N" 6010 GOSUB 8000 6020 RETURN 6100 PRINT AT 20,0;D$(C) 6110 PRINT AT 21,1;D$(C,28 TO ) 6120 INPUT I$ 6130 LET D$(C,28 TO )=I$ 6140 CLS 6150 PRINT D$(C) 6160 GOSUB 6500 6170 RETURN 6500 PRINT ,,"ANOTHER? %Y%/%N" 6519 GOSUB 8000 6520 RETURN 7000 CLS 7010 PRINT "YOU HAVE STOPPED THE PROGRAM",,,"REMEMBER: TO START IT AGAIN USE",TAB 10;"""GOTO 100""; TO SAVE IT";TAB 10;"USE ""GOTO 9000""",TAB 10;"NEVER USE ""RUN"" OR ",TAB 10;"DATA WILL BE LOST" 7020 STOP 8000 SLOW 8005 PAUSE 20 8006 POKE 16437,255 8010 IF INKEY$="" THEN GOTO 8010 8020 FAST 8030 CLS 8040 RETURN 8100 CLS 8105 PRINT "NOT FOUND. TRY AGAIN? %Y%/%N" 8110 GOSUB 8000 8120 RETURN 9000 SAVE "DXC%C" 9010 GOTO 100 1 REM PROGRAM "TYPE" BY W3ZQN- R. J. LEES, 705 JONATHAN RD., KING OF PRUSSIA, PA. 19406, JAN,1983 2 REM REV. 1, 5/83: ADDED LINES 625 AND 925; REVISED LINES 630 AND 930 FROM "GOTO 20" TO "GOTO 30" - THIS ALLOWS EDITING BY LINE NO. AND COLUMN NO. 5 LET L=0 10 LET N=21 20 LET C=0 30 PRINT AT N,C;"##" 40 SLOW 50 IF INKEY$<>"" THEN GOTO 50 60 IF INKEY$="" THEN GOTO 60 70 FAST 80 PRINT AT N,C;INKEY$; 90 IF INKEY$=CHR$ 118 THEN GOTO 300 100 IF INKEY$=CHR$ 114 THEN GOTO 400 110 IF INKEY$=CHR$ 119 THEN GOTO 500 120 IF INKEY$=CHR$ 117 AND C=0 THEN GOTO 600 130 LET C=C+1 140 IF C=32 THEN GOTO 410 150 IF C<27 THEN PRINT AT N,C;"##" 160 IF C=27 THEN PRINT AT N,C;"%5" 170 IF C=28 THEN PRINT AT N,C;"%4" 180 IF C=29 THEN PRINT AT N,C;"%3" 190 IF C=30 THEN PRINT AT N,C;"%2" 200 IF C=31 THEN PRINT AT N,C;"%1" 210 GOTO 40 300 PRINT AT N,C;" " 320 GOTO 130 400 PRINT AT N,C;" " 410 LET L=L+1 420 IF L=22 THEN GOTO 700 430 IF N<>21 THEN GOTO 10 440 SCROLL 450 GOTO 20 500 PRINT AT N,C;" " 510 IF C=0 THEN GOTO 530 520 LET C=C-1 530 GOTO 30 600 INPUT EL 610 LET N=21-EL 620 LET L=L-1 625 INPUT C 630 GOTO 30 700 SLOW 710 IF INKEY$<>"" THEN GOTO 710 720 IF INKEY$="" THEN GOTO 720 730 FAST 740 IF INKEY$=CHR$ 117 THEN GOTO 900 750 IF INKEY$=CHR$ 14 THEN GOTO 770 760 GOTO 700 770 COPY 780 PRINT AT 21,0;"-----" 790 SCROLL 800 GOTO 5 900 INPUT EM 910 LET N=22-EM 920 LET L=L-1 925 INPUT C 930 GOTO 30 9000 SAVE "TYP%E" 9010 GOTO 5 ```