One very useful function that is not even possible using the Basic Editor is to be able to renumber only part of a Basic program. For example, you may wish to open a gap in the program to insert a few extra lines, or you may have adopted a numbering scheme where, say, each procedure started at a line which was a multiple of 1000. The machine code utility given here implements just such a renumber.
Start by entering the program given in the listing, and save it to disc. Running it will assemble a machine code utility (Arc utilities are discussed elsewhere in this issue), and save it with the filename 'Renumber'.
The Renumber command can be used in one of three forms:
*Renumber -Help
*Renumber -Check [-Start <lnum>] [-End <lnum>]
*Renumber [-NoConfirm] [-Start <lnum>] [-End <lnum>] [-First <lnum>] [-Increment <lnum>]
Any of the parameters enclosed in square brackets may be omitted, in which case various defaults will be assumed, these being detailed later. It is also normally possible to omit the keywords (for example putting 12000 instead of -END 12000). However, the keywords must be used when omitting a parameter would lead to confusion over the meanings of the others. For example:
*Renumber 10 100 1
would be the same as:
*Renumber -Start 10 -End 100 -First 1
Had it been intended that the '1' was the Increment, the 'First' parameter having been omitted, then the correct form would be:
*Renumber 10 100 -Increment 1
In any case, all the keywords can be abbreviated to just the first letter, so the above command would become:
*Renumber 10 100 -I 1
Incidentally, whenever a numeric parameter is required, an expression yielding a numeric result can be used instead.
The first form of the command will simply print the syntax and exit immediately:
*Renumber -Help
The second form of the command will check that the line numbers of a program are in sequence. This is because by using a partial renumber, it is possible to end up with a situation where one line has a line number equal to, or less than, the previous line. This will not normally affect the execution of a program, but will confuse commands which operate on a range of lines (for example LIST and DELETE). By using:
*Renumber -Check
all discrepancies in the line sequencing will be displayed in the form:
xxxx - yyyy
where xxxx is the first line number, and yyyy is the second. By specifying start and end line numbers, the check can be restricted to just a part of the program, for example:
*Renumber -Check 100 1000
If the start line number is omitted, the first line of the program is assumed, and if the end is omitted, the last line is assumed. If the specified lines do not exist, then the numbers are treated in the same way as for LIST.
The third form of the command is the one actually used for renumbering. As shown in the syntax above, there can be up to five parameters. The first of these is an optional qualifier (-NoConfirm), and controls what action is taken when renumbering would result in out of sequence line numbers occurring. If the qualifier is not given, then you are asked to confirm that you don't mind out of sequence numbers. On the other hand, if the qualifier is given then no confirmation is sought, although a warning will be given. The second and third parameters specify the start and end of the range to be renumbered, as above. The fourth parameter is the starting line number for the new numbering, and the final one is the increment to be used when renumbering. Both these default to ten if omitted.
The following examples should make the syntax clearer:
*RENUMBER
Renumber whole program starting at line ten, in increments of ten (just as with Basic's RENUMBER).
*RENUMBER 100 200 1000
Renumber lines between 100 and 200. Start at 1000 and increase in increments of 10.
*RENUMBER -NoConfirm 100 200 1000 50
As above, but use an increment of 50. Additionally, don't seek confirmation if out of sequence numbers result.
*RENUMBER 80 -First 100
Renumber all lines from line 80 to the end of the program to start at 100, and increase in increments of 10.
*RENUMBER -First 100 -Increment 25
Renumber the entire program to start at line 100, and increase in increments of 25.
*RENUMBER -End 999 -First 1 -Increment 2
Renumber all the lines up to line 999 to start at line 1 and go up in increments of 2.
10 REM > RenumSrc
20 REM Program Partial Renumber
30 REM Version A 1.00
40 REM Author David Spencer
50 REM RISC User May 1989
60 REM Program Subject to Copyright
70 :
80 DIM code 2000
90 FOR pass=0 TO 3 STEP 3
100 P%=code
110 [OPT pass
120 STMFD R13!,{R1,R14}
130 MOV R0,#15:MOV R1,#0
140 SWI "OS_ChangeEnvironment"
150 MOV R6,R1:MOV R0,#18
160 ADR R1,basic:SWI "OS_Module"
170 CMP R6,R3:BCC notbasic
180 LDR R0,[R3,#-4]:ADD R3,R3,R0
190 CMP R6,R3:BCC getparam
200 .notbasic ADR R0,nberr
210 LDMFD R13!,{R1,R14}
220 ORRS PC,R14,#1<<28
230 .getparam LDMFD R13!,{R1}
240 ADR R0,defn:MOV R2,R12:MOV R3,#100
250 SWI "XOS_ReadArgs"
260 LDMVSFD R13!,{PC}
270 LDR R0,[R12]:CMP R0,#0
280 ADRNE R0,help:SWINE "OS_Write0"
290 LDMNEFD R13!,{PC}^
300 MOV R0,#&8F00:LDRB R0,[R0,#1]
310 CMP R0,#&FF:ADREQ R0,noprog
320 LDMEQFD R13!,{R14}
330 ORREQS PC,R14,#1<<28
340 BL getrange:LDR R0,[R12,#4]
350 CMP R0,#0:BEQ renumber
360 .seq LDRB R2,[R7,#1]
370 LDRB R1,[R7]:ADD R1,R2,R1,LSL #8
380 LDRB R2,[R7,#2]:ADD R7,R7,R2
390 LDRB R3,[R7]:LDRB R4,[R7,#1]
400 ADD R3,R4,R3,LSL #8
410 CMP R1,R3:BCC seqok
420 MOV R0,R1:MOV R1,#1:BL prtnum
430 SWI &120:SWI &100+ASC"-":SWI &120
440 MOV R0,R3:MOV R1,#0:BL prtnum
450 SWI "OS_NewLine"
460 .seqok CMP R7,R8:BNE seq
470 LDMFD R13!,{PC}^
480 :
490 .renumber
500 LDR R6,[R12,#8]:MOV R9,R5
510 BL candg:LDR R0,[R12,#&14]
520 CMP R0,#0:MOVEQ R3,#10
530 BLNE gnum:MOVNE R3,R0
540 LDR R0,[R12,#&18]:CMP R0,#0
550 MOVEQ R4,#10:BLNE gnum:MOVNE R4,R0
560 CMN R9,#1:BEQ nof
570 CMP R9,R3:BCS badseq
580 .nof MOV R0,R7:MOV R9,R3
590 .schk LDRB R1,[R0,#2]
600 ADD R0,R0,R1:CMP R0,R8
610 ADDNE R9,R9,R4:BNE schk
620 LDRB R1,[R0,#1]:LDRB R2,[R0]
630 ADD R1,R1,R2,LSL #8
640 CMP R9,R1:BCC renum
650 .badseq CMP R6,#0:ADRNE R0,warn
660 SWINE "OS_Write0":BNE renum
670 ADR R0,query:SWI "OS_Write0"
680 MOV R0,#15:MOV R1,#1:SWI "OS_Byte"
690 SWI "XOS_ReadC":LDMVSFD R13!,{PC}
700 MOVCS R0,#ASC"N":BIC R0,R0,#&20
710 CMP R0,#ASC"Y":MOVNE R0,#ASC"N"
720 SWI "OS_WriteC":SWI "OS_NewLine"
730 LDMNEFD R13!,{PC}
740 .renum AND R0,R3,#&FF00
750 MOV R0,R0,LSR #8:STRB R0,[R7]
760 AND R0,R3,#&FF:STRB R0,[R7,#1]
770 LDRB R0,[R7,#2]:ADD R7,R7,R0
780 ADD R3,R3,R4:CMP R7,R8:BNE renum
790 BL lrefs:LDMFD R13!,{PC}^
800 :
810 .lrefs MOV R11,R14:MOV R9,R5
820 MOV R0,#&8F00:ADD R0,R0,#1
830 .lrefs2 LDRB R1,[R0]:CMP R1,#&FF
840 MOVEQ PC,R11:MOV R1,#3
850 .lrefs3 LDRB R2,[R0,R1]
860 ADD R1,R1,#1:CMP R2,#&8D:BLEQ ch
870 BEQ lrefs3:CMP R2,#&D:BNE lrefs3
880 LDRB R2,[R0,#2]:ADD R0,R0,R2
890 B lrefs2
900 :
910 .ch STMFD R13!,{R14}:ADD R2,R0,R1
920 LDRB R3,[R2]:LDRB R4,[R2,#1]
930 LDRB R5,[R2,#2]:MOV R3,R3,LSL #2
940 AND R6,R3,#&C0:EOR R4,R4,R6
950 MOV R3,R3,LSL #2:AND R6,R3,#&C0
960 EOR R5,R5,R6:ADD R5,R4,R5,LSL #8
970 MOV R3,#&8F00:ADD R3,R3,#1
980 MOV R4,R9
990 .hunt LDR R7,[R4],#4:CMP R7,R5
1000 BEQ hdone:LDRB R7,[R3,#2]
1010 ADD R3,R3,R7:LDR R7,[R4]
1020 CMP R7,#&FF00:BCC hunt
1030 STMFD R13!,{R0-R1}
1040 ADR R0,fail:SWI "OS_Write0"
1050 MOV R0,R5:MOV R1,#0:BL prtnum
1060 ADR R0,fail2:SWI "OS_Write0"
1070 LDR R0,[R13]:LDRB R1,[R0,#1]
1080 LDR R0,[R0]:ADD R0,R1,R0,LSL #8
1090 MOV R1,#0:BL prtnum
1100 SWI "OS_NewLine"
1110 LDMFD R13!,{R0-R1,R14}
1120 ADD R1,R1,#3:MOVS PC,R14
1130 .hdone LDRB R4,[R3,#1]
1140 LDRB R5,[R3]:ADD R3,R4,R5,LSL #8
1150 AND R4,R3,#&3F:ORR R4,R4,#&40
1160 STRB R4,[R2,#1]:AND R4,R3,#&3F00
1170 MOV R4,R4,LSR #8:ORR R4,R4,#&40
1180 STRB R4,[R2,#2]:AND R4,R3,#&C0
1190 MOV R4,R4,LSR #2:AND R5,R3,#&C000
1200 MOV R5,R5,LSR #12:ORR R4,R4,R5
1210 EOR R4,R4,#&54:STRB R4,[R2]
1220 ADD R1,R1,#3:LDMFD R13!,{PC}^
1230 LDMFD R13!,{PC}^
1240 :
1250 .basic EQUS "BASIC":EQUB 0:ALIGN
1260 .nberr EQUD 0:EQUS "Not in Basic"
1270 EQUB 0:ALIGN
1280 .noprog EQUD 0:EQUS "No program"
1290 EQUB 0:ALIGN
1300 .help EQUS "Renumber -Help"
1310 EQUW &D0A
1320 EQUS "Renumber -Check [-Start <lno>] [-End <lno>]":EQUW &D0A
1330 EQUS "Renumber [-NoConfirm] [-Start <lno>] [-End <lno>] [-First <lno>] [-Increment <lno>]":EQUW &D0A:EQUB 0:ALIGN
1340 .nerr EQUD 0:EQUS "Bad line number":EQUB 0:ALIGN
1350 .nrerr EQUD 0
1360 EQUS "No room for renumber":EQUB 0
1370 ALIGN
1380 .bserr EQUD 0:EQUS "Bad range"
1390 EQUB 0:ALIGN
1400 .defn EQUS "Help/S,Check/S,NoConfirm/S,Start/E,End/E,First/E,Increment/E"
1410 EQUB 0:ALIGN
1420 .fail EQUS "Failed with "
1430 EQUB 0:ALIGN
1440 .fail2 EQUS " on line "
1450 EQUB 0:ALIGN
1460 .warn EQUS "Line numbers will be out of sequence":EQUW &D0A:EQUB 0:ALIGN
1470 .query EQUS "This will result in out of order line numbers - Continue (Y or N) ? ":EQUB 0
1480 :
1490 .gnum LDRB R1,[R0]:CMP R1,#0
1500 BNE bnum:LDRB R1,[R0,#3]
1510 LDRB R2,[R0,#4]:ORRS R1,R1,R2
1520 BNE bnum:LDRB R1,[R0,#2]
1530 CMP R1,#&FF:BEQ bnum
1540 LDRB R0,[R0,#1]
1550 ADD R0,R0,R1,LSL #8:MOVS PC,R14
1560 .bnum ADR R0,nerr:LDMFD R13!,{R14}
1570 ORRS PC,R14,#1<<28
1580 :
1590 .prtnum STMFD R13!,{R0-R3}
1600 MOV R3,R1:MOV R1,R12:MOV R2,#6
1610 SWI "XOS_ConvertCardinal2"
1620 CMP R3,#1:BNE prtnum2
1630 .cloop CMP R2,#1:BEQ prtnum2
1640 SWI &120:SUB R2,R2,#1:B cloop
1650 .prtnum2 SWI "OS_Write0"
1660 LDMFD R13!,{R0-R3}:MOV PC,R14
1670 :
1680 .candg MOV R0,#&8F00
1690 ADD R0,R0,#1:MOV R1,#0
1700 .candg2 LDRB R2,[R0,#1]
1710 LDRB R3,[R0]:ADD R2,R2,R3,LSL #8
1720 CMP R3,#&FF:ADDNE R1,R1,#1
1730 LDRNEB R3,[R0,#2]:ADDNE R0,R0,R3
1740 BNE candg2:ADD R0,R0,#4
1750 BIC R4,R0,#3:MOV R3,R1,LSL #2
1760 SWI "OS_GetEnv":ADD R0,R3,R4
1770 MOV R5,R4:CMP R0,R1:ADRHI R0,nrerr
1780 LDMHIFD R13!,{R14}
1790 ORRHIS PC,R14,#1<<28
1800 MOV R0,#&8F00:ADD R0,R0,#1
1810 .candg3 LDRB R2,[R0,#1]
1820 LDRB R3,[R0]:ADD R2,R2,R3,LSL #8
1830 STR R2,[R4],#4:CMP R3,#&FF
1840 LDRNEB R2,[R0,#2]:ADDNE R0,R0,R2
1850 BNE candg3:MOV PC,R14
1860 :
1870 .getrange MOV R11,R14:MOV R3,#0
1880 LDR R0,[R12,#12]:CMP R0,#0
1890 BEQ nostart:BL gnum:MOV R3,R0
1900 .nostart LDR R0,[R12,#16]
1910 MOV R4,#&FF00:SUB R4,R4,#1
1920 CMP R0,#0:BEQ noend
1930 BL gnum:MOV R4,R0
1940 .noend MVN R5,#0:MOV R6,#0
1950 MOV R2,#&8F00:ADD R2,R2,#1
1960 .gr LDRB R0,[R2,#1]
1970 LDRB R1,[R2]:ADD R0,R0,R1,LSL #8
1980 CMP R0,R3:BCC nolo:CMP R6,#0
1990 MOVEQ R7,R2:MVNEQ R6,#0
2000 .nolo CMP R0,R4:LDRLSB R8,[R2,#2]
2010 ADDLS R8,R2,R8:CMP R6,#0
2020 MOVEQ R5,R0:CMP R0,#&FF00
2030 LDRCCB R0,[R2,#2]:ADDCC R2,R2,R0
2040 BCC gr:CMP R8,R7:ADRLS R0,bserr
2050 LDMLSFD R13!,{R14}
2060 ORRLSS PC,R14,#1<<28:MOV PC,R11
2070 ]NEXT
2080 SYS "OS_File",10,"Renumber",&FFC,,code,P%