;********************************************************
;* *
;* 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 ; *
; * * * * * * * * * * * * * * * * * * * * * * * *