EPSON COPY

Date: 198x
Type: Program
Platform(s): TS 2068
Tags: Printer

EPSON COPY is a machine code screen dump utility that sends display data to Epson-compatible dot-matrix printers. The BASIC loader POKEs 240 bytes of Z80 machine code into memory starting at address 23296, verifying each 16-byte block against a checksum before saving. The routine interfaces with the printer via port 12 (0Ch), using Z80 instructions such as IN, OUT, and bit manipulation to convert screen pixel data into Epson graphics escape sequences (ESC “A”, ESC “L”). The program is designed to be loaded alongside a companion file called “DRAW DX-85” and saved back as a combined binary for screen dump functionality.


Program Structure

The program is a two-phase BASIC loader. Lines 20–30 handle the installation and verification of machine code, while lines 40–180 contain the raw data. Line 190 acts as a safety STOP, and line 200 saves the BASIC loader itself under the name “EPSON COPY”.

  1. Lines 10–30: Install and checksum-verify 15 blocks of 16 bytes each into RAM starting at address 23296 (0x5B00), then save the result.
  2. Lines 40–180: Fifteen DATA statements, each containing 16 machine code bytes followed by a checksum (sum of the 16 bytes).
  3. Line 200: Saves the BASIC loader program itself.

Machine Code Installation

The loader uses a pointer variable a initialized to 23296 and increments it with each POKE. After reading each group of 16 bytes, it reads a 17th value and compares it to the running sum s. A mismatch triggers an informative error message indicating the faulty DATA line (20+10*t), then halts with STOP. This is a robust integrity check for typed-in listings.

Save Mechanism

Line 30 uses SAVE *"draw dx-85",23296,256,23298. The asterisk form of SAVE appends a CODE block to an existing microdrive or device file named “draw dx-85”, saving 256 bytes from address 23296 with an autostart address of 23298. This merges the screen dump routine into the companion program rather than creating a standalone file.

Z80 Machine Code Analysis

Disassembling the 240 bytes of payload (15 × 16 bytes, noting the final block is padded with zeros) reveals the following functional areas:

  • Entry and setup (block 1, DATA line 40): Loads register pairs and begins iterating over the screen memory region (0x5CB7 = 23735, within display file territory).
  • Printer output (blocks 2–3): Uses RST 16 (byte 0xD7) for character output and interfaces with port 0x0C (12 decimal) via IN A,(12) (0xDB, 0x0C) to poll printer status.
  • Epson escape sequences (blocks 6–8, DATA lines 90–110): Sends ESC (0x1B), followed by “A” (0x41), byte value 8, and CR (0x0D) — this is the Epson ESC A n line spacing command. Also sends ESC “L” (0x4C) for graphics mode entry.
  • Pixel-to-dot conversion (blocks 10–12, DATA lines 140–160): Performs four right-shifts (SRL = 0xCB 0x1F series) to repack pixel nibbles, consistent with converting Spectrum pixel rows into Epson single-density graphics bytes.
  • Line termination (block 13, DATA line 160): Sends LF (0x0A) and CR (0x0D) after each graphics row.
  • Form-feed and reset logic (blocks 14–15, DATA lines 170–180): Includes conditional bit-set (SET 7,B = 0xCB 0xFB or similar) and a check against 0xC0, with a final RET (0xC9) and zero padding.

Checksum Table

DATA LineBlockDeclared Checksum
4011605
5021650
6032160
7041744
8051107
9061362
10071429
11081291
12091286
130101525
140111367
150121512
160131593
170141518
18015849

Notable Techniques

  • The 20+10*t expression in the error message dynamically reconstructs the offending DATA line number, giving the typist precise feedback without storing line numbers separately.
  • Placement at address 23296 (0x5B00) uses the area just below the system variables at 23552 (0x5C00), a common location for short machine code routines that avoids disturbing RAMTOP or the BASIC program.
  • The 17th value in each DATA group is an arithmetic checksum (simple byte sum, not modular), which catches both transcription errors and off-by-one data shifts.
  • The final DATA block (line 180) contains six trailing zero bytes, indicating the actual machine code is shorter than the full 240 bytes allocated — padding is used to maintain uniform block structure for the checksum loop.

Potential Anomalies

The SAVE * syntax (line 30) targets a Microdrive or Interface 1 device; the program will error on a standard tape interface without modification. Additionally, the companion file “draw dx-85” must already exist on the target device before line 30 executes, as the asterisk-form save appends rather than creates.

Source Code

  10 REM SCREEN COPY ON EPSON PRINTERS "COPY.EPSON"...LOAD WITH "DRAW DX-85"...FOR SCREEN DUMP
  20 LET a=23296:FOR t=1 TO 15:LET s=0:FOR n=1 TO 16:READ b:POKE a,b:LET s=s+b:LET a=a+1:NEXT n: READ b:IF b <>s THEN PRINT "Error in line";20+10*t:STOP 
  30 NEXT t:SAVE *"draw dx-85",23296,256,23298:STOP 
  40 DATA 2,6,33,183,92,1,60,91,113,35,112,219,12,225,195,226,1605
  50 DATA 1,197,197,22,8,120,215,176,34,71,4,126,7,16,253,203,1650
  60 DATA 19,193,4,197,21,32,238,193,193,201,213,95,205,121,26,209,2160
  70 DATA 201,58,0,91,61,200,62,3,50,0,91,201,254,252,194,26,1744
  80 DATA 1,33,71,91,195,9,1,205,65,10,205,219,1,1,0,0,1107
  90 DATA 62,27,205,42,91,62,65,205,42,91,62,8,205,42,91,62,1362
 100 DATA 13,205,42,91,205,62,12,40,21,246,32,254,97,32,15,62,1429
 110 DATA 27,205,42,91,62,65,205,42,91,62,12,195,42,91,58,1,1291
 120 DATA 91,95,28,29,40,7,62,32,205,42,91,24,246,62,27,205,1286
 130 DATA 42,91,62,76,205,42,91,175,205,42,91,205,49,91,58,0,1525
 140 DATA 91,205,42,91,205,17,91,205,49,91,123,40,24,31,31,31,1367
 150 DATA 31,22,4,203,15,203,27,203,43,21,32,247,123,205,42,91,1512
 160 DATA 123,205,42,91,123,205,42,91,12,32,217,62,10,205,42,91,1593
 170 DATA 62,13,205,42,91,205,49,91,62,8,40,2,203,63,128,254,1518
 180 DATA 192,200,71,195,100,91,0,0,0,0,0,0,0,0,0,0,849
 190 STOP 
 200 SAVE "EPSON COPY"

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.