; * * * * * * * * * * * * * * * * * * * * * * * * ; * ; COMPARE.ASM * ; * ; * * * * * * * * * * * * * * * * * * * * * * * * ; ;USED TO COMPARE 2 CP/M PROGRAMS ON DISK ; ;IF SENSE SWITCH A8 (01H) UP, PRINTS FILE 1 ;AS IT IS BEING READ ; ;10/01/77 ORIGINALLY WRITTEN ; ORG 100H CALL START ;PRINT ID MESSAGE DB 'COMPARE.COM AS OF 10/01/77',0DH,0AH,'$' START POP D CALL PRINT$MESSAGE ;INIT PRIVATE STACK LXI H,0 ;HL=0 DAD SP ;HL=CP/M'S STACK SHLD STACK ;SAVE IT LXI SP,STACK ;USE MY OWN ; ;MOVE THE SECOND FCB SO OPENING THE FIRST ;WON'T WIPE IT OUT ; CALL MOVE$FCB ; ;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 CALL PRINT$HEX$HL LXI D,BYTE$MSG CALL PRINT$MESSAGE LDA BUFAD1 ;GET FIRST BUFF ADDR SUI 80H ;SUBTRACT BIAS CALL XO ;PRINT IN HEX 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 $' ; * * * * * * * * * * * * * * * * * * * * * * * * ; * ; SUBROUTINES * ; * ; * * * * * * * * * * * * * * * * * * * * * * * * PRINT$MESSAGE: MVI C,PRINT 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 '++CAN''T OPEN FILE 1 ',0DH,0AH,'$' FILE$1$OPEN: LXI D,FCB2 MVI C,OPEN CALL BDOS INR A RNZ CALL ERXIT DB '++CAN''T 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 IN 0FFH ;READ SSW ANI 1 ;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 CALL XO 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,'++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,'++EOF ON FILE 2 BEFORE FILE 1$' A$OK LXI D,MATCH$MSG CALL PRINT$MESSAGE LHLD SECTOR$COUNT CALL PRINT$HEX$HL CALL ERXIT DB '(HEX) SECTORS',0DH,0AH,'$' MATCH$MSG: DB 0DH,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 ; 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 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 ; * PRINT 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 ; * SYSSIZ EQU 24 ;SYSTEM SIZE * CBIOS EQU SYSSIZ*1024-512 ; * SELDSK EQU CBIOS+1BH ; * SETTRK EQU SELDSK+3 ; * SETSEC EQU SETTRK+3 ; * SETDMA EQU SETSEC+3 ; * RDSEC EQU SETDMA+3 ; * WRSEC EQU RDSEC+3 ; * ; * * * * * * * * * * * * * * * * * * * * * * * *