This program walks the BASIC program area in memory to produce a line-by-line report of each line number, its byte length, and a weighted checksum of its contents. It uses system variables at addresses 23635–23636 (PROG, the start of the BASIC program) and 23627–23628 (VARS, marking the end) to determine the memory range to scan. For each line it reads the two-byte line number and two-byte length field directly with PEEK, then iterates over the line’s bytes computing an alternating-weight checksum where even-positioned bytes are doubled. Results are sent simultaneously to the screen via PRINT and to a printer via LPRINT.
Program Analysis
Program Structure
The program occupies lines 9987–9999, placing it at the very top of the line-number space so it can analyze whatever program precedes it in memory without disturbing its own working. The REM lines at 9987–9990 serve as a self-documenting header listing the variables and I/O channels used. Execution begins at line 9991 and follows a simple sequential flow with a single backward GO TO 9992 loop.
Memory Layout Traversal
The scanner uses two well-known system variable pairs to bracket the BASIC program area:
- PROG (23635–23636): two-byte address of the first byte of the BASIC program, used to initialize
byt. - VARS (23627–23628): two-byte address of the variables area, which immediately follows the last BASIC line, used as the stop sentinel.
Each BASIC line in memory has the standard four-byte header: two bytes of line number (high byte first) followed by two bytes of line length (low byte first, little-endian). The code at line 9993 reads the line number as 256*PEEK byt + PEEK (byt+1) (big-endian), and line 9994 reads the length as 256*PEEK (byt+1) + PEEK byt (little-endian), correctly reflecting the ZX Spectrum BASIC file format.
Checksum Algorithm
Line 9995 computes a weighted sum over the line’s payload bytes. The variable odd alternates between 1 and 0 using NOT odd, and the contribution of each byte is (odd+1) * PEEK byt. This means:
- Odd-positioned bytes (1st, 3rd, …) contribute with weight
2(sinceodd=1,odd+1=2). - Even-positioned bytes (2nd, 4th, …) contribute with weight
1(sinceodd=0,odd+1=1).
This alternating-weight scheme is reminiscent of modular checksum designs used to detect transposition errors, though it is a custom rather than standard algorithm.
Output
Line 9996 prints each record to the screen and line 9997 sends an identical record to the printer using LPRINT. The TAB calls at columns 6 and 13 create a fixed-width columnar layout: line number, a colon separator, byte length, another colon, and the checksum.
Loop Control
After processing a line, line 9998 checks whether byt has reached or passed stop (the VARS pointer). If more lines remain, control returns to 9992 to read the next line header. The loop terminates naturally at line 9999 with STOP.
Variable Summary
| Variable | Role |
|---|---|
start | Address of first byte of BASIC program (PROG system variable) |
stop | Address of first byte of VARS area (end sentinel) |
byt | Current memory pointer, advances through program bytes |
line | Current BASIC line number decoded from header |
length | Byte count of current line’s payload |
sum | Accumulated weighted checksum for current line |
odd | Alternating flag (1/0) controlling byte weight |
i | FOR loop counter over line bytes |
Anomalies and Notes
The variable sum is initialized once at line 9992 but is never reset between lines — it accumulates across all lines rather than resetting per line. This means the printed sum column is a running total, not a per-line checksum, which may or may not be the intended behavior. Similarly, start is computed but only used to set byt; because byt begins at start, the value of start itself is not needed afterward.
Because this program resides at lines 9987–9999, it will include its own lines in the scan output when run standalone, which is an unavoidable self-referential side-effect of the design.
Content
Source Code
9987 REM ! LIST
9988 REM ! LPRINT
9989 REM !INT +START,STOP,BYT,LINE,LENGTH,SUM,ODD,I
9990 REM ! OPEN #
9991 LET start=256*PEEK 23636+PEEK 23635: LET stop=256*PEEK 23628+PEEK 23627: LET byt=start
9992 LET line=0: LET length=0: LET sum=0
9993 LET line=256*PEEK byt+PEEK (byt+1): LET byt=byt+2
9994 LET length=256*PEEK (byt+1)+PEEK byt: LET byt=byt+2
9995 LET odd=1: FOR i=1 TO length: LET sum=sum+(odd+1)*PEEK byt: LET odd=NOT odd: LET byt=byt+1: NEXT i
9996 PRINT line;TAB 6;": ";length;TAB 13;": ";sum
9997 LPRINT line;TAB 6;": ";length;TAB 13;": ";sum
9998 IF byt<stop THEN GO TO 9992
9999 STOP
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
