This month we add commands to search disc files for a given byte, 32-bit word, or character sequence; and also a useful help command.
This month's listing should be entered in exactly the same way as for previous ones, ensuring the program has not been renumbered. Save the source code program and run it. This assembles and saves the Toolbox module which can then be loaded by typing QUIT followed by TOOLBOX.
The first new command is invoked using *TOOLS, or *HELP TOOLS. This lists out all the commands that the RISC User Toolbox accepts. More details of each command can be found using *HELP <command name>.
There are three commands for searching disc files. These are:
*DSEARCHB <byte>... <filename> [<pathname>] [V][C]
*DSEARCHW <word>... <filename> [<pathname>] [V][C]
*DSEARCHS <string> <filename> [<pathname>] [V][C]
They are used to search for byte sequences, 32-bit word sequences and character strings respectively.
All these commands have a similar syntax. Each starts with the search data, which is either a series of bytes or 32-bit words (both in hex) separated by spaces, or a character string enclosed in quotes for *DSEARCHS. Next is a wildcarded filename that specifies which files to search, and an optional pathname to show where the search is to start. Finally, there can be up to two qualifiers:
V | Display name of each file as it is searched. |
C | Ask for confirmation before searching a file. |
The commands will search the directory tree from the starting point specified, examining files that match the wildcarded filename given. If the C option is used, you are asked whether each match should be searched or not. You can also at this point choose to stop confirming for each file by pressing Q (for Quiet), or to abort the search by pressing A. As each file is searched, it is loaded into application memory. Therefore, any program in memory is lost, and should be saved first.
Here are some examples of the use of these commands:
*DSEARCHB 9F 5 1A "EDIT" $.UTILS
to search for the byte sequence 9F,5,1A in the file $.UTILS.EDIT. Note the use of quotes to stop the 'ED' of 'EDIT' being interpreted as a fourth byte to search for.
*DSEARCHW FFFF 0000 PROG* ADFS:$ VC
to search for the word sequence FFFF, 0000 in all files with names beginning 'PROG' on the current disc. Additionally, confirmation is asked before searching each file, and the name of each file is printed as it is searched.
*DSEARCHS "Hello" * "" C
to search for the word 'Hello' in all files starting from the current directory. Again, confirmation is sought before searching each file.
Note that if any qualifiers are given without a pathname, then "" must be used to show that it has been omitted, as in the last example.
For each match found, the name of the file is printed along with the position of the match in hex. Escape can be used to stop the search at any time, although it might take a few seconds before the program exits.
A number of minor changes are necessary in order to make the RISC User Toolbox function correctly with RISC OS. These will be covered in a future update which we expect to include in the next issue.
We have come to the end of the RISC User Toolbox for the time being. However, its flexible design means that further updates can be added at a later date, and we would still like to hear from members with any ideas which they would like to see included.
251 SWI "OS_WriteS"
252 EQUS "The RISC User Toolbox has been installed.":EQUW &D0A
253 EQUS "Use *TOOLS or *HELP TOOLS for a list of commands.":EQUW &D0A:EQUB 0
261 .gettaba
262 ADR R3,tab:MOV PC,R14
359 EQUS "Tools":EQUB 0
360 ALIGN:EQUD toolc:EQUD &20FF0000
361 EQUD 0:EQUD toolc
362 EQUS "DSearchB":EQUB 0
363 ALIGN:EQUD dsb:EQUD &FF0002
364 EQUD dsbsyn:EQUD dsbhlp
365 EQUS "DSearchW":EQUB 0
366 ALIGN:EQUD dsw:EQUD &FF0002
367 EQUD dswsyn:EQUD dswhlp
368 EQUS "DSearchS":EQUB 0
369 ALIGN:EQUD dsc:EQUD &FF0002
370 EQUD dscsyn:EQUD dschlp
1448 .dsbhlp EQUS "*DSearchB searches selected disc files for the given byte sequence.":EQUB 13
1449 .dsbsyn EQUS "Syntax: DSearchB <byte>... <filename> [<pathname>] [V] [C]":EQUB 0:ALIGN
1450 .dswhlp EQUS "*DSearchW searches selected disc files for the given 32-bit word sequence.":EQUB 13
1451 .dswsyn EQUS "Syntax: DSearchB <word>... <filename> [<pathname>] [V] [C]":EQUB 0:ALIGN
1452 .dschlp EQUS "*DSearchS searches selected disc files for the given character string.":EQUB 13
1453 .dscsyn EQUS "Syntax: DSearchS <string> <filename> [<pathname>] [V] [C]":EQUB 0:ALIGN
6870 CMP R3,#4
7210 .se3 ADD R4,R12,#256:BL swi1:BEQ se5
14870 BNE nohash:CMP R3,#0:MOVEQ R3,#1
14871 MOVNES R3,#0:B ma
14872 .nohash EOR R3,R2,R3
14880 AND R3,R3,#&DF:.ma CMP R3,#0
15480 :
15490 .toolc STMFD R13!,{R14}
15500 MOV R0,#&75:SWI "OS_Byte"
15510 STMFD R13!,{R1}:SWI &10E
15520 SWI "OS_NewLine"
15530 SWI "OS_WriteS"
15540 EQUS "The RISC User Toolbox module offers the following commands:"
15550 EQUW &D0A:EQUB 0
15560 BL gettaba
15570 .toolc2 MOV R0,R3:SWI "OS_Write0"
15580 ADD R3,R0,#19:BIC R3,R3,#3
15590 LDRB R0,[R3]:CMP R0,#0
15600 BNE toolc25:SWI "OS_NewLine"
15610 LDMFD R13!,{R1}:TST R1,#4
15620 SWIEQ &10F:SWI "OS_WriteS"
15630 EQUS "Use *HELP <command> for details of individual commands."
15640 EQUW &D0A:EQUB 0:LDMFD R13!,{PC}
15650 .toolc25 SWI &120
15660 MOV R0,#&86:SWI "OS_Byte"
15670 CMP R1,#101:SWICS "OS_NewLine"
15680 BCS toolc2
15690 .toolc3 SUBS R1,R1,#20
15700 BCS toolc3
15710 .toolc4 SWI &120
15720 ADDS R1,R1,#1:BNE toolc4
15730 B toolc2
15740 :
15750 .dsw MOV R3,#4:B dsb2
15760 .dsb MOV R3,#1
15770 .dsb2 STMFD R13!,{R14}
15780 LDR R12,[R12]:ADD R5,R12,#&400
15790 .getseq MOV R1,R0:MOV R4,#16
15800 .getseq2 MOV R0,#16
15810 CMP R3,#4:ORRNE R0,R0,#1<<30
15820 ORR R0,R0,#1<<31
15830 SWI "OS_ReadUnsigned"
15840 STR R2,[R5,R4]:ADD R4,R4,#4
15850 SUB R1,R1,#1
15860 .getseq3 ADD R1,R1,#1
15870 LDRB R2,[R1]:CMP R2,#32
15880 BEQ getseq3:CMP R2,#&30
15890 BCC getseq4:CMP R2,#ASC"G"
15900 BCS getseq4:CMP R2,#&3A
15910 BCC getseq2:CMP R2,#ASC"A"
15920 BCS getseq2
15930 .getseq4 STR R4,[R5,#4]
15940 CMP R2,#32:ADRCC R0,nofile
15950 LDMCCFD R13!,{R14}
15960 ORRCCS PC,R14,#1<<28
15970 .dscont MOV R0,#0
15980 STRB R0,[R12,#&402]
15990 STMFD R13!,{R1}:SWI "OS_GetEnv"
16000 SUB R1,R1,#&8000
16010 STR R1,[R12,#&408]
16020 LDMFD R13!,{R1}:MOV R0,R1
16030 MOV R2,#1<<29:SWI "OS_GSInit"
16040 ADD R5,R5,#512
16050 .gfnn SWI "OS_GSRead"
16060 MOVCS R1,#0:STRB R1,[R5],#1
16070 BCC gfnn:SUB R0,R0,#2
16080 TST R2,#1<<28:SUBNE R0,R0,#1
16090 .gfnn2 LDRB R1,[R0,#1]!
16100 CMP R1,#32:BEQ gfnn2:MOV R4,R0
16110 MOVCC R2,#0:BCC gopdone
16120 MOV R2,#1<<29:SWI "OS_GSInit"
16130 .skpath SWI "OS_GSRead":BCC skpath
16140 TST R2,#1<<28:SUBNE R0,R0,#1
16150 MOV R2,#0:SUB R0,R0,#1
16160 .gop LDRB R1,[R0],#1: CMP R1,#32
16170 BEQ gop:BCC gopdone:AND R1,R1,#&DF
16180 CMP R1,#ASC"V":ORREQ R2,R2,#1
16190 BEQ gop:CMP R1,#ASC"C"
16200 ORREQ R2,R2,#2:BEQ gop:B bqual
16210 .gopdone STRB R2,[R12,#1024]
16220 STRB R3,[R12,#1025]
16230 ADR R0,getout:STMFD R13!,{R0}
16240 STR R13,[R12,#&3FC]
16250 MOV R0,R4:ADR R1,serrou
16260 BL swi11:ADD R13,R13,#4
16270 .getout LDRB R0,[R12,#&402]
16280 CMP R0,#0:LDMEQFD R13!,{PC}^
16290 SWI "OS_Exit"
16300 .dsc STMFD R13!,{R14}
16310 LDR R12,[R12]
16320 MOV R2,#1<<29:SWI "OS_GSInit"
16330 ADD R3,R12,#256
16340 .dsc2 SWI "OS_GSRead"
16350 MOVCS R1,#0:STRB R1,[R3],#1
16360 BCC dsc2:TST R2,#1<<28
16370 SUBNE R0,R0,#1:SUB R0,R0,#2
16380 STMFD R13!,{R0}
16390 ADD R0,R12,#256
16400 ADD R1,R12,#&410:BL swi2
16410 LDMFD R13!,{R1}:MOV R3,#0
16420 .ssss LDRB R0,[R1,#1]!:CMP R0,#32
16430 BEQ ssss:B dscont
16440 :
16450 .serrou STMFD R13!,{R0-R1}
16460 ADD R0,R0,#20:ADD R1,R12,#&600
16470 BL swi13:CMP R3,#0
16480 LDMNEFD R13!,{R0-R1,PC}
16490 ADD R2,R12,#255
16500 .concat LDRB R3,[R2,#1]!
16510 CMP R3,#0:BNE concat
16520 STMFD R13!,{R2}:ADD R3,R12,#256
16530 CMP R2,R3:BEQ nodot
16540 LDRB R3,[R2,#-1]:CMP R3,#ASC":"
16550 MOVNE R3,#&2E:STRNEB R3,[R2],#1
16560 .nodot
16570 LDR R0,[R13,#4]:ADD R0,R0,#20
16580 .concat2 LDRB R3,[R0],#1
16590 CMP R3,#0:STRB R3,[R2],#1
16600 BNE concat2:LDR R0,[R13,#4]
16610 LDR R1,[R0,#16]:CMP R1,#2
16620 BEQ nosthis:LDR R1,[R0,#8]
16630 LDR R0,[R12,#&408]:CMP R1,R0
16640 BCC lenok:SWI "OS_WriteS"
16650 EQUS "File ":EQUB 0
16660 ADD R0,R12,#256
16670 SWI "OS_Write0":SWI "OS_WriteS"
16680 EQUS " too long - skipping."
16690 EQUW &D0A:EQUB 0:B nosthis
16700 .lenok STR R1,[R12,#&40C]
16710 LDRB R0,[R12,#&400]:TST R0,#2
16720 BEQ noconf:SWI "OS_WriteS"
16730 EQUS "Search file ":EQUB 0
16740 ADD R0,R12,#256:SWI "OS_Write0"
16750 SWI "OS_WriteS"
16760 EQUS " (Y/N/Q/A) ? ":EQUB 0
16770 .kkget SWI "OS_ReadC"
16780 BCS abort:AND R0,R0,#&DF
16790 CMP R0,#ASC"N":BLEQ pnl
16800 BEQ nosthis:CMP R0,#ASC"Y"
16810 BLEQ pnl:BEQ noconf
16820 CMP R0,#ASC"A":BLEQ pnl
16830 BEQ abort:CMP R0,#ASC"Q"
16840 BNE kkget:BL pnl
16850 LDRB R0,[R12,#&400]
16860 BIC R0,R0,#2:STRB R0,[R12,#&400]
16870 .noconf LDRB R0,[R12,#&400]
16880 TST R0,#1:BEQ notell
16890 SWI "OS_WriteS"
16900 EQUS "Searching file ":EQUB 0
16910 ADD R0,R12,#256:SWI "OS_Write0"
16920 SWI "OS_NewLine"
16930 .notell ADD R1,R12,#256
16940 MOV R2,#&8000:MOV R3,#0
16950 MOV R0,#&FF:SWI "OS_File"
16960 MOV R0,#1:STRB R0,[R12,#&402]
16970 LDR R2,[R12,#&40C]
16980 MOV R0,#&8000:ADD R1,R2,R0
16990 LDR R2,[R12,#&404]
17000 SUB R2,R2,#16:MOV R2,R2,LSR #2
17010 LDRB R3,[R12,#&401]
17020 CMP R3,#4:BICEQ R1,R1,#3
17030 CMP R3,#0:BEQ smsl
17040 ADD R4,R12,#&410
17050 .msl BL swi1:BNE nosthis
17060 BL fndprt
17070 ADD R0,R0,R3:B msl
17080 .smsl LDRB R0,[R12,#&410]
17090 LDR R2,[R12,#&40C]:SUB R2,R2,R0
17100 ADD R2,R2,#&8000:MOV R0,#&8000
17110 ADD R1,R12,#&410
17120 .smsl2 BL swi3:BEQ smsl4
17130 .smsl3 ADD R0,R0,#1:CMP R0,R2
17140 BNE smsl2:B nosthis
17150 .smsl4 BL fndprt:B smsl3
17160 .fndprt STMFD R13!,{R0-R3,R14}
17170 SWI "OS_WriteS":EQUS "Match found in file ":EQUB 0
17180 ADD R0,R12,#256:SWI "OS_Write0"
17190 SWI "OS_WriteS":EQUS " at offset &":EQUB 0
17200 LDR R1,[R13]:SUB R1,R1,#&8000
17210 BL adrprt:SWI "OS_NewLine"
17220 LDMFD R13!,{R0-R3,PC}
17230 .abort LDR R13,[R12,#&3FC]
17240 LDMFD R13!,{PC}
17250 .nosthis LDMFD R13!,{R0}
17260 MOV R1,#0:STRB R1,[R0]
17270 LDMFD R13!,{R0-R1,PC}
17280 .pnl STMFD R13!,{R14}
17290 SWI "OS_WriteC":SWI "OS_NewLine"
17300 LDMFD R13!,{PC}^
17310 .nofile EQUD 0
17320 EQUS "Missing Filename"
17330 EQUB 0