;*********************************************** ;11/??/77 ORIGINALLY WRITTEN BY WARD CHRISTENSEN ;12/31/77 ADD PICKUP OF SECOND FILENAME IF BLANK ;09/18/85 RE-WRITTEN BY FRANK SAUCIUNAS ;*********************************************** ; VERSION 1.10 ;*********************************************** ; ;COMPARE.ASM - COMPARES 2 FILES ; ;COMMAND FORMAT: ; COMPARE (NAME1.TYP) (NAME2.TYP) ; IF NAME2 = NAME1 BUT IS ON B DISK, ; JUST TYPE: COMPARE (NAME1.TYP) (B:) ; ;NOTE: LAST BYTE DISPLAYED IN HEX DUMP IS THE ; LAST BYTE TO HAVE AN EQUAL COMPARE. ; ;*********************************************** ; BSIZE EQU 4096*2 ; Disk buffer siz (times 2) ; CONI EQU 01 ; Console input CON EQU 02 ; Console display BDOS EQU 05 ; Bdos entry piont MSG EQU 09 ; Send message OPN EQU 15 ; Open file DMA EQU 26 ; Set dma address SECT EQU 128 ; Sector size TAB EQU 09H ; Tab LF EQU 0AH ; Line feed FF EQU 0CH ; Form feed CR EQU 0DH ; Carriage return EOF EQU 1AH ; End of file FRD EQU 20 ; File read operation TFCB EQU 5CH ; File control block TBUF EQU 80H ; Buffer address WMBOOT EQU 0000 ; Cpm return ; ORG 100H ; ;INIT STACK ; START: POP H ; Get cp/m ret addr SHLD EXIT+1 ; Modify return addr LXI SP,STACK ; Get my stack LXI D,SIGNON MVI C,MSG CALL BDOS QUEST: LXI D,OFFSET MVI C,MSG CALL BDOS MVI C,CONI CALL BDOS CPI 60H JC NOSUB SUI 20H NOSUB: CPI 'N' JZ START1 CPI 'Y' JNZ QUEST LXI H,256 SHLD CNTR MVI A,'6' STA BYTES+5 MVI A,'5' STA BYTES+4 MVI A,'2' STA BYTES+3 MVI A,0FFH STA OSFLG ; START1: LXI D,CRLF2 MVI C,MSG CALL BDOS ; ;IF THE SECOND FCB IS BLANK, ;MOVE IN THE NAME FROM THE FIRST ; LDA TFCB+17 CPI ' ' JNZ FILE1TYP ; Not blank MVI B,11 LXI D,TFCB+1 LXI H,TFCB+17 CALL MOVER ; ;'DECLARE' BOTH FCB'S ; FILE1TYP: JMP FILE1 DEF1: MOV A,M STAX D INX H INX D DCR C JNZ DEF1 RET FILE1: LXI H,TFCB LXI D,FCBFILE1 MVI C,0CH CALL DEF1 JMP XDEF1 FCBFILE1: DB 0 DS 32 FILE1ADR: DW BUFFER1 FILE1LEN: DW BUFSZ FILE1PTR: DS 2 ; XDEF1: JMP PSUB1 GETFILE1: LHLD FILE1LEN XCHG LHLD FILE1PTR MOV A,L SUB E MOV A,H SBB D JC PNC1 LXI H,0 SHLD FILE1PTR PND1: XCHG LHLD FILE1LEN MOV A,E SUB L MOV A,D SBB H JNC EOB1 LHLD FILE1ADR DAD D XCHG MVI C,DMA CALL BDOS LXI D,FCBFILE1 MVI C,FRD CALL BDOS ORA A JNZ EOD1 LXI D,SECT LHLD FILE1PTR DAD D SHLD FILE1PTR JMP PND1 EOD1: LHLD FILE1PTR SHLD FILE1LEN EOB1: LXI D,TBUF MVI C,DMA CALL BDOS LXI H,0 SHLD FILE1PTR PNC1: XCHG LHLD FILE1ADR DAD D XCHG LHLD FILE1LEN MOV A,L ORA H MVI A,EOF RZ LDAX D LHLD FILE1PTR INX H SHLD FILE1PTR RET PSUB1: XRA A STA FCBFILE1+12 STA FCBFILE1+32 LXI H,BSIZE SHLD FILE1LEN SHLD FILE1PTR MVI C,OPN LXI D,FCBFILE1 CALL BDOS INR A JNZ FILE2TYP MVI C,MSG LXI D,MSG1 CALL BDOS JMP WMBOOT MSG1: DB 'NO FILE 1 FOUND' DB CR,LF DB '$' ; FILE2TYP: LXI H,TFCB+16 LXI D,FCBFILE2 MVI C,0CH CALL DEF1 JMP XDEF2 FCBFILE2: DB 0 DS 32 FILE2ADR: DW BUFFER2 FILE2LEN: DW BUFSZ FILE2PTR: DS 2 ; XDEF2: JMP PSUB2 GETFILE2: LHLD FILE2LEN XCHG LHLD FILE2PTR MOV A,L SUB E MOV A,H SBB D JC PNC2 LXI H,0 SHLD FILE2PTR PND2: XCHG LHLD FILE2LEN MOV A,E SUB L MOV A,D SBB H JNC EOB2 LHLD FILE2ADR DAD D XCHG MVI C,DMA CALL BDOS LXI D,FCBFILE2 MVI C,FRD CALL BDOS ORA A JNZ EOD2 LXI D,SECT LHLD FILE2PTR DAD D SHLD FILE2PTR JMP PND2 EOD2: LHLD FILE2PTR SHLD FILE2LEN EOB2: LXI D,TBUF MVI C,DMA CALL BDOS LXI H,0 SHLD FILE2PTR PNC2: XCHG LHLD FILE2ADR DAD D XCHG LHLD FILE2LEN MOV A,L ORA H MVI A,EOF RZ LDAX D LHLD FILE2PTR INX H SHLD FILE2PTR RET PSUB2: XRA A STA FCBFILE2+12 STA FCBFILE2+32 LXI H,BSIZE SHLD FILE2LEN SHLD FILE2PTR MVI C,OPN LXI D,FCBFILE2 CALL BDOS INR A JNZ COMP MVI C,MSG LXI D,MSG2 CALL BDOS JMP WMBOOT MSG2: DB 'NO FILE 2 FOUND' DB CR,LF DB '$' ; ;COMPARE THE 2 FILES 1 BYTE AT A TIME ; COMP: CALL READ1 MOV B,A ; Save char PUSH B CALL READ2 POP B CMP B JZ COMP ; ;FILES UNEQUAL ; UNEQUAL: LXI D,ERROR MVI C,MSG CALL BDOS LXI D,BYTES MVI C,MSG CALL BDOS LHLD CNTR MOV A,H CALL HEX MOV A,L CALL HEX LXI D,HBYTE MVI C,MSG CALL BDOS LHLD PRTPTR MOV A,L STA LSTGD LHLD CNTR SBB L MOV L,A SHLD ADRPTR LDA OSFLG CPI 0 JZ NOADR CALL PRTADD NOADR: LXI H,BUFF DCR L SHLD BUFADR SHLD ASCBUF PRTLP: LHLD BUFADR INR L SHLD BUFADR MOV A,M CALL HEX MVI A,' ' CALL TYPE LDA COL INR A STA COL CPI 10H JNZ NEXT XRA A STA COL CALL SP2 CALL TYPASC LXI D,CRLF MVI C,MSG CALL BDOS LDA OSFLG CPI 0 JZ NEXT CALL PRTADR NEXT: LDA LSTGD DCR A STA LSTGD JNZ PRTLP JMP EXIT ; HEX: PUSH PSW ; Save char RAR RAR RAR RAR CALL NIBBL POP PSW CALL NIBBL RET ; NIBBL: ANI 0FH CPI 10 JC NUM ADI 7 NUM: ADI '0' ; ;TYPE AN ASCII CHARACTER ; TYPE: PUSH B PUSH D PUSH H PUSH PSW MVI C,CON MOV E,A CALL BDOS POP PSW POP H POP D POP B RET ; PRTADR: LHLD ADRPTR MVI A,10H ADD L MOV L,A SHLD ADRPTR PRTADD: MOV A,H CALL HEX MOV A,L CALL HEX CALL SP2 RET ; TYPASC: LHLD ASCBUF ASCLP: INR L MOV A,M CPI 7FH JNC DOT CPI ' ' JNC NODOT DOT: MVI A,'.' NODOT: CALL TYPE LDA ASCPTR INR A STA ASCPTR CPI 10H JNZ ASCLP XRA A STA ASCPTR SHLD ASCBUF RET ; ;READ BYTE FROM FILE 1 ; READ1: CALL GETFILE1 JZ EOF1 ; Got eof? LHLD PRTPTR MOV M,A INR L SHLD PRTPTR PUSH PSW ; Save char LHLD CNTR INX H SHLD CNTR LXI H,BYTES+5 READI: MOV A,M ORI '0' ; In case it was blank INR A MOV M,A CPI '9'+1 ; Time to carry? JNZ READNC MVI M,'0' DCX H JMP READI READNC: POP PSW RET ; ;EOF ON FILE 1 - SET FLAG, READ 2 ; EOF1: MVI A,'Y' STA EOFLG CALL READ2 LXI D,FILE1R MVI C,MSG CALL BDOS JMP UNEQUAL ; READ2: CALL GETFILE2 RNZ ; No eof ; ;GOT EOF ON FILE 2, MUST HAVE GOTTEN IT ON FILE 1 ; EOF2: LDA EOFLG CPI 'Y' JZ AOK LXI D,FILE2R MVI C,MSG CALL BDOS JMP UNEQUAL ; ;A-OK - FILES MATCH ; AOK: LXI D,MATCH MVI C,MSG CALL BDOS LXI D,BYTES MVI C,MSG CALL BDOS LHLD CNTR MOV A,H CALL HEX MOV A,L CALL HEX LXI D,HBYTE MVI C,MSG CALL BDOS ; ;NOTE THE FOLLOWING DOES NOT RESTORE CP/M'S ;STACK POINTER, BUT THAT IS 'OK' BECAUSE THE ;FIRST INSTRUCTION IN CP/M IS A LXI SP ; EXIT: JMP $-$ ; Cp/m ret addr (modified) ERXIT: POP D ; Get message MVI C,MSG CALL BDOS JMP EXIT ; SP2: MVI C,MSG LXI D,SPSP CALL BDOS RET ; ;MOVE FROM (DE) TO (HL) LENGTH IN B ; MOVER: LDAX D MOV M,A INX D INX H DCR B JNZ MOVER RET ; SIGNON: DB CR,LF DB 'FILE COMPARE UTILITY 09/18/85' CRLF2: DB CR,LF,CR,LF,'$' OFFSET: DB 'Turn on <0100H> OFFSET (Y/N)? ','$' ERROR: DB ' FILES UNEQUAL AFTER ' CRLF: DB CR,LF,'$' FILE1R: DB 'EOF ON FILE 1 BEFORE FILE 2' DB CR,LF,'$' FILE2R: DB 'EOF ON FILE 2 BEFORE FILE 1' DB CR,LF,'$' MATCH: DB ' LENGTH IS ',CR,LF,'$' BYTES: DB ' BYTES (DEC) ','$' HBYTE: DB ' BYTES (HEX)',CR,LF,'$' SPSP: DB ' ','$' EOFLG: DB 'N' PRTPTR: DW BUFF CNTR: DW 0000 BUFADR: DW 0000 ADRPTR: DW 0000 ASCBUF: DW 0000 ASCPTR: DB 0 OSFLG: DB 0 COL: DB 0 LSTGD: DB 0 DS 30 ; Stack ;ORG TO PAGE BECAUSE 'INR L' USED TO LOOP THRU IT ORG ($+255) AND 0FF00H ; To page STACK EQU $-2 BUFF EQU $ DB ' ' DB ' ' DB ' ' DB ' ' DB ' ' DB ' ' DB ' ' DB ' ' DB ' ' DB ' ' DB ' ' DB ' ' DB ' ' DB ' ' DB ' ' DB ' ' BUFFER1 EQU $ DS BSIZE BUFSZ EQU $-BUFFER1 BUFFER2 EQU $ MEMSIZE EQU BUFFER2 END