PROGRAM BINCMP C C ************************************************************************ C * C THIS PROGRAM IS PROVIDED ON AN "AS IS" BASIS ONLY. DIGITAL EQUIPMENT * C COMPUTER USER'S SOCIETY, DIGITAL EQUIPMENT CORPORATION, MONSANTO, AND * C THE AUTHOR DISCLAIM ALL WARRANTIES ON THE PROGRAM, INCLUDING WITHOUT * C LIMITATION, ALL IMPLIED WARRANTIES OF MERCHANTABLITY AND FITNESS. * C * C FULL PERMISSION AND CONSENT IS HEREBY GIVEN TO DECUS AND TO THE DECUS * C SPECIAL INTEREST GROUPS TO REPRODUCE, DISTRIBUTE, AND PUBLISH AND * C PERMIT OTHERS TO REPRODUCE IN WHOLE OR IN PART, IN ANY FORM AND * C WITHOUT RESTRICTION, THIS PROGRAM AND ANY INFORMATION RELATING THERETO * C * C ************************************************************************ C C VERSION: V01.01 C C AUTHOR: RW STAMERJOHN MAPS 12-JAN-78 C C MODIFICATIONS: C C V01.01 RWS 14-JAN-78 PRINT OCTAL NUMBERS WITH LEADING ZEROS. C C THIS PROGRAM COMPARES TWO FILES WORD BY WORD. C C C BUILD INSTRUCTIONS: C C OUTPUT,LISTING=BINCMP C C PAGE 2 - DATA STORAGE DESCRIPTIONS. C C VARIABLE AND ARRAY DEFINITIONS: C C FILE AND STRING ARRAYS. C LOGICAL*1 FNAMEO(40) !OUTPUT FILENAME. LOGICAL*1 FNAME1(40) !INPUT FILENAME #1. LOGICAL*1 FNAME2(40) !INPUT FILENAME #2. LOGICAL*1 CHAR !CHARACTER INTPUT. C C ADDRESS VARIABLES. C INTEGER*4 OFFST1 !FILE #1 STARTING OFFSET. INTEGER*4 OFFST2 !FILE #2 STARTING OFFSET. INTEGER*4 OFFSTA !ADDRESS OFFSET. INTEGER*4 BEGADR !BEGINNING ADDRESS OF COMPARE. INTEGER*4 ENDADR !END ADDRESS OF COMPARE. INTEGER*4 CURADR !CURRENT ADDRESS. C C PRINT VARIABLES. C LOGICAL*1 DFSW !PRINT DIFFERENCE RANGES. LOGICAL*1 VLSW !PRINT DIFFERENT VALUES. LOGICAL*1 STRING(80) !CHARACTER MANIPULATION ARRAY. INTEGER*4 PTR !ADDRESS POINTER. INTEGER*4 ADR !ADDRESS VARIABLE. C C DIFFERENCE VARIABLES. C INTEGER*2 WORD1 !CURRENT WORD FROM FILE #1. INTEGER*2 WORD2 !CURRENT WORD FROM FILE #2. INTEGER*4 TOTDF !TOTAL NUMBER OF DIFFERENCES. INTEGER*4 TOTSC !TOTAL NUMBER OF SECTIONS. INTEGER*4 BEGDF !BEGINNING ADDRESS OF A DIFFERENCE. INTEGER*4 NUMDF !NUMBER OF DIFFERENCES IN SECTION. INTEGER*4 ENDDF !END ADDRESS OF A DIFFERENCE. C C MISC. VARIABLES. C INTEGER*2 CNT !COUNT VARIABLE. INTEGER*2 I !DO INDEX. C C PAGE 3 - GET PARAMETERS FROM USER AND OPEN FOR I/O. C C OUTPUT ANNOUCEMENT MESSAGE. C WRITE (5,1000) C C GET OUTPUT FILE AND OPEN FOR I/O. C 100 CONTINUE WRITE (5,1001) READ (5,1004) CNT,FNAMEO FNAMEO(CNT+1) = 0 OPEN (UNIT=1,NAME=FNAMEO,TYPE='NEW',ACCESS='SEQUENTIAL',ERR=100) C C GET FIRST INPUT FILE AND OPEN FOR I/O. C 110 CONTINUE WRITE (5,1002) READ (5,1004) CNT,FNAME1 FNAME1(CNT+1) = 0 OPEN (UNIT=2,NAME=FNAME1,TYPE='OLD',ACCESS='SEQUENTIAL',ERR=110, 1 READONLY,SHARED,BUFFERCOUNT=-1) C C GET SECOND INPUT FILE AND OPEN FOR I/O. C 120 CONTINUE WRITE (5,1003) READ (5,1004) CNT,FNAME2 FNAME2(CNT+1) = 0 OPEN (UNIT=3,NAME=FNAME2,TYPE='OLD',ACCESS='SEQUENTIAL',ERR=120, 1 READONLY,SHARED,BUFFERCOUNT=-1) C C GET FILE OFFSETS. C 130 CONTINUE WRITE (5,1005) READ (5,1010,ERR=130) OFFST1 131 CONTINUE WRITE (5,1006) READ (5,1010,ERR=131) OFFST2 132 CONTINUE WRITE (5,1007) READ (5,1010,ERR=132) OFFSTA 133 CONTINUE WRITE (5,1008) READ (5,1010,ERR=133) BEGADR IF (BEGADR.LT.OFFSTA) GOTO 133 134 CONTINUE WRITE (5,1009) READ (5,1010,ERR=134) ENDADR IF (ENDADR.LT.BEGADR) GOTO 134 C C PAGE 4 - INITIALIZE THE PROGRAM AND OUTPUT TITLE PAGE. C C GET OUTPUT OPTIONS. C DFSW = .FALSE. VLSW = .FALSE. WRITE (5,2000) READ (5,2002) CHAR IF (CHAR.EQ.'Y') DFSW = .TRUE. WRITE (5,2001) READ (5,2002) CHAR IF (CHAR.EQ.'Y') VLSW = .TRUE. C C INITIALIZE THE GET ROUTINES. C CALL F1INIT (OFFST1,OFFSTA) CALL F2INIT (OFFST2,OFFSTA) C C INITIALIZE DIFFERENCE VARIABLES. C CURADR = BEGADR TOTDF = 0 TOTSC = 0 C C INTIALIZE OUTPUT VARIABLES AND OUTPUT TITLE. C CALL PGINIT WRITE (1,2003) FNAMEO CALL O8CNVT (OFFST1,STRING(1)) WRITE (1,2004) FNAME1,(STRING(I),I=1,8) CALL O8CNVT (OFFST2,STRING(1)) WRITE (1,2005) FNAME2,(STRING(I),I=1,8) CALL O8CNVT (OFFSTA,STRING(1)) CALL O8CNVT (BEGADR,STRING(9)) CALL O8CNVT (ENDADR,STRING(17)) WRITE (1,2006) (STRING(I),I=1,24) LINE = LINE+8 C C TELL TERMINAL STARTING SEARCH. C WRITE (5,2007) C C PAGE 5 - SEARCH FOR DIFFERENCES AND OUTPUT WHEN FOUND. C C SEARCH FOR START OF DIFFERENCE SECTION. C 300 CONTINUE IF (CURADR.GT.ENDADR) GOTO 400 CALL F1WORD (WORD1,CURADR) CALL F2WORD (WORD2,CURADR) CURADR = CURADR+2 IF (WORD1.EQ.WORD2) GOTO 300 C C MARK START OF DIFFERENCE AND COUNT SECTION. C BEGDF = CURADR-2 TOTSC = TOTSC+1 C C SEARCH FOR END OF DIFFERENCE SECTION. C 310 CONTINUE IF (CURADR.GT.ENDADR) GOTO 320 CALL F1WORD (WORD1,CURADR) CALL F2WORD (WORD2,CURADR) CURADR = CURADR+2 IF (WORD1.NE.WORD2) GOTO 310 C C FOUND END OF DIFFERENCES, SET END MARK AND COMPUTE TOTAL NUMBER. C 320 CONTINUE ENDDF = CURADR-4 NUMDF = (ENDDF-BEGDF)/2+1 TOTDF = TOTDF+NUMDF C C IF WANTED, OUTPUT DIFFERENCE SEGMENT MESSAGE. C IF (.NOT.DFSW) GOTO 330 CALL O8CNVT (BEGDF,STRING(1)) CALL O8CNVT (ENDDF,STRING(9)) WRITE (1,3000) NUMDF,(STRING(I),I=1,16) CALL PGCHKR (3) C C IF WANTED, OUTPUT ACTUAL DIFFERENCES. C 330 CONTINUE IF (.NOT.VLSW) GOTO 340 CNT = 0 ADR = BEGDF DO 331 PTR = BEGDF,ENDDF,2 IF (CNT.NE.4) GOTO 332 CALL O8CNVT (ADR,STRING(1)) WRITE (1,3001) (STRING(I),I=1,56) CALL PGCHKR (1) CNT = 0 ADR = PTR 332 CONTINUE CALL F1WORD (WORD1,PTR) CALL O6CNVT (WORD1,STRING(9+CNT*12)) CALL F2WORD (WORD2,PTR) CALL O6CNVT (WORD2,STRING(15+CNT*12)) CNT = CNT+1 331 CONTINUE WRITE (1,3001) (STRING(I),I=1,8+CNT*12) CALL PGCHKR (1) 340 CONTINUE GOTO 300 C C PAGE 6 - CLOSE UP ALL OPERATIONS AND RESTART. C C OUTPUT FINAL SUMMARY. C 400 CONTINUE CALL PGCHKR (-1) WRITE (1,4000) TOTDF,TOTSC WRITE (5,4000) TOTDF,TOTSC C C CLOSE FILES. C CLOSE (UNIT=1) CLOSE (UNIT=2) CLOSE (UNIT=3) C C LOOP TO START OF PROGRAM. C GOTO 100 C C PAGE 7 - FORMAT STATEMENTS. C C FILENAME STATEMENTS. C 1000 FORMAT (/,' BINARY COMPARE - V01.01',/) 1001 FORMAT ('$OUTPUT FILE[A]: ') 1002 FORMAT ('$INPUT FILE #1[A]: ') 1003 FORMAT ('$INPUT FILE #2[A]: ') 1004 FORMAT (Q,40A1) C C OFFSET STATEMENTS. C 1005 FORMAT (/,'$FILE #1 OFFSET[O]: ') 1006 FORMAT ('$FILE #2 OFFSET[O]: ') 1007 FORMAT ('$ADDRESS OFFSET[O]: ') 1008 FORMAT ('$START ADDRESS[O]: ') 1009 FORMAT ('$LAST ADDRESS[O]: ') 1010 FORMAT (O8) C C OUTPUT OPTIONS STATEMENTS. C 2000 FORMAT (/,'$SEGMENT OUTPUT[Y/N]: ') 2001 FORMAT ('$VALUE OUTPUT[Y/N]: ') 2002 FORMAT (A1) C C TITLE PAGE STATEMENTS. C 2003 FORMAT (' OUTPUT FILE: ',40A1) 2004 FORMAT (' INPUT FILE #1: ',40A1,' OFFSET: ',8A1) 2005 FORMAT (' INPUT FILE #2: ',40A1,' OFFSET: ',8A1) 2006 FORMAT (/,' ADDRESS OFFSET: ',8A1,' SEARCH RANGE: ',8A1,'-',8A1,/) C C STARTING SEARCH STATEMENT. C 2007 FORMAT (/,' STARTING COMPARE!!!',/) C C COMPARE OUTPUT STATEMENTS. C 3000 FORMAT (/,' ',I8,'. DIFFERENCES FOUND, ADDRESS RANGE ', 1 8A1,'-',8A1,/) 3001 FORMAT (6X,8A1,6X,4(6A1,'-',6A1,2X)) C C SUMMARY OUTPUT. C 4000 FORMAT (/,' ',I8,'. TOTAL DIFFERENCES FOUND IN ',I5, 1 '. SECTIONS',/) C END C C PAGE 8 - PAGE CONTROL SUBROUTINES. C C THESE SUBROUTINES HANDLE PAGING. TWO ENTRIES ARE AVAILABLE: C C PGINIT - INITIALIZE PAGE ROUTINE. C PGCHKR - CHECK FOR NEW PAGE. C SUBROUTINE PGDMMY C C VARIABLE AND ARRAY DECLARATIONS. C LOGICAL*1 DATEA(9) !DATE STRING. LOGICAL*1 TIMEA(8) !TIME STRING. INTEGER*2 PAGE !PAGE NUMBER. INTEGER*2 LINE !LINE NUMBER. INTEGER*2 LCNT !LINE COUNT TO ACCOUNT FOR. C C PGINIT - PROCESS START OF NEW PAGE. C ENTRY PGINIT C PAGE = 0 CALL DATE (DATEA) CALL TIME (TIMEA) GOTO 100 C C PGCHKR - CHECK IF NEW PAGE NEEDED. C ENTRY PGCHKR (LCNT) C IF (LCNT.LT.0) GOTO 100 LINE = LINE+LCNT IF (LINE.GT.55) GOTO 100 GOTO 200 C C OUTPUT NEW PAGE. C 100 CONTINUE PAGE = PAGE+1 LINE = 1 WRITE (1,1000) DATEA,TIMEA,PAGE C C RETURN TO CALLER. C 200 CONTINUE RETURN 1000 FORMAT ('1BINARY COMPARE V01.01 ',9A1,1X,8A1,T65,'PAGE ',I3,/) END C C PAGE 9 - FILE INPUT ROUTINES. C C THESE SUBROUTINES INPUT FROM THE FILES BEING COMPARED. FOUR ENTRIES ARE C AVAILABLE. C C F1INIT - INTIALIZE FOR I/O FROM FILE #1. C F2INIT - INTIALIZE FOR I/O FROM FILE #2. C F1WORD - GET WORD FROM FILE #1. C F2WORD - GET WORD FROM FILE #2. C SUBROUTINE FXDMMY C C VARIABLE AND ARRAY DECLARATIONS. C INTEGER*4 FOFF !FILE OFFSET. INTEGER*4 FOFFA(2) !FILE OFFSET STORAGE ARRAY. INTEGER*4 AOFF !ADDRESS OFFSET. INTEGER*4 AOFFA(2) !ADDRESS OFFSET STORAGE ARRAY. INTEGER*4 CBLKA(2) !CURRENT DISK BLOCK. INTEGER*4 ADDR !DESIRED ADDRESS. INTEGER*4 DISKA !ADDRESS IN DISK SPACE. INTEGER*4 DISKB !DISK BLOCK NUMBER. INTEGER*4 DISKW !DISK BLOCK WORD. INTEGER*2 FILE !FILE NUMBER. INTEGER*2 WORD !RETURN VARIABLE. INTEGER*2 WORDA(256,2) !INPUT BUFFERS. INTEGER*2 IOSB(2) !I/O STATUS BLOCK. INTEGER*2 PRMS(6) !QIO PARAMETER BLOCK. C C F1INIT - INITIALIZE FILE #1. C ENTRY F1INIT (FOFF,AOFF) C FILE = 1 GOTO 100 C C F2INIT - INITIALIZE FILE #2. C ENTRY F2INIT (FOFF,AOFF) C FILE = 2 C C ENTER COMMON INITIALIZATION CODE. C 100 CONTINUE FOFFA(FILE) = FOFF AOFFA(FILE) = AOFF CBLKA(FILE) = -1 RETURN C C F1WORD - GET WORD FROM FILE #1. C ENTRY F1WORD (WORD,ADDR) C FILE = 1 GOTO 200 C C F2WORD - GET WORD FROM FILE #2. C ENTRY F2WORD (WORD,ADDR) C FILE = 2 C C ENTER COMMON GET WORD CODE. C 200 CONTINUE WORD = 0 C C GET DISK BLOCK AND WORD. C DISKA = ADDR-AOFFA(FILE)+FOFFA(FILE) DISKB = (DISKA/512)+1 DISKW = (DISKA-((DISKB-1)*512))/2+1 C C SEE IF NEW DISK BLOCK MUST BE READ INTO CORE. C IF (DISKB.EQ.CBLKA(FILE)) GOTO 300 CBLKA(FILE) = -1 CALL GETADR (PRMS(1),WORDA(1,FILE)) PRMS(2) = 512 PRMS(3) = 0 PRMS(4) = 0 PRMS(5) = DISKB CALL WTQIO ("10400,FILE+1,1,,IOSB,PRMS,) IF (IOSB(1).NE.1) GOTO 310 CBLKA(FILE) = DISKB C C RETURN WORD TO CALLER. C 300 CONTINUE WORD = WORDA(DISKW,FILE) C C RETURN TO CALLER, ALL DONE. C 310 CONTINUE RETURN END C C PAGE 10 - OCTAL CONVERSION ROUTINES. C C THESE SUBROUTINES CONVERT THE GIVEN VARAIBLE TO ITS ASCII EQUVALENT AND C STORE IN THE GIVEN STRING. LEADING ZEROS ARE USED. TWO ENTRIES ARE AVAILABLE: C C O8CNVT - CONVERT I*4 VARIABLE TO 8 DIGITS. C O6CNVT - CONVERT I*2 VARIABLE TO 6 DIGITS. C SUBROUTINE OXCNVT C C VARAIBLE AND ARRAY DECLARATION. C INTEGER*4 VAL !WORKING VALUE. INTEGER*4 DIGIT !LOW DIGIT. INTEGER*4 VAL8 !O8CNVT CALLING VALUE. INTEGER*2 VAL6 !O6CNVT CALLING VALUE. INTEGER*2 STEP !STEP COUNT. INTEGER*2 I !DO INDEX. BYTE ADDR(8) !OUTPUT ADDRESS. C C O8CNVT - CONVERT I*4 TO 8 DIGITS. C ENTRY O8CNVT (VAL8,ADDR) C VAL = VAL8 STEP = 8 GOTO 100 C C O6CNVT - CONVERT I*2 TO 6 DIGITS. C ENTRY O6CNVT (VAL6,ADDR) C VAL = VAL6 STEP = 6 C C ENTER COMMON CONVERSION CODE. C 100 CONTINUE C C LOOP STEP TIMES, AND CONVERT OFF LOWER OCTAL DIGIT. C DO 110 I = STEP,1,-1 DIGIT = IAND(VAL,7) DIGIT = DIGIT+'0' ADDR(I) = DIGIT VAL = ISHFT(VAL,-3) 110 CONTINUE C C RETURN TO CALLER. C RETURN END