--- title: "Pixel Print Font Utility Package 1" id: 55090 type: "computer_media" slug: "pixel-print-font-utility-package-1" url: "http://localhost/computer_media/pixel-print-font-utility-package-1/" markdown_url: "http://localhost/computer_media/pixel-print-font-utility-package-1.md" published_at: "2024-06-14T21:25:32+00:00" modified_at: "2026-04-03T07:59:07+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2023/09/Pixel-Print-Font-Package-1.jpg" excerpt: "A three-part font design suite lets you build, edit, and download custom pixel-print character sets directly to a dot-matrix printer using an interactive grid editor." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "Lemke Software Development" slug: "lemke-software-development" taxonomy: "post_tag" url: "http://localhost/tag/lemke-software-development/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" indiv: - name: "Stan Lemke" slug: "stan-lemke" taxonomy: "indiv" url: "http://localhost/indiv/stan-lemke/" genre: - name: "Desktop Publishing" slug: "desktop-publishing" taxonomy: "genre" url: "http://localhost/type/desktop-publishing/" - name: "Font" slug: "font" taxonomy: "genre" url: "http://localhost/type/font/" - name: "Utility" slug: "utility" taxonomy: "genre" url: "http://localhost/type/utility/" media_type: "Program" programmers: - name: "Stan Lemke" slug: "stan-lemke" taxonomy: "indiv" url: "http://localhost/indiv/stan-lemke/" download_url: "https://archive.org/download/timex-sinclair-software-archive/Pixel%20Print%20Font%20Utility%20Package%201%20%281987%29%28Lemke%20Software%20Development%29%28TS2068%29%28US%29%28Cassette%29.zip" mediadate: "1987" producer_company: - id: 11046 title: "Lemke Software Development" type: "company" url: "http://localhost/company/lemke-software-development/" related_products: - id: 55091 title: "Pixel Print Font Utility Package 1" type: "product" url: "http://localhost/product/pixel-print-font-utility-package-1/" - id: 13579 title: "Pixel Print PLUS!" type: "product" url: "http://localhost/product/pixel-print-plus/" - id: 13580 title: "Pixel Print Professional!" type: "product" url: "http://localhost/product/pixel-print-professional/" media_type_tags: "Desktop Publishing, Font, Utility" --- # 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: | Address | Bytes | Instruction | Purpose | | --- | --- | --- | --- | | 32000 | 17, 0, 64 | LD DE,16384 | Destination: display file | | 32003 | 33, 232, 128 | LD HL,33000 | Source: loaded logo data | | 32006 | 1, 0, 27 | LD BC,6912 | Byte count: full screen + attributes | | 32009 | 237, 176 | LDIR | Block copy | | 32011 | 201 | RET | Return 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: | Address | Contents | | --- | --- | | 37139 | Start of Char-Lib CODE block (452 bytes) | | 37169–37170 | Pointer to font load address (`plib`) | | 37199–37200 | Font count (`clib`), low/high byte | | 37359 + i*10 | Font name string for font `i` (10 bytes) | | 39000 + 1000*i | Font 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. ## 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 ```