“BOLD” Character Subroutine

Developer(s): Frank Bouldin (W5GAA)
Date: 1985
Type: Program
Platform(s): TS 2068
Tags: Font

This program implements a “BOLD” character display routine for the TS2068 by patching the system font pointer at address 23607. A 80-byte machine code routine is loaded via DATA statements into RAM at address 63900 and executed with RANDOMIZE USR 63900; it copies and modifies the character set to RAM starting at address 64000 (FA00 hex), ORing pixel pairs together to create a bold effect. The user is prompted whether to activate bold characters, and the routine switches between the modified font (POKE 23607,250) and the standard ROM font (POKE 23607,60) accordingly. The demonstration prints a full alphanumeric sample string using FLASH and waits for a keypress before looping.


Program Analysis

Program Structure

The listing divides into three logical sections:

  1. Lines 10–60: Documentation REMs, a demonstration loop that prints a sample alphabet and sentence, and a FLASH prompt to repeat.
  2. Lines 9000–9080: The “BOLD” subroutine proper — machine code loader (9020–9030) and the interactive bold-on/off prompt (9040–9070).
  3. Lines 9500–9530: DATA statements holding the 80 bytes of Z80 machine code.

Line 9999 performs a CLEAR and saves the program with auto-run from line 1 (which falls through to GO SUB 9000 at line 45 via the absence of an explicit line 1, so execution starts at the lowest line, line 10, and reaches line 45).

Machine Code Loader

Line 9020 uses RESTORE 9500 followed by a FOR/READ/POKE loop to deposit 80 bytes into addresses 63900–63979. Line 9030 then calls this code with RANDOMIZE USR 63900. The target area (F9DC–FA27 hex) sits well above the normal BASIC/variable area and is below the UDG region, making it a safe scratch space on a stock TS2068.

Z80 Machine Code Disassembly

Reconstructing the DATA bytes (63900 onward):

OffsetBytesMnemonicNotes
042 54 92LD HL,(5C54h)Load CHARS system variable (font base pointer − 256)
317 00 FA… DE = FA00hDestination buffer at 64000
601 00 04LD BC,0400hCopy 1024 bytes (256 chars × 4 bytes used)
Inner loopReads source byte, ORs with shifted copies to fatten strokes, stores to destination
201RETReturn to BASIC

The repeated pattern 230,N … 203,2xx corresponds to AND N / SET b,(HL) sequences that test individual pixel columns and set the adjacent column, effectively expanding each lit pixel one position to the right to produce boldness. The final bytes 62,0,18,19,35,11,120,177,32,186,201 handle the loop counter decrement (DEC BC; test B|C) and the RET.

Font Switching Mechanism

The TS2068 (like the ZX Spectrum) uses the system variable CHARS at address 23607 (5C57h) to point to the character set base minus 256. The standard ROM font lives at address 15616 (3D00h), so CHARS normally holds 60 (3Ch). After the machine code copies and boldifies the font into RAM at FA00h, POKE 23607,250 (FAh) redirects CHARS to the new bold font at FA00h. Restoring normal characters requires only POKE 23607,60.

Interactive Prompt (Lines 9040–9070)

The subroutine prints a yes/no question and polls INKEY$ in a tight loop (lines 9050–9070). Both upper- and lower-case Y and N are accepted. This is a straightforward busy-wait rather than using PAUSE 0, meaning the CPU spins continuously until a key is detected.

Demonstration Loop (Lines 50–60)

Line 50 prints a comprehensive sample string covering all letters (upper and lower case), digits, and punctuation at fixed AT positions. Line 60 uses FLASH 1 for the repeat prompt, then PAUSE 0 to wait for any keypress, CLS, GO SUB 9040 to re-query bold preference, and GO TO 50 to loop. This means the bold/normal choice can be changed on every cycle.

Notable Techniques

  • Storing machine code above address 63900 keeps it safely outside the BASIC program area without requiring a CLEAR to reserve RAM (the CLEAR on line 9999 is only in the SAVE statement).
  • Using RESTORE 9500 before the load loop ensures the DATA pointer is reset correctly even if the subroutine is called more than once.
  • VAL is not used here; line numbers are literal, which is consistent with the program’s educational/demonstration intent.
  • The DATA is split across multiple lines (9500, 9510, 9520, 9530) with intervening REM lines (9505, 9515, 9525) purely for readability; the REMs are skipped by the sequential READ.

Potential Issues

  • The machine code copies only 1024 bytes (BC = 0400h), covering characters 32–159 (128 chars × 8 bytes). If the full 768-byte standard set (96 printable chars) or UDGs are needed, the count may need adjustment depending on exact implementation.
  • Line 9999 calls CLEAR immediately before SAVE; when the saved program is later loaded and run, CLEAR is not re-executed before the machine code is poked in, which is correct — but users who issue CLEAR manually with a high address could overwrite the code buffer at 63900.
  • The busy-wait loop at lines 9050–9070 does not include a PAUSE, so it will consume all CPU time while waiting for input.

Content

Appears On

One of the largest single-tape collections anywhere, with over 40 programs spanning flight planning, satellite tracking, hydrology, Forth programming, a 17-game mega-pack, and a complete calligraphic font renderer. A snapshot of a thriving Texas user group at its peak.
The foundation of Tony Willing's numbered library series — play Breakout, write documents in a 64-column word processor, morph a triangle into a square with flicker-free animation, or run a complete fig-FORTH system. Fifty programs covering every category.

Related Products

Related Articles

Related Content

Image Gallery

Source Code

  10 REM  "BOLD" Character sub- routine
  20 REM  by F. Bouldin & Ben      Jackson (7-12-85)
  30 REM  Near beginning of yourprogram before any print state- ments add statement "GOSUB 9000"then add subroutine below (lines9000-9530).
  40 REM  Example:
  42 REM 
  45 GO SUB 9000
  50 PRINT AT 10,2;"TIMEX-SINCLAIR 2068 Computer";AT 12,6;"---sample fonts---";AT 14,0;"AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890.,*/?`:©;)('&%$#@!......Now is thetime for all good men to come tothe aid of their country!"
  55 REM note required statement"GOSUB 9040" in line 60 for thisexample.
  60 PRINT FLASH 1;AT 10,2;AT 21,2;" Press any key to repeat ": PAUSE 0: CLS : GO SUB 9040: GO TO 50
 7000 REM 
 8000 REM 
 9000 REM  "BOLD" character sub- routine
 9010 REM  Machine code routine
 9020 RESTORE 9500: FOR I=63900 TO 63979: READ A: POKE I,A: NEXT I
 9030 RANDOMIZE USR 63900
 9040 PRINT AT 11,0;"""BOLD"" characters desired?...Y/N"
 9050 IF INKEY$="Y" OR INKEY$="y" THEN POKE 23607,250: CLS : RETURN 
 9060 IF INKEY$="N" OR INKEY$="n" THEN POKE 23607,60: CLS : RETURN 
 9070 GO TO 9050
 9080 REM 
 9500 DATA 42,54,92,17,0,250,1,0,4,126,18,230,3,32,4,126,203,207
 9505 REM 
 9510 DATA 18,126,230,7,32,4,126,203,215,18,126,230,15,32,4,126
 9515 REM 
 9520 DATA 203,223,18,126,230,31,32,4,126,203,231,18,126,230,63,32,4,126,203,239,18,126,254,66,32
 9525 REM 
 9530 DATA 4,126,203,239,18,126,254,0,32,3,62,0,18,19,35,11,120,177,32,186,201
 9999 CLEAR : SAVE "BOLD" LINE 1

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

Scroll to Top