; DATE 10/06/83 20:06 LAST REVISION TITLE 'FIND version 2.0B for CP/M-86' ; by: H.M. Van Tassell, 120 Hill Hollow Rd, Watchung NJ 07060 (201)755-5372 ; DATE: 10/06/83 ; ; This is an XLT86 translation of the original program that was on SIG/M ; volume 123. It is even more messy than the usual XTL86 translation since ; it had MACRO's. ; ; The only change is to add a HELP screen that is involked with // ; ; TO GENERATE PROGRAM: ; ASM86 FIND $SZPZ ; GENCMD FIND 8080 CODE[M100] ; ; The default file name is at 183h when you load FIND into DDT86 ; To change default file name using DDT86 (SID86): ; A>DDT86 ; -RFIND.CMD Loads FIND.CMD into DDT86, keeps header record for rewrite. ; -D183 Now see default filename - so change it using S command. ; -WFIND1.CMD This writes the changed file called FIND1.CMD. ; ;* FIND.ASM VERSION 2.0 10/05/82 ;* ;* ORIGINALLY WRITTEN BY WARD CHRISTENSEN ;* ENHANCED AND REWRITTEN BY RICH ANGELO - 10-05-82 ;* ;* 'FIND'S ASCII, CHARACTER STRINGS IN A FILE. ;* MAY TAKE A GENERIC FILE NAME, THUS MAY SEARCH ALL *.ASM FILES ;* ON A DISK. ALSO VERY USEFUL FOR FINDING THINGS IN MAST.CAT - ;* FOR EXAMPLE IF YOU ARE LOOKING FOR ALL MODEM OR BYE PROGRAMS ;* YOU COULD FIND MAST.CAT MOD|BYE TO SEE THEM ALL. ;* ;* ANOTHER USEFUL FUNCTION IS FOR DOCUMENTATION. FOR EXAMPLE; ;* ;* PRINT ALL OF THIS, ENTER: FIND FIND.ASM ;* ;* ;* PRINT MAINLINE COMMENTS, FIND FIND.ASM *> ;* ;* PRINT SUBROUTINES, FIND FIND.ASM *S> ;* ;* OR TRY THIS, FIND FIND.ASM *>|*S> ;* ;* PRINT MACROS USED, FIND FIND.ASM *M> ;* ;* DOCUMENTING A PROGRAM IN THIS FASHION IS AN EASY WAY TO SEPERATE ;* COMMENTS FROM CODE. THERE ARE MANY WAYS TO IDENTIFY A PORTION OF ;* A PROGRAM. MAYBE A STANDARD CAN BE ESTABLISHED, THAT WE ALL CAN ;* SHARE. THIS IS THE FIRST STEP IN THAT DIRECTION. ;* ;* ANY COMMENTS USE, ;* ONE OF THE POPULAR CHICAGO AREA RBBS OR CBBS SYSTEMS. ;* ;* RICH ANGELO ;* ;* USED WITH LIST.COM WHICH TAKES A STARTING LINE NUMBER, ;* YOU CAN: 1) USE FIND TO FIND A PARTICULAR PART OF THE CODE, ;* THEN 2) USE LIST SPECIFYING A STARTING LINE NUMBER JUST BEFORE ;* THE PART OF THE CODE YOU WANTED TO SEE. ;* ;* NOTE THAT FIND NOW HAS A DEFAULT FILE NAME AND THE ABILITY ;* TO PROMPT FOR SEARCH STRING. THIS FEATURE IS HANDY IF YOU WANT TO ;* SEARCH FOR SPECIFIC CHARACTERS ONLY, WHEREAS ENTERING THE SEARCH ;* STRING ON THE COMMAND LINE WILL DISPLAY BOTH UPPER AND LOWER CASE. ;* ;* SPECIAL SEARCH FEATURES OF FIND ARE; ;* ;* 1. MAKE "_" MATCH A TAB ;* 2. MAKE "|" AN "OR" ;* AS IN: FIND B:*.ASM _IN_|_OUT_ ;* ;* ;* COMMAND FORMATS; ;* ;* FIND <--- DEFAULTS TO FILENAME IN DFLTNAM. ;* WILL PROMPT FOR SEARCH STRING LOWER CASE VALID. ;* ALSO WILL SEARCH FOR ANY CHARACTER SEQ. PASSED ;* THRU CPM READ STRING FUNCTION. ;* ;* FIND FN.FT <--- PROMPT FOR SEARCH STRING. ;* ;* FIND FN.FT STR <--- WILL DISPLAY UPPER & LOWER CASE OF STRING ;* USING FILE SPECIFIED. ;* ;* FN.FT MAY BE AMBIGUOUS, *.ASM OR CBBS*.ASM ;* ;*---------------------------------------------------------------------- ;* CLS EQU 01Ah ;CLEAR SCREEN M EQU Byte Ptr 0[BX] ;THE USUAL EQUATES RDCON EQU 1 WRCON EQU 2 PRINT EQU 9 RSTRING EQU 10 CONST EQU 11 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 TBUFF EQU 80H CR EQU 0DH LF EQU 0AH EOF EQU 1AH TAB EQU 09H CSEG ORG 100H JMP START L_1 EQU $ DSEG ORG Offset L_1 ;*++++++> DATA AREA ; ; DFLTNAM DB 'SIG/M CAT' ;DEFAULT FILE NAME ; HELPMSG DB CLS,'FIND - version 2.0B for CP/M-86',CR,LF,LF DB TAB,'Special Search Features of FIND are:',CR,LF DB TAB,'1. Make "_" match a TAB',CR,LF DB TAB,'2. Make "|" an "OR"',CR,LF DB TAB,' as in: FIND B:*.ASM _IN_|_OUT_',CR,LF,LF DB TAB,'Command Formats:',CR,LF,LF DB TAB,'FIND',TAB,TAB,'<--- Defaults to filename SIG/M.CAT.',CR,LF DB TAB,TAB,TAB,'will prompt for search string lower case valid.',CR,LF DB TAB,TAB,TAB,'also will search for any character seq.',CR,LF DB TAB,TAB,TAB,'passed thru CPM read string function.',CR,LF,LF DB TAB,'FIND FN.FT <--- prompt for search string.',CR,LF,LF DB TAB,'FIND FN.FT STR <--- will display upper & lower case of string',CR,LF DB TAB,' using specified File.',CR,LF,LF DB TAB,'FN.FT may be ambiguous, *.ASM OR CBBS*.ASM',CR,LF,'$' PGMID DB 'FIND version 2.0B - // for Help' DB CR,LF,'$' DB EOF ; ABORT DB CR,LF,'++FIND ABORTED++$' NOFILE DB CR,LF,'++CANNOT FIND' FILMSG DB '----> FILE ' FNAME DB 'XXXXXXXX.XXX' DB CR,LF CRLF DB CR,LF,'$' PROMPT DB CR,LF,'Enter String>$' ;RDBYTE FIELDS EFCB DW (Offset BUFF) ;BUFFER ADDR EFCBCT DW 0 ;BYTES LEFT DB 20 ;BUFFER SIZE (IN PAGES) DW FCB ;FCB ADDRESS ;MFNAME FIELDS MFFLG1 DB 0 ;1ST TIME SW MFREQ RS 12 ;REQ NAME MFCUR RS 12 ;CURR NAME CONBUF DB (Offset CONLEN) ;LENGTH OF CONSOLE BUFFER CONSIZ RS 1 ;RESULTING SIZE AFTER READ STRING RS 30 ;WHAT TO SEARCH FOR CONLEN EQU (Offset $)-(Offset CONSIZ) LINENO DB ' ',TAB,'$' ;LINE NUMBER RS 32 ;STACK AREA STACK RS 2 STRPTR RS 2 ;POINTER FOR "|" SCAN LINE RS 133 L_2 EQU $ CSEG ORG Offset L_2 ;------> END OF DATA AREA ;******> ;******>START - PRINT SIGN-ON, LOOK FOR FILE SPEC. START: PUSH CX PUSH DX PUSH BX MOV CL,PRINT MOV DX,(Offset PGMID) INT 224 POP BX POP DX POP CX MOV AL,Byte Ptr .FCB+1 CMP AL,' ' ;IF A FILE WAS SPECIFIED JE M_1 ;JMP IF NO FILE NAME CMP AL,'/' ;CHECK FOR HELP REQUEST JNZ SETSTR ;NO... GO SET UP STRING ENTERED MOV AL,Byte Ptr .FCB+2 CMP AL,'/' ;// = HELP REQUEST JNE SETSTR ;NO... GO SET UP STRING MOV DX,OFFSET HELPMSG MOV CL,PRINT INT 224 JMP EXIT ; ELSE ; MOVE IN DEFAULT FILENAME JMPS M_1 MMOVE: MOV AL,CH OR AL,CL JNZ L_3 RET L_3: MOV AL,M MOV SI,DX MOV [SI],AL INC BX INC DX DEC CX JMPS MMOVE M_1: MOV BX,(Offset DFLTNAM) MOV DX,FCB+1 MOV CX,11 CALL MMOVE JMPS GETSTR ; GO PROMPT FOR STRING. ;******>SETSTR - SET STRING POINTERS, AND END DELIMITER. SETSTR: MOV DX,TBUFF ;DE=TBUFF MOV SI,DX ;LENGTH MOV AL,[SI] MOV CL,AL ;SAVE LENGTH MOV CH,0 ;SETUP BC FOR MOVE INC DX ;PAST LENGTH MOV BL,AL ;L=LENGTH MOV BH,0 ;HL=LENGTH ADD BX,DX ;HL=LAST CHAR MOV M,0 ;STORE END DELIM XCHG BX,DX ;START TO HL ;******>SCAN - LOOK FOR STRING, IF FOUND SAVE IT. SCAN: INC BX ;TO NEXT CHAR MOV AL,M ;LOOK FOR ' ' OR AL,AL ;END? JZ GETSTR ;..YES, THEN GET IT FROM THE CONSOLE CMP AL,' ' ; JNZ SCAN ;NOT AT ' ' LAHF ;TO STRING INC BX SAHF MOV DX,(Offset STRING) CALL MMOVE CALL FRSTFI ;SEE IF FILE EXISTS JMP OPFILE ;GO PROCESS IT ;******>GETSTR - ACCEPT STRING FROM CONSOLE. GETSTR: CALL FRSTFI ;LOOK FOR FILE PUSH CX PUSH DX PUSH BX MOV CL,PRINT MOV DX,(Offset PROMPT) INT 224 POP BX POP DX POP CX PUSH CX PUSH DX PUSH BX MOV CL,RSTRING MOV DX,(Offset CONBUF) INT 224 POP BX POP DX POP CX MOV AL,Byte Ptr CONSIZ OR AL,AL JNZ L_4 JMP EXIT L_4: MOV BL,AL ;STORE DELIMITER MOV BH,0 MOV DX,(Offset STRING) LAHF ADD BX,DX RCR SI,1 SAHF RCL SI,1 MOV M,0 PUSH CX PUSH DX PUSH BX MOV CL,PRINT MOV DX,(Offset CRLF) INT 224 POP BX POP DX POP CX JMPS OPFILE ;PROCESS FILE ;******>FRSTFI - SEARCH FOR INITIAL FILE AND PRINT IT'S NAME. FRSTFI: CALL MFNAME ;IF FILE DOES NOT EXIST JNAE L_5 RET ; TELL THEM AND EXIT. L_5: MOV BX,FCB+1 MOV DX,(Offset FNAME) MOV CX,8 CALL MMOVE MOV BX,FCB+9 MOV DX,(Offset FNAME)+9 MOV CX,3 CALL MMOVE PUSH CX PUSH DX PUSH BX MOV CL,PRINT MOV DX,(Offset NOFILE) INT 224 POP BX POP DX POP CX JMP EXIT ;******>NEXTFL - LOOK FOR ANOTHER FILE, IF NONE THEN EXIT. NEXTFL: PUSH CX PUSH DX PUSH BX MOV CL,PRINT MOV DX,(Offset CRLF) INT 224 POP BX POP DX POP CX CALL MFNAME JNB L_6 JMP EXIT L_6: ;******>OPFILE - OPEN FILE AND PRINT NAME. OPFILE: PUSH CX PUSH DX PUSH BX MOV CL,OPEN MOV DX,FCB INT 224 POP BX POP DX POP CX INC AL JNZ L_7 JMP EXIT L_7: CALL M_3 M_2 DB ' 0' M_3: POP BX ;GET FROM MOV CX,(Offset M_3)-(Offset M_2) ;GET LEN MOV DX,(Offset LINENO) CALL MMOVE MOV BX,FCB+1 MOV DX,(Offset FNAME) MOV CX,8 CALL MMOVE MOV BX,FCB+9 MOV DX,(Offset FNAME)+9 MOV CX,3 CALL MMOVE PUSH CX PUSH DX PUSH BX MOV CL,PRINT MOV DX,(Offset FILMSG) INT 224 POP BX POP DX POP CX MOV BX,0 MOV Word Ptr EFCBCT,BX ;******>NEXTLN - SET UP NEXT LINE NUMBER. NEXTLN: MOV BX,(Offset LINENO)+3 NEXT01: MOV AL,M ;GET DIGIT OR AL,'0' ;MAKE ASCII INC AL MOV M,AL CMP AL,'9'+1 ;CARRY? JNZ NEXTNC MOV M,'0' DEC BX JMPS NEXT01 ;******>NEXTNC - READ A LINE FROM FILE. NEXTNC: MOV BX,(Offset LINE) MOV CH,0FFH ;SO LONG LINE WON'T BLOW NEXT02: INC CH JS LONG ;TOO LONG A LINE PUSH CX PUSH BX MOV BX,(Offset EFCB) CALL RDBYTE POP BX POP CX MOV M,AL INC BX CMP AL,EOF JNZ L_8 JMP NEXTFL ;NEXT FILE L_8: CMP AL,LF JNZ NEXT02 JMPS EOL ;******>LONG - GOT A LONG LINE, CHOP IT OFF. LONG: MOV M,CR INC BX MOV M,LF ;******>EOL - CHECK FOR OPERATOR ABORT, POINT TO STRING. EOL: PUSH CX PUSH DX PUSH BX MOV CL,CONST INT 224 POP BX POP DX POP CX OR AL,AL JZ L_9 JMP CHRXIT ;ABORT REQUESTED L_9: MOV BX,(Offset STRING) ;******>XXXXXX - WE HAVE A LINE, NOW SCAN FOR THE STRING. ORLINE: MOV Word Ptr STRPTR,BX MOV BX,(Offset LINE) NEXTST: XCHG BX,DX MOV BX,Word Ptr STRPTR XCHG BX,DX ;(HL)->LINE - (DE)->STRING PUSH BX ;******>NEXTC - REPLACE '_' WITH A TAB. NEXTC: MOV SI,DX MOV AL,[SI] CMP AL,'_' JNZ NOTAB MOV AL,TAB NOTAB: INC DX OR AL,AL ;END OF STRING? JZ MATCHED CMP AL,'|' JZ MATCHED ;FIRST PART MOV CL,M ;FOR LOWER CASE TEST CMP AL,M LAHF INC BX SAHF JZ NEXTC MOV CH,AL ;SAVE CHAR MOV AL,CL ;GET CHAR CMP AL,61H ;LOWER? JB NOTEQ ;NO, SO NO MATCH CMP AL,7BH JNB NOTEQ AND AL,5FH ;MAKE UPPER CASE CMP AL,CH JZ NEXTC ;MATCHED NOTEQ: POP BX ;RESTORE ADDR INC BX MOV AL,M CMP AL,CR JNZ NEXTST MOV BX,Word Ptr STRPTR ;******>FINDOR - IF AN "OR" (|) IS IN THE LINE, SCAN FOR IT. FINDOR: MOV AL,M INC BX CMP AL,'|' JZ ORLINE OR AL,AL JNZ FINDOR JMP NEXTLN ;******>MATCHED - GOT A MATCH PRINT IT. MATCHED:POP BX ;KILL STACKED ADDR PUSH CX PUSH DX PUSH BX MOV CL,PRINT MOV DX,(Offset LINENO) INT 224 POP BX POP DX POP CX MOV BX,(Offset LINE) MATCHLP:MOV AL,M MOV DL,AL PUSH CX PUSH DX PUSH BX MOV CL,WRCON INT 224 POP BX POP DX POP CX MOV AL,M INC BX CMP AL,LF JNZ MATCHLP JMP NEXTLN ;******>CHRXIT - READ KEYBOARD, PRINT ABORT MESSAGE. CHRXIT: PUSH CX PUSH DX PUSH BX MOV CL,RDCON INT 224 POP BX POP DX POP CX PUSH CX PUSH DX PUSH BX MOV CL,PRINT MOV DX,(Offset ABORT) INT 224 POP BX POP DX POP CX ;******>EXIT - RELEASE MEMORY AND RETURN OS EXIT: MOV CL,0 MOV DL,0 INT 224 ;*****S> SUBROUTINES ;*****S> ;*****S>RDBYTE - READ BYTE FROM FILE. ;*****S> HL POINTS TO EFCB: ;*****S> EFCB; ;*****S> 2 BYTE BUFFER ADDR ;*****S> 2 BYTE "BYTES LEFT" (INIT TO 0) ;*****S> 1 BYTE BUFFER SIZE (IN PAGES) ;*****S> 2 BYTE FCB ADDRESS ;*****S> RDBYTE: MOV DL,M ;DE = BUFFER ADDR INC BX ;X MOV DH,M ;X INC BX ;BC = BYTES LEFT MOV CL,M ;X INC BX ;X MOV CH,M ;X MOV AL,CH ;IF BYTE-COUNT NOT = ZERO OR AL,CL ; GO READ NEXT BYTE JZ L_10 JMP RDGETB ; ELSE L_10: INC BX ; READ ANOTHER SECTOR. MOV AL,M ;GET COUNT ADD AL,AL ;MULTIPLY BY 2 MOV CH,AL ;SECTOR COUNT IN B INC BX ;TO FCB PUSH BX ;SAVE FCB POINTER MOV AL,M ;GET.. INC BX ;..FCB.. MOV BH,M ;..ADDR.. MOV BL,AL ;..TO HL RDBLP: MOV AL,EOF ;PUT EOF CHAR IN BUF MOV SI,DX ; IN CASE OF EOF. MOV [SI],AL PUSH DX ;SAVE DMA ADDR PUSH BX ;SAVE FCB ADDR PUSH CX PUSH DX PUSH BX MOV CL,STDMA INT 224 POP BX POP DX POP CX POP DX ;GET FCB PUSH CX PUSH DX PUSH BX MOV CL,READ INT 224 POP BX POP DX POP CX OR AL,AL ;CHECK FOR EOF POP BX ;HL=DMA, DE=FCB JNZ RDBRET ;GOT EOF MOV AL,BL ;BUMP BUFFER POINTER ADD AL,80H ;TO NEXT BUFF MOV BL,AL ;X MOV AL,BH ;X ADC AL,0 ;X MOV BH,AL ;X XCHG BX,DX ;DMA TO DE, FCB TO HL DEC CH ;MORE SECTORS? JZ L_11 JMP RDBLP ;YES, MORE L_11: RDBRET: POP BX ;GET FCB POINTER DEC BX ;TO LENGTH MOV AL,M ;GET LENGTH DEC BX ;TO COUNT MOV M,AL ;SET PAGE COUNT DEC BX ;TO LO COUNT DEC BX ;TO HI FCB DEC BX ;TO EFCB START JMP RDBYTE ;LOOP THRU AGAIN RDGETB: INC BX ;POINT TO BUFFER SIZE MOV AL,M ;GET LENGTH (PAGES) XCHG BX,DX ;BUFF TO HL ADD AL,BH ;HL = END OF BUFF MOV BH,AL ;X MOV AL,BL ;X SUB AL,CL ;HL = DATA POINTER MOV BL,AL ;X MOV AL,BH ;X SBB AL,CH ;X MOV BH,AL ;X MOV AL,M ;GET BYTE XCHG BX,DX ;EFCB POINTER BACK TO HL CMP AL,EOF ;EOF? JNZ L_12 RET ;YES, LEAVE POINTERS L_12: LAHF ;DECR COUNT DEC CX SAHF LAHF ;POINT BACK TO "BYTES LEFT" DEC BX SAHF MOV M,CH ;STORE BACK COUNT LAHF ;X DEC BX SAHF MOV M,CL ;X RET ;RETURN TO CALLER ;*****S> ;*****S> ;*****S> ;*****S>MFNAME - MULT-FILE ACCESS SUBROUTINE. ;*****S> ;*****S> MULTI-FILE ACCESS SUBROUTINE. ALLOWS PROCESSING ;*****S> OF MULTIPLE FILES (I.E. *.ASM) FROM DISK. THIS ;*****S> ROUTINE BUILDS THE PROPER NAME IN THE FCB EACH ;*****S> TIME IT IS CALLED. THIS COMMAND WOULD BE USED ;*****S> IN SUCH PROGRAMS AS MODEM TRANSFER, TAPE SAVE, ;*****S> ETC IN WHICH YOU WANT TO PROCESS SINGLE OR ;*****S> MULTIPLE FILES. ;*****S> ;*****S> JUST CALL "MFNAME" (MULTIPLE FILE NAME) AND THE FCB ;*****S> WILL BE SET UP WITH THE NEXT NAME, READY TO ;*****S> DO NORMAL PROCESSING (OPEN, READ, ETC.) ;*****S> ;*****S> CARRY IS SET IF NO MORE NAMES CAN BE FOUND ;*****S> ;*****S> THE ROUTINE IS COMMENTED IN PSEUDO CODE, ;*****S> EACH PSEUDO CODE STATEMENT IS IN <<...>> ;*****S> MFNAME: PUSH CX PUSH DX PUSH BX MOV CL,STDMA MOV DX,80H INT 224 POP BX POP DX POP CX XOR AL,AL MOV Byte Ptr .FCBEXT,AL MOV Byte Ptr .FCBRNO,AL MOV AL,Byte Ptr MFFLG1 ;<> OR AL,AL JNZ MFN01 MOV AL,1 ; <> MOV Byte Ptr MFFLG1,AL MOV BX,FCB MOV DX,(Offset MFREQ) MOV CX,12 CALL MMOVE MOV AL,Byte Ptr .FCB MOV Byte Ptr MFCUR,AL MOV BX,(Offset MFREQ) MOV DX,FCB MOV CX,12 CALL MMOVE PUSH CX PUSH DX PUSH BX MOV CL,SRCHF MOV DX,FCB INT 224 POP BX POP DX POP CX JMPS MFN02 ;<> MFN01: MOV BX,(Offset MFCUR) MOV DX,FCB MOV CX,12 CALL MMOVE PUSH CX PUSH DX PUSH BX MOV CL,SRCHF MOV DX,FCB INT 224 POP BX POP DX POP CX MOV BX,(Offset MFREQ) MOV DX,FCB MOV CX,12 CALL MMOVE PUSH CX PUSH DX PUSH BX MOV CL,SRCHN MOV DX,FCB INT 224 POP BX POP DX POP CX MFN02: INC AL ;<> STC JNZ L_13 RET L_13: DEC AL ;<> AND AL,3 ADD AL,AL ADD AL,AL ADD AL,AL ADD AL,AL ADD AL,AL ADD AL,81H MOV BL,AL MOV BH,0 PUSH BX MOV DX,(Offset MFCUR)+1 MOV CX,11 CALL MMOVE POP BX ;<> MOV DX,FCB+1 MOV CX,11 CALL MMOVE XOR AL,AL ;<> MOV Byte Ptr .FCBEXT,AL RET ;<> BUFF EQU (Offset $) ;DISK READ BUFER END