home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol084
/
findp.asm
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
13KB
|
669 lines
;FIND.ASM
;
;03/Aug/82 ADDED DETECT OF CONTROL X TO SKIP TO NEXT FILE
; AFTER DISASSEMBLING A VERSION OF FIND DATED
; 8/Nov/80 (FOR WHICH I DIDN'T HAVE THE SOURCE)
; AND FINDING THAT FEATURE IMPLEMENTED. Bill Bolton
;
;01/Aug/82 DOING "FIND *.* [any garbage string]" ON AN RCPM
; SYSTEM WOULD GIVE A DIRECTORY OF ALL FILES ON THE
; DISK, INCLUDING TAGGED AND SYSTEM FILES WHICH MAY
; HAVE BEEN INTENDED TO BE "INVISIBLE". ADDED FILE
; TYPE AND ATTRIBUTE CHECKING FROM "DISPLAY" TO
; PREVENT THIS HAPPENING. FILES WITH TYPE "ALL"
; (WHICH I USE FOR CATALOGUES) WILL BE SCANNED NO
; MATTER WHAT ATTRIBUTES ARE SET. THIS ALLOWS THE
; CATALOGUES TO BE "FIND"ed AND "DISPLAY"ed BUT NOT
; "TYPE"ed OR "XMODEM"ed. IMPLEMENTED FOR CONDITIONAL
; ASSEMBLY. ALSO CHANGED ABORT TO ONLY RESPOND TO
; CONTROL-C OR CONTROL-K TO ELIMINATE PROBLEMS ON
; REMOTE SYSTEMS WITH SUPRIOUS CHARACTERS OFF THE LINE
; PREMATURELY ABORTING A "FIND". CHANGED THE ABORT CHECK
; TO DIRECT CONSOLE INPUT (BDOS 6) SO THE A CP/M VERSION
; NUMBER CHECK WAS ADDED. Bill Bolton
;
;18/Mar/80 MAKE "_" MATCH A TAB; MAKE "|" AN "OR"
; AS IN: FIND B:*.ASM _IN_|_OUT_
;
;27/Feb/80 TRANSLATE FILE READ CHARS TO UPPER CASE
; SO CASE DOESN'T MATTER IN FILE CONTENTS.
; ALSO PUT IN "JUST IN CASE" TEST FOR LINE
; LONGER THAN 128.
;
;27/Jan/80 PUT IN CTL-C BREAK
;
;23/Jun/79 ORIGINALLY WRITTEN BY WARD CHRISTENSEN
; ----------------
;USED TO DO A CHARACTER STRING SEARCH
;OF ONE OR MORE FILES. ANY ASCII STRING
;MAY BE SEARCHED FOR. CASE DOESN'T MATTER.
;
;COMMAND FORMAT:
;
; FIND FILENAME STRING
;
;FILENAME MAY BE AMBIGUOUS,
; E.G. *.ASM OR CBBS*.ASM
;
;"_" IN STRING WILL MATCH A TAB.
;
CR EQU 0DH
LF EQU 0AH
EOF EQU 1AH
CNTRLC EQU 3
TAB EQU 9
CNTRLK EQU 11
CNTRLS EQU 19
CNTRLX EQU 24
;
FALSE EQU 0
TRUE EQU NOT FALSE
;
RCPM EQU TRUE ;True for restricted filetype search
;
MF SET 0 ;SHOW MOVE NOT REQUESTED
CF SET 0 ;SHOW COMP NOT REQUESTED
;
;(FROM EQU8.LIB...)
;DEFINE SOME MACROS TO MAKE THINGS EASIER
;
;DEFINE DATA MOVE MACRO: MOVE from,to,length
; from may be addr, or quoted string
;
MOVE MACRO ?F,?T,?L
IF NOT NUL ?F
IRPC ?C,?F
?Q SET '&?C&?C' ;;TEST FOR QUOTE
EXITM
ENDM
IF ?Q EQ ''''
LOCAL ?B,?Z
CALL ?Z
?B DB ?F
?Z POP H ;GET FROM
LXI B,?Z-?B ;GET LEN
ELSE
LXI H,?F
ENDIF
ENDIF
IF NOT NUL ?T
LXI D,?T
ENDIF
IF NOT NUL ?L
LXI B,?L
ENDIF
CALL MOVER
MF SET -1 ;;SHOW EXPANSION
ENDM
;COMPARE MACRO
COMP MACRO ?F,?T,?L
IF NOT NUL ?F
IRPC ?C,?F
?Q SET '&?C&?C' ;;TEST FOR QUOTE
EXITM
ENDM
IF ?Q EQ ''''
LOCAL ?B,?Z
CALL ?Z
?B DB ?F
?Z POP H ;GET FROM
LXI B,?Z-?B ;GET LEN
ELSE
LXI H,?F
ENDIF
ENDIF
IF NOT NUL ?T
LXI D,?T
ENDIF
IF NOT NUL ?L
LXI B,?L
ENDIF
IF NOT NUL ?I
LOCAL ?B,?Z
CALL ?Z
?B DB ?I
?Z POP D ;GET TO
LXI B,?Z-?B
ENDIF
CALL COMPR
CF SET -1 ;;SHOW EXPANSION
ENDM
;
;DEFINE CP/M MACRO - CPM FNC,PARM
;
CPM MACRO ?F,?P
PUSH B
PUSH D
PUSH H
IF NOT NUL ?F
MVI C,?F
ENDIF
IF NOT NUL ?P
LXI D,?P
ENDIF
CALL BDOS
POP H
POP D
POP B
ENDM
;
ORG 100H
CALL START
DB 'FIND.COM '
DB '03/Aug/82'
DB 0DH,0AH,'$'
START POP D ;GET ID
MVI C,PRINT
CALL BDOS ;PRINT ID
;
;INIT LOCAL STACK
;
LXI H,0
DAD SP
SHLD STACK
LXI SP,STACK
;
;START OF PROGRAM EXECUTION
;
CPM VERSION
MOV A,L ;A <---- VERSION NUMBER
CPI 20H
JNC CHECK$NAME
CALL ERXIT
DB '++ CP/M Version 2.0 or later is required to run FIND$'
;
CHECK$NAME:
LDA FCB+1
CPI ' '
JNZ GETSTR
CALL ERXIT
DB '++NO FILE NAME++$'
;
;FIND START OF STRING IN TBUFF
;
GETSTR LXI D,80H ;DE=TBUFF
LDAX D ;LENGTH
MOV C,A ;SAVE LENGTH
MVI B,0 ;SETUP BC FOR MOVE
INX D ;PAST LENGTH
MOV L,A ;L=LENGTH
MVI H,0 ;HL=LENGTH
DAD D ;HL=LAST CHAR
MVI M,0 ;STORE END DELIM
;
;SCAN FOR START OF STRING
;
XCHG ;START TO HL
SCAN INX H ;TO NEXT CHAR
MOV A,M ;LOOK FOR ' '
ORA A ;END?
JZ BADSTR ;..YES, BAD
CPI ' '
JNZ SCAN ;NOT AT ' '
INX H ;TO STRING
;
MOVE ,STRING, ;HL = FROM, BC=LENGTH
NEXTFL CALL MFNAME ;GET NEXT
JC EXIT
CPM OPEN,FCB
INR A
JZ EXIT
IF RCPM
;
;Check for .ALL file, which can always be scanned
;
ALLCHK:
LDA FCB+11
CPI 'L' ;WAS LAST CHAR AN 'L'?
JNZ CKFIL ;IF NOT, TRY NEXT TEST
LDA FCB+10 ;CHK NEXT
ANI 07FH ;Forget attributes for this test
CPI 'L' ;AN 'L'?
JNZ CKFIL ;IF NOT, TRY NEXT TEST
LDA FCB+9 ;WAS 'L', CHK NEXT CHAR
ANI 07FH ;Forget attributes for this test
CPI 'A' ; 'A' AS IN '.ALL'?
JZ OK$SCAN ;YES, GO SCAN IT
;
;Check for file protected by CP/M 2.x f2' attribute
;
CKFIL: LDA FCB+2 ;POINT TO TAG FILE ATTR
ANI 80H ;IS IT TAGGED?
JZ CKFIL2 ;IF NOT, CONTINUE
;
PROXIT:
JMP NEXTFL ;SEE IF ANOTHER
;
CKFIL2: LDA FCB+10 ;POINT TO SYS FILE ATTR
ANI 80H ;IS IT SYS?
JNZ PROXIT ;SYS file, can't print it
;
;Check for .COM file, which can't be scanned
;
LDA FCB+11
CPI 'M' ;WAS LAST CHAR AN 'M'?
JNZ OBJCHK ;IF NOT, CHK FOR '.OBJ' TYPE
LDA FCB+10
ANI 7FH ;STRIP CP/M 2.x ATTR
CPI 'O' ;AN 'O'?
JNZ OK$SCAN ;IF NOT IT'S OK TO SCAN
LDA FCB+9
ANI 7FH ;STRIP CP/M 2.x ATTR
CPI 'C' ;'C' AS IN '.COM'?
JNZ OK$SCAN ;IF NOT, IT'S OK TO SCAN
JMP NEXTFL ;MORE TO PRINT?
;
;Check for .OBJ file, which can't be scanned
;
OBJCHK:
CPI 'J' ;WAS LAST CHAR AN 'J' ?
JNZ OK$SCAN ;IF NOT, OK TO SCAN
LDA FCB+10 ;MIGHT BE '.OBJ', CHK NEXT CHR
ANI 7FH ;STRIP CP/M 2.x ATTR
CPI 'B' ;IS IT A 'B'?
JNZ OK$SCAN ;IF NOT, SCAN
LDA FCB+9 ;WAS, CHK FIRST CHAR
ANI 7FH ;STRIP CP/M 2.x ATTR
CPI 'O' ;'O' AS IN '.OBJ'?
JNZ OK$SCAN ;IF NOT, SCAN THE FILE, IF SO
JMP NEXTFL ;MORE TO SCAN?
ENDIF ;RCPM
;
OK$SCAN:
MOVE ' 0',LINENO
MOVE FCB+1,FNAME,8
MOVE FCB+9,FNAME+9,3
CALL ILPRT
DB '----> FILE '
FNAME DB 'XXXXXXXX.XXX'
DB CR,LF,0
LXI H,0
SHLD EFCBCT ;ZERO COUNT
;
;BUMP ASCII LINE #
;
NEXTLN LXI H,LINENO+3
NEXTADD MOV A,M ;GET DIGIT
ORI '0' ;MAKE ASCII
INR A
MOV M,A
CPI '9'+1 ;CARRY?
JNZ NEXTNC
MVI M,'0'
DCX H
JMP NEXTADD
;
NEXTNC LXI H,LINE
MVI B,0FFH ;SO LONG LINE WON'T BLOW
NEXTLC INR B
JM LONG ;TOO LONG A LINE
PUSH B
PUSH H
LXI H,EFCB
CALL RDBYTE
POP H
POP B
MOV M,A
INX H
CPI EOF
JZ NEXTFL ;NEXT FILE
CPI LF
JNZ NEXTLC
JMP EOL
;
;GOT A LONG LINE - STICK CRLF IN MIDDLE
;
LONG MVI M,0DH
INX H
MVI M,0AH
EOL CPM DIRECT,0FFH ;TEST FOR USER COMMAND
ORA A
CNZ CHREXIT ;PARSE COMMAND
JC NEXTFL
;
;READ IN A LINE, NOW SCAN FOR THE STRING
;
LXI H,STRING
ORLINE SHLD STRPTR
LXI H,LINE
NEXTST XCHG
LHLD STRPTR
XCHG
PUSH H
NEXTC LDAX D
CPI '_'
JNZ NOTAB
MVI A,TAB
NOTAB INX D
ORA A ;END OF STRING?
JZ MATCHED
CPI '|'
JZ MATCHED ;FIRST PART
MOV C,M ;FOR LOWER CASE TEST
CMP M
INX H
JZ NEXTC
MOV B,A ;SAVE CHAR
MOV A,C ;GET CHAR
CPI 61H ;LOWER?
JC NOTEQ ;NO, SO NO MATCH
CPI 7BH
JNC NOTEQ
ANI 5FH ;MAKE UPPER CASE
CMP B
JZ NEXTC ;MATCHED
NOTEQ POP H ;RESTORE ADDR
INX H
MOV A,M
CPI CR
JNZ NEXTST
;
;IF AN "OR" (|) IS IN THE LINE, SCAN FOR IT
;
LHLD STRPTR
FINDOR MOV A,M
INX H
CPI '|'
JZ ORLINE
ORA A
JNZ FINDOR
JMP NEXTLN
;
;GOT MATCH, PRINT IT
;
MATCHED POP H ;KILL STACKED ADDR
CALL ILPRT
LINENO DB ' ',TAB,0
;
LXI H,LINE
MATCHLP MOV A,M
MOV E,A
CPM WRCON
MOV A,M
INX H
CPI LF
JNZ MATCHLP
JMP NEXTLN
;
;INLINE PRINT - CALL ILPRT FOLLOWED BY MSG,
;WHICH ENDS IN A: 0
;
ILPRT XTHL ;GET MSG ADDR, SAVE HL
ILPLP MOV E,M
CPM WRCON
INX H
MOV A,M
ORA A ;END?
JNZ ILPLP
XTHL
RET
;
BADSTR CALL ERXIT
DB '++BAD STRING++$'
;
;FOLLOWING FROM 'EQU8.LIB'---->
;
;MOVE, COMPARE SUBROUTINES
;
IF MF ;MACRO EXPANSION FLAG SET?
;
MOVER MOV A,M
STAX D
INX H
INX D
DCX B
MOV A,B
ORA C
JNZ MOVER
RET
ENDIF
;
IF CF ;MACRO EXPANSION FLAG SET?
COMPR LDAX D
CMP M
RNZ
INX D
INX H
DCX B
MOV A,B
ORA C
JNZ COMPR
RET
ENDIF
;
; FROM EQU8.LIB: AS OF 05/06/79
;
;RDBYTE, HL POINTS TO EXTENDED FCB:
;
; 2 BYTE BUFFER ADDR
; 2 BYTE "BYTES LEFT" (INIT TO 0)
; 1 BYTE BUFFER SIZE (IN PAGES)
; 2 BYTE FCB ADDRESS
;
RDBYTE MOV E,M
INX H
MOV D,M ;GET BUFFER ADDR
INX H
MOV C,M
INX H
MOV B,M ;BC = BYTES LEFT
MOV A,B ;GET COUNT
ORA C
JNZ RDBNORD ;NO READ
;
INX H ;TO BUFFER SIZE
MOV A,M ;GET COUNT
ADD A ;MULTIPLY BY 2
MOV B,A ;SECTOR COUNT IN B
INX H ;TO FCB
PUSH H ;SAVE FCB POINTER
MOV A,M ;GET..
INX H ;..FCB..
MOV H,M ;..ADDR..
MOV L,A ;..TO HL
;
RDBLP MVI A,1AH ;GET EOF CHAR
STAX D ;SAVE IN CASE EOF
PUSH D ;SAVE DMA ADDR
PUSH H ;SAVE FCB ADDR
CPM STDMA ;SET DMA ADDR
POP D ;GET FCB
CPM READ
ORA A
POP H ;HL=DMA, DE=FCB
JNZ RDBRET ;GOT EOF
MOV A,L
ADI 80H ;TO NEXT BUFF
MOV L,A
MOV A,H
ACI 0
MOV H,A
XCHG ;DMA TO DE, FCB TO HL
DCR B ;MORE SECTORS?
JNZ RDBLP ;YES, MORE
RDBRET POP H ;GET FCB POINTER
DCX H ;TO LENGTH
MOV A,M ;GET LENGTH
DCX H ;TO COUNT
MOV M,A ;SET PAGE COUNT
DCX H ;TO LO COUNT
DCX H ;TO HI FCB
DCX H ;TO EFCB START
JMP RDBYTE ;LOOP THRU AGAIN
;
RDBNORD INX H ;TO LENGTH
MOV A,M ;GET LENGTH (PAGES)
XCHG ;BUFF TO HL
ADD H
MOV H,A ;HL = END OF BUFF
MOV A,L
SUB C
MOV L,A
MOV A,H
SBB B
MOV H,A ;HL = DATA POINTER
MOV A,M ;GET BYTE
XCHG ;EFCB BACK TO HL
CPI 1AH ;EOF?
RZ ;YES, LEAVE POINTERS
DCX B ;DECR COUNT
DCX H ;BACK TO "BYTES LEFT"
MOV M,B
DCX H
MOV M,C ;STORE BACK COUNT
RET
;
;SAMPLE EFCB:
;
;EFCB DW BUFF ;BUFFER ADDR
; DW 0 ;BYTES LEFT
; DB 20 ;BUFFER SIZE (IN PAGES)
; DW FCB ;FCB ADDRESS
;
; MUST BE ASSEMBLED BY "MAC"
;
;MULTI-FILE ACCESS SUBROUTINE. ALLOWS PROCESSING
;OF MULTIPLE FILES (I.E. *.ASM) FROM DISK. THIS
;ROUTINE BUILDS THE PROPER NAME IN THE FCB EACH
;TIME IT IS CALLED. THIS COMMAND WOULD BE USED
;IN SUCH PROGRAMS AS MODEM TRANSFER, TAPE SAVE,
;ETC IN WHICH YOU WANT TO PROCESS SINGLE OR
;MULTIPLE FILES.
;
;JUST CALL "MFNAME" (Multiple File NAME) AND THE FCB
;WILL BE SET UP WITH THE NEXT NAME, READY TO
;DO NORMAL PROCESSING (OPEN, READ, ETC.)
;
;CARRY IS SET IF NO MORE NAMES CAN BE FOUND
;
;------------------------------------------------
;
; MULTI-FILE ACCESS SUBROUTINE
;
;THE ROUTINE IS COMMENTED IN PSEUDO CODE,
;EACH PSEUDO CODE STATEMENT IS IN <<...>>
;
MFNAME:
;<<INIT DMA ADDR, FCB>>
CPM STDMA,80H
XRA A ! STA FCBEXT ! STA FCBRNO
;<<IF FIRST TIME>>
LDA MFFLG1 ! ORA A ! JNZ MFN01
; <<TURN OFF 1ST TIME SW>>
MVI A,1 ! STA MFFLG1
; <<SAVE THE REQUESTED NAME>>
MOVE FCB,MFREQ,12 ;SAVE ORIG REQ
LDA FCB ! STA MFCUR ;SAVE DISK IN CURR FCB
; <<SRCHF REQ NAME>>
MOVE MFREQ,FCB,12
CPM SRCHF,FCB
;<<ELSE>>
JMP MFN02
MFN01:
; <<SRCHF CURR NAME>>
MOVE MFCUR,FCB,12
CPM SRCHF,FCB
; <<SRCHN REQ NAME>>
MOVE MFREQ,FCB,12
CPM SRCHN,FCB
;<<ENDIF>>
MFN02:
;<<RETURN CARRY IF NOT FOUND>>
INR A ! STC ! RZ
;<<MOVE NAME FOUND TO CURR>>
DCR A ! ANI 3 ! ADD A
ADD A ! ADD A ! ADD A ! ADD A
ADI 81H ! MOV L,A ! MVI H,0
PUSH H ;SAVE NAME POINTER
MOVE ,MFCUR+1,11
;<<MOVE NAME FOUND TO FCB>>
POP H ! MOVE ,FCB+1,11
;<<SETUP FCB>>
XRA A ! STA FCBEXT
;<<RETURN>>
RET
;
;MULTI-FILE ACCESS WORK AREA
;
MFFLG1 DB 0 ;1ST TIME SW
MFREQ DS 12 ;REQ NAME
MFCUR DS 12 ;CURR NAME
;------------------------------------------------
;
;EXIT, READING CHAR WHICH WAS TYPED TO INTERRUPT
;
CHREXIT:
CPI CNTRLC ;ABORT?
JZ ABORT
CPI CNTRLK ;ABORT?
JZ ABORT
CPI CNTRLX ;SKIP TO NEXT FILE?
STC
RZ
CPI CNTRLS ;PAUSE?
JZ PLOOP
ORA A ;RESET CARRY FLAG
RET
;
PLOOP:
CPM DIRECT,0FFH
ORA A
JZ PLOOP
JMP CHREXIT
;
ABORT:
CALL MSGEXIT
DB CR,LF,'++ABORT++$'
;
;EXIT WITH ERROR MESSAGE
;
MSGEXIT EQU $ ;EXIT W/"INFORMATIONAL" MSG
ERXIT POP D ;GET MSG
MVI C,PRINT
CALL BDOS
;
;EXIT, RESTORING STACK AND RETURN
;
EXIT LHLD STACK
SPHL
RET ;TO CCP
;
EFCB DW BUFF ;BUFFER ADDR
EFCBCT DW 0 ;BYTES LEFT
DB 20 ;BUFFER SIZE (IN PAGES)
DW FCB ;FCB ADDRESS
;
STRING DS 30 ;WHAT TO SEARCH FOR
DS 200 ;STACK AREA
STACK DS 2
STRPTR DS 2 ;POINTER FOR "|" SCAN
LINE DS 133
BUFF EQU $ ;DISK READ BUFER
;
;BDOS/CBIOS EQUATES (VERSION 8)
;
RDCON EQU 1
WRCON EQU 2
DIRECT EQU 6
PRINT EQU 9
RDCONBF EQU 10
CONST EQU 11
VERSION EQU 12
OPEN EQU 15
CLOSE EQU 16
SRCHF EQU 17
SRCHN EQU 18
ERASE EQU 19
READ EQU 20
WRITE EQU 21
MAKE EQU 22
REN EQU 23
STDMA EQU 26
BDOS EQU 5
FCB EQU 5CH
FCB2 EQU 6CH
FCBEXT EQU FCB+12
FCBRNO EQU FCB+32