home *** CD-ROM | disk | FTP | other *** search
- ; PROGRAM: COMPARE
- ; AUTHOR: Richard Conn
- ; VERSION: 1.4
- ; DATE: 6 JAN 83
- ; PREVIOUS VERSIONS: 1.3 (19 DEC 82)
- ; PREVIOUS VERSIONS: 1.2 (8 DEC 82), 1.1 (21 JULY 82), 1.0 (11 JULY 82)
- VERS EQU 14
-
- ;
- ; This program is Copyright (c) 1982, 1983 by Richard Conn
- ; All Rights Reserved
- ;
- ; ZCPR2 and its utilities, including this one, are released
- ; to the public domain. Anyone who wishes to USE them may do so with
- ; no strings attached. The author assumes no responsibility or
- ; liability for the use of ZCPR2 and its utilities.
- ;
- ; The author, Richard Conn, has sole rights to this program.
- ; ZCPR2 and its utilities may not be sold without the express,
- ; written permission of the author.
- ;
-
-
- ;
- ; COMPARE is designed to provide the user with a convenient method
- ; to compare the contents of two files. It is invoked by one of two basic
- ; forms:
- ;
- ; COMPARE filename.typ
- ; or
- ; COMPARE file1.typ file2.typ
- ;
- ; The first form compares the file named "filename.typ" on drive A:
- ; to the file of the same name on drive B:; the second form compares the
- ; file named "file1.typ" on drive A: to the file named "file2.typ" on drive
- ; B:.
- ;
-
- ; CP/M Constants
- CPM equ 0 ; CP/M Warm Boot
- BUFF equ CPM+80H ; Temporary Buffer
- CR equ 0DH
- LF equ 0AH
-
- ; CRC ROUTINES
- EXT CRCCLR,CRCUPD,CRCDONE
-
- ; SYSLIB ROUTINES
- EXT COMPHD,BDOS,INITFCB,LOGUD,RETUD
- EXT F$OPEN,F$CLOSE,F$READ
- EXT CAPS,CIN,COUT,CRLF
- EXT PADC,MOVEB,PRINT
- EXT ZGPINS,ZFNAME
-
- ;
- ; Branch to Start of Program
- ;
- JMP START
-
- ;
- ;******************************************************************
- ;
- ; SINSFORM -- ZCPR2 Utility Standard General Purpose Initialization Format
- ;
- ; This data block precisely defines the data format for
- ; initial features of a ZCPR2 system which are required for proper
- ; initialization of the ZCPR2-Specific Routines in SYSLIB.
- ;
-
- ;
- ; EXTERNAL PATH DATA
- ;
- EPAVAIL:
- DB 0FFH ; IS EXTERNAL PATH AVAILABLE? (0=NO, 0FFH=YES)
- EPADR:
- DW 40H ; ADDRESS OF EXTERNAL PATH IF AVAILABLE
-
- ;
- ; INTERNAL PATH DATA
- ;
- INTPATH:
- DB 0,0 ; DISK, USER FOR FIRST PATH ELEMENT
- ; DISK = 1 FOR A, '$' FOR CURRENT
- ; USER = NUMBER, '$' FOR CURRENT
- DB 0,0
- DB 0,0
- DB 0,0
- DB 0,0
- DB 0,0
- DB 0,0
- DB 0,0 ; DISK, USER FOR 8TH PATH ELEMENT
- DB 0 ; END OF PATH
-
- ;
- ; MULTIPLE COMMAND LINE BUFFER DATA
- ;
- MCAVAIL:
- DB 0FFH ; IS MULTIPLE COMMAND LINE BUFFER AVAILABLE?
- MCADR:
- DW 0FF00H ; ADDRESS OF MULTIPLE COMMAND LINE BUFFER IF AVAILABLE
-
- ;
- ; DISK/USER LIMITS
- ;
- MDISK:
- DB 4 ; MAXIMUM NUMBER OF DISKS
- MUSER:
- DB 31 ; MAXIMUM USER NUMBER
-
- ;
- ; FLAGS TO PERMIT LOG IN FOR DIFFERENT USER AREA OR DISK
- ;
- DOK:
- DB 0FFH ; ALLOW DISK CHANGE? (0=NO, 0FFH=YES)
- UOK:
- DB 0FFH ; ALLOW USER CHANGE? (0=NO, 0FFH=YES)
-
- ;
- ; PRIVILEGED USER DATA
- ;
- PUSER:
- DB 10 ; BEGINNING OF PRIVILEGED USER AREAS
- PPASS:
- DB 'chdir',0 ; PASSWORD FOR MOVING INTO PRIV USER AREAS
- DS 41-($-PPASS) ; 40 CHARS MAX IN BUFFER + 1 for ending NULL
-
- ;
- ; CURRENT USER/DISK INDICATOR
- ;
- CINDIC:
- DB '$' ; USUAL VALUE (FOR PATH EXPRESSIONS)
-
- ;
- ; DMA ADDRESS FOR DISK TRANSFERS
- ;
- DMADR:
- DW 80H ; TBUFF AREA
-
- ;
- ; NAMED DIRECTORY INFORMATION
- ;
- NDRADR:
- DW 00000H ; ADDRESS OF MEMORY-RESIDENT NAMED DIRECTORY
- NDNAMES:
- DB 64 ; MAX NUMBER OF DIRECTORY NAMES
- DNFILE:
- DB 'NAMES ' ; NAME OF DISK NAME FILE
- DB 'DIR' ; TYPE OF DISK NAME FILE
-
- ;
- ; REQUIREMENTS FLAGS
- ;
- EPREQD:
- DB 0FFH ; EXTERNAL PATH?
- MCREQD:
- DB 0FFH ; MULTIPLE COMMAND LINE?
- MXREQD:
- DB 0FFH ; MAX USER/DISK?
- UDREQD:
- DB 0FFH ; ALLOW USER/DISK CHANGE?
- PUREQD:
- DB 000H ; PRIVILEGED USER?
- CDREQD:
- DB 0FFH ; CURRENT INDIC AND DMA?
- NDREQD:
- DB 0FFH ; NAMED DIRECTORIES?
- Z2CLASS:
- DB 0 ; CLASS 0
- DB 'ZCPR2'
- DS 10 ; RESERVED
-
- ;
- ; END OF SINSFORM -- STANDARD DEFAULT PARAMETER DATA
- ;
- ;******************************************************************
- ;
-
- ;
- ; Start of Program
- ;
- START:
- CALL ZGPINS ; INIT ZCPR2 BUFFERS
- XRA A ; SET NO MULTIPLE RUN
- STA MULT
- CALL RETUD ; GET CURRENT USER/DISK
- MOV A,B ; SAVE DISK
- STA CDISK
- MOV A,C ; SAVE USER
- STA CUSER
- LXI H,BUFF ; PROCESS OPTIONS IN BUFFER
- MOV A,M ; GET CHAR COUNT
- INX H ; PT TO FIRST CHAR
- PUSH H ; SAVE PTR TO FIRST CHAR
- ADD L ; HL=HL+A
- MOV L,A
- MOV A,H
- ACI 0
- MOV H,A
- MVI M,0 ; STORE ENDING ZERO
- POP H ; GET PTR TO FIRST CHAR
- LXI D,INLINE ; PT TO INPUT LINE BUFFER
- PUSH D ; SAVE PTR
- START0:
- MOV A,M ; COPY INPUT LINE SO BUFF MAY BE USED
- STAX D ; PUT BYTE
- INX H ; PT TO NEXT
- INX D
- ORA A ; EOL?
- JNZ START0
- POP H ; PT TO FIRST CHAR
- CALL SBLANK ; SKIP SPACES
- ORA A ; EOL?
- JZ PRHELP ; PRINT HELP IF SO
- CPI '/' ; ASKING FOR HELP?
- JZ PRHELP
- LXI D,FCBS ; PT TO SOURCE FCB
- CALL ZFNAME ; EXTRACT NAME AND DIRECTORY DATA
- JNZ START1
- UDERR:
- CALL PRINT
- DB CR,LF,'Invalid Disk or User -- Aborting',0
- RET
- START1:
- MOV A,B ; SAVE SOURCE DISK
- CPI 0FFH ; CHECK FOR CURRENT
- JNZ SDISK1
- LDA CDISK ; SPECIFY CURRENT DISK INSTEAD
- INR A ; ADD 1 FOR FOLLOWING DECREMENT
- SDISK1:
- DCR A ; DOWN 1 SO RANGE IS 0-F
- STA SDISK
- MOV A,C ; SAVE SOURCE USER
- CPI 0FFH ; CHECK FOR CURRENT
- JZ SUSER0
- CPI '?' ; WILD IS CURRENT
- JNZ SUSER1
- SUSER0:
- LDA CUSER ; GET CURRENT USER
- SUSER1:
- STA SUSER
- MOV A,M ; GET SEPARATION CHAR
- CPI ',' ; COMMA IF SECOND NAME SPECIFIED
- JZ START2
- PUSH H ; SAVE PTR
- LXI H,FCBS+1 ; NO 2ND NAME, SO SET IT TO SAME AS FIRST
- LXI D,FCBD+1
- MVI B,11 ; 11 BYTES
- CALL MOVEB
- LDA CDISK ; SET DISK AND USER TO CURRENT
- STA DDISK
- LDA CUSER
- STA DUSER
- POP H ; GET PTR
- JMP START3
- START2:
- INX H ; PT TO NEXT CHAR AFTER COMMA
- LXI D,FCBD ; SET DEST FCB
- CALL ZFNAME ; PROCESS NAME
- JZ UDERR
- LDA FCBD+1 ; CHECK FOR AMBIGUOUS NAME
- CPI '?' ; ASSUME ALL IS AMBIGUOUS IF FIRST CHAR IS
- JNZ NOSET
- PUSH H ; SAVE PTR
- PUSH B ; SAVE USER/DISK
- LXI H,FCBS+1 ; SET NAMES THE SAME
- LXI D,FCBD+1 ; COPY SOURCE TO DEST
- MVI B,11 ; 11 BYTES
- CALL MOVEB
- POP B ; RESTORE BC
- POP H ; RESTORE PTR
- NOSET:
- MOV A,B ; GET DISK
- CPI 0FFH
- JNZ DDISK1
- LDA CDISK ; SELECT CURRENT DISK IF DEFAULT
- INR A ; ADD 1 FOR FOLLOWING DECREMENT
- DDISK1:
- DCR A
- STA DDISK
- MOV A,C ; GET USER
- CPI 0FFH ; CURRENT?
- JZ DUSER0
- CPI '?' ; WILD IS CURRENT
- JNZ DUSER1
- DUSER0:
- LDA CUSER
- DUSER1:
- STA DUSER ; SET DEST USER
- START3:
- CALL SBLANK ; SKIP SPACES
- CPI 'M' ; MULTIPLE OPTION?
- JNZ START4
- MVI A,0FFH ; SET FLAG
- STA MULT
- START4:
- LXI H,FCBS ; SET UP SOURCE FCB
- CALL QCHECK ; NO AMBIGUOUS ENTRIES PERMITTED
- LXI H,FCBD ; SET UP DESTINATION FCB
- CALL QCHECK ; NO AMBIGUOUS ENTRIES PERMITTED
- MLOOP:
- CALL BANNER ; PRINT BANNER
- LDA MULT ; MULTIPLE RUNS?
- ORA A ; 0=NO
- JZ MLOOP1
- CALL PRS1 ; PRINT SOURCE FILE 1
- CALL PRS2 ; PRINT SOURCE FILE 2
- CALL PRINT
- DB CR,LF,' Change Disks if Desired and Type ^C or A to Abort or '
- DB '<RETURN> to Continue - ',0
- CALL CIN ; GET RESPONSE
- CALL CAPS ; CAPITALIZE
- CPI 3 ; ABORT?
- RZ
- CPI 'A' ; ABORT?
- RZ
- MVI C,13 ; RESET DISKS
- CALL BDOS
- MLOOP1:
- CALL VERIFY ; PERFORM VERIFICATION
- CALL CRLF ; NEW LINE
- LDA MULT ; MULTIPLE RUNS?
- ORA A ; 0=NO
- JNZ MLOOP ; CONTINUE IF SO
- RET
-
- ;
- ; SKIP TO NON-BLANK CHAR
- ;
- SBLANK:
- MOV A,M ; GET CHAR
- INX H ; PT TO NEXT
- CPI ' ' ; BLANK?
- JZ SBLANK
- DCX H ; PT TO NON-BLANK
- RET
-
- ;
- ; PRINT HELP MESSAGE
- ;
- PRHELP:
- CALL BANNER ; PRINT BANNER
- CALL PRINT
- DB CR,LF
- DB CR,LF,'COMPARE is used to quickly compare two files for '
- DB 'equality'
- DB CR,LF
- DB CR,LF,'COMPARE is invoked by a command like:'
- DB CR,LF,' COMPARE dir:file1.typ,dir:file2.typ M'
- DB CR,LF,'where:'
- DB CR,LF,' "file1.typ" must be specified and is unambiguous'
- DB CR,LF,' "dir:" is an optional named directory (or DU:)'
- DB CR,LF,' "file2.typ" is optional and set equal to '
- DB '"file1.typ" if omitted'
- DB CR,LF,' "M" is optional and allows Multiple Runs if given'
- DB CR,LF
- DB CR,LF,'Examples:'
- DB CR,LF,'Command Files Compared'
- DB CR,LF,'COMPARE T.COM,A1: $$:T.COM, A1:T.COM'
- DB CR,LF,'COMPARE A:T.COM A$:T.COM, $$:T.COM'
- DB CR,LF,'COMPARE A:T.COM,ROOT: A$:T.COM, ROOT:T.COM'
- DB CR,LF,'COMPARE A:T.COM,B:S.COM A$:T.COM, B$:S.COM'
- DB 0
- RET
-
- ;
- ; CHECK FOR ANY QUESTION MARKS FROM HL+1 TO HL+11
- ; AFFECT ONLY AF REGISTERS IF OK
- ;
- QCHECK:
- PUSH H ; SAVE HL
- PUSH B ; SAVE BC
- INX H ; PT TO FIRST CHAR
- MVI B,11 ; 11 BYTES
- MVI C,'?' ; SCAN FOR '?'
- QC:
- MOV A,M ; GET BYTE
- CMP C ; '?'?
- JZ QC1
- INX H ; PT TO NEXT
- DCR B ; COUNT DOWN
- JNZ QC
- POP B ; RESTORE
- POP H
- RET
- QC1:
- POP B ; RESTORE AND ABORT
- POP H
- POP D ; CLEAR RETURN ADDRESS
- XCHG ; FCB PTR IN DE
- CALL BANNER ; PRINT BANNER
- CALL CRLF
- CALL PRFN ; PRINT FILE NAME
- CALL PRINT
- DB ' Ambiguous File Name not Allowed',CR,LF,0
- RET
-
- ;
- ; PRINT BANNER
- ;
- BANNER:
- CALL PRINT
- DB 'COMPARE Version '
- DB VERS/10+'0','.',(VERS MOD 10)+'0'
- DB 0
- RET
-
- ;
- ; PRINT NAMES OF SOURCE FILES
- ; PRS1 -- SOURCE FILE 1
- ; PRS2 -- SOURCE FILE 2
- ;
- PRS1:
- CALL PRINT
- DB CR,LF,'Source File 1 -- ',0
- LXI H,SDISK ; PT TO FIRST BYTE
- CALL PRUD
- LXI D,FCBS ; COMPUTE CRC FOR SOURCE FCB
- JMP PRFN ; PRINT FILE NAME
- PRS2:
- CALL PRINT
- DB CR,LF,'Source File 2 -- ',0
- LXI H,DDISK ; PT TO FIRST BYTE
- CALL PRUD
- LXI D,FCBD ; COMPUTE CRC FOR DESTINATION FCB
- JMP PRFN ; PRINT FILE NAME
-
- ;
- ; MAIN VERIFY ROUTINE
- ;
- VERIFY:
- CALL PRS1 ; PRINT SOURCE 1
- LDA SDISK ; SELECT DISK AND USER
- MOV B,A
- LDA SUSER
- MOV C,A
- CALL LOGUD ; LOG IN DISK AND USER IN B,C
- CALL CRCCLR ; CLEAR CRC
- CALL COMPCRC ; READ IN FILE
- CALL CRCDONE ; GET CRCK VALUE
- SHLD CRCVAL ; SAVE IT
- LDA BCNT ; GET OLD BLOCK COUNT
- STA BCNT1 ; SAVE IT
- CALL PRS2 ; PRINT NAME OF SOURCE 2
- LDA DDISK ; SELECT DISK AND USER
- MOV B,A
- LDA DUSER
- MOV C,A
- CALL LOGUD ; LOG IN DISK AND USER IN B,C
- CALL CRCCLR ; CLEAR CRC
- CALL COMPCRC ; READ IN FILE
- LDA BCNT ; GET BLOCK COUNT
- MOV B,A ; RESULT IN B
- LDA BCNT1 ; CHECK FOR SAME SIZE
- CMP B ; COMPARE BLOCK SIZES
- JNZ NOMATCH ; NO MATCH IF NOT SAME
- LHLD CRCVAL ; GET OLD CRC VALUE
- XCHG ; VALUE IN DE
- CALL CRCDONE ; UPDATE COMPLETE
- CALL COMPHD ; COMPARE HL TO DE
- JNZ NOMATCH
- CALL PRINT
- DB CR,LF,'** Files are Identical **',0
- RET
-
- ; VERIFY ERROR
- NOMATCH:
- CALL PRINT
- DB CR,LF,'** Files are Different **',0
- RET
-
- ;
- ; READ IN FILE AND COMPUTE ITS CRC; DE PTS TO FILE'S FCB
- ;
- COMPCRC:
- CALL CRCCLR ; CLEAR CRCK VALUE
- CALL INITFCB ; INIT FCB FIELDS
- CALL F$OPEN ; OPEN FILE
- CPI 0FFH ; FILE NOT FOUND?
- JNZ LOAD ; LOAD DATA AND COMPUTE CRCVAL AND BCNT
- POP H ; CLEAR 2 LEVELS OF RETURN ADDRESS
- POP H
- CALL CRLF
- CALL PRFN ; PRINT FILE NAME
- CALL PRINT
- DB ' File Not Found',CR,LF,0
- RET
-
- ;
- ; LOAD BUFFER FROM FILE WHOSE FCB IS PTED TO BY DE
- ; ON OUTPUT, BCNT=NUMBER OF BLOCKS LOADED (UP TO 128) AND
- ; CONT=0 IF DONE OR 128 IF NOT DONE
- ;
- LOAD:
- XRA A ; A=0
- STA BCNT ; SET BLOCK COUNT
-
- ; MAIN CRC EVALUATION LOOP
- LOAD1:
- CALL F$READ ; READ IN BLOCK
- ORA A ; END OF FILE?
- JNZ LOAD3 ; RETURN
- LXI H,BUFF ; PT TO BUFFER TO COMPUTE CRC FROM
- MVI B,128 ; COPY 128 BYTES
- LOAD2:
- MOV A,M ; GET BYTE
- CALL CRCUPD ; UPDATE CRC
- INX H ; PT TO NEXT
- DCR B ; COUNT DOWN
- JNZ LOAD2
- LDA BCNT ; GET BLOCK COUNT
- INR A ; INCREMENT IT
- STA BCNT ; SET IT
- JMP LOAD1 ; CONTINUE
- LOAD3:
- CALL F$CLOSE ; CLOSE FILE
- RET
-
- ;
- ; PRINT DISK/USER PTED TO BY HL (2 BYTES)
- ;
- PRUD:
- MOV A,M ; GET DISK
- ADI 'A' ; CONVERT TO LETTER
- CALL COUT
- INX H ; PT TO USER
- MOV A,M ; GET USER
- CALL PADC ; PRINT AS DEC
- CALL PRINT
- DB ': ',0
- RET
-
- ;
- ; PRINT FILE NAME WHOSE FCB IS PTED TO BY DE
- ;
- PRFN:
- PUSH H ; SAVE REGS
- PUSH D
- PUSH B
- XCHG ; FN PTED TO BY HL
- INX H ; PT TO FIRST CHAR
- MVI B,8 ; 8 CHARS
- CALL PRFN1
- MVI A,'.'
- CALL COUT
- MVI B,3 ; 3 CHARS FOR FILE TYPE
- CALL PRFN1
- POP B ; RESTORE REGS
- POP D
- POP H
- RET
- PRFN1:
- MOV A,M ; GET CHAR
- INX H ; PT TO NEXT
- CALL COUT ; PRINT
- DCR B ; COUNT DOWN
- JNZ PRFN1
- RET
-
- ;
- ; BUFFERS
- ;
- MULT:
- DS 1 ; MULTIPLE RUN FLAG (0=NO MULT RUNS)
- CDISK:
- DS 1 ; CURRENT DISK
- CUSER:
- DS 1 ; CURRENT USER
- SDISK:
- DS 1 ; SOURCE DISK (MUST BE FOLLOWED BY SUSER)
- SUSER:
- DS 1 ; SOURCE USER
- FCBS:
- DS 36 ; SOURCE FCB
- DDISK:
- DS 1 ; DEST DISK (MUST BE FOLLOWED BY DUSER)
- DUSER:
- DS 1 ; DEST USER
- FCBD:
- DS 36 ; DESTINATION FCB
- CRCVAL:
- DS 2 ; CRC VALUE
- CURDISK:
- DS 1 ; CURRENT DISK NUMBER
- BCNT:
- DS 1 ; BUFFER COUNT
- BCNT1:
- DS 1 ; SECOND BUFFER COUNT
- INLINE:
- DS 200 ; INPUT LINE BUFFER
-
- END
-