;******************************************************** ;* * ;* BINARY FILE COMPARE UTILITY * ;* * ;******************************************************** ; ; ; Portions Copyright (C) 1980 ; ; Bill Bolton, ; Software Tools, ; P.O. Box 80, ; Newport Beach,, ; NSW, 2106 ; AUSTRALIA ; ; History: ; ; 1/Oct/77 Version 1.00 by Ward Christensen ; ; 31/Jan/80 Version 1.10 by Bill Bolton, improved ; error messages and optional file display ; ; 6/Sept/80 Version 1.20 by Bill Bolton, copy second ; filename from first, if second blank ; ; MACLIB MACRO3 ;OFTWARE TOOLS SPECIAL MACROS ; ORG 100H ; CALL START ;PRINT ID MESSAGE ; DB 0DH,0AH,'Binary File Compare ' DB 'Utility : Version 1.20' DB 0DH,0AH DB 'DDH Compatible Display by Bill Bolton' DB 0DH,0AH DB 'Software Tools, Australia' DB 0DH,0AH,'$' ; START: POP D CALL PRINT$MESSAGE LXI H,0 DAD SP ;HL=CP/M'S STACK SHLD STACK ;SAVE IT LXI SP,STACK ;SET UP NEW STACK ; LDA FCB+17 ;POINT TO FILENAME IN SECOND FCB CPI ' ' ;EMPTY? JNZ SAVE$NAME ;NO, JUST MOVE IT LXI D,FCB+1 ;YES, POINT TO FILENAME IN FIRST FCB LXI H,FCB+17 ;POINT TO FILENAME IN SECOND FCB MVI B,11 ;LENGTH OF FILE NAME CALL MOVEIT ;MOVE FILENAME ; ;MOVE THE SECOND FCB SO OPENING THE FIRST ;WON'T WIPE IT OUT ; SAVE$NAME: CALL MOVE$FCB ; ;PRINT OPENING MESSAGE ; LXI D,FIRST CALL PRINT$MESSAGE CALL CONSOLE CPI 'Y' JNZ BLANK MVI A,0FFH STA PRFLAG BLANK: LXI D,NEWLINE CALL PRINT$MESSAGE ; ;OPEN BOTH FILES, EXITING IF EITHER DOESN'T EXIST ; CALL OPEN$FILES ; ;READ EACH FILE 1 BYTE AT A TIME, COMPARING THEM ; COMPARE: CALL READ1 MOV B,A ;SAVE CHAR READ CALL READ2 CMP B ;SAME? JZ COMPARE ; ;UNEQUAL COMPARE ; LXI D,UNEQ$MSG CALL PRINT$MESSAGE LHLD SECTOR$COUNT DECOUT LXI D,SPACEIT CALL PRINT$MESSAGE LXI D,BYTE$MSG CALL PRINT$MESSAGE LDA BUFAD1 ;GET FIRST BUFF ADDR SUI 81H ;SUBTRACT BIAS CALL XO ;PRINT IN HEX LXI D,SPACEIT CALL PRINT$MESSAGE CALL CONSTAT ORA A JZ COMPARE CALL CONSOLE CPI 3 ;IS ^C? JZ EXIT CPI 20H ;IS IT SPACE? JNZ COMPARE EXIT: LHLD STACK ;GET CP/M'S STACK SPHL ;RESTORE IT RET ;..AND RETURN ; ERXIT: POP D ;GET MESSAGE CALL PRINT$MESSAGE JMP EXIT ; UNEQ$MSG: DB 0DH,0AH,'++ FILES UNEQUAL IN SECTOR $' ; BYTE$MSG: DB 'AT BYTE $' ; SPACEIT: DB ' $' ; NEWLINE: DB 0DH,0AH,'$' ; FIRST: DB 0DH,0AH,'Do you want file 1 printed ' DB 'as it is compared ?' DB '....[Y/N] (CR="N") ' ,'$' ; ; * * * * * * * * * * * * * * * * * * * * * * * * ; * ; SUBROUTINES * ; * ; * * * * * * * * * * * * * * * * * * * * * * * * ; PRINT$MESSAGE: MVI C,STRING JMP BDOS ;PRINT, RETURN ; PRINT$HEX$HL: MOV A,H CALL XO MOV A,L CALL XO MVI A,' ' ;FALL INTO 'TYPE' ; TYPE: PUSH B PUSH D PUSH H MOV E,A ;AS REQ'D BY CP/M MVI C,WRCON CALL BDOS POP H POP D POP B RET ; XO: PUSH PSW ;HEX OUT RAR RAR RAR RAR CALL NIBBL ;LEFT NIBBL POP PSW NIBBL: ANI 0FH CPI 10 JC ISNUM ADI 7 ISNUM: ADI '0' JMP TYPE ; OPEN$FILES: LXI D,FCB MVI C,OPEN CALL BDOS INR A ;OPEN OK? JNZ FILE$1$OPEN CALL ERXIT DB 0DH,0AH,'***** CANT OPEN FILE 1 ***** ',0DH,0AH,'$' FILE$1$OPEN: LXI D,FCB2 MVI C,OPEN CALL BDOS INR A RNZ CALL ERXIT DB 0DH,0AH,'***** CANT OPEN FILE 2 *****',0DH,0AH,'$' ; READ1: LHLD BUFAD1 ;TIME TO READ? DCR H ;AT 100H? JNZ NO$READ$1 ; ;PHYSICALLY READ FILE 1 ; LXI H,80H ;BUFFER ADDR SHLD BUFAD1 XCHG ;TO D,E MVI C,STDMA CALL BDOS LXI D,FCB MVI C,READ CALL BDOS ORA A ;OK? JNZ EOF$FILE$1 LHLD SECTOR$COUNT INX H SHLD SECTOR$COUNT NO$READ$1: LHLD BUFAD1 MOV A,M ;GET CHAR INX H ;POINT TO NEXT SHLD BUFAD1 ; ;REQUEST TO PRINT? ; MOV L,A ;SAVE CHAR LDA PRFLAG ;SET IF FILE 1 TO BE PRINTED ON CONSOLE CPI 0 ;PRINT? MOV A,L ;RESTORE CHAR FOR RET RZ ;RET IF NO PRINT REQ ; ;SHOW THE CHARACTER ; CPI 0DH ;C/R? JZ SHOWIT CPI 0AH ;L/F? JZ SHOWIT CPI 9 ;TAB? JZ SHOWIT CPI ' ' ;PRINTABLE? JC SHOWHEX ;HEX IF NOT PRINTABLE CPI 7FH JC SHOWIT ;SHOW IN HEX SHOWHEX: MVI A,'(' CALL TYPE MOV A,L ;GET CHAR MVI A,')' SHOWA: CALL TYPE MOV A,L ;GET CHAR RET SHOWIT: MOV A,L ;GET CHAR JMP SHOWA RET ; ;GOT EOF ON FILE 1 - SHOULD GET EOF ON FILE 2 ; EOF$FILE$1: MVI A,1 ;GET FLAG STA EOF$FLAG CALL READ2 ;SHOULD NOT RETURN CALL ERXIT DB 0DH,0AH,0AH,'***** EOF ON FILE 1, NOT FILE 2 *****$' ; READ2: LHLD BUFAD2 ;GET SECOND BUFF MOV A,L ;GET ADDR CPI (BUF2+128) AND 0FFH ;END? JNZ NO$READ$2 ; ;DO PHYSICAL READ ON FILE 2 ; LXI H,BUF2 SHLD BUFAD2 XCHG ;TO DE MVI C,STDMA PUSH B ;SAVE CHAR FROM FILE 1 CALL BDOS LXI D,FCB2 MVI C,READ CALL BDOS POP B ORA A JNZ EOF$FILE$2 NO$READ$2: LHLD BUFAD2 MOV A,M ;GET CHAR INX H ;POINT TO NEXT SHLD BUFAD2 ;SAVE BACK RET ; EOF$FILE$2: ;SHOULD HAVE EOF ON 1, THUS EOF$FLAG SHOULD BE ON LDA EOF$FLAG ORA A ;ON? JNZ A$OK CALL ERXIT DB 0DH,0AH,0AH,'***** EOF ON FILE 2 BEFORE FILE 1 *****$' A$OK: LXI D,MATCH$MSG CALL PRINT$MESSAGE LHLD SECTOR$COUNT DECOUT CALL ERXIT DB ' SECTORS .....',0DH,0AH,0AH,'$' MATCH$MSG: DB 0DH,0AH,0AH,'..... FILES MATCH, LENGTH IS $' ; MOVE$FCB: LXI H,FCB2 LXI D,FCB+16 MVI B,16 ;FCB LENGTH MOVEIT: LDAX D MOV M,A INX D INX H DCR B JNZ MOVEIT RET ; CONSTAT: MVI C,11 CALL BDOS RET ; CONSOLE: MVI C,1 CALL BDOS RET ; DS 40 ;STACK AREA STACK: DS 2 SECTOR$COUNT: DW 0 EOF$FLAG: DB 0 ;=1 IF EOF FILE 1 FCB2: DB 0,'XXXXXXXXYYY',0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 PRFLAG: DB 0 BUFAD1: DW 80H+128 ;INIT TO READ FIRST BUFAD2: DW BUF2+128 ;LIKEWISE BUF2: DS 128 ; ; * * * * * * * * * * * * * * * * * * * * * * * * ; * ;BDOS/CBIOS EQUATES (VERSION 5) * ; * RDCON EQU 1 ; * WRCON EQU 2 ; * STRING EQU 9 ; * OPEN EQU 15 ;0FFH=NOT FOUND * CLOSE EQU 16 ; " " * SRCHF EQU 17 ; " " * SRCHN EQU 18 ; " " * ERASE EQU 19 ;NO RET CODE * DELT EQU ERASE ; * READ EQU 20 ;0=OK, 1=EOF * WRITE EQU 21 ;0=OK, 1=ERR, 2=?, * ; 0FFH=NO DIR SPC * MAKE EQU 22 ;0FFH=BAD * REN EQU 23 ;0FFH=BAD * STDMA EQU 26 ; * BDOS EQU 5 ; * FCB EQU 5CH ; * ; * * * * * * * * * * * * * * * * * * * * * * * *