home *** CD-ROM | disk | FTP | other *** search
- ;
- ;01/16/88 ADDED HELP MESSAGE, USER AREA SUPPORT. TAH
- ; FIX EXIT BUG.
- ; FOR HELP TYPE: COMPARE
- ; OR
- ; COMPARE $?
- ;
- ;REQUIRES MAC.COM AND SEQIOU.LIB FOR ASSEMBLY
- ; SEQIOU.LIB IS A REVISED VERSION OF SEQIO.LIB FROM CPMUG VOL 29
- ; WITH USER AREA SUPPORT ADDED TO THE "FILE" MACRO.
- ;
- ;11/??/77 ORIGINALLY WRITTEN BY WARD CHRISTENSEN
- ;12/31/77 ADD PICKUP OF SECOND FILENAME IF BLANK
- ;01/08/78 ADD SEQIO MACLIB TO READ BIG BLOCKS
- ;
- BSIZE EQU 4096 ;DISK BUFFER SIZE (TIMES 2)
- LINES EQU 14 ;LINES TO PRINT BEFORE PAUSE
- CTRLC EQU 03 ;CONTROL C
- ;
- ORG 100H
- ;
- MACLIB SEQIOU
- ;
- ;COMPARE.ASM - COMPARES 2 FILES
- ;
- ;COMMAND FORMAT: COMPARE NAME1 NAME2
- ; IF NAME2 = NAME1 BUT IS ON B DISK,
- ; JUST TYPE: COMPARE NAME1 B:
- ;
- ;INIT STACK
- ;
- POP H ;GET CP/M RET ADDR
- SHLD EXIT1+1 ;MODIFY RETURN ADDR
- LXI SP,STACK ;GET MY STACK
- ;
- CALL INLMSG
- DB 'COMPARE.COM v3',0DH,0AH,'$'
- LXI H,@TBUF
- MOV A,M
- ORA A
- JZ HELP ;IF EMPTY COMMAND LINE, GIVE HELP
- MOV E,A ;CHARACTER COUNT
- MVI D,00 ;CLEAR D
- DAD D ;HL POINTS TO END OF LINE
- INR E
- INIT: DCR E
- JZ HELP
- MOV A,M
- DCX H
- CPI ' ' ;SCAN BACKWARDS FOR FIRST SPACE
- JNZ INIT ;LOOP BACK IF NOT SPACE
- INX H
- INX H
- MOV A,M
- CPI '$' ;IS SPACE FOLLOWED BY $ ?
- JNZ INIT2 ;NO, OPTIONS NOT SPECIFIED.
- INX H ;YES, CHECK NEXT CHAR.
- MOV A,M
- CPI '?' ;NEED HELP MESSAGE
- JZ HELP
- CPI 'S'
- JNZ INIT2
- STA SHOFLG ;SAVE S OPTION.
- INX H
- MOV A,M
- XCHG ;POINTER TO DE
- LXI H,0100H ;DEFAULT ORIGIN ADDRESS
- CALL VALHEX ;HEX ADDRESS GIVEN?
- JC INIT1 ;NO, USE DEFAULT VALUE
- LXI H,0 ;YES, CONVERT ASCII TO BINARY
- MVI B,0
- ;
- ADRLUP: LDAX D
- INX D
- CALL VALHEX ;CHECK FOR VALID HEX CHARACTER
- JC INIT1 ;QUIT IF NOT.
- ADDNIB: DAD H ;*2
- DAD H ;*4
- DAD H ;*8
- DAD H ;*16 TO SHIFT PARTIAL SUM
- MOV C,A
- DAD B ;ADD IN NEXT DIGIT
- JMP ADRLUP
- INIT1: SHLD ADDR ;SAVE S OPTION ADDRESS
- ;
- INIT2: CALL PCL ;PARSE COMMAND LINE
- ;
- ;IF THE SECOND FCB IS BLANK,
- ;MOVE IN THE NAME FROM THE FIRST
- ;
- LDA @TFCB+17
- CPI ' '
- JNZ MOVE2 ;NOT BLANK
- MVI B,11
- LXI D,@TFCB+1
- LXI H,@TFCB+17
- CALL MOVER
- ;
- ;'DECLARE' BOTH FCB'S
- ;
- MOVE2 FILE INFILE,FILE1,,1,,BSIZE
- FILE INFILE,FILE2,,2,,BSIZE
- ;
- ;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 FIXADDR ;IF THE SAME, CONTINUE
- ;
- ;FILES UNEQUAL
- ;
- MOV C,A ;SAVE FILE2 CHARACTER
- LDA SHOFLG
- CPI 'S' ;SHOW ALL DIFFERENCES?
- JNZ UNEQUAL ;NO, DISPLAY FILE BUFFER AND QUIT
- CALL SHOW ;YES, SHOW ADDRESS AND DATA...
- FIXADDR:
- LHLD ADDR
- INX H ;...UPDATE ADDRESS
- SHLD ADDR
- JMP COMP ;GO BACK FOR MORE.
- ;
- UNEQUAL CALL INLMSG
- DB 'FILES UNEQUAL AFTER ','$'
- PRBYTES LXI D,BYTES
- MVI C,@MSG
- CALL @BDOS
- CALL INLMSG
- DB 'LAST DATA READ FROM FILE 1:',0DH,0AH,'$'
- LHLD PRTPTR
- ;
- ;THE FOLLOWING DISPLAYS THE LAST CONTENTS OF THE FILE1 BUFFER
- ;IN A MANNER SIMILAR TO THE DDT "D" COMMAND (HEX DATA FOLLOWED
- ;BY ASCII EQUIVALENT)
- ;
- DISP MVI B,16 ;DISPLAY 16 LINES
- DISP0 MVI C,16 ;AT 16 CHAR PER LINE
- PUSH H
- DISP1 MOV A,M ;GET DATA BYTE
- INR L ;BUMP POINTER
- CALL HEXOUT ;DISPLAY AS HEX
- MVI A,' ' ;FOLLOW WITH A SPACE
- CALL TYPE
- DCR C
- JNZ DISP1 ;DO 16 TIMES
- POP H
- MVI C,16
- DISP2 MOV A,M ;GET DATA AGAIN
- INR L
- CPI ' '
- JC DOTOUT ;REPLACE NON-PRINTING CHAR. WITH DOT
- CPI 7FH
- JC NODOT
- DOTOUT MVI A,'.'
- NODOT CALL TYPE ;DISPLAY THE CHARACTER
- DCR C
- JNZ DISP2 ;LOOP FOR 16 COUNT
- PUSH H
- PUSH B
- CALL INLMSG ;START A NEW LINE
- DB 0DH,0AH,'$'
- POP B
- POP H
- DCR B
- JNZ DISP0 ;DISPLAY LAST 256 BYTES OF FILE1
- JMP EXIT ;AND QUIT
- ;
- ;READ BYTE FROM FILE 1
- ;
- READ1 GET FILE1
- JZ EOF1 ;GOT EOF?
- LHLD PRTPTR
- MOV M,A
- INR L
- SHLD PRTPTR
- PUSH PSW ;SAVE CHAR
- 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
- CALL INLMSG
- DB 'EOF FILE 1, NOT FILE 2',0DH,0AH,'$'
- JMP UNEQUAL
- ;
- READ2 GET FILE2
- RNZ ;NO EOF
- ;
- ;GOT EOF ON FILE 2, MUST HAVE GOTTEN IT ON FILE 1
- ;
- EOF2 LDA EOFLG
- CPI 'Y'
- JZ AOK
- CALL INLMSG
- DB 'EOF FILE 2 BEFORE FILE 1',0DH,0AH,'$'
- JMP UNEQUAL
- ;
- ;A-OK - FILES MATCH
- ;
- AOK LDA ERRFLG
- ORA A
- JNZ EXIT
- CALL INLMSG
- DB 'FILES MATCH, LENGTH IS ','$'
- LXI D,BYTES
- 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 MVI C,20H ;RESTORE USER NUMBER
- LDA DEFUSR
- MOV E,A
- CALL @BDOS
- EXIT1 JMP $-$ ;CP/M RET ADDR (MODIFIED)
- ;
- ERXIT POP D ;GET MESSAGE
- MVI C,@MSG
- CALL @BDOS
- JMP EXIT
- ;
- ;MOVE FROM (DE) TO (HL) LENGTH IN B
- MOVER LDAX D
- MOV M,A
- INX D
- INX H
- DCR B
- JNZ MOVER
- RET
- ;
- ;DISPLAY HEX ADDRESS AND FILE1, FILE2 DATA
- ;
- SHOW MVI A,0FFH
- STA ERRFLG ;SET FILE MISMATCH FLAG
- LHLD ADDR
- PUSH B
- CALL HLOUT ;DISPLAY HEX ADDRES
- MVI A,'-'
- CALL TYPE
- POP B
- PUSH B
- MOV A,B
- CALL HEXOUT ;FIRST DATA BYTE
- MVI A,' '
- CALL TYPE
- POP B
- MOV A,C
- CALL HEXOUT ;SECOND DATA BYTE
- CALL INLMSG ;START NEW LINE.
- DB 0DH,0AH,'$'
- LDA LINCNT
- DCR A
- STA LINCNT
- RNZ
- MVI A,LINES
- STA LINCNT
- CALL INLMSG ;ALLOW TIME TO VIEW THE SCREEN
- DB '[More]','$'
- MVI C,1
- CALL @BDOS ;WAIT FOR KEYPRESS
- ANI 5FH
- CPI CTRLC ;ABORT IF CTRL C
- JZ EXIT
- CALL INLMSG ;ELSE, SHOW MORE
- DB 0DH,0AH,'$'
- RET
- ;
- ;DISPLAY HL AS HEX
- ;
- HLOUT MOV A,H
- PUSH H
- CALL HEXOUT
- POP H
- MOV A,L
- ;
- ;DISPLAY ACC. AS HEX
- ;
- HEXOUT PUSH PSW
- RAR
- RAR
- RAR
- RAR
- CALL PRTNBL
- POP PSW
- PRTNBL ANI 0FH
- CPI 10 ;CONVERT TO ASCII
- JC SML
- ADI 7
- SML ADI '0'
- JMP TYPE
- ;
- ;CONVERT ACC FROM ASCII TO HEX DIGIT, RETURN CARRY FLAG CLEAR
- ;IF VALID HEX DIGIT.
- ;
- VALHEX SUI '0' ;SUBTRACT ASCII ZERO OFFSET
- RC
- CPI 16+7 ;GREATER THAN "F" ?
- CMC ;ADJUST CARRY FLAG
- RC
- CPI 10
- CMC ;ADJUST CARRY FLAG
- RNC
- SUI 7 ; A-F OFFSET
- RET
- ;
- ; OUTPUT IN-LINE MESSAGE TO CONSOLE
- INLMSG: XTHL ;SAVE H, GET TEXT LOCATION
- PUSH PSW
- MOV A,M
- INLML: CALL TYPE
- INX H
- MOV A,M
- CPI '$'
- JNZ INLML ;$ ENDS TEXT
- INX H
- POP PSW
- XTHL
- RET ;RETURN AFTER TEXT
- ;
- ;SEND CONTENTS OF ACC. TO CONSOLE
- ;
- TYPE PUSH B
- PUSH D
- PUSH H
- MOV E,A
- MVI C,2
- CALL @BDOS
- POP H
- POP D
- POP B
- RET
- ;
- ;THE FOLLOWING ROUTINE ALLOWS FILES IN DIFFERENT USER AREAS
- ;TO BE COMPARED.
- ;SINCE THE CP/M CCP CANNOT DEAL WITH THE d/u: FORM OF DRIVE/USER
- ;SPECIFICATION WE MUST PROVIDE A BUILT-IN ROUTINE TO PARSE THE
- ;COMMAND LINE FILE NAMES AND BUILD THE DEFAULT FCB AT 5CH AND 6CH.
- ;
- PCL: MVI C,20H
- MVI E,0FFH
- CALL @BDOS ;GET CURRENT USER NUMBER
- STA DEFUSR ;AND SAVE
- ;
- LXI H,@TBUF+2
- LXI D,@TFCB
- CALL SCAN
- MOV A,C ;GET USER FOR FILE 1
- STA FILE1USR
- MOV A,B ;GET DRIVE FOR FILE 1
- STA @TFCB
- MOV A,M
- CPI 00H ;COMMAND LINE TERMINATOR?
- JZ PCL1 ;IF YES, DONE.
- INX H ;SKIP SPACE
- LXI D,@TFCB+16
- CALL SCAN
- MOV A,C ;GET USER FOR FILE 2
- STA FILE2USR
- MOV A,B ;GET DRIVE FOR FILE 2
- STA @TFCB+16
- RET
- PCL1: LDA DEFUSR
- STA FILE2USR ;SET USER FOR FILE2 TO DEFAULT.
- RET
- ;
- ;SFNAME.MAC FROM SYSLIB 2.0
- ;*
- ;* SCAN is a file name scanner. Pointing to the first character
- ;* of a file name specification of the form 'du:filename.typ', where
- ;* any part of this specification is optional, this routine
- ;* properly initializes the FN and FT (File Name and
- ;* File Type) fields if 'filename.typ' or any part thereof is present,
- ;* and returns the value of d and u if they are specified
- ;*
- ;*
- MAXDISK EQU 16 ; MAX NUMBER OF DISKS
- MAXUSER EQU 31 ; MAX USER NUMBER
- ;*
- ;* MAIN MODULE
- ;* ON ENTRY, DE PTS TO FCB TO BE FILLED AND HL PTS TO FIRST BYTE OF
- ;* TARGET STRING; FCB IS 36 BYTES LONG
- ;* ON EXIT, B=DISK NUMBER (1 FOR A, ETC) AND C=USER NUMBER
- ;* HL PTS TO TERMINATING CHAR
- ;* A=0 AND Z SET IF ERROR IN DISK OR USER NUMBERS, A=0FFH AND NZ
- ;* IF OK
- ;*
- SCAN:
- MVI A,00H ; SET DEFAULT DISK AND USER
- STA DISK
- LDA DEFUSR
- STA USER
- PUSH D
- PUSH H ; SAVE PTR
- COLON: ; SCAN FOR COLON IN STRING
- MOV A,M ; SCAN FOR COLON OR SPACE
- INX H ; PT TO NEXT
- CPI ':' ; COLON FOUND?
- JZ COLON1
- CPI ',' ; COMMA FOUND?
- JZ GETF1
- CPI ' '+1 ; DELIM?
- JC GETF1
- JMP COLON ; CONTINUE IF NOT END OF LINE
- COLON1:
- POP H ; CLEAR STACK
- MOV A,M ; SAVE POSSIBLE DRIVE SPEC
- CPI 'A' ; DIGIT IF LESS THAN 'A'
- JC USERCK ; PROCESS USER NUMBER
- SUI 'A' ; CONVERT TO 0-15
- CPI MAXDISK ; WITHIN BOUNDS?
- JC SVDISK
- ERREXIT:
- XRA A ; ERROR INDICATOR
- POP D ; RESTORE DE
- CALL ERXIT
- DB CR,LF,'COMMAND LINE SYNTAX ERROR','$'
- RET ; REDUNDANT
-
- ; LOG IN SPECIFIED DISK
- SVDISK:
- INR A ; ADJUST TO 1 FOR A
- STA DISK ; SAVE FLAG
- INX H ; PT TO NEXT CHAR
-
- ; CHECK FOR USER
- USERCK:
- MOV A,M ; GET POSSIBLE USER NUMBER
- CPI ':' ; NO USER NUMBER
- JZ GETFILE
- CPI '?' ; ALL USER NUMBERS?
- JNZ USERC1
- JMP ERREXIT ; FATAL ERROR
- USERC1:
- XRA A ; ZERO USER NUMBER
- MOV B,A ; B=ACCUMULATOR FOR USER NUMBER
- USRLOOP:
- MOV A,M ; GET DIGIT
- INX H ; PT TO NEXT
- CPI ':' ; DONE?
- JZ USRDN
- SUI '0' ; CONVERT TO BINARY
- JC ERREXIT ; USER NUMBER ERROR?
- CPI 10
- JNC ERREXIT
- MOV C,A ; NEXT DIGIT IN C
- MOV A,B ; OLD NUMBER IN A
- ADD A ; *2
- ADD A ; *4
- ADD B ; *5
- ADD A ; *10
- ADD C ; *10+NEW DIGIT
- MOV B,A ; RESULT IN B
- JMP USRLOOP
- USRDN:
- MOV A,B ; GET NEW USER NUMBER
- CPI MAXUSER+1 ; WITHIN RANGE?
- JNC ERREXIT
- STA USER ; SAVE IN FLAG
- JMP GETFILE
-
- ; EXTRACT FILE NAME
- GETF1:
- POP H ; GET PTR TO BYTE
- GETFILE:
- MOV A,M ; PTING TO COLON?
- CPI ':'
- JNZ GFILE1
- INX H ; SKIP OVER COLON
- GFILE1:
- MOV A,M ; GET NEXT CHAR
- CPI ',' ; DELIM?
- JZ GFQUES
- CPI ' '+1 ; NOT A DELIMITER?
- JNC GFILE2
- GFQUES:
- INX D ; FILL WITH ' '
- MVI B,11 ; 11 BYTES
- MVI A,' '
- GFFILL:
- STAX D ; PUT SPACE
- INX D ; PT TO NEXT
- DCR B ; COUNT DOWN
- JNZ GFFILL
- FNDONE:
- LDA DISK ; GET DISK NUMBER
- MOV B,A ; ... IN B
- LDA USER ; GET USER NUMBER
- MOV C,A ; ... IN C
- POP D ; RESTORE REGS
- MVI A,0FFH ; NO ERROR
- ORA A ; SET FLAGS
- RET
- ; GET FILE NAME FIELDS
- GFILE2:
- MVI B,8 ; AT MOST 8 BYTES FOR FN
- CALL SCANF ; SCAN AND FILL
- MVI B,3 ; AT MOST 3 BYTES FOR FT
- MOV A,M ; GET DELIMITER
- CPI '.' ; FN ENDING IN '.'?
- JNZ GFILE3
- INX H ; PT TO CHAR AFTER '.'
- CALL SCANF ; SCAN AND FILL
- JMP FNDONE ; DONE ... RETURN ARGS
- GFILE3:
- CALL SCANF4 ; FILL WITH <SP>
- JMP FNDONE
- ;
- ; SCANNER ROUTINE
- ;
- SCANF:
- CALL DELCK ; CHECK FOR DELIMITER
- JZ SCANF4 ; <SP> FILL IF FOUND
- INX D ; PT TO NEXT BYTE IN FN
- CPI '*' ; ? FILL?
- JZ ERREXIT ;NO WILDCARDS ALLOWED
- CPI '?'
- JZ ERREXIT ;NO WILDCARDS ALLOWED
- SCANF1:
- STAX D ; PLACE CHAR
- INX H ; PT TO NEXT POSITION
- SCANF2:
- DCR B ; COUNT DOWN
- JNZ SCANF ; CONTINUE LOOP
- SCANF3:
- CALL DELCK ; "B" CHARS OR MORE - SKIP TO DELIMITER
- RZ
- INX H ; PT TO NEXT
- JMP SCANF3
- SCANF4:
- INX D ; PT TO NEXT FN OR FT
- MVI A,' ' ; <SP> FILL
- STAX D
- DCR B ; COUNT DOWN
- JNZ SCANF4
- RET
-
- ;*
- ;* BUFFERS
- ;*
- DISK: DS 1 ; DISK NUMBER
- USER: DS 1 ; USER NUMBER
-
- ;
- ; CHECK CHAR PTED TO BY HL FOR A DELIMITER
- ; RET WITH Z FLAG SET IF DELIMITER
- ;
- DELCK:
- MOV A,M ; GET CHAR
- ORA A ; 0=DELIM
- RZ
- CPI ' '+1 ; <SP>+1
- JC DELCK1 ; <SP> OR LESS
- CPI '='
- RZ
- CPI 5FH ; UNDERSCORE
- RZ
- CPI '.'
- RZ
- CPI ':'
- RZ
- CPI ';'
- RZ
- CPI ','
- RZ
- CPI '<'
- RZ
- CPI '>'
- RET
- DELCK1:
- CMP M ; COMPARE WITH SELF FOR OK
- RET
- ;
- HELP LXI D,USAGE
- MVI C,9
- CALL @BDOS
- JMP EXIT
- ;
- USAGE DB CR,LF
- DB 'Determines if two files are equal',CR,LF
- DB ' Usage:',CR,LF,CR,LF
- DB 'COMPARE [du:]UFN1.UFT [du:][UFN2.UFT] ['
- DB '$' OR 80H ;ALLOWS DOLLAR SIGN IN MESSAGE
- DB 'S[ADDR]]',CR,LF,CR,LF
- DB 'du are optional drive and user area for the files.',CR,LF
- DB 'UFN1.TYP is the first unambiguous file name.',CR,LF
- DB 'UFN2.TYP is the second unambiguous file name and',CR,LF
- DB 'will default to UFN1.TYP if only du2: is given.',CR,LF
- DB CR,LF
- DB 'The optional ', '$' OR 80H, 'S '
- DB 'is primarily for .COM or similar files',CR,LF
- DB 'and will Show all addresses with data bytes that differ.'
- DB CR,LF
- DB 'ADDR is an optional HEX origin address (default = 0100)'
- DB CR,LF,CR,LF
- DB 'Example: COMPARE B:FOOBAR.COM C3:WOMBAT.OBJ ','$' OR 80H
- DB 'S7E00',CR,LF
- DB '$'
- ;
- EOFLG DB 'N'
- COL DB 0
- BYTES DB ' BYTES',0DH,0AH,'$'
- PRTPTR DW BUFF
- ;
- DEFUSR DB 0
- F1USER DB 0
- F2USER DB 0
- ;
- LINCNT DB LINES
- SHOFLG DB 0
- ADDR DW 1
- ERRFLG DB 0
- DS 30 ;STACK
- STACK EQU $
- ;ORG TO PAGE BECAUSE 'INR L' USED TO LOOP THRU IT
- ORG ($+255) AND 0FF00H ;TO PAGE
- BUFF EQU $
- REPT 16
- DB ' '
- ENDM
- BUFFERS EQU $
- MEMSIZE EQU BUFFERS+@NXTB
- END