; COMPARE - CP/M FILE COMPARISON UTILITY ; ORG 0100H JMP COMPARE DB '(C) 1979 - N D H HAMMOND' PRGNAME DB 'COMPARE VSN 1.0 OF 3JAN80',0DH,0AH,'$' ; ; ;SYSTEM ADDRESSES WBOOTE EQU 0000H ;REBOOT ADDRESS SFCB EQU 005CH ;SOURCE FILE CONTROL BLOCK SFCBCR EQU SFCB+32 ;NEXT RECORD COUNTER TBUF EQU 0080H ;SYSTEM DEFAULT BUFFER ;CONSTANTS CCPL EQU (3200H-2900H) SHR 8 ;PAGES IN CCP TRUE EQU 0FFH ETX EQU 03H LF EQU 0AH CR EQU 0DH EOM EQU '$' ; ; MAIN PROGRAM ; COMPARE LXI H,0 ;SAVE OLD STACK POINTER DAD SP SHLD OLDSP LXI SP,STACK LXI D,PRGNAME CALL WRITESTRING CALL INITVAR CALL SOURCEDISK CALL OPENSOURCE CALL LOADBUF CALL COMPDISK CALL OPENCOMP REPEAT CALL COMPBUF LDA FINISH CPI TRUE JZ ENDCOMP CALL SOURCEDISK CALL LOADBUF CALL COMPDISK JMP REPEAT ENDCOMP LDA FIRST ORA A JZ EXIT LXI D,COMPMSG CALL WRITESTRING EXIT LHLD OLDSP SPHL RET ;RETURN TO CP/M ; ; SUBROUTINBS ; INITVAR ;INITIALIZE VARIABLES XRA A STA FINISH ;SET EXTENT TO CP/M CBASE LHLD ENTRY+1 ;HL:=FBASE MOV A,H SBI CCPL MOV H,A ;HL:=CBASE MOV A,L ;ENSURE EXTENT IS AT ANI 80H ; A PAGE BOUNDARY MOV L,A SHLD EXTENT LXI D,CFCB ;ZERO CFCB MVI B,32 XRA A ZCFB STAX D INX D DCR B JNZ ZCFB LXI D,CFCB LXI H,SFCB+16 ;GET COMP FILE NAME MVI B,12 CALL COPYSTRING MVI A,TRUE ;INITIALIZE VARIABLES STA FIRST XRA A STA RECNO RET ; ; OPENSOURCE ;OPEN SOURCE FILE LXI D,SFCB CALL OPENFILE CPI 0FFH JNZ OPEN$OK MVI B,1 JMP ERROR OPEN$OK XRA A STA SFCBCR RET ; ; OPENCOMP ;OPEN COMP FILE LXI D,CFCB CALL OPENFILE CPI 0FFH JNZ OP$OK MVI B,1 JMP ERROR OP$OK XRA A STA CFCBCR RET ; ; LOADBUF ;LOAD BUFFER FROM SOURCE FILE LXI D,BUFFER RDNXT PUSH D CALL SETDMA LXI D,SFCB CALL READREC POP D ORA A JZ RD$OK CPI 1 JZ EOF MVI B,3 JMP ERROR RD$OK LXI B,80H ;UPDATE BUFFER XCHG DAD B LXI B,EXTENT CALL COMP XCHG JNZ RDNXT RET EOF MVI A,TRUE STA FINISH XCHG SHLD EXTENT RET ; ; COMPBUF ;COMPARE BUFFER AND TEMP FILE LXI D,TBUF ;TBUF FOR COMPFILE CALL SETDMA LXI D,BUFFER ;D IS BUFFER POINTER COMPLP PUSH D CALL COMPREC ;COMPARE 1 RECORD JC TERMCK ;TERMCK IF EOF(COMP) POP D LXI B,80H ;UPDATE POINTER XCHG DAD B LXI B,EXTENT ;CHECK END OF BUFFER CALL COMP XCHG JNC COMPLP ;LOOP IF NOT PAST END MVI B,5 ;CHECK FOR COMPFILE TOO LONG LDA FINISH ORA A JZ ERROR RET ;RETURN FOR NEXT BUFFER TERMCK POP D LXI B,EXTENT ;CHECK FOR COMP FILE TOO SHORT XCHG CALL COMP MVI B,7 JNZ ERROR LDA FINISH ORA A JZ ERROR RET ;COMPARE COMPLETE ; ; COMPREC ;COMPARE NEXT COMP FILE RECORD ;WITH CORRESPONDING BUFFER RECORD ;IN: D:=BUFFER POINTER PUSH D LXI D,CFCB ;GET COMPFILE RECORD CALL READREC POP D ORA A ;CHECK READ OK JZ READ$OK CPI 1 ;CHECK EOF JZ EOFCOMP MVI B,3 ;REPORT ERROR JMP ERROR READ$OK LXI H,TBUF ;HL:=TBUF POINTER MVI B,80H-1 ;B:=BYTE COUNTER CPRLP LDAX D CMP M ;COMPARE BYTE PUSH B PUSH D PUSH H CNZ DIFFERENT POP H POP D POP B INX H INX D DCR B JNZ CPRLP ;LOOP UNTIL LAST BYTE LDA RECNO ;INCREMENT RECORD NO INR A STA RECNO ORA A ;CLEAR CARRY RET EOFCOMP STC ;SET CARRY TO INDICATE EOF RET ; ; DIFFERENT ;REPORT NON MATCHING BYTES ;IN DE,HL:=^BYTES ; B:=7FH-BYTE NO IN RECORD PUSH H ;SAVE PARAMETERS PUSH D PUSH B LDA FIRST ;HEADINGS IF FIRST IS TRUE ORA A JZ NOHDG XRA A ;FIRST:=FALSE STA FIRST LXI D,HDGMSG CALL WRITESTRING NOHDG LDA RECNO ;WRITE RECORD NO CALL OUTHEX POP B ;WRITE BYTE NO MVI A,80H-1 SUB B CALL OUTHEX POP D ;WRITE SOURCE BYTE LDAX D PUSH PSW CALL OUTHEX POP PSW CALL OUTASC POP H ;WRITE COMP BYTE MOV A,M PUSH PSW CALL OUTHEX POP PSW CALL OUTASC LXI D,CRLFMSG CALL WRITESTRING CALL CHECKSTAT ;CHECK INPUT FROM OPERATOR ORA A JNZ EXIT ;ABORT IF SO RET ; ; OUTHEX ;OUTPUT HEX VALUE OF ACCUMULATOR PUSH PSW LXI D,SPCMSG ;WRITE 4 SPACES CALL WRITESTRING POP PSW PUSH PSW ANI 0F0H ;GET TOP 4 BITS RAR RAR RAR RAR CALL OUTH ;PRINT POP PSW ;GET BOTTOM 4 BITS ANI 00FH CALL OUTH RET ; ; OUTH ;PRINT 1 HEX CHAR CPI 0AH JC NUM ADI 40H ;CONVERT 10..15 TO 'A'..'F' SUI 9 JMP WR NUM ADI 30H ;CONVERT 0..9 TO '0'..'9' WR MOV E,A MVI D,0 CALL WRITECHAR RET ; ; OUTASC ;OUTPUT ASCII VALUE OF ACC PUSH PSW LXI D,SPCMSG CALL WRITESTRING POP PSW ;CHECK FOR GRAPHIC CHAR PUSH PSW CPI 20H JC NOTASC ;<' ' CPI 7FH JNC NOTASC ;>'\' MVI D,0 MVI E,'"' ;WRITE "" CALL WRITECHAR POP PSW MVI D,0 MOV E,A CALL WRITECHAR MVI D,0 MVI E,'"' CALL WRITECHAR RET NOTASC LXI D,NASCMSG ;WRITE ??? CALL WRITESTRING POP PSW RET ; ; COPYSTRING ;COPY STRING OF LENGTH B ;FROM HL^ TO DE^ MOV A,M STAX D INX H INX D DCR B JNZ COPYSTRING RET ; ; ERROR ;PRINT ERROR MESSAGE LXI D,OPMSG MOV A,B CPI 1 JZ EPRINT LXI D,REMSG CPI 3 JZ EPRINT LXI D,FSMSG CPI 5 JZ EPRINT LXI D,FCMSG EPRINT CALL WRITESTRING JMP EXIT ; ; COMP ;COMPARE BC^ AND HL - SET FLAGS INX B LDAX B DCX B CMP H RNZ LDAX B CMP L RET ; ; SOURCEDISK ;ADVISE OPERATOR, WAIT FOR RESPONSE, LXI D,SDMSG CALL WRITESTRING CALL WAIT RET ; ; COMPDISK ;ADVISE OPERATOR, WAIT FOR RESPONSE LXI D,DDMSG CALL WRITESTRING CALL WAIT RET ; ; WAIT ;WAIT FOR OPERATOR TO TYPE RETURN CALL READCHAR CPI 03H JZ WBOOTE CPI CR JNZ WAIT RET ; ; CP/M COMMUNICATION ROUTINES ; ; ENTRY EQU 0005H ; BDOS ENTRY POINT ; ; READCHAR ; READ A CHARACTER FROM CONSOLE MVI C,1 JMP ENTRY ; ; WRITECHAR ; WRITE A CHARACTER TO CONSOLE MVI C,2 JMP ENTRY ; ; WRITESTRING ; WRITE A STRING ON CONSOLE MVI C,9 JMP ENTRY ; ; CHECKSTAT ; CHECK CONSOLE INPUT STATUS MVI C,11 JMP ENTRY ; ; OPENFILE ; OPEN A NEW FILE MVI C,15 JMP ENTRY ; ; READREC ; READ NEXT 128 BYTE RECORD MVI C,20 JMP ENTRY ; ; SETDMA ; SET DMA ADDRESS FOR READ OR WRITE MVI C,26 JMP ENTRY ; ; ; ; DATA AREA ; OLDSP DS 2 CFCB DS 33 ;COMPARE FILE CONTROL BLOCK CFCBCR EQU CFCB+32 ;CURRENT RECORD COUNTER FIRST DS 1 ;FIRST TIME THROUGH FLAG RECNO DS 1 ;RECORD NUMBER COUNTER EXTENT DS 2 ;EXTENT OF COPY BUFFER FINISH DS 1 ;LAST BUFFER FLAG SDMSG DB LF,'INSERT SOURCE DISK, TO CONTINUE' DB CR,LF,EOM DDMSG DB 'INSERT COMP DISK, TO CONTINUE' DB CR,LF,EOM OPMSG DB LF,'FILE NOT FOUND',CR,LF,EOM REMSG DB 'READ ERROR ON FILE',CR,LF,EOM COMPMSG DB 'COMPARE COMPLETE - FILES IDENTICAL' DB CR,LF,EOM FSMSG DB 'COMP FILE LONGER THAN SOURCE',CR,LF,EOM FCMSG DB 'COMP FILE SHORTER THAN SOURCE',CR,LF,EOM HDGMSG DB LF,CR,' RECORD BYTE SOURCE FILE' DB ' COMP FILE',LF,CR,' NO' DB ' NO HEX ASCII HEX ASCII' DB CR,LF,CR,LF,EOM SPCMSG DB ' ',EOM NASCMSG DB '???',EOM CRLFMSG DB CR,LF,EOM DS 20H ;MINIMUM STACK SPACE ;SET START OF BUFFER TO MULTIPLE OF SECTOR SIZE ORG (($ + 7FH) / 80H) * 80H STACK EQU $ ;GROWS DOWN BUFFER EQU $ ;FILLS REST OF MEMORY TO CBASE END