Large Characters

This file is part of and ISTUG Public Domain Library 6. Download the collection to get this file.
Date: 198x
Type: Program
Platform(s): TS 2068
Tags: Demo

This program displays each printable ASCII character (CHR$ 32 through CHR$ 126) rendered as a large 8×8 pixel grid using a custom UDG character. It reads the ROM character set by locating the font address via system variables at 23606–23607, then uses bit-shifting arithmetic to extract each pixel bit from the font bytes. A single UDG (char 144) is defined with a border/box pattern from the DATA statement at line 100, and its inverse (CHR$ 143, i.e., 144−1) is used to represent set pixels while CHR$ 144 represents clear pixels. The program pauses for a keypress between each character display, stepping through all 96 printable characters before stopping.


Program Analysis

Program Structure

The program is organized into three functional phases:

  1. Initialization (lines 5–10): Defines UDG ‘A’ (char 144) from inline DATA and locates the ROM character set base address.
  2. Display loop (lines 15–65): Iterates over all 96 printable characters (CHR$ 32–126), rendering each as a large pixel grid.
  3. Data (line 100): Eight bytes defining a bordered rectangle UDG pattern (255,129,129,129,129,129,129,255).

UDG Setup

Line 5 uses RESTORE followed by a FOR loop to POKE all 8 bytes of the DATA at line 100 into the address returned by USR CHR$ 144 (i.e., USR "\a"), defining UDG ‘A’. The pattern 255,129,129,129,129,129,129,255 creates a hollow box — a full top row, full bottom row, and only the outermost bits set in middle rows.

Font Address Lookup

Line 10 computes the character set base address using system variables:

  • PEEK 23606 + 256 * PEEK 23607 reads the two-byte system variable CHARS (address &5C36), which points 256 bytes before the font data.
  • Adding 256 corrects for this offset, giving c as the true start of the font bitmap data.

This technique works whether the font is in ROM or has been relocated to RAM.

Pixel Extraction and Rendering

For each character j and each row p (0–7), the program fetches the font byte at c + p + j*8 (line 25). The inner loop (lines 35–50) extracts bits from least-significant to most-significant using integer division:

  • LET x = INT(byte/2) — integer right-shift by one.
  • LET bit = byte - 2*x — isolates the LSB (0 or 1).
  • LET byte = x — advances to the next bit.

The extracted bit is used to select either CHR$ 143 (set pixel, 144−1) or CHR$ 144 (clear pixel, 144−0). Because bits are extracted LSB-first but printed left-to-right starting at column 8 down to column 1 (via AT p, 9-l), the pixel order is naturally reversed back to the correct left-to-right visual orientation.

Display Layout

Screen elementPosition
Large pixel gridRows 0–7, columns 1–8
Raw byte valuesRows 0–7, column 15
CHR$ label and characterRow 4, column 20
“Press any key” promptRow 15, column 0

Notable Techniques

  • Using CHR$ (144 - bit) elegantly selects between two UDG states with a single expression rather than an IF branch.
  • The PAUSE 0 on line 60 (conditioned on j <> 95) waits for a keypress on every character except the last, avoiding a redundant pause before STOP.
  • The font lookup via CHARS system variable is portable and will correctly follow any relocated or custom font.

Potential Anomalies

  • Line 60 uses PAUSE 0 alone without reading INKEY$; PAUSE 0 on the Spectrum/TS2068 waits until any key is pressed, so this is valid and sufficient.
  • The UDG box pattern is defined but only its code-point relationship (144 - bit) matters; the actual visual appearance of the box/blank pixels is a design choice and not central to correctness.
  • Line 10 adds 256 to the CHARS pointer. The CHARS system variable holds a value 256 less than the font start, so this addition is correct and intentional.

Content

Appears On

Library tape of the Indiana Sinclair Timex User’s Group.

Related Products

Related Articles

Related Content

Image Gallery

Large Characters

Source Code

    1 REM LARGE CHARACTERS
    5 RESTORE : FOR j=0 TO 7: READ a: POKE USR CHR$ 144+j,a: NEXT j
   10 LET c=PEEK 23606+256*PEEK 23607+256
   15 FOR j=0 TO 95: CLS : PRINT AT 4,20;"CHR$ ";j+32;" ";CHR$ (j+32)
   20 FOR p=0 TO 7
   25 LET byte=PEEK (c+p+j*8)
   30 PRINT AT p,15;byte
   35 FOR l=1 TO 8
   40 LET x=INT (byte/2): LET bit=byte-2*x: LET byte=x
   45 PRINT AT p,9-l;CHR$ (144-bit)
   50 NEXT l
   55 NEXT p
   60 IF j<>95 THEN PRINT AT 15,0;"Press any key for next character": PAUSE 0
   65 NEXT j: STOP 
  100 DATA 255,129,129,129,129,129,129,255
 9998 SAVE "LARGE CHAR" LINE 0

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

People

No people associated with this content.

Scroll to Top