TMS9918A Video Enhanced Basic EPROM Programmer

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:

  1. Tape integrity check (line 17, subroutine 8000): calls USR 16514 and validates the result.
  2. Optional tape copy (lines 19–23): offers SAVE "PRO%G" at line 7000 before proceeding.
  3. Initialisation (lines 25–340): reads 8 KB from addresses 0–8191 via PEEK into A$(8192), then applies patches via a GOSUB copy loop.
  4. Option selection (lines 400–660): collects printer patch, colour, border, and memory-check preferences.
  5. EPROM burn (lines 675–740): iterates over the array and POKEs each byte with a short pause.
  6. Checksum verification (lines 800–880): sums all byte values and displays the result.

Subroutines

LinesPurposeEntry point label
3–7Copy B$(X…) into A$(A TO B)L (via GOSUB L)
8–11Accumulate checksum: sum CODE A$(N) for N=1–8192line 8
8000–8110Tape-load verification via USR 16514line 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 L at lines 90–330 uses the variable name L as a line-number argument — the value of L is 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 certainly GOSUB 3.
  • GOTO 2 is 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

Appears On

Related Products

Two board, extensive upgrade that integrates the TMS 9918A video display processor into the ZX81/TS1000. Provides: color multiple graphics resolutions,...
For use with the TMS9918A Video Project/Upgrade.

Related Articles

Related Content

Image Gallery

TMS9918A Video Enhanced Basic EPROM Programmer

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.

Scroll to Top