Renumber

Developer(s): Charles Stelding
Date: 198
Type: Program
Platform(s): TS 2068

This program is a BASIC line renumbering utility that loads a 383-byte Z80 machine code routine via DATA statements encoded as hexadecimal ASCII strings. The machine code, stored at address 64986, scans the BASIC program area and updates all line-number references in GOTO, GOSUB, ON ERR GOTO, RESTORE, and similar statements. The hex loader in line 9943 converts each pair of ASCII hex digits into a byte value using CODE and arithmetic on the characters, then POKEs them sequentially into RAM. After loading, line 9998 prompts the user for a starting line number and step value, storing them at addresses 23297–23299 before invoking the routine with RANDOMIZE USR 64986.

To use this routine, enter RUN, SAVE the code as SAVE “RENUMBER”CODE 64986,383. DELETE 10,9996 and merge line 9998 into your program you wish to renumber.


Program Analysis

Program Structure

The program is divided into three functional zones:

  1. Lines 10–12: REM blocks providing authorship, usage instructions, and adaptation notes.
  2. Lines 9943–9991: The hex loader (line 9943) and 48 DATA lines (9944–9991) containing the machine code as hexadecimal ASCII strings.
  3. Line 9998: The user interface — prompts for start line number and step, POKEs parameters, and launches the machine code via RANDOMIZE USR 64986.

Hex Loader (Line 9943)

Line 9943 is the most technically dense part of the BASIC. It reads each DATA string, iterates over character pairs with STEP 2, and converts each hex digit pair to a byte using the expression:

(CODE a$(k)-48-(7 AND a$(k)>"9"))*16+(CODE a$(k+1)-48-(7 AND a$(k+1)>"9"))

This is a standard hex-decode idiom: subtracting 48 converts ASCII digits 0–9 to 0–9; the additional 7 AND a$(k)>"9" term subtracts 7 more for letters A–F (since ‘A’ is ASCII 65, and 65−48−7=10). The decoded byte is POKEd to consecutive addresses starting at 64986, loading all 383 bytes of machine code. After loading, LIST is called, which is an unusual choice — it simply refreshes the display rather than jumping to the run interface.

Machine Code Overview

The 383-byte Z80 routine is loaded into the high RAM area at address 64986 (hex FD9A). Based on the DATA bytes and the description in lines 11–12, the routine walks the BASIC program area, identifies numeric arguments to keywords like GOTO, GOSUB, RESTORE, and ON ERR GOTO, and rewrites those line numbers according to the new start and step values. The original routine is sourced from the book 40 Best Machine Code Routines for the ZX Spectrum by Hardman and Hewson (1982), adapted for the Timex 2068 by Charles Stelding.

Parameter Passing (Line 9998)

Line 9998 passes two parameters to the machine code via direct memory POKEs:

AddressContentPurpose
23297L - (INT(L/256))*256Low byte of starting line number
23298INT(L/256)High byte of starting line number
23299Step valueIncrement between renumbered lines

Addresses 23297–23299 fall within the system variables area. On the Spectrum/TS2068, this region (just above the system variables proper at 23296) is used here as a convenient scratchpad that the machine code routine knows to read from. The low byte is stored before the high byte, consistent with Z80 little-endian convention.

Notable Techniques

  • Hex string DATA encoding: Packing machine code as hex strings in DATA lines is a space-efficient and human-readable method compared to decimal DATA, halving the number of tokens per byte.
  • Single-pass hex decode loop: The nested FOR loop in line 9943 processes all 48 DATA strings in sequence using RESTORE 9944 to reset the DATA pointer explicitly.
  • High RAM placement at 64986: This address is near the top of the 64K address space, placing the routine safely above the BASIC and variable areas while remaining below the UDG/system stack region.
  • Usage workflow: The intended workflow (line 12) is to load the utility, SAVE the machine code block separately with SAVE "RENUMBER" CODE 64986,383, then delete lines 10–9996 and merge only line 9998 into the target program — a clean integration pattern.

Bugs and Anomalies

  • The LIST at the end of line 9943 is mildly anomalous; it serves as a visual cue that loading is complete but provides no functional feedback about success or failure of the POKE operations.
  • The step value input in line 9998 reuses variable L, overwriting the starting line number. This is intentional (the start line has already been POKEd) but could confuse a reader expecting separate variables.
  • No bounds checking is performed on the step value or starting line number entered by the user, so values that would produce line numbers exceeding 9999 could cause the machine code to behave unpredictably.

Content

Appears On

Related Products

Related Articles

Related Content

Image Gallery

Renumber

Source Code

   10 REM   RENUMBER UTILITYfrom "40 Best Machine Code      Routines for the ZX      Spectrum" by John Hardman      & Andrew Hewson, 1982adapted to the TIMEX 2068 by      Charles Stelding     1415 S. Baxter      Tyler TX 75701      214 593-3331
   11 REM This utility will renumberGOSUBS, ON ERR GOTO, GOTO,RESTORE, etc. within the BASIC  line.
   12 REM To use this routine, enter RUN, SAVE the code as SAVE "RENUMBER"CODE 64986,383, DELETE 10,9996  and merge line 9998 into your   program you wish to renumber.
 9943 RESTORE 9944: LET addr=64986: PRINT "Loading DATA lines...": FOR j=1 TO 48: READ a$: FOR k=1 TO LEN a$ STEP 2: LET num=(CODE a$(k)-48-(7 AND a$(k)>"9"))*16+(CODE a$(k+1)-48-(7 AND a$(k+1)>"9")): POKE addr,num: LET addr=addr+1: NEXT k: NEXT j: LIST 
 9944 DATA "2A015B7CB5C82A03"
 9945 DATA "5B7CB5C82A535CED"
 9946 DATA "5B015BCD4CFF3016"
 9947 DATA "4672234E73237123"
 9948 DATA "7023E52A035B19EB"
 9949 DATA "E1CD41FF18E52A53"
 9950 DATA "5C23232323CDEBFE"
 9951 DATA "D2B8FE545D060004"
 9952 DATA "237EFE2E2003EB18"
 9953 DATA "ECFE0E20F2232323"
 9954 DATA "2323237EFE3A2804"
 9955 DATA "FE0D20EA78FE0428"
 9956 DATA "1030E3D5626BF53E"
 9957 DATA "30CDEE0AF13CD118"
 9958 DATA "EC424BD521000011"
 9959 DATA "E803CDE2FE116400"
 9960 DATA "CDE2FE1E0ACDE2FE"
 9961 DATA "0AD6305F19444D2A"
 9962 DATA "535C2323CD4CFF38"
 9963 DATA "03E118997EB93007"
 9964 DATA "2323CD41FF18EB23"
 9965 DATA "7EB838F52B2B4E2B"
 9966 DATA "6669C1C5E511E803"
 9967 DATA "CDD4FE116400CDD4"
 9968 DATA "FE1E0ACDD4FE1E01"
 9969 DATA "CDD4FE0397020302"
 9970 DATA "03E17D02037C0203"
 9971 DATA "9702E1C30FFE2A53"
 9972 DATA "5C2323CD4CFFD054"
 9973 DATA "5D2323CD41FFE537"
 9974 DATA "ED522BEB732372E1"
 9975 DATA "18E73E30A7ED5238"
 9976 DATA "033C18F8190203C9"
 9977 DATA "0A03D62F3DC81918"
 9978 DATA "FB7ECD4CFFD0FEEA"
 9979 DATA "200D237EFE0D20FA"
 9980 DATA "232323232318EAFE"
 9981 DATA "222009237EFE2220"
 9982 DATA "FA2318DDFE0D28E8"
 9983 DATA "CD021628D4FEED28"
 9984 DATA "1BFEEC2817FEF728"
 9985 DATA "13FEF0280FFEE528"
 9986 DATA "0BFEE12807FECA28"
 9987 DATA "032318B5237EFE30"
 9988 DATA "38AFFE3A30ABC97E"
 9989 DATA "CD021628FBFE0D23"
 9990 DATA "20F5E5D5ED5B4B5C"
 9991 DATA "A7ED52D1E1C97E00"
 9998 INPUT "BEGINNING NEW LINE #? ";L: POKE 23298,INT (L/256): POKE 23297,L-(INT (L/256))*256: INPUT "Step? ";L: POKE 23299,L: RANDOMIZE USR 64986

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top