Print Sizer

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

Print Sizer is a demonstration program for a machine code routine that renders BASIC strings at arbitrary sizes on screen. The machine code, 1,500 bytes long, resides at address 63000 (48K) or 31000 (16K) and is invoked via RANDOMIZE USR 63000. Seven consecutive memory locations starting at address 63010 control print parameters: character height (1–20 rows), width (1–16 columns), slant direction (−1, 0, or +1), foreground shade (0–7), background shade (0–7), attribute printing toggle, and inverse video flag. The demo program walks through progressively more complex examples—scaling, mixed dimensions, all 64 foreground/background combinations, inverse mode, and slanting—before displaying the parameter reference and optionally listing its own source. The SAVE lines at 9875 preserve both the BASIC loader and the machine code as a separate CODE file named “P. sizer C”.


Program Structure

The program is organized into three logical blocks. Lines 10–820 form the sequential demo and information display. Lines 9800–9845 are the POKE/USR subroutine that configures and invokes the machine code. Lines 9850–9875 contain utility routines: a “Press Space” pause (9850–9865), a code loader (9870), and SAVE statements (9875).

Machine Code Interface

All rendering is delegated to 1,500 bytes of machine code stored at address 63000. The BASIC side communicates with it through seven consecutive POKEs:

Address (48K)Address (16K)VariableParameter
6301031010HHeight (1–20)
6301131011WWidth (1–16)
6301231012SSlant (−1, 0, +1)
6301331013FForeground shade (0–7)
6301431014BBackground shade (0–7)
6301531015AAttributes on/off (1/0)
6301631016IInverse (1/0)

The machine code reads the string from Z$ and prints from the current PRINT AT position without updating it afterward, which is noted explicitly in the demo text at line 590.

Subroutine at 9805

The central subroutine at line 9805 performs all seven POKEs in sequence, then calls RANDOMIZE USR 63000 (line 9840). Using RANDOMIZE USR rather than the return value of USR avoids cluttering the display with a numeric result and discards the return value silently. The subroutine ends with RETURN at line 9845.

Key BASIC Idioms

  • All seven rendering parameters are held in short single-letter variables (H, W, S, F, B, A, I) to minimize typing and token storage.
  • Multiple assignments are chained on single lines (e.g., LET Z$="...":LET H=2:LET W=H:LET S=0:...) to reduce line overhead.
  • PRINT AT row,col; immediately before GO SUB 9805 sets the print cursor without advancing to a new line, exploiting the fact that the machine code prints from the current position.
  • The “Press Space” pause routine (9850–9865) first flushes any held key with a INKEY$ <> "" loop, then waits for a space, a clean debounce pattern.
  • POKE 23692,19 at line 800 prevents the automatic scroll prompt when listing more than one screenful of program, allowing a full page of LIST output before pausing.

Demo Sequence

  1. Title screen with scaled “A PRINT UTILITY” and “DEMO” text.
  2. Height scaling: normal, double, treble (lines 90–130).
  3. Extreme height: 22-row characters (lines 140–160).
  4. Width scaling: normal through 16× (lines 170–220).
  5. Mixed height and width (lines 230–260).
  6. All 64 foreground/background shade combinations in a grid (lines 300–360).
  7. Inverse mode over the same grid (lines 380–430).
  8. Slant in both directions (lines 440–470).
  9. Attribute printing toggle to control jagged edges on slanted text (lines 480–520).
  10. Parameter reference screen and optional self-listing (lines 570–820).

Variable Aliasing and Case Inconsistency

The Spectrum treats uppercase and lowercase variable names as identical for single-letter variables, so H and h, Z$ and z$, etc., refer to the same storage locations. The listing uses both cases interchangeably (e.g., LET Z$= in early lines, LET z$= from line 100 onward), which is valid but inconsistent. This does not cause any runtime errors.

Notable Anomalies

  • Line 760 contains STOP :CLEAR 65367:LOAD "". The STOP halts execution immediately, so CLEAR and LOAD "" on the same line are unreachable dead code.
  • Line 9865 uses INPUT "" solely as a pause mechanism after the space key is detected; it displays nothing but consumes a keypress, acting as an extra guard against immediately re-triggering the next section.
  • The REM at line 9800 is split across what appear to be continuation characters within the REM text (“CAN BE USED IN YOUR OWN PROGRAMS”), formatted to align within the 32-column display.
  • Line 9870 is a self-contained loader: it clears RAM below 63000, prints a loading message, loads the code file, and restarts — designed to be the autostart line when the BASIC file is saved with LINE 9870.

Image Gallery

Source Code

   10 REM   PRINT UTILITY PROGRAM
   20 REM  Pete Cooke April 85
   30 PAPER 6:INK 1:BORDER 6:CLS 
   40 LET Z$="A PRINT UTILITY":LET H=2:LET W=H:LET S=0:LET F=4:LET B=5:LET A=S:LET I=A:PRINT AT A,1;:GO SUB 9805
   50 LET Z$="DEMO":LET H=8:LET W=6:LET S=0:LET F=7:LET B=S:LET A=S:LET I=A:PRINT AT 5,4;:GO SUB 9805
   60 GO SUB 9850
   70 REM  demo
   80 CLS 
   90 PRINT "Using this program you can printcharacters at any size, from"
  100 LET z$="Normal Height":LET H=1:LET W=1:LET F=4:LET B=0:LET S=b:LET A=b:LET I=b:PRINT AT 5,5;:GO SUB 9805
  110 LET z$="Double Height":LET H=2:PRINT AT 7,5;:GO SUB 9805
  120 LET z$="Treble Height":LET H=3:PRINT AT 10,5;:GO SUB 9805
  130 GO SUB 9850:CLS 
  140 PRINT "Up to 22 characters high!"
  150 LET z$="Really high man":LET h=22:PRINT AT 1,0;:GO SUB 9805
  160 GO SUB 9850:CLS 
  170 PRINT "You can also use any width..."
  180 LET z$="Normal":LET h=1:LET w=h:PRINT AT 5,5;:GO SUB 9805
  190 LET z$="Double width":LET w=2:PRINT AT 7,5;:GO SUB 9805
  200 LET z$="Treble !":LET w=3:PRINT AT 9,5;:GO SUB 9805
  210 LET z$="W":LET w=16:PRINT AT 11,5;:GO SUB 9805
  220 GO SUB 9850:CLS 
  230 PRINT "and you can mix these sizes.."
  240 LET z$="Mixed":LET h=3:LET w=4:PRINT AT 5,5;:GO SUB 9805
  250 LET z$="More mixed":LET h=5:LET w=2:PRINT AT 11,5;:GO SUB 9805
  260 GO SUB 9850:CLS 
  270 PRINT "Now you may be saying 'So what! the free tape with the horizons program could do all of that!', and this is where this program  takes over..."
  280 PRINT ''"Apart from simple black on whitecharacters you can choose from  8 foreground and background"'"shades"
  290 LET z$=" ":LET h=2:LET w=h:FOR n=0 TO 7:PRINT AT 12,1+3*n;:LET b=n:GO SUB 9805:NEXT n
  300 GO SUB 9850:CLS 
  310 PRINT "and mix any pair of these..."
  320 LET z$="A":LET w=4:LET h=2
  330 FOR f=0 TO 7:FOR b=0 TO 7
  340 PRINT AT 2*b+3,4*f;:GO SUB 9805
  350 NEXT b:NEXT f
  360 PRINT AT 19,0;"as you can see, some"'"combinations work better than"'"others!";
  370 GO SUB 9850:CLS 
  380 PRINT "You can also print the"'"characters in inverse!"
  390 LET i=1
  400 FOR f=0 TO 7:FOR b=0 TO 7
  410 PRINT AT 2*b+3,4*f;:GO SUB 9805
  420 NEXT b:NEXT f
  430 GO SUB 9850:CLS 
  440 PRINT "and you can also slant the"'"letters to left or right."
  450 LET z$="Slanted text":LET h=3:LET w=2:LET f=4:LET b=1:LET i=0:LET s=b:PRINT AT f,b;:GO SUB 9805
  460 LET z$="and the other way":LET h=4:LET w=1:LET f=h:LET b=0:LET i=b:LET s=-1:PRINT AT 10,w;:GO SUB 9805
  470 GO SUB 9850:CLS 
  480 PRINT "finally you can turn attribute  printing on and off (this cuts  the jagged edges on slanted"'"characters)"
  490 LET z$="Attributes on":LET a=1:LET h=3:LET w=2:LET i=a:LET f=4:LET b=a:PRINT AT 5,a;:PAPER 5:INK a:BRIGHT a:GO SUB 9805
  500 LET z$="Attributes off":LET a=0:LET h=4:LET w=2:LET i=a:LET s=-1:LET f=h:LET b=1:PRINT AT 12,b;:GO SUB 9805
  510 PAPER 7:INK 0:BRIGHT 0
  520 GO SUB 9850:CLS 
  530 LET h=10:LET w=8:LET i=0:LET f=3:LET b=1:LET s=i:LET a=b:PAPER 6:INK b:LET z$="MORE":PRINT AT i,i;:GO SUB 9805
  540 LET h=2:LET w=h:LET i=1:LET f=3:LET b=i:LET z$="Information":PAPER 4:INK 0:PRINT AT 16,4;:GO SUB 9805
  550 LET z$="Follows ...":PRINT AT 18,4;:GO SUB 9805
  560 PAPER 7:INK 0:GO SUB 9850:CLS 
  570 PRINT ''"The machine code is 1500 bytes  long and is at 63000 (for 48k)  and 31000 (for 16k)"
  580 PRINT ''"to pass a string to the code"'"simply build it up in z$ and"'"call USR 63000."
  590 PRINT ''"The code will print from the"'"latest print position (USE AT)"'"but will not alter it."
  600 GO SUB 9850:CLS 
  610 PRINT "The code uses 7 locations"'"to define the type of printing  (16k in brackets)"
  620 PRINT '"63010 (31010) Height (1-20)"
  630 PRINT '"63011 (31011) Width (1-16)"
  640 PRINT '"63012 (31012) Slant  +1 or -1"; TAB 14;"(0=No slant)"
  650 PRINT '"63013 (31013) Foreground"; TAB 14;"Shading (0-7)"
  660 PRINT '"63014 (31014) Background"; TAB 14;"Shading (0-7)"
  670 PRINT '"63015 (31015) Attributes"; TAB 14;"1=On 0=Off"
  680 PRINT '"63016 (31016) Inverse"; TAB 14;"1=On 0=Off"
  690 GO SUB 9850:CLS 
  700 PRINT ''"To see how these are used simplyLIST the program."'''"The subroutine at line 9000"'"pokes in these values from"'"basic variables."
  710 GO SUB 9850:CLS 
  720 LET z$="The End":LET h=15:LET w=4:LET s=0:LET a=1:LET i=s:LET f=7:LET b=a:INK 2:PAPER 6:PRINT AT 2,2;:GO SUB 9805
  730 LET h=1:LET w=h:LET z$=" Space to list prog.:q to quit  ":LET f=4:LET b=0:LET s=-1:LET a=1:LET i=a:PRINT AT 20,b;:GO SUB 9805
  740 IF INKEY$ <>"" THEN GO TO 740
  750 LET i$= INKEY$
  760 IF i$="q" THEN STOP :CLEAR 65367:LOAD ""
  770 IF INKEY$="" THEN GO TO 750
  780 IF INKEY$ <>" " THEN GO TO 780
  790 PAPER 7:INK 0:PRINT ''
  800 POKE 23692,19:REM  stop scroll for 1 page
  810 LIST 
  820 STOP 
 9800 REM  SUBROUTINE TO POKE              IN THEDATA ...                 CAN BE USED IN YOUR             OWN PROGRAMS....
 9805 POKE 63010,H:POKE 63011,W
 9810 REM  heigth^        width^
 9815 POKE 63012,S:REM SLANT
 9820 POKE 63013,F:REM FORGROUND SHADE
 9825 POKE 63014,B:REM BACKGROUND SHADE
 9830 POKE 63015,A:REM 0=DON'TPRINT ATTRIBUTES
 9835 POKE 63016,I:REM INVERSE 
 9840 RANDOMIZE USR 63000
 9845 RETURN 
 9850 PRINT #1; AT 0,8;"Press Space";
 9855 IF INKEY$ <>"" THEN GO TO 9855
 9860 IF INKEY$ <>" " THEN GO TO 9860
 9865 INPUT "":RETURN 
 9870 CLEAR 62999:PRINT ''''"    Loading CODE "''"     Please wait..":LOAD "P. sizer C"CODE :RUN 
 9875 CLEAR :SAVE "P. sizer" LINE 9870:SAVE "P. sizer C"CODE 63000,1500

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