--- title: "Renumber" id: 53845 type: "computer_media" slug: "renumber" url: "http://localhost/computer_media/renumber/" markdown_url: "http://localhost/computer_media/renumber.md" published_at: "2024-05-13T19:02:05+00:00" modified_at: "2026-03-30T21:44:57+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2019/02/20230809-041332.jpg" excerpt: "A memory-poking BASIC renumberer lets you reassign a chosen range of program lines to a new start number and step, all without any machine code." 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/" indiv: - name: "Roger Valentine" slug: "roger-valentine" taxonomy: "indiv" url: "http://localhost/indiv/roger-valentine/" genre: - name: "Renumber" slug: "renumber" taxonomy: "genre" url: "http://localhost/type/renumber/" - name: "Utility" slug: "utility" taxonomy: "genre" url: "http://localhost/type/utility/" media_contents: - id: 55361 title: "SINCUS Exchange Tape 102 – Utilities & Business" type: "computer_media" url: "http://localhost/computer_media/sincus-exchange-tape-102-utilities-business/" media_type: "Program" programmers: - name: "Roger Valentine" slug: "roger-valentine" taxonomy: "indiv" url: "http://localhost/indiv/roger-valentine/" mediadate: "1983" images: - url: "http://localhost/wp-content/uploads/2024/05/renumber-sincus-102.png" related_content: - id: 20956 title: "The Timex Sinclair 2068: what can you do with it?" type: "book" url: "http://localhost/book/the-timex-sinclair-2068-what-can-you-do-with-it/" media_type_tags: "Renumber, Utility" --- This program renumbers a specified range of lines in a BASIC program stored in memory, reading the line number and length bytes directly via PEEK and POKE operations. The user supplies the first and last line numbers to renumber, a new starting number, and a step value, all subject to minimum-value guards. It locates the BASIC program area using system variables at addresses 23635–23638 (PROG and VARS pointers), then walks each line’s header in memory, rewriting the two-byte line-number field in place. The program is drawn from [Roger Valentine’s](http://localhost/indiv/roger-valentine/) book “[The Timex Sinclair 2068 Explored](http://localhost/book/the-timex-sinclair-2068-explored/)” and was entered by G.F. Chambers. *** ## Program Analysis ### Program Structure The program is organized into two phases: user input collection (lines 1–5) and in-memory line traversal with renumbering (lines 6–10). Lines 9998–9999 handle saving and verifying the program to tape and are not part of the renumbering logic itself. 1. **Lines 1–5:** Collect and validate four parameters — first line (`f`), last line (`e`), new starting number (`r`), and step (`s`). Each has a guard that loops back on invalid input. 2. **Lines 6–10:** Walk the BASIC program in memory, renaming lines whose original numbers fall within [`f`, `e`]. ### System Variable Usage The program uses two pairs of system variable addresses to bracket the BASIC program area: | Addresses | System Variable | Purpose | | --- | --- | --- | | 23635–23636 | PROG | Start address of the BASIC program | | 23637–23638 | VARS | Start of the variables area (marks end of BASIC) | Line 6 reads these two 16-bit little-endian values into `p` (current line pointer) and `v` (end sentinel). The condition `p=v` on line 8 detects that the entire program has been scanned. ### BASIC Line Header Format Each BASIC line in memory has a 4-byte header: two bytes for the line number (stored big-endian, high byte first) and two bytes for the line length (stored little-endian). Line 7 reconstructs the line number as `256*PEEK p + PEEK (p+1)` into `n`, and the line length as `PEEK (p+2) + 256*PEEK (p+3)` into `l`. Advancing the pointer by `4+l` on line 10 skips over the header plus the line body to reach the next line. ### Renumbering Logic Line 7 checks whether the current line number `n` is below the target range; if so, line 9 is skipped via `GO TO 9` and the pointer simply advances. When `n` is within range, line 9 overwrites the two header bytes in place using POKE: the high byte is `INT(r/256)` and the low byte is `r - (p1*256)`, after which `r` is incremented by the step `s`. Line 8 terminates traversal when the line number exceeds `e` or the end of the BASIC area is reached, then calls `LIST` to display the result before stopping. ### Notable Techniques - The renumbering operates entirely in-place with no copy of the program, relying solely on PEEK and POKE — no machine code or USR calls are needed. - Lines skipped because they fall before `f` still advance the counter `r` via the `GO TO 9` path — however, this is actually a subtle issue: on line 9, `r` is incremented unconditionally whether or not the line was in range. Because the `GO TO 9` on line 7 always falls through to line 9, lines before `f` will also consume a renumber slot, meaning the effective new numbers assigned may not start exactly at the user-supplied `r`. - The use of `LIST : STOP` on line 8 provides immediate visual confirmation of the renumbered program. - Input validation uses backward `GO TO` jumps rather than structured loops, a common BASIC idiom to enforce minimum values. - The line-length field being little-endian while the line-number field is big-endian accurately mirrors the Spectrum/TS2068 memory map, and the code correctly handles both byte orders. ### Bugs and Anomalies The most significant issue is that line 9 is always executed — both for lines within the renumber range and for lines before `f` (which jump directly to line 9 from the `IF ne 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 "" ```