This program is a ZX81/TS1000 EPROM programmer utility that guides the user through copying a ROM image into an 8192-byte array, applying user-selected patches, and then burning the result to an EPROM chip. It reads the first 8 KB of memory address space using PEEK (addresses 0–8191) into a string array A$(8192), then selectively overlays specific byte ranges from a secondary buffer B$ using a GOSUB-based copy routine at line 3. Options include a parallel printer-port patch, a configurable power-up character color (0–15), background and border color bytes, and a switch between 16K and 48K memory-check ROM routines. The EPROM burning loop at line 700 uses POKE with a 3-frame PAUSE per byte to meet programming timing requirements, and a checksum is calculated via a second GOSUB loop that sums all CODE values. A machine-code routine at address 16514, called via USR 16514, performs a tape-load integrity check against the expected value 55194.
Program Structure
The program is organised into several logical phases, each separated by CLS and user prompts:
- Tape integrity check (line 17, subroutine 8000): calls
USR 16514and validates the result. - Optional tape copy (lines 19–23): offers
SAVE "PRO%G"at line 7000 before proceeding. - Initialisation (lines 25–340): reads 8 KB from addresses 0–8191 via
PEEKintoA$(8192), then applies patches via a GOSUB copy loop. - Option selection (lines 400–660): collects printer patch, colour, border, and memory-check preferences.
- EPROM burn (lines 675–740): iterates over the array and
POKEs each byte with a short pause. - Checksum verification (lines 800–880): sums all byte values and displays the result.
Subroutines
| Lines | Purpose | Entry point label |
|---|---|---|
| 3–7 | Copy B$(X…) into A$(A TO B) | L (via GOSUB L) |
| 8–11 | Accumulate checksum: sum CODE A$(N) for N=1–8192 | line 8 |
| 8000–8110 | Tape-load verification via USR 16514 | line 8000 |
The copy subroutine at lines 3–7 uses shared variables A, B, and X: A and B define the destination range in A$, while X is a running index into B$ that is not reset between calls, so segments are copied sequentially from B$ into non-contiguous ranges of A$.
EPROM Burn Loop
The burn loop at lines 700–740 contains a notable bug: the loop variable N iterates from 1 to X (which was set to 8192 at line 690), but inside the loop X itself is incremented (LET X=X+1 at line 720), and POKE X, CODE A$(N) uses the modified X as the destination address rather than N. This means bytes are written starting at address 8193 (0x2001) rather than address 0, and the destination address drifts upward in parallel with N. The PAUSE 3 at line 730 provides approximately 3 frame-periods (~50 ms at 50 Hz) per byte to satisfy EPROM programming pulse-width requirements.
Patch Application
After the bulk copy, line 340 directly overwrites three bytes of A$:
A$(517 TO 519) = CHR$ 195 + "%I\ '"— writes three specific byte values (0xC3 = Z80 JP instruction, then two address bytes) into what is likely a jump vector.
The printer-patch option (lines 450–472) writes either "COS " / "4" or " SCROLL " / "\ '" into A$(2168) and A$(2169), corresponding to different ROM bytes at offset 0x877–0x878 depending on whether the parallel printer port patch is applied.
The 48 K memory-check option (lines 640–650) writes " RETURN " and " COPY " into A$(4) and A$(5), patching the early ROM memory-test routine to skip the 16 K limit.
Colour Configuration
The program prompts for a foreground colour (0–15) stored in A and a background colour in B, computing a packed byte C = A*16 + B (line 520) and storing it into A$(7751). A separate border byte is similarly computed and stored at A$(7688). Value 16 for the border is treated as “no border” (line 560 jumps past the packing step). These offsets correspond to specific locations in what appears to be a custom ROM image.
Notable Idioms and Anomalies
GOSUB Lat lines 90–330 uses the variable nameLas a line-number argument — the value ofLis never explicitly set, so it defaults to 0, which would jump to line 0 (or the nearest line, line 1 in most implementations). This appears to be an error; the intent is almost certainlyGOSUB 3.GOTO 2is never used; line 2 (GOTO 17) is only reachable via the tape-copy restart at line 7010 (GOTO 1→ REM, falls through to line 2).PAUSE 4E4(lines 680 and 825) pauses for 40,000 frames — approximately 13 minutes at 50 Hz — giving the user time to switch the EPROM programmer’s VPP supply voltage before the burn begins.
Content
Source Code
1 REM
2 GOTO 17
3 FOR N=A TO B
4 LET A$(N)=B$(X)
5 LET X=X+1
6 NEXT N
7 RETURN
8 FOR N=1 TO 8192
9 LET X=X+CODE A$(N)
10 NEXT N
11 RETURN
15 REM DIM B$(704)
17 GOSUB 8000
19 PRINT AT 8,0;"IF YOU DESIRE TO MAKE A BACK UP OF THIS TAPE, OR A COPY FOR A FRIEND, THEN ENTER ""S"" AFTER RECORDER IS READY AND RUNNING.";AT 20,0;" ""S-ENTER"" TO COPY OR ""ENTER"" ONLY TO CONTINUE"
21 INPUT K$
22 CLS
23 IF K$="S" THEN GOTO 7000
25 PRINT AT 9,0;"THERE WILL NOW BE A DELAY FOR INITIALIZATION....";AT 21,7;"%P%L%E%A%S%E %S%T%A%N%D %B%Y"
27 FAST
29 PAUSE 400
31 DIM A$(8192)
33 FOR N=1 TO 8192
40 LET A$(N)=CHR$ (PEEK (N-1))
50 NEXT N
60 LET X=1
70 LET A=57
80 LET B=73
90 GOSUB L
100 LET A=103
110 LET B=126
120 GOSUB L
130 LET A=528
140 LET B=553
150 GOSUB L
160 LET A=596
170 LET B=699
180 GOSUB L
190 LET A=732
200 LET B=743
210 GOSUB L
220 LET A=749
230 LET B=751
240 GOSUB L
250 LET A=1041
260 LET B=1043
270 GOSUB L
280 LET A=2225
290 LET B=2227
300 GOSUB L
310 LET A=7681
320 LET B=8192
330 GOSUB L
340 LET A$(517 TO 519)=CHR$ 195+"%I\ '"
390 SLOW
400 CLS
410 PRINT AT 1,0;"INITIALIZATION COMPLETE.",,,"NOW, FOR THE OPTIONS.";AT 8,0;"WOULD YOU LIKE TO INCLUDE THE PRINTER PATCH AT 0876H FOR MY PARALLEL PRINTER PORT PUBLISHED IN SQ NO. 1?";AT 21,0;"ENTER ""Y"" FOR YES OR ""N"" FOR NO"
420 INPUT K$
430 IF K$="" THEN GOTO 470
440 IF K$(1)<>"Y" THEN GOTO 470
450 LET A$(2168)="COS "
460 LET A$(2169)="4"
465 GOTO 475
470 LET A$(2168)=" SCROLL "
472 LET A$(2169)="\ '"
475 CLS
480 PRINT "ENTER DEFAULT ON POWER UP CHARACTER COLOR DESIRED.","(WHITE RECCOMENDED)";AT 5,0;" 0=TRANSPARENT",," 1=BLACK",," 2=MEDIUM GREEN",," 3=LIGHT GREEN",," 4=DARK BLUE",," 5=LIGHT BLUE",," 6=DARK RED",," 7=CYAN",," 8=MEDIUM RED",," 9=LIGHT RED",,"10=DARK YELLOW",,"11=LIGHT YELLOW",,"12=DARK GREEN",,"13=MAGNETA",,"14=GREY",,"15=WHITE"
490 INPUT A
495 IF A>15 THEN GOTO 480
500 PRINT AT 1,0;"BACKGROUND";AT 2,1;"BLACK"
510 INPUT B
520 LET C=A*16+B
530 LET A$(7751)=CHR$ C
540 PRINT AT 1,0;" BORDER ";AT 2,1;"NO BORDER RECCOMENDED)";AT 21,0;"16=NO BORDER"
550 INPUT B
560 IF B=16 THEN GOTO 590
570 IF B>16 THEN GOTO 550
580 LET C=A*16+B
590 LET A$(7688)=CHR$ C
600 CLS
610 PRINT AT 3,0;"WOULD YOU LIKE A FULL 48K MEMORYCHECK ON POWER-UP, OR THE NORMAL16K MEMORY CHECK?";AT 21,6;"ENTER ""16"" OR ""48"""
620 INPUT K$
630 IF K$<>"48" THEN GOTO 660
640 LET A$(4)=" RETURN "
650 LET A$(5)=" COPY "
660 CLS
670 PRINT AT 2,0;"OPTION PROGRAMMING COMPLETE";AT 9,0;"PREPARE PROGRAMMER TO PROGRAM EPROM BY SWITCHING ITS VPP POWERSUPPLY FROM 4.4V TO 21VDC";AT 21,0;"PRESS ""ENTER"" TO PROGRAM EPROM"
675 FAST
680 PAUSE 4E4
690 LET X=8192
700 FOR N=1 TO X
710 POKE X,CODE A$(N)
720 LET X=X+1
730 PAUSE 3
740 NEXT N
800 CLS
810 PRINT AT 5,0;"EPROM IS NOW PROGRAMMED";AT 11,0;"SWITCH VPP POWER SUPPLY VOLTAGE BACK TO 4.4 VOLTS";AT 20,0;"PRESS ""ENTER"" TO START CHECKSUM COMPUTATION"
820 LET X=0
825 PAUSE 4E4
830 GOSUB 8
860 CLS
865 SLOW
870 PRINT AT 2,0;"CHECKSUM FOR YOUR EPROM=";X;AT 8,0;"WRITE DOWN YOUR CHECKSUM FOR LATER VERIFICATION OF YOUR EPROM";AT 15,0;"UNPLUG THE VPP SUPPLY AND THEN DOWNPOWER YOUR COMPUTER--";AT 21,0;"YOUR EPROM IS READY......"
880 STOP
\n7000 SAVE "PRO%G"
\n7010 GOTO 1
\n8000 LET CS=USR 16514
\n8005 CLS
\n8010 IF CS<>55194 THEN GOTO 8100
\n8020 PRINT AT 10,0;"THE TAPE LOAD CHECKS GOOD"
\n8040 PAUSE 150
\n8050 CLS
\n8070 RETURN
\n8100 PRINT AT 8,0;"THE TAPE LOAD CHECKS BAD";AT 12,0;"TRY LOADING THE TAPE AGAIN"
\n8110 STOP
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

