--- title: "HEXSPEC" id: 54530 type: "computer_media" slug: "hexspec" url: "http://localhost/computer_media/hexspec/" markdown_url: "http://localhost/computer_media/hexspec.md" published_at: "2024-06-02T16:31:10+00:00" modified_at: "2026-03-30T21:42:58+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2019/02/20230809-041332.jpg" excerpt: "A hands-on hex loader that lets you POKE machine code directly into memory, with per-line checksum verification to catch any mistyped bytes." 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 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/" genre: - name: "Programming" slug: "programming" taxonomy: "genre" url: "http://localhost/type/programming/" - name: "Utility" slug: "utility" taxonomy: "genre" url: "http://localhost/type/utility/" media_contents: - id: 51213 title: "CATS Library Tape 3" type: "computer_media" url: "http://localhost/computer_media/cats-library-tape-3/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/06/hex-1-loader.png" media_type_tags: "Programming, Utility" --- # HEXSPEC This program is a hexadecimal machine-code loader that reads hex byte values entered by the user and POKEs them into memory. The user specifies a start and finish address, then enters each group of eight bytes as space-separated two-digit hex pairs (e.g., “C5 3A 00 42…”) per line. A running checksum total is accumulated and compared against a user-supplied value to catch data entry errors. Two DEF FN functions handle the hex conversion: `FN h$` converts a byte value to its two-character hex string, and `FN h` converts a single hex character back to its numeric nibble value. *** ## Program Analysis ### Program Purpose The program allows a user to manually enter machine code listings in hexadecimal format and write them directly into RAM. It processes eight bytes per line, accumulates a checksum, and prompts the user to confirm the total before advancing, providing a basic error-detection mechanism for hand-typed hex data. ### Program Structure | Lines | Role | | --- | --- | | 10–15 | REM headers identifying the program | | 20–30 | DEF FN definitions for hex conversion | | 40–50 | User input: start and finish addresses | | 60–170 | Main loop: prompt, input, decode, POKE, checksum verify | ### Hex Conversion Functions Two complementary `DEF FN` functions handle the hex/decimal translation: - `FN h$(a)` (line 20): Converts a byte value (0–255) to a two-character uppercase hex string. It splits the byte into high and low nibbles, adds 48 (ASCII ‘0’), and applies a +7 offset for values above 9 to bridge the gap between ‘9’ and ‘A’ in the character set. - `FN h(h$)` (line 30): Converts a single hex character to its numeric nibble value. It reverses the encoding: subtracts 48 and conditionally subtracts 7 for letters A–F (characters greater than ‘9’). Note that `FN h$` is defined but never called in the main loop — only `FN h` is used to decode input characters. ### Input Parsing Each input line `a$` is expected to contain eight two-digit hex values separated by single spaces, e.g. `C5 3A 00 42 FF 01 7E 42`. The inner loop (lines 80–120) processes the string by always reading characters 1 and 2, converting them via `FN h(a$(1))*16+FN h(a$(2))`, then slicing the string with `LET A$=A$(4 TO )` to discard the consumed pair and its trailing space. This is a compact sliding-window parse technique common in Spectrum BASIC. ### Checksum Mechanism The variable `tot` (line 65) accumulates the sum of all eight decoded byte values. After the inner loop completes, the user is asked to `INPUT t` (line 140), supplying the expected total from the printed listing. If `t <> tot`, an error message is shown and control jumps back to line 62 to re-enter the same line. This is a simple additive checksum, not a CRC, but it is effective at catching most single-character transpositions. ### Notable Techniques and Idioms - The `IF a$="END" THEN STOP` guard at line 75 provides a clean exit before the full address range is exhausted. - Mixed-case variable usage: the string is initially assigned to `a$` (lowercase) but later manipulated as `A$` (uppercase) at line 110, which are the same variable in Sinclair BASIC. This inconsistency is harmless but worth noting. - Similarly, the inner loop counter is declared as `b` (line 80) but the `NEXT` statement references `B` (line 120) — again equivalent in Sinclair BASIC. - The `STEP 8` on the outer `FOR` loop (line 60) advances the address pointer by 8 after each full line is processed, matching the eight-bytes-per-line input format. ### Bugs and Anomalies - The comment at line 66 spells “hexadecimal” as “HEXIDECIMAL” — a common misspelling, not a code defect. - If the finish address `f` is not a multiple of 8 bytes beyond `s`, the `FOR n=s TO f STEP 8` loop may not reach exactly `f`, potentially leaving the last few bytes unloaded. - There is no bounds checking on `a$` length; if the user enters fewer than the expected 23 characters (8 pairs + 7 spaces), the `A$(4 TO)` slice at line 110 will eventually cause a BASIC error on the fifth or later iteration. - `FN h$` is defined but unused in the program’s logic, suggesting this loader may be a stripped-down version of a larger utility that also included a hex-dump display feature. ## Source Code ``` 10 REM "HEX 1"loader--SPECTRUM 15 REM list 1 -- SPECTRUM 20 DEF FN h$(a)=CHR$ (INT (a/16)+48+7*(a>159))+CHR$ (a-16*INT (a/16)+48+7*((a-16*INT (a/16))>9)) 30 DEF FN h(h$)=CODE h$-48-7*(h$>"9") 40 INPUT "START ADDRESS:";s 50 INPUT "FINISH ADDRESS:";f 60 FOR n=s TO f STEP 8 62 PRINT n;": "; 65 LET tot=0 66 REM INPUT THE WHOLE LINE OF EIGHT HEXIDECIMAL FIGURES FROM THE FIRST DIGIT TO THE LAST WITH SPACES BETWEEN 67 REM eg. at address 50000 input the line from C5 to 42 70 INPUT a$ 75 IF a$="END" THEN STOP 77 PRINT a$ 80 FOR b=0 TO 7 90 LET z=FN h(a$(1))*16+FN h(a$(2)) 95 LET tot=tot+z 100 POKE (n+b),z 110 LET A$=A$(4 TO ) 120 NEXT B 130 PRINT " = "; 135 REM enter total 140 INPUT t 150 IF t<>tot THEN PRINT "DATA INPUT ERROR": GO TO 62 160 PRINT t 170 NEXT n ```