--- title: "Big Char Exam" id: 57650 type: "computer_media" slug: "big-char-exam" url: "http://localhost/computer_media/big-char-exam/" markdown_url: "http://localhost/computer_media/big-char-exam.md" published_at: "2024-10-06T01:29:44+00:00" modified_at: "2026-04-03T07:58:09+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/bigchar-exam.png" excerpt: "Type any character and watch it rendered as a giant 8×8 block-graphic glyph, pulled straight from the ROM font data with PEEK." 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: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" indiv: - name: "Gene G. Buza" slug: "gene-g-buza" taxonomy: "indiv" url: "http://localhost/indiv/gene-g-buza/" genre: - name: "Utility" slug: "utility" taxonomy: "genre" url: "http://localhost/type/utility/" media_contents: - id: 56728 title: "Synchro-Sette September 1983" type: "computer_media" url: "http://localhost/computer_media/synchro-sette-september-1983/" media_type: "Program" programmers: - name: "Gene G. Buza" slug: "gene-g-buza" taxonomy: "indiv" url: "http://localhost/indiv/gene-g-buza/" mediadate: "September 1983" images: - url: "http://localhost/wp-content/uploads/2024/10/bigchar-exam.png" media_type_tags: "Utility" --- # Big Char Exam This program renders any typed character as a large 8×8 pixel block graphic on screen, scaled up by mapping each bit of the character’s ROM font data to a full character cell. It reads the font bitmap directly from memory starting at address 7688 (the ROM character set base), using PEEK to extract each byte. Bits are isolated using the classic modulo-2 / integer-division idiom: `A-2*INT(A/2)` extracts the least-significant bit, and a value of 1 is mapped to CHR$ 128 (a solid block graphic) while 0 produces a space. Characters are printed column by column from the bottom up, accumulating horizontally across the screen in groups of 8 columns; after four characters fill the 32-column display, the screen scrolls up 8 lines to make room for the next group. *** ## Program Structure The program is organised into four logical phases: 1. **Initialisation** (line `10`): resets the horizontal screen offset `S` to 0. 2. **Character input & rendering** (lines `20`–`170`): prompts for a character, locates its ROM bitmap, and prints each bit as a block character cell. 3. **Advance & wrap check** (lines `180`–`200`): moves the horizontal cursor right by 8 columns; if it would exceed column 25 (effectively beyond column 31) the display is scrolled. 4. **Scroll & restart** (lines `300`–`330`): issues 8 `SCROLL` commands to clear the 8-row glyph band, then restarts from `10`. ### ROM Font Access The character set in the ROM begins at address 7680 (0x1E00). The program uses the base address 7688 (= 7680 + 8), skipping the first character entry, which corresponds to the space character at code 32. The offset into the font is computed as: - `F = CODE A$` — ASCII/Spectrum character code of the input. - `F = 8*F - 8` — byte offset: 8 bytes per glyph, minus 8 to compensate for the +8 base address bias, effectively giving `7680 + 8*CODE(A$)`. - Lines `100`–`170` then PEEK each of the 8 bytes in sequence. ### Bit-Extraction Idiom Each font byte encodes one row of 8 pixels. Bits are extracted LSB-first using the expression `A - 2*INT(A/2)`, which is equivalent to `A MOD 2` (BASIC on this platform lacks a MOD operator). The result (0 or 1) is multiplied by 128 to select either CHR$ 0 (space) or CHR$ 128 (solid block █). The byte is then halved with `INT(A/2)` to shift to the next bit. Because the inner loop runs `I` from 7 down to 0 and bits are extracted LSB-first, the glyph columns are printed in the correct left-to-right order within the 8-column band. ### Screen Layout | Variable | Role | | --- | --- | | `S` | Horizontal column offset (0, 8, 16, 24…) | | `P` | Row countdown (7→0), controlling vertical position via `AT 21-P, ...` | | `B` | Loop variable iterating over 8 ROM bytes for the glyph | | `I` | Bit/column index within a glyph row (7 down to 0) | | `A` | Current ROM byte being processed | | `F` | Byte offset into the character ROM | Each glyph occupies rows 14–21 (8 rows) and 8 columns starting at `S`. Up to four glyphs fit side-by-side before `S` exceeds 25 and the scroll routine is triggered. ### Notable Techniques - Reading directly from the ROM font with `PEEK` avoids any need to store glyph data in the program itself. - The `CHR$ (bit * 128)` trick neatly maps a binary digit to either a space or the solid block graphic (character 128) in a single expression. - Printing glyphs from the bottom row upward (`AT 21-P` with `P` decrementing) means the glyph grows naturally as each font byte is processed in order. - The threshold check `IF S>25 THEN GOTO 300` allows the last glyph to start at column 24, giving columns 24–31 for its 8 pixels, making full use of the 32-column display. ## Source Code ``` 10 LET S=0 20 PRINT AT 0,0;"ENTER ANY CHARACTER :::" 25 INPUT A$ 30 LET P=7 40 LET F=CODE A$ 50 LET F=8*F-8 100 FOR B=7688+F TO 7688+F+7 110 LET A=PEEK B 120 FOR I=7 TO 0 STEP -1 130 PRINT AT 21-P,I+S;CHR$ ((A-2*INT (A/2))*128) 140 LET A=INT (A/2) 150 NEXT I 160 LET P=P-1 170 NEXT B 180 LET S=S+8 190 IF S>25 THEN GOTO 300 200 GOTO 20 300 FOR N=1 TO 8 310 SCROLL 320 NEXT N 330 GOTO 10 9998 SAVE "BIG/CHAR EXA%M" 9999 RUN ```