Renumbering Basic Statements

See all articles from SYNC v2 n6

Many versions of Basic have a Renumber utility. This is used to renumber Basic statements starting at a specified statement and spacing statements with a given increment between the statements. For example, if the starting number is 4 and the increment is 7, the lines in the Basic program would go: 4, 11, 18, 25, 32, etc. Most programmers start their programs at statement 10 and use increments of 10.

The advantages to a Renumber utility should be readily apparent. Sometimes a programmer uses all of the numbers between two Basic statements while modifying a program. A Renumber utility can be used to place unused statement numbers between all statements. A completed program is also more attractive if all of the statements are spaced at constant increments.

A Sinclair Basic Renumber Program

This article presents two Basic renumbering programs in Sinclair Basic for the 8K ROM. The program in Program 1 is a short program that can be used with 1K or 16K RAM. This program only renumbers the Basic statements. It does not do anything about the destination addresses for GOSUB and GOTO keywords that must be changed after a program is renumbered.

The program in Program 2 is a longer program that also calculates the destination address for each GOTO and GOSUB statement.

How to Use the Program

The user must select one of the two programs and enter it on a cassette tape. Whenever the user decides to work on a new program, he first enters the renumber program into his computer. During the stages of program development the renumber program can be saved on cassette along with the user’s program. The renumber programs occupy consecutive high statement numbers (9981 through 9999 for Program 1 and 9938 for Program 2). This leaves almost all possible Basic statement numbers for the program that is being developed.

The variables in the renumber program were selected so that it would be very unlikely that the user would have the same variable names in the program that he is developing.

When the programmer decides to renumber the program, he enters GOTO 9982 (shorter program) or GOTO 9939 (longer program). Both programs prompt the user for the new starting statement of the user program and the increment between Basic statements. The user can choose any number from 1 to 255 for the starting number and for the increment between statements. After these numbers are entered, both programs renumber the user’s program. If the longer renumber program is used, the program prints out a series of statements such as

25 GOTO 50
30 GOSUB 5
40 GOTO *

The user must edit statement 25 in the renumbered program so that the number after GOTO is changed to 50. Statement 30 must be edited so that 5 occurs after the GOSUB. The * in statement 40 indicates that the GOTO in statement 40 was not followed by a number or that the original number did not start immediately after the GOTO. Note that the renumber program is written so that it does not get renumbered while the users program is renumbered. In fact, any statement number above 8959 will not be renumbered.

After a program is completed and renumbered, the renumber program can be deleted statement by statement. Once the renumber program is deleted, a modified program cannot be renumbered by the renumber program unless the user is willing to reinsert the renumber program by hand.

How Program 1 Works

Sinclair computers with the 8K ROM start storing Basic statements at memory location 16509. Each stored statement starts with two bytes that contain the number of the Basic statement. The first of these two bytes, byte 16509 for the first Basic statement, contains the low portion of the statement number. Suppose that one has a Basic program in the computer. The command

PRINT PEEK 16509*256+PEEK 16510

would print the decimal equivalent of the first statement number.

The second two bytes in a program statement, 16511 and 16512 for the first program statement, contain a number that is the length of the Basic statement including the ENTER that occurred at the end of the statement. These two bytes have the high portion of the number in the higher byte (16512 for the first Basic statement) and the lower portion of the number in the lower byte (16511 for the first Basic statement).

Suppose that the variable III contains the address of the first (high) byte of a Basic statement (e.g., 16509). Location III = 1 contains the second byte of the statement number. Numbers III = 2 and III = 3 are equal to the locations of the low and high bytes of the number of bytes in the statement. If III is set to the location of the high byte of a statement number, the high byte of the next statement number has to be

PEEK (III+2)+PEEK (III+3)*256+4

That is,

PEEK (III+2)+PEEK (III+3)*256

is equal to the length of the current Basic statement including ENTER. The 4 is the sum of the two bytes occupied by the statement number and the two bytes that indicate the statement length. The statement

LET III=III+PEEK(III+2)+PEEK (III+3)*256+4

can be used to increment III to the address of the first byte of the statement number of the next Basic statement.

Suppose that one has a decimal number that is less than 255. This number can be added to the low byte of a statement number. The computer contains a number between 0 and 255 in this byte. If the sum of these numbers is greater than 255, a 1 must be added to the high byte of the statement number. Statements 9991 through 9998 in Program 1 are a subroutine that adds the increment (interval between Basic statements) to what was the number of the last renumbered statement. Assume GGG contains the new statement number for a statement that is being renumbered. Statement 9992 tests to determine if the number is less than 256. If it is less than 256, control passes to statement 9955 which pokes 0 into the high byte of the statement number because JJJ was set to 0 in statement 9982. Then statement 9996 pokes the new statement number in the low byte of the statement number in GGG by the appropriate increment, FFF. Then the main program is reentered (statement 9998) as statement 9984.

If the current statement number is greater than 256, JJJ, the high byte of the statement number, is corrected in statement 9994. That is, the low byte of the statement must have 256 subtracted to account for the 1 that was added to the high byte. Statements 9995 and 9996 POKE in the new high and low bytes for the statement number. Statement 9997 increments the statement number and statement 9998 returns control to the main program.

Statements 9983 through 9986 in Program 1 request and input the starting number and increment for the renumber program. Statement 9987 sets III to the address of the high byte of the first statement number. Statement 9998 transfers control to the subroutine that POKEs in the new statement number. When the main program is later reentered, statement 9989 increments III to the address of the high byte of the next statement number.

Statement 9988 returns the program to statement 9988 so that the next statement can be renumbered. Every time the subroutine for incrementing the statement number is entered, statement 9991 checks to determine if the current high byte of a statement number is greater than 34. If this number is greater than 34, the program stops, insuring that the renumber program will not be renumbered.

How Program 2 Works

Statements 9940 through 9944 request and input the starting number, GGG, and the increment, FFF. Statements 9944 through 9946 provide a heading for the GOTO and GOSUB statements that will be listed. Variable III is set to 16513, the beginning of the first Basic statement, in statement 9947.

Statement 9948 determines if one has reached the end of a Basic statement. The number 118 is the Sinclair code for the ENTER that terminates each Basic statement. If the end of a statement has not been reached, statements 9952 and 9953 determine if III is pointing to a GOTO (236) or a GOSUB (237) code. The variable HHH is set to 1 for a GOTO or 2 for a GOSUB code in statements 9952 and 9953. The variable HHH remains a 0 (set in statement 9939) if III is not pointing to a GOTO or a GOSUB code.

Statement 9954 checks to determine if III is set to the code (126) that indicates a five byte binary number is to follow. If a binary number follows in the Basic program listing sequence, statement 9954 increments III to the address of the first byte after the binary number. That is, statement 9954 adds 5 to III and statement 9956 adds an additional 1 to make a total of 6. The binary number plus the 126 code takes a total of six bytes in the Basic statement. A binary number can contain 126, 236, or 237 in any or all of the five locations occupied by the binary number. These numbers must not be interpreted as a GOTO, GOSUB, or the beginning of a number code.

Statement 9955 transfers control to statement 9958 if a GOTO or GOSUB code is encountered. If a GOTO or GOSUB code is not reached, III is incremented by 1 to the next byte (statement 9956) and control is returned to statement 9948 to check the next memory location. When an ENTER code is finally detected in statement 9948, the next byte in the Basic sequence is checked (statement 9949) to determine if the last program statement is renumbered. That is, III is set to the first byte of a statement number. If this byte is greater than 34, the statement number is above 8959 and is not renumbered.

Statement 9950 increments MMM which was set equal to the starting number for the Basic program in statement 9942. Every time statement 9950 is encountered, MMM is incremented by FFF which contains the increment number for the renumber program. Since statements 9948 and 9949 are only encountered when III is set to the address of ENTER (118) at the end of a statement, statement 9951 is used to increment III to the next Basic keyword. That is, the next statement number address and the two bytes containing the length of the next Basic statement are skipped.

Statement 9958 prints out the renumbered statement number of a GOTO or GOSUB statement. The word GOTO (statement 9959) or the word GOSUB (statement 9960) is printed by statement 9958 or statement 9959. Remember that HHH is 1 for a GOTO statement 9961. Statements 9958 through 9961 cannot be encountered unless III points to the address of a GOTO or a GOSUB code in the Basic statement.

The numbers that a user enters after a GOTO or GOSUB keyword are coded by the Sinclair ROM as a number between 28 and 37. That is, 0 is 28, 1 is 29 . . . 9 is 37. A GOTO or GOSUB code need not be followed by a number. An expression such as (A * B) could have been entered after the GOTO or GOSUB. Statement 9962 checks to determine if a number follows the GOTO or GOSUB code. If a number does not follow the GOTO or GOSUB code, an asterisk (statement 9963) is placed after the statement number and GOTO or GOSUB that are on the screen. Then control is returned to statement 9956 so that III can be incremented to the next location in the Basic sequence.

If a number is located after GOTO or GOSUB, statement 9962 causes statement 9965 to be encountered. Statements 9965 through 9968 start JJJ at 2 and increment JJJ as successive memory addresses are checked to determine the length of the number. If the number is greater than 4, statement 9968 transfers control to statement 9963 to print an asterisk after the GOTO or GOSUB on the television screen. The program assumes a valid number following a GOTO or GOSUB cannot be greater than 4 bytes long.

After statement 9966 detects a byte containing 126 (the beginning of a binary number), control is transferred to statement 9970. At this point III + JJJ points to the location after the number in the GOTO or GOSUB sequence. Statements 9970 and 9971 set LLL and KKK to 1 and 0, respectively.

Statements 9972 through 9976 form a loop that changes the coded number of following GOTO or GOSUB into a decimal number. The loop starts (statement 9972) by examining the last coded digit in the number, and subtracting 28 from this coded number to make it into a decimal number. The number is multiplied by LLL which is started at 1. The variable JJJ is decremented by 1 in statement 9973.

If the number was only one digit long or a 236 (GOTO) or 237 (GOSUB) code is detected in statement 9974, control is transferred to statement 9977. If the number is more than one digit long, the multiplier LLL is multiplied by 10 and statement 9976 transfers control to statement 9974. Statement 9974 decodes the second from the last digit of the number, multiplies it by LLL, which is now 10, and adds this number to the last digit of the number. The loop in statements 9972 through 9975 is not completed until the entire number is decoded.

Statement 9997 sets JJJ to 16509, the starting address of the Basic statements. The loop in statements 9979 through 9982 looks at each Basic statement address and checks to determine if the address is greater than or equal to KKK which is the decoded old address of the current GOTO or GOSUB statement. After an address is checked, 1 is added to the variable NNN.

When an address is encountered that is greater than KKK, NNN contains a number that equals the number of Basic statements before the statement that is the destination of the GOTO or GOSUB statement.

Statement 9983 uses this formula: New destination address = New starting address + (number of Basic statements before the destination statement – 1) * increment. This is used to calculate the new destination address for the GOTO or GOSUB statement in question. Statement 9984 prints the new destination address after the GOTO or

Finally, statement 9985 returns control to statement 9956 to repeat the process outlined above for the next Basic statement. When the last GOTO or GOSUB statement is listed, statement 9949 transfers control to statement9986. Up to this point the original program has not been renumbered. Statements 9989 through 9998 renumber the program in the same way that statements were renumbered in Program 1. In fact, statements 9987 through 9998 in Program 2 are identical to the statements with the same statement numbers in Program 1.

Program 1. Renumber (1K).

9981 STOP
9982 LET JJJ=0
9983 PRINT "ENTER STARTING NUMBER"
9984 INPUT GGG
9985 PRINT "ENTER INCREMENT"
9986 INPUT FFF
9987 LET III=16509
9988 GOSUB 9991
9989 LET III=III+PEEK (III+2)+PEEK (III+3)*256+4
9990 GOTO 9988
9991 IF PEEK II6>34 THEN STOP
9992 IF GGG<256 THEN GOTO 9995
9993 LET JJJ=JJJ+1
9994 LET GGG=GGG-256
9995 POKE III,JJJ
9996 POKE (III+1),GGG
9997 LET GGG=GGG+FFF
9998 RETURN
9999 STOP

Program 2. Renumber with GOTO and GOSUB Destinations.

9938 STOP
9939 LET HHH=0
9940 PRINT "ENTER STARTING NUMBER"
9941 INPUT GGG
9942 LET MMM=GGG
9943 PRINT "ENTER INCREMENT"
9944 INPUT FFF
9945 PRINT "REINSERT THESE STATEMENTS"
9946 PRINT
9947 LET III=16513
9948 IF PEEK III<>118 THEN GOTO 9952
9949 IF PEEK (III+1)>34 THEN GOTO 9986
9950 LET MMM=MMM+FFF
9951 LET III=III+5
9952 IF PEEK III=236 THEN LET HHH=1
9953 IF PEEK III=237 THEN LET HHH=2
9954 IF PEEK III=126 THEN LET III=III+5
9955 IF HHH>0 THEN GOSUB 9958
9956 LET III=III+1
9957 GOTO 9948
9958 PRINT MMM;
9959 IF HHH=1 THEN PRINT " GOTO ";
9960 IF HHH=2 THEN PRINT " GOSUB ";
9961 LET HHH=0
9962 IF PEEK (III+1)>27 AND PEEK (III+1)<38 THEN GOTO 9965
9963 PRINT " * "
9964 RETURN
9965 LET JJJ=2
9966 IF PEEK (III+JJJ)=126 THEN GOTO 9970
9967 LET JJJ=JJJ+1
9968 IF JJJ>5 THEN GOTO 9963
9969 GOTO 9966
9970 LET LLL=1
9971 LET KKK=0
9972 LET KKK=KKK+(PEEK (III+JJJ-1)-28)*LLL
9973 LET JJJ=JJJ-1
9974 IF PEEK (III+JJJ-1)=236 OR PEEK (III+JJJ-1)=237 THEN GOTO 9977
9975 LET LLL=LLL*10
9976 GOTO 9972
9977 LET JJJ=16509
9978 LET NNN=0
9979 IF PEEK JJJ*256+PEEK (JJJ+1)>=KKK THEN GOTO 9983
9980 LET NNN=NNN+1
9981 LET JJJ=JJJ+PEEK (JJJ+2)+PEEK (JJJ+3)*256+4
9982 GOTO 9979
9983 LET KKK=GGG+NNN*FFF
9984 PRINT KKK
9985 RETURN
9986 LET JJJ=0
9987 LET III=16509
9988 GOSUB 9991
9989 LET III=III+PEEK (III+2)+PEEK (III+3)*256+4
9990 GOTO 9988
9991 IF PEEK III>34 THEN STOP
9992 IF GGG<256 THEN GOTO 9995
9993 LET JJJ=JJJ+1
9994 LET GGG=GGG-256
9995 POKE III,JJJ
9996 POKE (III+1),GGG
9997 LET GGG=GGG+FFF
9998 RETURN
9999 STOP

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