home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Guide
/
c-cplusplus-interactive-guide.iso
/
c_ref
/
csource3
/
109_01
/
search.asm
< prev
next >
Wrap
Assembly Source File
|
1985-03-11
|
12KB
|
550 lines
; SEARCH.ASM
;
; Version 1.2 30-June-80
;
; this program searches RAM or a file for the specified
; data and reports the addresses of any occurences. in the
; case of a file, the entire file is read into RAM in order
; to search as quickly as possible (a 16K file is searched
; in less than 10 seconds) - the size of the file that may be
; searched is limited therefore by memory size. an attempt
; to read a file that is too large will result in an error
; message - the file however will be compared as far as
; possible.
;
; protocol: A>SEARCH RA STRING (RAM ASCII data)
; SEARCH RH XX XX XX (RAM HEX data)
; SEARCH FA STRING [FILENAME.EXT] (file ASCII data)
; SEARCH FH XX XX XX [FILENAME.EXT] (file HEX data)
;
; note: since the CP/M command line is converted
; to UPPER CASE, the HEX data format must be
; used to search for lower case characters.
;
; addresses are given in HEX and offset octal format for
; RAM searches, and in sector-byte format for file
; searches.
;
BASE EQU 4200H ; HEATH base
BDOS EQU BASE+5 ; entry point to DOS
MEMSIZ EQU BASE+2 ; last page of system memory
TBUFF EQU BASE+80H ; I/O buffer
TPA EQU BASE+100H ; Transient Program Area
WRCON EQU 2 ; write console character
PRINTF EQU 9 ; print routine
OPENF EQU 15 ; open file
READF EQU 20 ; read next record
SETDMA EQU 26 ; set DMA
BELL EQU 7 ; terminal bell
LF EQU 10 ; line feed
CR EQU 13 ; carriage return
ESC EQU 27 ; escape
SECTOR EQU 128 ; sector size
BDOSERR EQU 255 ; BDOS error code
SPACE EQU ' ' ; space
EOL EQU '$' ; string terminator
CHL EQU 1894H ; ROM complement HL routine
COMP EQU 1830H ; ROM compare routine
DU66 EQU 1846H ; ROM divide routine
CDEHL EQU 188EH ; ROM compare DEHL routine
MOVE EQU 18AAH ; ROM move routine
MU66 EQU 18DFH ; ROM multiply routine
RSTALL EQU 1927H ; ROM restore all routine
SAVALL EQU 192CH ; ROM save all routine
UDD EQU 196FH ; ROM unpack routine
;
ORG TPA
START:
LDA MEMSIZ ; get high memory page
STA LAST+1 ; save
LXI H,TBUFF+1 ; point to first space
MOV A,M ; get char
CPI SPACE ; space?
JNZ SYNERR ; no: error
LXI H,TBUFF+4 ; point to second space
MOV A,M ; get char
CPI SPACE ; space?
JNZ SYNERR ; no: error
DCX H ; point to mode byte 1
DCX H ;
MOV A,M ; get mode
CPI 'F' ; file?
JZ GOTFILE ; yes: bypass
CPI 'R' ; RAM?
JNZ MODERR ; error: process
STARTF:
INX H ; point to mode byte 2
MOV A,M ; get mode
CPI 'A' ; ASCII?
JZ GOTASCII ; yes: bypass
CPI 'H' ; HEX?
JZ GOTHEX ; yes: bypass
MODERR:
LXI D,MODMSG ; print error message
JMP PRTERR ; bypass
SYNERR:
LXI D,SYNMSG ; msg pntr
PRTERR:
CALL PERR ; print it
RET ; to CP/M
;
GOTHEX:
LDA TBUFF ; get command line count
SUI 3 ; adjust
MVI B,0 ; divide by 3
MOV C,A ;
LXI D,3 ;
CALL DU66 ;
MOV A,L ; get result
STA TBUFF ; save as HEX data count
MOV C,A ; convert ASCII data
CALL CONVERT ; to binary data
LDA TBUFF ; restore count again
JMP HEXSTART ; bypass
GOTASCII:
LXI H,TBUFF ; get command length
MOV A,M ;
SUI 4 ; adjust
HEXSTART:
MOV C,A ; set C to data count
LXI D,TBUFF+5 ; set DE to data
LHLD FIRST ; set HL to start of memory
LOOP: PUSH B ; save
PUSH D ;
PUSH H ;
CALL COMP ; compare data with memory
POP H ; restore
POP D ;
POP B ;
JZ FOUNDIT ; found?
INX H ; no: bump memory pntr
CALL CHECKEND ; finished?
JNZ LOOP ; no: continue
LDA FLAG ; was anything found?
CPI 0 ;
RNZ ; yes: return to CP/M
LXI D,NFMSG ; no: print 'not found'
CALL PSTR ;
RET ; to CP/M
;
GOTFILE:
LXI H,TYPE
INR M
LXI H,TBUFF+5 ; pntr to first byte of cmd
MVI C,2 ; reset cntr
CNTCHAR:
INR C ; cntr + 1
MOV A,M ; get char
INX H ; bump pntr
CPI '['
INX D ;
DCR C ; done?
JNZ GETEXT1 ; no: continue
DONE ; get cntr
STA TBUFF ; save cntr
CALL SAVTBUFF ; save tbuff
SHLD FNPNTR ; save filename pntr
;
LXI D,FILEFCB ; FCB pntr
INX H ; bump pntr to possible ':'
MOV A,M ; get byte
CPI ':' ; drive specified?
JNZ NODRV ; no: bypass
DCX H ; get drive
MOV A,M
SUI 'A'-1 ; subtract offset
STA FILEFCB ; save
INX H ; pntr to first letter
INX H ;
SHLD FNPNTR ; save
JMP GET1 ; bypass
NODRV:
DCX H ; pntr to first letter
GET1:
LXI D,FILEFCB+1 ; pntr to FILEFCB+1
MVI C,8 ; cntr
GETBYT:
MOV A,M ; get byte
CPI '.' ; beginning of .EXT?
JNZ GET2 ; no: bypass
INX H ; bump pntr
JMP GETEXT ; bypass
GET2:
STAX D ; save
INX H ; bump pntrs
INX D ;
DCR C ; done?
JNZ GETBYT ; no: continue
MOV A,M ; get byte
CPI '.' ; extent specified?
JNZ DONEGET ; no: bypass
GETEXT:
MVI C,3 ; move ext
LXI D,FILEFCB+9 ; set pntr
GETEXT1:
MOV A,M ;
STAX D ;
INX H ; bump pntrs
INX D ;
DCR C ; done?
JNZ GETEXT1 ; no: continue
DONEGET:
CALL READFILE ; get file
CALL RSTTBUFF ;
LXI H,TBUFF+2 ; setup
JMP STARTF ;
SAVTBUFF:
CALL SAVALL
LXI B,50 ;
LXI D,TBUFF
LXI H,TEMPBUF
CALL MOVE
JMP RSTALL
RSTTBUFF:
CALL SAVALL
LXI B,50
LXI D,TEMPBUF
LXI H,TBUFF
CALL MOVE
JMP RSTALL
;
FOUNDIT:
MVI A,1 ; set flag
STA FLAG ;
LDA TYPE
ORA A
JZ FOUND1
;
PUSH B
PUSH D
PUSH H
LHLD FIRST
CALL CHL
MOV D,H
MOV E,L
POP H
PUSH H
DAD D
MOV B,H
MOV C,L
LXI D,SECTOR
CALL DU66
PUSH D
INX H
MOV B,H
MOV C,L
MVI A,3
LXI H,FFMSG2
CALL UDD
POP D
INX D
MOV B,D
MOV C,E
MVI A,3
LXI H,FFMSG3
CALL UDD
LXI D,FFMSG1
CALL PSTR
POP H
POP D
POP B
JMP FOUND2
FOUND1:
PUSH D ; save
LXI D,FMSG ; print 'found'
CALL PSTR ;
POP D ; restore
CALL PADDR ; print addr (hex and offset octal)
FOUND2:
CALL CHECKEND ; finished?
RZ ; yes: return to CP/M
INX H ; no: bump memory pointer
JMP LOOP ; continue
;
; compare present address with high memory limit
;
CHECKEND:
PUSH D ; save
PUSH H ;
XCHG ; DE = present addr
LHLD LAST ; HL = high memory limit
CALL CDEHL ; done?
POP H ; restore
POP D ;
RET ; return
;
; print address in hex and split octal
;
PADDR:
PUSH B ; save
PUSH D ;
PUSH H ;
MOV A,H ; print high HEX byte
CALL PHEX ;
MOV A,L ; print low HEX byte
CALL PHEX ;
MVI A,' ' ; print space
CALL PCHAR ;
MVI A,'(' ; print '('
CALL PCHAR ;
POP H ; restore address
PUSH H ; save again
MOV A,H ; print high OCTAL byte
CALL POCT ;
MVI A,'.' ; print '.'
CALL PCHAR ;
POP H ; restore address
PUSH H ; save again
MOV A,L ; print low OCTAL byte
CALL POCT ;
MVI A,')' ; print ')'
CALL PCHAR ;
MVI A,CR ; print CRLF
CALL PCHAR ;
MVI A,LF ;
CALL PCHAR ;
POP H ; restore
POP D ;
POP B ;
RET ; return
;
; print hex byte in register A
;
PHEX:
PUSH PSW ; save
RRC ; shift high 4 bits
RRC ;
RRC ;
RRC ;
CALL PNIB ; print it
POP PSW ; restore
CALL PNIB ; print it
RET ; return
;
PNIB:
ANI 0FH ; mask out high 4 bits
CPI 10 ; alphabetic?
JNC P10 ; yes: bypass
ADI '0' ; add ASCII offset
JMP PRN ; bypass
P10 ADI 'A'-10 ; add ASCII & letter offset
PRN CALL PCHAR ; print it
RET ; return
;
; print character in register A
;
PCHAR:
PUSH B ; save
PUSH D ;
PUSH H ;
MVI C,WRCON ; print CON: char function
MOV E,A ; set up -> E
CALL BDOS ; do it
POP H ; restore
POP D ;
POP B ;
RET ; return
;
; print EOL terminated string pointed to by DE
;
PSTR:
PUSH B ; save
PUSH D ;
PUSH H ;
MVI C,PRINTF ; print CON: string function
CALL BDOS ; do it
POP H ; save
POP D ;
POP B ;
RET ; return
;
; print octal byte in register A
;
POCT PUSH PSW ; save
RRC ; shift left 2 bits
RRC ;
RRC ;
RRC ;
RRC ;
RRC ;
ANI 03H ; mask out high 6 bits
ADI '0' ; add ASCII offset
CALL PCHAR ; print it
POP PSW ; restore
PUSH PSW ; save again
RRC ; shift middle 3 bits
RRC ;
RRC ;
ANI 07H ; mask out high 5 bits
ADI '0' ; add ASCII offset
CALL PCHAR