This program is a machine code entry utility that accepts hexadecimal byte values as two-character strings and POKEs them into memory. The user first specifies a base address and the number of data bytes to zero-initialise, then enters hex opcodes one pair at a time until the sentinel value “S” is typed. Each hex pair is decoded using the formula `16*(CODE C$(1)-28)+CODE C$(2)-28`, which exploits the ZX81/TS1000 character set where digits ‘0’–’9′ have codes 28–37, converting ASCII hex pairs directly to byte values. After entry is complete, a second block of nine bytes is written from an array `M()`, suggesting a fixed machine code stub or loader is appended automatically. The REM at line 5 warns that the program must be entered via GOTO 10 rather than RUN, because RUN would reset variables and clear the `M()` array that the routine depends on.
Program Analysis
Program Structure
The program is divided into four logical phases:
- Initialisation (lines 10–90): Prompts for a base address
Band byte countD, then zero-fills the rangeBtoB+D-1. - Code entry (lines 100–170): Accepts two-character hex strings in a loop, decoding and POKEing each byte at successive addresses starting at
B+D(i.e. immediately after the data area). - Termination and stub append (lines 180–220): When the user types
"S", clears the screen, writes nine bytes from arrayM()at the current pointer, and STOPs. - Save (lines 230–240): Saves the program and loops back to line 5.
Hex Decoding Technique
The core decoding expression at line 150 is:
16*(CODE C$(1)-28) + CODE C$(2)-28
In the ZX81/TS1000 character set, the digit characters ‘0’–’9′ are assigned codes 28–37. Subtracting 28 therefore converts a decimal digit character to its numeric value 0–9. Multiplying the high nibble by 16 and adding the low nibble reconstructs the full byte. This only works for decimal digit pairs (0–9), so the scheme supports decimal-encoded bytes (00–99) rather than true hexadecimal (0–FF). The label “CODE:” and variable name C$ suggest hex was the original intent, but the arithmetic is calibrated to the ZX81 character table for decimal digits.
Memory Layout
| Region | Address range | Purpose |
|---|---|---|
| Data area | B to B+D-1 | Zero-initialised by lines 70–90 |
| Code area | B+D onwards | User-entered bytes POKEd here |
| Stub | After last entered byte | Nine bytes from array M() |
The M() Array and GOTO 5 Warning
Lines 190–210 write nine bytes from a numeric array M() that is never defined within this listing. This array must be pre-populated before the program runs — hence the REM at line 5 explicitly warning the user to GOTO 10 rather than RUN. Issuing RUN would invoke the NEW-variable behaviour and erase M(), causing a crash or garbage output at lines 200. The nine bytes likely form a fixed machine code stub (e.g. a call dispatcher or return sequence) that completes the assembled routine.
Notable BASIC Idioms
- Pointer variable
A: Initialised toB+Dat line 100 and incremented at line 160, acting as a write cursor through memory. - Sentinel-terminated input loop (lines 120–170): A string comparison
IF C$="S"provides the exit condition, a common ZX81 pattern for indefinite data entry. - Echo printing (lines 140, 30, 60): Each input is immediately PRINTed back, giving visual confirmation without a separate verification step.
Bugs and Anomalies
- The decoding formula only works correctly for two-character strings consisting of decimal digits (‘0’–’9’). Characters outside this range produce incorrect byte values. Despite the “CODE:” prompt implying hexadecimal, true A–F hex digits are not supported.
- There is no bounds or length check on
C$; entering a single character or an empty string at line 120 would cause a subscript error whenC$(2)is evaluated at line 150. - The save filename at line 230 contains
%6, which is an inverse-video ‘6’ character — a common auto-run encoding.
Content
Source Code
5 REM USE GOTO 10 NOT RUN
10 PRINT "BASE ADDRESS: ";
20 INPUT B
30 PRINT B
40 PRINT "NO.OF DATA BYTES: ";
50 INPUT D
60 PRINT D
70 FOR I=0 TO D-1
80 POKE B+I,0
90 NEXT I
100 LET A=B+D
110 PRINT "CODE:"
120 INPUT C$
130 IF C$="S" THEN GOTO 180
140 PRINT C$
150 POKE A,16*(CODE C$(1)-28)+CODE C$(2)-28
160 LET A=A+1
170 GOTO 120
180 CLS
190 FOR I=1 TO 9
200 POKE I-1+A,M(I)
210 NEXT I
220 STOP
230 SAVE "1024%6"
240 GOTO 5
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
