This program renumbers a specified range of BASIC lines in memory, replacing line numbers with a new starting value and user-defined step increment. It operates directly on the BASIC program area using PEEK and POKE, reading the program start address from system variables at addresses 23635–23638 (PROG and VARS pointers). Each BASIC line’s stored format — two bytes for the line number followed by two bytes for the line length — is traversed in sequence, and the line number bytes are overwritten in place. The program accepts a first line, last line, new starting number, and step value, then walks the program area until the renumbered range is exhausted or the VARS boundary is reached.
Program Analysis
Program Structure
The program is short and entirely self-contained, consisting of an input phase (lines 1–5), a memory-traversal loop (lines 6–10), and save/verify lines (9998–9999). There are no subroutines; control flow is handled purely with GO TO and a conditional STOP.
- Lines 1–5: Collect user inputs: first line (
f), last line (e), new starting number (r), and step (s), with simple validation guards. - Line 6: Reads system variable pointers to obtain
p(start of BASIC program area) andv(start of VARS area). - Lines 7–10: Walk each BASIC line in memory, reading line number and length, conditionally poking new line numbers, and advancing the pointer.
System Variable Usage
The program uses four system variable addresses to anchor itself within the machine’s memory map:
| Address | System Variable | Purpose |
|---|---|---|
| 23635–23636 | PROG | Address of first byte of BASIC program |
| 23637–23638 | VARS | Address of BASIC variables area (used as end sentinel) |
The two-byte little-endian values are read with the idiom PEEK low + 256 * PEEK high. Note that line 6 re-reads p from PROG on every iteration of the loop, which is intentional: it always resets the scan to the beginning of the program so that lines before f are skipped each pass.
BASIC Line Format Traversal
Each BASIC line in memory is stored as: two bytes for the line number (big-endian), two bytes for the line length (little-endian), followed by the tokenized line content. Line 7 reads the line number as 256 * PEEK p + PEEK (p+1) (big-endian) and the length as PEEK (p+2) + 256 * PEEK (p+3) (little-endian). Line 10 advances the pointer by 4 + l to step over the header and body of the current line.
Renumbering Logic
Line 9 performs the actual renumbering. The new line number r is split into its high byte (p1 = INT(r/256)) and low byte (r - p1*256), then POKEd into the two line-number bytes at p and p+1. After each poke, r is incremented by the step s. Because the scan restarts from PROG on each loop iteration (line 6 is the loop target via line 10’s GO TO 6), lines before f are simply skipped each time, which is functionally correct but inefficient for large programs.
Key BASIC Idioms
- Input validation with immediate
GO TOback to the input line: e.g.,IF f<10 THEN GO TO 1. - Big-endian line-number read:
256*PEEK p + PEEK (p+1). - Little-endian length read:
PEEK (p+2) + 256*PEEK (p+3). - High/low byte split for POKE:
INT(r/256)and remainder arithmetic instead of bitwise operations (unavailable in BASIC).
Notable Limitations and Anomalies
- GO TO targets are not updated: The program renumbers only the stored line-number header bytes. Any
GO TO,GO SUB, orRESTOREstatements within the program that reference the renumbered lines by number will become invalid after renumbering — a well-known limitation of simple in-place renumberers. - Loop restarts from PROG each iteration: Because line 10 jumps to line 6 (which re-reads PROG into
p), the scan always starts from the very first line of the program. This means the tool scales as O(n²) in the number of lines before the target range. A more efficient design would preservepacross iterations. - No upper bound on
r: There is no check that the renumbered values stay below 9999 (the maximum BASIC line number). Renumbering with a large step or many lines could produce invalid line numbers. - Line 8 termination condition: The loop stops when either the current line number exceeds
e(n>e) or the pointer reaches the VARS area (p=v), at which point it issuesLIST : STOPto display results and halt.
Content
Source Code
1 REM RENUMBER \''\''\''\''\''\''\''\'' from the book entitled "THE TIMEX SINCLAIR 2068" by ROGER VALINTINE entered by G.F. Chambers
2 INPUT "First line to renumber ";f: IF f<10 THEN GO TO 1
3 INPUT "Last line to renumber ";e
4 INPUT ("New number for ";f;" ");r: IF r<10 THEN GO TO 3
5 INPUT "Step ";s: IF s<1 THEN GO TO 4
6 LET p=PEEK 23635+256*PEEK 23636: LET v=PEEK 23637+256*PEEK 23638
7 LET n=256*PEEK p+PEEK (p+1): LET l=PEEK (p+2)+256*PEEK (p+3): IF n<f THEN GO TO 9
8 IF n>e OR p=v THEN LIST : STOP
9 LET p1=INT (r/256): POKE p,p1: POKE p+1,r-(p1*256): LET r=r+s
10 LET p=4+p+l: GO TO 6
9998 SAVE "RENUMBER" LINE 1
9999 VERIFY ""
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
