This program is a 64-column print utility that uses an external machine code routine (loaded from tape at address 57000, 2671 bytes long) to enable 64-character-wide mode. Text is entered by the user one character at a time, stored in a large 20,000-byte string array `a$`, and passed to the machine code via POKEs to addresses 57039 and 57041 before calling specific entry points (57077 for display file rendering, 57090/57104 for type-input handling, 57131 for a clear/reset routine, and 58000 for copy/print). Pages are 1,408 characters each, allowing the array to hold approximately 14 pages of text. The utility supports typing new text, loading existing data from tape, displaying it on screen, copying to printer, and saving the text buffer back to tape as a raw CODE block.
Program Analysis
Program Structure
The program is organized into a set of short subroutines at low line numbers (10–90), a type-input loop (100–160), a display-file section (300–310), a main initialization block (9000–9060), and a save/master-copy line (9999). The listing appears three times in the source, which is a formatting artifact of the submission — the program itself is a single unit.
| Lines | Role |
|---|---|
| 20 | Display-file subroutine: renders stored text via machine code |
| 40 | Type subroutine A: passes character to machine code entry point 57090 |
| 50 | Type subroutine B: passes character to machine code entry point 57104 |
| 60 | Initializes machine code page parameters (column offset 0, width 64) |
| 70 | CLS then calls machine code clear/reset at 57131 |
| 90 | Clears the lower status bar (stream #0, row 0) |
| 100–160 | Interactive text-entry loop, one character at a time |
| 300–310 | Display/review loop, page by page |
| 9000–9060 | Startup: dimensions array, loads machine code, sets colors, menu |
| 9999 | Development save line: saves BASIC and machine code to tape |
Machine Code Interface
The heart of the utility is a 2,671-byte machine code block loaded at address 57000. BASIC communicates with it entirely through POKEs to a small parameter area before each RANDOMIZE USR call:
POKE 57039, CODE a$(i)+1— writes the character code (incremented by 1, likely converting to an internal token/index) for display renderingPOKE 57041, CODE a$(i+1)— writes the second character of a pair for the display-file pathPOKE 57043, 0andPOKE 57044, 64— set the column offset and line width for the 64-column mode
The machine code exposes at least five distinct entry points:
| Address | Purpose |
|---|---|
| 57000 | Main initialization routine |
| 57077 | Display-file character renderer (processes pairs from a$) |
| 57090 | Type-mode handler, first character in a pair |
| 57104 | Type-mode handler, second character in a pair |
| 57131 | Screen/printer clear or reset |
| 58000 | Copy/print trigger |
The OUT 255,54 at line 9040 is a hardware port write, likely controlling a printer interface or related peripheral to set it into 64-column mode.
Text Storage and Paging
Text is held in a$, dimensioned to 20,000 characters. A page is exactly 1,408 characters (64 columns × 22 rows, the printable area). Characters are stored in pairs and processed two at a time by the display loop at line 20, which iterates FOR i=c1 TO c2 STEP 2. The variable c1 advances by 1,408 on each new page, so up to approximately 14 pages can be stored in the array without reloading.
Machine Code Address Recovery
Line 9005 contains a notable technique for recovering the load address of the machine code block after it has been loaded from tape. Since LOAD ""CODE without an explicit address uses the address stored in the tape header, the code reads system variables 23629/23630 (the last LOAD address, sometimes called PROG or a related pointer) via PEEK and reconstructs the 16-bit address into j:
POKE 56998, PEEK 23629 : POKE 56999, PEEK 23630 : LET j = 256*PEEK 56999 + PEEK 56998
This value j is then used both as the base address for subsequent LOAD ""CODE j calls (line 9030) and as the start address for SAVE "64c"CODE j,i+1 (line 135).
Key BASIC Idioms
VAL "number"in GO TO/GO SUB: Used extensively throughout to encode branch targets as string literals, saving tokenized number storage bytes in the BASIC line.PAUSE 0: LET b$=INKEY$: Standard efficient keypress-wait pattern appearing at lines 110, 120, 130, 305.LET a$(1)=a$(1)at line 9005: A dummy self-assignment used to force the interpreter to allocate and fix the DIM’d string array in memory before its address is captured.- Stream
#0for status messages: All user-facing prompts are written to the lower screen viaPRINT #0;AT ..., keeping the main display area undisturbed.
Notable Anomalies
- Line 9010 contains a typo:
"Pleae press 2"instead of"Please press 2". - The
©keyword (RESET) appears in the REM header (line 3) as part of the author attribution layout, not as executable code. - Line 135 saves
CODE j, i+1— the lengthi+1reflects the current character count, making each save a variable-length snapshot of typed content. - The display loop at line 310 advances
c2by adding 1407 to the newc1(LET c2=c1+1407), which is correct for a 1,408-character page (indicesc1toc1+1407inclusive).
Content
Source Code
1 REM ***********************
2 REM 64 Column Print Utility
3 REM RESET by S D Lemke
4 REM 2144 White Oak
5 REM Wichita, Ks 67207
6 REM ***********************
10 REM Display File
20 FOR i=c1 TO c2 STEP 2: POKE 57039,(CODE a$(i)+1): POKE 57041,CODE a$(i+1): RANDOMIZE USR 57077: NEXT i: RETURN
30 REM Type
40 POKE 57039,CODE b$+1: RANDOMIZE USR 57090: RETURN
50 POKE 57039,CODE b$+1: RANDOMIZE USR 57104: RETURN
60 POKE VAL "57043",VAL "0": POKE VAL "57044",VAL "64": RETURN
70 CLS : RANDOMIZE USR VAL "57131": RETURN
90 PRINT #0;AT 0,0;" ": RETURN
100 PRINT #0;AT 1,10;"TYPE INPUT"
110 PAUSE 0: LET b$=INKEY$: GO SUB 40: LET i=i+1: LET a$(c1+i)=b$
120 PAUSE 0: LET b$=INKEY$: GO SUB 50: LET i=i+1: LET a$(c1+i)=b$: IF i<=1408 THEN GO TO 110
130 PRINT #0;AT 0,0;"Press N for Next Page, S to Save C to Copy, D to Display File": FOR k=1 TO 20: NEXT k: PAUSE 0: LET b$=INKEY$: GO SUB VAL "90"
135 IF b$="S" OR b$="s" THEN SAVE "64c"CODE j,i+1: GO TO VAL "130"
140 IF b$="C" OR b$="c" THEN PRINT #0;AT 0,0;TAB 31;" ";';TAB 31;" ": RANDOMIZE USR VAL "58000": GO TO VAL "130"
145 IF b$="D" OR b$="d" THEN GO SUB VAL "60": CLS : RANDOMIZE USR VAL "57131": GO TO VAL "300"
150 GO SUB VAL "70": LET c1=1408+c1
160 GO SUB VAL "60": GO TO VAL "100"
300 LET c1=VAL "1": LET c2=VAL "1408": GO SUB VAL "60": GO SUB VAL "70"
305 GO SUB VAL "20": PRINT #0;AT 0,8;"Press any key.": PRINT #0;AT 1,7;"Press C to Copy": PAUSE 0: IF INKEY$="C" OR INKEY$="c" THEN GO SUB VAL "90": RANDOMIZE USR VAL "58000"
310 GO SUB VAL "70": LET c1=c1+1408: LET c2=c1+1407: GO SUB VAL "60": GO TO VAL "305"
9000 DIM a$(20000): LOAD ""CODE : PAPER VAL "1": BORDER VAL "1": INK VAL "7": CLS
9005 LET i=VAL "0": LET c1=VAL "0": GO SUB VAL "60": LET a$(1)=a$(1): POKE VAL "56998",PEEK VAL "23629": POKE VAL "56999",PEEK VAL "23630": LET j=VAL "256"*PEEK VAL "56999"+PEEK VAL "56998"
9010 CLS : PRINT AT VAL "2",VAL "4";"64 Column Print Utility": PRINT AT VAL "10",VAL "0";"Press 1 to type a page";';" 2 to load & display a file Pleae press 2 to load an explanation of this utility and the demo program."
9020 PAUSE VAL "0": LET b$=INKEY$: IF b$="1" OR b$="2" THEN GO TO VAL "9030"
9025 GO TO VAL "9020"
9030 IF b$="2" THEN PRINT AT 14,10;"START TAPE";AT 18,0;" ": LOAD ""CODE j
9040 RANDOMIZE USR VAL "57000": OUT 255,54: CLS : RANDOMIZE USR VAL "57131"
9050 IF b$="1" THEN GO TO VAL "100"
9060 GO TO VAL "300"
9999 CLEAR : SAVE "64c" LINE 9000: SAVE "64c"CODE 57000,2671
1 REM ***********************
2 REM 64 Column Print Utility
3 REM RESET by S D Lemke
4 REM 2144 White Oak
5 REM Wichita, Ks 67207
6 REM ***********************
10 REM Display File
20 FOR i=c1 TO c2 STEP 2: POKE 57039,(CODE a$(i)+1): POKE 57041,CODE a$(i+1): RANDOMIZE USR 57077: NEXT i: RETURN
30 REM Type
40 POKE 57039,CODE b$+1: RANDOMIZE USR 57090: RETURN
50 POKE 57039,CODE b$+1: RANDOMIZE USR 57104: RETURN
60 POKE VAL "57043",VAL "0": POKE VAL "57044",VAL "64": RETURN
70 CLS : RANDOMIZE USR VAL "57131": RETURN
90 PRINT #0;AT 0,0;" ": RETURN
100 PRINT #0;AT 1,10;"TYPE INPUT"
110 PAUSE 0: LET b$=INKEY$: GO SUB 40: LET i=i+1: LET a$(c1+i)=b$
120 PAUSE 0: LET b$=INKEY$: GO SUB 50: LET i=i+1: LET a$(c1+i)=b$: IF i<=1408 THEN GO TO 110
130 PRINT #0;AT 0,0;"Press N for Next Page, S to Save C to Copy, D to Display File": FOR k=1 TO 20: NEXT k: PAUSE 0: LET b$=INKEY$: GO SUB VAL "90"
135 IF b$="S" OR b$="s" THEN SAVE "64c"CODE j,i+1: GO TO VAL "130"
140 IF b$="C" OR b$="c" THEN PRINT #0;AT 0,0;TAB 31;" ";';TAB 31;" ": RANDOMIZE USR VAL "58000": GO TO VAL "130"
145 IF b$="D" OR b$="d" THEN GO SUB VAL "60": CLS : RANDOMIZE USR VAL "57131": GO TO VAL "300"
150 GO SUB VAL "70": LET c1=1408+c1
160 GO SUB VAL "60": GO TO VAL "100"
300 LET c1=VAL "1": LET c2=VAL "1408": GO SUB VAL "60": GO SUB VAL "70"
305 GO SUB VAL "20": PRINT #0;AT 0,8;"Press any key.": PRINT #0;AT 1,7;"Press C to Copy": PAUSE 0: IF INKEY$="C" OR INKEY$="c" THEN GO SUB VAL "90": RANDOMIZE USR VAL "58000"
310 GO SUB VAL "70": LET c1=c1+1408: LET c2=c1+1407: GO SUB VAL "60": GO TO VAL "305"
9000 DIM a$(20000): LOAD ""CODE : PAPER VAL "1": BORDER VAL "1": INK VAL "7": CLS
9005 LET i=VAL "0": LET c1=VAL "0": GO SUB VAL "60": LET a$(1)=a$(1): POKE VAL "56998",PEEK VAL "23629": POKE VAL "56999",PEEK VAL "23630": LET j=VAL "256"*PEEK VAL "56999"+PEEK VAL "56998"
9010 CLS : PRINT AT VAL "2",VAL "4";"64 Column Print Utility": PRINT AT VAL "10",VAL "0";"Press 1 to type a page";';" 2 to load & display a file Pleae press 2 to load an explanation of this utility and the demo program."
9020 PAUSE VAL "0": LET b$=INKEY$: IF b$="1" OR b$="2" THEN GO TO VAL "9030"
9025 GO TO VAL "9020"
9030 IF b$="2" THEN PRINT AT 14,10;"START TAPE";AT 18,0;" ": LOAD ""CODE j
9040 RANDOMIZE USR VAL "57000": OUT 255,54: CLS : RANDOMIZE USR VAL "57131"
9050 IF b$="1" THEN GO TO VAL "100"
9060 GO TO VAL "300"
9999 CLEAR : SAVE "64c" LINE 9000: SAVE "64c"CODE 57000,2671
1 REM ***********************
2 REM 64 Column Print Utility
3 REM RESET by S D Lemke
4 REM 2144 White Oak
5 REM Wichita, Ks 67207
6 REM ***********************
10 REM Display File
20 FOR i=c1 TO c2 STEP 2: POKE 57039,(CODE a$(i)+1): POKE 57041,CODE a$(i+1): RANDOMIZE USR 57077: NEXT i: RETURN
30 REM Type
40 POKE 57039,CODE b$+1: RANDOMIZE USR 57090: RETURN
50 POKE 57039,CODE b$+1: RANDOMIZE USR 57104: RETURN
60 POKE VAL "57043",VAL "0": POKE VAL "57044",VAL "64": RETURN
70 CLS : RANDOMIZE USR VAL "57131": RETURN
90 PRINT #0;AT 0,0;" ": RETURN
100 PRINT #0;AT 1,10;"TYPE INPUT"
110 PAUSE 0: LET b$=INKEY$: GO SUB 40: LET i=i+1: LET a$(c1+i)=b$
120 PAUSE 0: LET b$=INKEY$: GO SUB 50: LET i=i+1: LET a$(c1+i)=b$: IF i<=1408 THEN GO TO 110
130 PRINT #0;AT 0,0;"Press N for Next Page, S to Save C to Copy, D to Display File": FOR k=1 TO 20: NEXT k: PAUSE 0: LET b$=INKEY$: GO SUB VAL "90"
135 IF b$="S" OR b$="s" THEN SAVE "64c"CODE j,i+1: GO TO VAL "130"
140 IF b$="C" OR b$="c" THEN PRINT #0;AT 0,0;TAB 31;" ";';TAB 31;" ": RANDOMIZE USR VAL "58000": GO TO VAL "130"
145 IF b$="D" OR b$="d" THEN GO SUB VAL "60": CLS : RANDOMIZE USR VAL "57131": GO TO VAL "300"
150 GO SUB VAL "70": LET c1=1408+c1
160 GO SUB VAL "60": GO TO VAL "100"
300 LET c1=VAL "1": LET c2=VAL "1408": GO SUB VAL "60": GO SUB VAL "70"
305 GO SUB VAL "20": PRINT #0;AT 0,8;"Press any key.": PRINT #0;AT 1,7;"Press C to Copy": PAUSE 0: IF INKEY$="C" OR INKEY$="c" THEN GO SUB VAL "90": RANDOMIZE USR VAL "58000"
310 GO SUB VAL "70": LET c1=c1+1408: LET c2=c1+1407: GO SUB VAL "60": GO TO VAL "305"
9000 DIM a$(20000): LOAD ""CODE : PAPER VAL "1": BORDER VAL "1": INK VAL "7": CLS
9005 LET i=VAL "0": LET c1=VAL "0": GO SUB VAL "60": LET a$(1)=a$(1): POKE VAL "56998",PEEK VAL "23629": POKE VAL "56999",PEEK VAL "23630": LET j=VAL "256"*PEEK VAL "56999"+PEEK VAL "56998"
9010 CLS : PRINT AT VAL "2",VAL "4";"64 Column Print Utility": PRINT AT VAL "10",VAL "0";"Press 1 to type a page";';" 2 to load & display a file Pleae press 2 to load an explanation of this utility and the demo program."
9020 PAUSE VAL "0": LET b$=INKEY$: IF b$="1" OR b$="2" THEN GO TO VAL "9030"
9025 GO TO VAL "9020"
9030 IF b$="2" THEN PRINT AT 14,10;"START TAPE";AT 18,0;" ": LOAD ""CODE j
9040 RANDOMIZE USR VAL "57000": OUT 255,54: CLS : RANDOMIZE USR VAL "57131"
9050 IF b$="1" THEN GO TO VAL "100"
9060 GO TO VAL "300"
9999 CLEAR : SAVE "64c" LINE 9000: SAVE "64c"CODE 57000,2671
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.







