Pixel Print Font Utility Package 1

Program for designing fonts for use with Pixel Print.

This package contains three interrelated BASIC programs: a loader/menu (lines 1–9999 of the first program), a font designer utility called FONT-D, and an SG-10 dot-matrix printer font downloader called FONT-S. The loader uses a 12-byte Z80 machine code routine POKEd into address 32000 to perform an LDIR block copy (opcodes 17, 0, 64, 33, 232, 128, 1, 0, 27, 237, 176, 201), transferring 6912 bytes of screen data from address 33000 to the display file at 16384. FONT-S implements an 8×11 pixel grid editor that uses a two-dimensional array V(8,11) and a 240-entry font table A$(240,14), packing column bit-patterns into bytes for Epson ESC/P download commands (ESC & and ESC :). The TS2068-specific STICK function handles joystick input alongside keyboard controls, and ON ERR/RESET blocks provide tape error recovery. Font library management stores character data at fixed memory addresses (37139 onward) with a count stored at 37199–37200, allowing multiple fonts to be saved and loaded as individual CODE blocks.


Program Analysis

Program Structure

The listing contains three distinct programs concatenated together:

  1. Loader/Splash (lines 1–9999, first block): Displays a title screen by block-copying a logo image with machine code, then chains to FONT-D.
  2. FONT-D (lines 1–9999, second block): Font library manager with LOAD/SAVE/VERIFY routines for a “Char-Lib” tape archive.
  3. FONT-S (lines 1–9999, third block): The interactive pixel-print font designer and Epson SG-10 printer downloader.

Machine Code Usage

The loader at line 2 POKEs 12 bytes into address 32000 and executes them with RANDOMIZE USR 32000. The byte sequence disassembles as a standard Z80 LDIR block copy:

AddressBytesInstructionPurpose
3200017, 0, 64LD DE,16384Destination: display file
3200333, 232, 128LD HL,33000Source: loaded logo data
320061, 0, 27LD BC,6912Byte count: full screen + attributes
32009237, 176LDIRBlock copy
32011201RETReturn to BASIC

Line 3 then re-POKEs bytes 32001–32005 to redirect the same routine to copy a different memory region before re-executing it, reusing the stub for a second display operation. FONT-D also calls RANDOMIZE USR 34512 and RANDOMIZE USR 34303, which invoke separately loaded machine code beyond the BASIC listing.

FONT-S: Grid Editor Logic

The character editor uses a DIM v(8,11) array representing an 8-row by 11-column pixel grid. Navigation is handled by lines 80–180, with the cursor position tracked in variables R (row, 2–9) and C (column, 1–11). Pressing “1” (k=49) sets a pixel and prints UDG \a (a filled block shaped by POKEs in line 9990); pressing “0” (k=48) clears it. The PLOT and PLOT INVERSE 1 calls mirror the grid state into the small preview box drawn in the top-right of the screen.

Bit-Packing and Printer Download

At line 200, each column of the 8×11 grid is packed into a single byte by summing row values as powers of two:

M(C) = V(8,C) + V(7,C)*2 + V(6,C)*4 + ... + V(1,C)*128

Lines 210–265 auto-detect the start column (SC) and end column (EC) of the non-zero region to trim whitespace. The control byte M0 at line 270 encodes descender flag, start column, and end column into a single byte: 128*D + 16*SC + EC.

Download to the Epson SG-10 (line 340–370) uses standard ESC/P sequences:

  • ESC : 0 0 0 — copy ROM characters to RAM
  • ESC & 0 [data] — define custom character
  • ESC % 1 0 — select user-defined character set

The POKE 23728,1 call suppresses output through a ZPRINT-80 driver intercept, routing subsequent LPRINT commands directly to the printer rather than through any screen-capture layer.

TS2068-Specific Features

FONT-S uses the STICK function at lines 7–11 for joystick input. Joystick directions map to key codes: up=55 (“7”), down=54 (“6”), right=56 (“8”), left=53 (“5”), fire=toggles a pixel. The ON ERR/RESET idiom at lines 8000 and 8100 provides structured tape-error handling not available in standard Spectrum BASIC.

Font Library Memory Map

FONT-D manages a library with a fixed memory layout:

AddressContents
37139Start of Char-Lib CODE block (452 bytes)
37169–37170Pointer to font load address (plib)
37199–37200Font count (clib), low/high byte
37359 + i*10Font name string for font i (10 bytes)
39000 + 1000*iFont data CODE block for font i (768 bytes)

Notable Bugs and Anomalies

  • Line 2030 contains the misspelling "Saveing" in the progress message — this appears in the printed output on screen.
  • Line 120 sets LET k=13 after placing a “0” pixel but does not advance C, whereas line 110 explicitly increments C. Clearing a pixel therefore does not advance the cursor automatically.
  • Lines 130–160 contain wrap-around logic gated on variable W, but the wrap toggle message at line 9030 always prints “Wrap is Off” and only conditionally appends "n " (intended to show “On”) — the “On” state message is effectively truncated to an incomplete string.
  • Line 9989 is a self-documenting stub instructing the user to remove it and configure their printer driver; STOP there prevents accidental execution without setup.
  • The SAVE "FONT-S" LINE 9989 at the end auto-starts at the stub/warning line rather than the main menu, reinforcing the requirement for user customization before use.

Content

Appears On

Related Products

Desktop publishing program, WYSIWYG (what you see is what you get).
Based on Pixel Print Plus! desktop publisher. Bank-switching for perfect page layout, 64 column printing. Available for cassette, Aerco disk,...

Related Articles

Related Content

Image Gallery

Source Code

    1 REM ***********************                                Pixel Print FONT Utility Package                                 * by Lemke Software Development          2144 White Oak               Wichita,  Ks.  67207                                     ******************************** 
    2 DATA 17,0,64,33,232,128,1,0,27,237,176,201: PAPER 1: INK 1: BORDER 1: CLS : LOAD ""CODE 33000: FOR j=0 TO 11: READ a: POKE 32000+j,a: NEXT j: RANDOMIZE USR 32000
    3 POKE 32001,232: POKE 32002,128: POKE 32004,0: POKE 32005,64: PAUSE 100: INK 7
    4 CLS : PRINT AT 2,0;"     
 "
    5 PRINT AT 5,0;"This tape contains  2  separate programs that work with FONTS...                                FONT DESIGNER: FONT-D                use this to browse the font     library, modify or create       new FONTS.                                                 SG-10 FONT DL: FONT-S                 use this as an example of       FULL SIZE PRINTER FONT          DESIGN and DOWN LOADING"
    6 PRINT #0;AT 0,0;" Press Any key to LOAD FONT-D.": PAUSE 0: PAPER 7: INK 0: BORDER 7: CLS : RANDOMIZE USR 32000: LOAD ""
 9999 SAVE "FONT PKG" LINE 1: SAVE "LSD LOGO"CODE 33000,6912
 
 
   10 REM ***********************                                            PIXEL-PRINT               "the Desktop Publisher"                                      * by     S D Lemke      1987                                      Lemke Software Development           2144 White Oak              Wichita,  Ks.   67207                                     ********************************   
   20 REM  Font Builder Utility                                  ******************************** 
   30 CLS : RANDOMIZE USR 34512
 1000 CLS : PRINT AT 6,0;" Press ENTER to LOAD a Library. ": PAUSE 0: IF CODE INKEY$=13 THEN GO SUB 8010: GO TO 1020
 1010 GO TO 30
 1020 LOAD "Char-Lib"CODE 37139,452: LET clib=PEEK 37199+256*PEEK 37200: IF clib=0 THEN GO TO 30
 1030 FOR i=1 TO clib: BEEP .01,20: PRINT AT 16,0;" Loading No. ";i;" of ";clib;" fonts.": LOAD ""CODE : NEXT i: GO TO 30
 2000 CLS : PRINT AT 10,0;"Press ENTER to SAVE the Library.": PAUSE 0: IF CODE INKEY$=13 THEN GO TO 2020
 2010 GO TO 30
 2020 LET clib=PEEK 37199+256*PEEK 37200: IF clib=0 THEN PRINT ''"Library Empty.  Save Terminated!": FOR i=1 TO 10: BEEP .01,20: PAUSE 30: NEXT i: GO TO 30
 2030 SAVE "Char-Lib"CODE 37139,452: FOR i=1 TO clib: BEEP .01,20: PRINT AT 16,0;"  Saveing No. ";i;" of ";clib;" fonts.": LET a$="": FOR j=(37359+i*10) TO (37368+i*10): LET a$=a$+CHR$ PEEK j: NEXT j: SAVE a$CODE (39000+1000*i),768: NEXT i
 2040 CLS : GO SUB 8000: VERIFY "Char-Lib"CODE 
 2050 FOR i=1 TO clib: BEEP .01,20: PRINT AT 16,0;" Verifying No. ";i;" of ";clib;" fonts.": VERIFY ""CODE : NEXT i: GO TO 30
 3000 CLS : PRINT AT 10,0;"  Press ENTER to LOAD a FONT.   ": PAUSE 0: IF CODE INKEY$=13 THEN GO TO 3020
 3010 GO TO 30
 3020 GO SUB 8010: LET plib=PEEK 37169+256*PEEK 37170: LOAD ""CODE plib,768: GO TO 30
 8000 PRINT AT 10,0;" Rewind your tape and PLAY to        VERIFY your SAVE. "
 8010 PRINT '" IF a LOAD ERROR occurs then:         TYPE RUN (ENTER)          ": RETURN 
 9000 LOAD "FONT-D"CODE 
 9100 CLEAR 28990: PAPER 1: BORDER 1: INK 7: CLS 
 9200 RANDOMIZE USR 34303
 9300 STOP 
 9999 SAVE "FONT-D" LINE 9000: SAVE "FONT-D"CODE 30000,7139
 
 
    1 REM ***********************                                    SG-10 Download Character Set                                                                     * by    S D Lemke                Lemke Software Development          2144 White Oak                Wichita, Ks. 67207                                      ********************************   
    5 IF KB THEN PAUSE 0: LET k=CODE INKEY$: RETURN 
    6 PAUSE 3
    7 LET JS=|(1,1): IF JS=1 OR JS=5 OR JS=9 THEN LET K=55: RETURN 
    8 LET JS=|(1,1): IF JS=2 OR JS=6 OR JS=10 THEN LET K=54: RETURN 
    9 LET JS=|(1,1): IF JS=8 THEN LET K=56: RETURN 
   10 LET JS=|(1,1): IF JS=4 THEN LET K=53: RETURN 
   11 LET JS=|(2,1): IF JS=1 THEN LET K=48+1-V(R-1,C): RETURN 
   12 IF CODE INKEY$=226 THEN LET k=226: RETURN 
   13 GO TO 7
   15 REM      GRID 
   20 FOR x=4 TO 101 STEP 16: PLOT x,160: DRAW 0,-64: NEXT x: FOR y=160 TO 96 STEP -8: PLOT 4,y: DRAW 96,0: NEXT y: PLOT 120,171: DRAW 18,0: DRAW 0,-13: DRAW -18,0: DRAW 0,13
   30 PRINT AT 11,1;"1 3 5 7 9 B";AT 3,15;"ASCII Code:___";AT 5,15;"Descender:_";AT 8,15;"Start Column:_";AT 9,15;"End Column:__": RETURN 
   35 REM       Define Font
   40 CLS : GO SUB 20: INPUT "DL Replacement for: ";C$: LET CNT=CODE C$: LET A$(CNT,1)=C$: LET A$(CNT,2)=C$: PRINT AT 3,26;CODE C$;TAB 31
   50 INPUT "Is this a Descender (Y/N)? ";C$: LET D=0: IF C$="n" OR C$="N" THEN LET D=1
   60 PRINT AT 5,25;D: PRINT #0;AT 0,0;"Define your Character...        Press "" STOP "" when complete."
   70 LET R=2: LET C=1: DIM v(8,11)
   80 PRINT AT R,C; FLASH 1; OVER 1;" ": GO SUB 5
   90 PRINT AT R,C; FLASH 0; OVER 1;" "
  100 IF k=226 THEN GO TO 190
  110 IF k=49 THEN PRINT AT R,C;"a": LET V(R-1,C)=1: PLOT 123+c,170-r: LET C=C+1: LET k=13: GO TO 90
  120 IF k=48 THEN PRINT AT R,C;"_": LET V(R-1,C)=0: PLOT INVERSE 1;123+c,170-r: LET k=13: GO TO 90
  130 IF k=56 THEN LET C=C+1: IF C>11 THEN LET C=11: IF W THEN LET C=1: LET R=R+1: IF R>9 THEN LET R=9: LET C=11
  140 IF k=53 THEN LET C=C-1: IF C<1 THEN LET C=1: IF W THEN LET C=11: LET R=R-1: IF R<2 THEN LET R=2: LET C=1
  150 IF k=54 THEN LET R=R+1: IF R>9 THEN LET R=9: IF W THEN LET R=2: LET C=C+1: IF C>11 THEN LET C=11: LET R=9
  160 IF k=55 THEN LET R=R-1: IF R<2 THEN LET R=2: IF W THEN LET R=9: LET C=C-1: IF C<1 THEN LET C=1: LET R=2
  170 IF k=13 THEN LET C=C+1: IF C>11 THEN LET C=1: LET R=R+1: IF R>9 THEN LET R=9: LET C=11
  180 GO TO 80
  190 PRINT AT 13,8;"  WORKING  "
  200 DIM M(11): FOR C=1 TO 11: LET M(C)=V(8,C)+V(7,C)*2+V(6,C)*4+V(5,C)*8+V(4,C)*16+V(3,C)*32+V(2,C)*64+V(1,C)*128: NEXT C
  210 FOR C=1 TO 7: IF M(C)<>0 THEN GO TO 230
  220 NEXT C: LET C=1
  230 LET SC=C-1: PRINT AT 8,28;SC;TAB 31
  240 FOR C=11 TO 4 STEP -1: IF M(C)<>0 THEN GO TO 260
  250 NEXT C: LET C=11
  260 IF C<11 THEN LET C=C+1
  265 LET EC=C: PRINT AT 9,26;EC;TAB 31
  270 LET M0=128*D+16*SC+EC
  280 PRINT AT 14,0;M0,,;: FOR C=1 TO 11: PRINT M(C),;: NEXT c
  290 LET A$(CNT,3)=CHR$ M0
  300 FOR C=1 TO 11: LET A$(CNT,3+C)=CHR$ M(C): NEXT C
  310 PAUSE 60: GO TO 40
  330 REM       Down Load
  335 REM  NOTE; the POKE in the next line tells ZPRINT-80 that the following commands are printer commands... and are not printed.
  340 PRINT #0;"  DOWNLOADing Font to printer.  ": POKE 23728,1: LPRINT CHR$ 27;CHR$ 58;CHR$ 0;CHR$ 0;CHR$ 0: FOR C=1 TO 240: IF A$(C,1)=" " THEN GO TO 360
  350 LPRINT CHR$ 27;CHR$ 38;CHR$ 0;: FOR I=1 TO 14: LPRINT a$(C,I);: NEXT I: LPRINT 
  360 NEXT c
  370 LPRINT CHR$ 27;CHR$ 37;CHR$ 1;CHR$ 0: POKE 23728,0: LPRINT "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z"
  380 LPRINT "a b c d e f g h i j k l m n o p q r s t u v w x y z"
  390 LPRINT "0 1 2 3 4 5 6 7 8 9"
  400 GO TO 9991
 8000 ON ERR RESET : ON ERR GO TO 8010: INPUT "File to LOAD? "; LINE C$: LOAD C$ DATA a$(): GO TO 9991
 8010 BEEP .05,20: PRINT #0;"LOAD ERROR...... Try again!": GO TO 9991
 8100 ON ERR RESET : ON ERR GO TO 8110: INPUT "File to SAVE? "; LINE C$: SAVE C$ DATA a$(): PRINT #0;"REWIND tape and Play to VERIFY.": VERIFY C$ DATA A$(): GO TO 9991
 8110 BEEP .05,20: PRINT #0;"VERIFY ERROR...... Try again!": GO TO 9991
 9000 IF C$="8" THEN ON ERR RESET : STOP 
 9010 IF C$="7" THEN LET KB=1: BEEP .05,20: PRINT AT 20,8;"KEYBOARD is On ": GO TO 9991
 9020 IF C$="6" THEN LET KB=0: BEEP .05,20: PRINT AT 20,8;"KEYBOARD is Off": GO TO 9991
 9030 IF C$="5" THEN LET W=NOT W: BEEP .05,20: PRINT AT 20,8;"Wrap is Off": IF W THEN PRINT AT 20,17;"n "
 9035 IF C$="5" THEN GO TO 9991
 9040 IF C$="4" THEN GO TO 340
 9050 IF C$="3" THEN GO TO 8000
 9060 IF C$="2" THEN GO TO 8100
 9070 IF C$="1" THEN GO TO 40
 9989 BEEP .01,40: CLS : PRINT "Remove this line and modify the next line to LOAD and initializeyour printer driver. This exampleis set to use the ZPRINT-80 HI  code...": STOP 
 9990 LOAD ""CODE : RANDOMIZE USR 64000: DIM a$(240,14): LET W=0: LET KB=1: POKE USR "A",0: POKE USR "A"+7,0: FOR C=1 TO 6: POKE USR "A"+C,126: NEXT C: LET cnt=0
 9991 ON ERR RESET : PAUSE 60
 9992 CLS : PRINT AT 5,3;"Printer Font Downloader";''';"PRESS: 1 to CREATE Font                2 to SAVE Font                  3 to LOAD Font                  4 to DOWNLOAD Font              5 to toggle WRAP                6 for JOYSTICK                  7 for KEYBOARD                  8 to STOP"
 9993 PAUSE 0: LET C$=INKEY$: IF C$<"1" OR C$>"8" THEN BEEP .05,1: GO TO 9993
 9994 ON ERR GO TO 9992
 9995 GO TO 9000
 9997 DIM a$(240,14): POKE USR "A",0: POKE USR "A"+7,0: FOR C=1 TO 6: POKE USR "A"+C,126: NEXT C: LET cnt=0: GO TO 40
 9998 STOP 
 9999 SAVE "FONT-S" LINE 9989

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

Scroll to Top