.TITLE VCOMP ;VIRTUAL BLOCK FILE(S) COMPARE. .IDENT /02/ ; ; ; ; DESCRIPTION: ; TO COMPARE TWO FILES THAT ARE SUPPOSED(?) TO BE THE SAME. THE COMPARE ; IS PERFORMED IN BLOCK MODE, SO NO THOUGHT IS GIVEN TO RECORD LAYOUT OF ; THE FILES. THE PROGRAM CAN PERFORM A SINGLE COMPARISON (OF TWO FILES), ; OR COMPARISON OF ALL FILES IN ONE UIC WITH THE EQUIVALENT NAMED FILES ; IN ANOTHER UIC. THE PROGRAM IS INVOKED BY AN OPERATOR COMMAND LINE, AND ; OUPUT OF THE RESULTS IS TO THE OPERATOR'S TERMINAL (BY DEFAULT), OR TO ; THE OPERATOR SPECIFIED DEVICE-FILE. ; ; UNLESS THE OPERATOR SPECIFIES THE EXPLICIT VERSION NUMBER OF FILE 2, OR ; THE /VE SWITCH IS USED, FILE 2 WILL HAVE THE SAME VERSION NUMBER AS FILE ; 1. IF FILE 2 DOES NOT EXIST WITH THAT VERSION NUMBER, THEN THE OPEN ; WILL BE RETRIED FOR THE LATEST VERSION OF THE FILE. ; ; THE PROGRAM MAXIMIZES I/O BY PERFORMING THE READ TO BOTH FILES WITHOUT ; WAITING FOR I/O COMPLETE IN BETWEEN, AND PERFORMING MULTIPLE BUFFERING ; (A TOTAL OF 4 READS). PROGRAM COMMENTS USE "1" AND "2" TO REFER TO THE ; TWO INPUT FILES, AND "A" AND "B" TO REFER TO THE APPROPRIATE PAIR ; OF BLOCK RECORD BUFFERS BEING PROCESSED. ; ; IN ADDITION TO MULTIPLE BUFFERING, IF BOTH FILES ARE CONTIGUOUS, THEN ; "NBLOCK" VB'S WILL BE READ PER DISC READ QIO. ; ; VERSION: 03 ; HISTORY: ; 01 19-SEP-78 D.ALDRIDGE ; 02 27-NOV-78 D.ALDRIDGE ; ADD QIO'S FOR CONTIGUOUS BLOCKS. ; 03 25-SEP-80 Phil Stephensen-Payne ; Add Help Facility & Grand Totals ; ; INVOCATION: VCO>OUTPUT=FILE1,FILE2/MAX:NN/VE ;-OR- ; VCO>FILE1,FILE2 ;WHERE OUTPUT = TI: ; ; PARAMETERS: OUTPUT = FILE TO GET REPORT OF COMPARISON ; FILE1 = A FILE TO BE COMPARED. ; FILE2 = ANOTHER FILE TO BE COMPARED. ; NOTE: FILES TO BE COMPARED MAY BE SPECIFIED AS ; SINGLE FILE NAMES, OR JUST A UIC. ; /MAX = USED TO OVERRIDE THE DEFAULT MAXIMUM NUMBER OF ; DIFFERENCES THAT ARE DETECTED BEFORE THE ; COMPARE IS STOPPED. (DEFAULT CURRENTLY = 50). ; /VE = NORMALLY, FILE 2 WILL HAVE THE SAME VERSION ; NUMBER AS FILE 1. THIS SWITCH WILL OVERRIDE ; THAT FUNCTION, FORCING FILE 2 TO ALWAYS BE ; THE LATEST VERSION. ; .PAGE .SBTTL MACROS ; ; M O D U L E M A C R O S ; .PAGE .SBTTL DECLAR ; ; ; ; M O D U L E E Q U A T E S ; LUNOPR= 1 ;LUNS: GET COMMAND LINE. LUNOUT= 2 ; OUTPUT FILE. LUNIN1= 3 ; INPUT FILE 1. LUNIN2= 4 ; INPUT FILE 2. LUNTI= 5 ; TI: ; EF1A= 1 ;EVENT FLAGS: INPUT FILE 1, BLOCK SET "A". EF2A= 2 ; INPUT FILE 2, BLOCK SET "A". EF1B= 3 ; INPUT FILE 1, BLOCK SET "B". EF2B= 4 ; INPUT FILE 2, BLOCK SET "B". EFTI= 5 ; TI: ; EF1AM= 000001 ;MASKS FOR ABOVE INPUT EF2AM= 000002 ; FILE EVENT FLAGS. EF1BM= 000004 ; EF2BM= 000010 ; ; IOEFS= EF1AM!EF2AM!EF1BM!EF2BM ;MASK OF ALL ABOVE INPUT FILE EVENT FLAG MASKS. ; NBLOCK= 20. ;NO. BLOCKS PER INPUT BUFFER (MAX. BLOCKS IF CONTIGUOUS FILE). BLKSIZ= NBLOCK*512. ;SIZE (BYTES) OF AN INPUT BUFFER. ; MAXDEF= 50. ;DEFAULT NUMBER OF DIFFERENCES BEFORE ; COMPARISON IS STOPPED. ; NB.SVR= 10 ;(REFER "N.STAT" IN FDB'S FILENAME BLOCK). NB.STP= 20 ; NB.SNM= 40 ; ; WILDCD= NB.SVR!NB.STP!NB.SNM ;WILD CARD BITS IN FILENAMEBLOCK. ; CR= 015 ;CARRIAGE CONTROLS. LF= 012 ; CRLF= CR+ ; LFLF= LF+ ; ; FNMSIZ= 35. ;SPACE REQUIRED TO CREATE A FULL ; FILENAME STRING. ; MSKMAX= 000000 ;CSI SWITCH MSKVER= 000001 ; MASKS. MSKHEL= 000002 ; .PAGE ; ; M O D U L E D A T A B A S E ; .MCALL FSRSZ$, FHDOF$, FDBDF$, FDAT$A, FDRC$A, FDBK$A, FDOP$A, NMBLK$ .MCALL OPEN$W, OPNS$R, READ$, WAIT$, PUT$, CLOSE$ .MCALL CSI$, CSI$1, CSI$2, CSI$SW, CSI$SV, CSI$ND .MCALL GCMLB$, GCML$, SPWN$, DIR$, WTSE$S .MCALL QIOW$S, QIO$S, GLUN$S, WTLO$S, RDAF$S, CLEF$S, EXIT$S ; FSRSZ$ 4 ;3 INDIRECT + 1 OUTPUT FILE USING RECORD I/O. FHDOF$ DEF$L ;DEFINE FILE HEADER OFFSETS. ; .PSECT DATA,RW ; ; GCMLB: GCMLB$ 3,VCO,,LUNOPR ;GET COMMAND LINE CONTROL BLOCK (3 INDIRECT). ; CSI$ ;DEFINE CSI CONTROL BLOCK CSIB: .BLKB C.SIZE ; OFFSETS AND SYMBOLS. MAXSW: CSI$SW MAX,MSKMAX,,,,MAXSWT ;DEFINE TABLE FOR CSI$SW HE,MSKHEL ; CSI$SW VER,MSKVER ; ALL SWITCHES. CSI$ND ; MAXSWT: CSI$SV NUMERIC,MAXDIF,2 ;DEFINE SWITCH CSI$ND ; VALUE. HLSPWN: SPWN$ MCR...,,,,,1,,,HELCMD,HELCML HELCMD: .ASCII /HELP VCO/ HELCML=.-HELCMD .EVEN ; MAXDIF: .BLKW 1 ;MAX DIFFERENCES BEFORE ABORTING COMPARE. GOTDIF: .BLKW 1 ;DIFFERENCES FOUND (IS DECREMENTED). ; RECBUF: .BLKB 90. ;RECORD BUFFER. RECBUZ= .-RECBUF ; ; SUIC1: .BLKW 2 ;ADDRESS/SIZE OF UIC SUIC2: .BLKW 2 ; STRINGS FOR INPUT SUICO: .BLKW 2 ; AND OUTPUT FILES. ; BLOK1A: .BLKB BLKSIZ ;BLOCK INPUT BUFFERS FOR BLOK2A: .BLKB BLKSIZ ; BOTH FILES, DUPLICATED BLOK1B: .BLKB BLKSIZ ; (CALLED BLOCK SETS "A" BLOK2B: .BLKB BLKSIZ ; AND "B"). ; OUTDEF: .WORD 2,TI ;DEFAULT OUTPUT .WORD 0,0 ; DEVICE .WORD 0,0 ; SPECIFICATION. TI: .ASCII /TI/ ; ; TOTDIF: .BLKW 1 ; Total Differences Found FCOUNT: .BLKW 1 ;COUNT OF FILES COMPARED. ; BCOUNT: .BLKW 1 ;COUNT OF BLOCKS COMPARED IN A FILE. ; FINIS: .BLKW 1 ;FLAG SET WHEN COMPARES FINISHED. ; LASTBR: .BLKW 1 ;FLAG SET WHEN LAST BLOCK HAS BEEN READ. ; EFBUF: .BLKW 4 ;BUFFER INTO WHICH EVENT FLAGS ARE READ. ; IOST1A: .BLKW 2 ;I/O STATUS BLOCKS FOR EACH IOST2A: .BLKW 2 ; FILE IN BLOCK SET "A". IOST1B: .BLKW 2 ;I/O STATUS BLOCKS FOR EACH IOST2B: .BLKW 2 ; FILE IN BLOCK SET "B". ; ;STATUS FLAGS FOR EACH BLOCK SET: STATA: .WORD -1 ; WORD 1 = STATUS: -1 = READY FOR READ .WORD 0,0 ; 0 = I/O COMPLETE ON BOTH FILES. .WORD EF1A,EF2A ; 1 = ONE READ STILL GOING. STATB: .WORD -1 ; 2 = BOTH READS STILL GOING. .WORD 0,0 ; WORD 2 = VBN LAST READ FROM FILES. .WORD EF1B,EF2B ; WORD 3 = NO.VB'S IN LAST READ QIO. ; WORD 4-5 = EVENT FLAGS FOR FILES 1 AND 2. ; F1END: .BLKW 2 ;END-OF-FILE VBN AND OFFSET F2END: .BLKW 2 ; (F.EFBK+2 AND F.FFBY) ; HEDR: .BYTE -12,0 ;READ FILE .WORD BLOK1A,0 ; HEADER. ; CONTGF: .BLKB 2 ;FLAG FOR EACH FILE (0=NON, 1=CONTIGUOUS). ; RBSIZ: .BLKW 1 ;NUMBER OF BLOCKS TO BE READ IN NEXT QIO. ; LVBN: .BLKW 1 ;LAST VBN IN LAST READ. ; TTYDEV: .WORD 0 ;FLAG SET = 1 IF OUTPUT DEVICE IS A TERMINAL DEVICE. .PAGE OUTFDB: FDBDF$ ;OUTPUT FILE. FDAT$A R.VAR,FD.CR ;NEW FILE, WITH VARIABLE LENGTH RECORDS. FDRC$A ,,100. ;PUT$ MODE. FDOP$A LUNOUT ;LUN. ; IN1FDB: FDBDF$ ;INPUT FILE 1. FDRC$A FD.RWM ;READ$ MODE. FDBK$A ,512. ; FDOP$A LUNIN1,CSIB+C.DSDS,DEFNAM ; IN2FDB: FDBDF$ ;INPUT FILE 2. FDRC$A FD.RWM ;READ$ MODE. FDBK$A ,512. ; FDOP$A LUNIN2,CSIB+C.DSDS,DEFNAM ; DEFNAM: NMBLK$ ,,,SY,0 ;DEFAULT FILE NAME BLOCK. ; WILDN: .ASCII \*.*;*\ ;TO SEARCH WHOLE OF A UIC. WILDNZ= .-WILDN ; .EVEN ; .PAGE BADCML: .BYTE CR,LF ;MESSAGE ISSUED FOR GET COMMAND LINE ERROR. .ASCII \VCO - *FATAL* - GET COMMAND LINE ERROR\ BADCMZ= .-BADCML ; ; SYNERR: .BYTE CR,LF ;IF OPERATOR COMMAND HAS SYNTAX ERROR. .ASCII \VCO - *FATAL* - SYNTAX ERROR\ SYNERZ= .-SYNERR ; ; CNTGER: .BYTE CR,LF,LF ; .ASCII \VCO - *NOTE* - FILE \ CNTG1F: .BLKB FNMSIZ ; .ASCII \IS \ ; .EVEN ; CNTG1C: .ASCII \XXXXCONTIGUOUS, AND\ .BYTE CR,LF ; .ASCII \ FILE \ CNTG2F: .BLKB FNMSIZ ; .ASCII \IS \ ; .EVEN ; CNTG2C: .ASCII \XXXXCONTIGUOUS.\ .BYTE CR,LF ; CNTGEZ= .-CNTGER ; ; IOERR: .BYTE CR,LF ;IF I/O ERROR DETECTED. .ASCII \VCO - *FATAL* - I/O ERROR CODE \ IOERRC: .ASCII \NNNNNN - FILE \ IOERRF: .BLKB FNMSIZ ; .BYTE CR,LF,LF ; IOERRZ= .-IOERR ; ; HEADNG: .BYTE FF ;REPORT HEADING. .ASCII \VCO - VIRTUAL BLOCK FILE COMPARE \ HEADN1= .-HEADNG ; .BLKB 70. ; ; FBIGR: .BYTE CR,LF ; .ASCII \**** FILES COMPARED UNTIL FILE \ FBIGRA: .ASCII \X WAS FOUND TO BE LARGER THAN FILE \ FBIGRB: .ASCII \X\ ; FBIGRZ= .-FBIGR ; ; DIFMSG: .BYTE CR,LF ; .ASCII \** \ ; .EVEN ; DIFMSV: .ASCII \XXXXXX. DIFFERENCES FOUND IN THE \ .EVEN ; DIFMSB: .ASCII \XXXXXX. BLOCKS COMPARED\ DIFMSZ= .-DIFMSG ; ; DF1MSG: .BYTE CR,LF,LF ; .ASCII \** \ ; .EVEN ; DF1MSV: .ASCII \XXXXXX. DIFFERENCES FOUND IN THE \ .EVEN ; DF1MSB: .ASCII \XXXXXX. FILES COMPARED\ DF1MSZ= .-DF1MSG ; ; DIFHDN: .BYTE CR,LF,LF ; .ASCII \ \ ; DIFBLK= .-DIFHDN ; .ASCII \ BLOCK \ ; DIFOFF= .-DIFHDN-3 ; .ASCII \OFFSET \ ; DIFDEC= .-DIFHDN-1 ; .ASCII \DECIMAL \ ; DIFOCT= .-DIFHDN-3 ; .ASCII \ OCTAL \ ; DIFBYT= .-DIFHDN-3 ; .ASCII \ BYTES \ ; DIFASC= .-DIFHDN-3 ; .ASCII \ASCII \ ; DIFR50= .-DIFHDN ; .ASCII \RAD-50\ ; DIFHDZ= .-DIFHDN ; ; .EVEN ; .PAGE .SBTTL MAIN ;MAINLINE CODE OF PROGRAM/TASK. .PSECT CODE,RO ; ; ; ; DESCRIPTION: ; (AS ON FRONT PAGE). ; ; CALLING SEQUENCE: ; ; ; INPUT PARAMETERS: ; ; ; IMPLICIT INPUTS: ; ; ; OUTPUT PARAMETERS: ; ; ; IMPLICIT OUTPUTS: ; ; ; COMPLETION CODES: ; ; MAIN: ; ;INITIALIZATION FOR NEXT OPERATOR COMMAND: CLR FCOUNT ;CLEAR COUNT OF FILES COMPARED. CLR TOTDIF ;Clear Total Number of Differences MOV #MAXDEF,MAXDIF ;DEFAULT MAXIMUM NUMBER OF DIFFERENCES ALLOWED. CLR FINIS ;CLEAR "FINISHED" FLAG. CLR DEFNAM+N.FNAM+0 ;CLEAR DEFAULT CLR DEFNAM+N.FNAM+2 ; FILE CLR DEFNAM+N.FNAM+4 ; NAME CLR DEFNAM+N.FTYP ; BLOCK. ; GCML$ #GCMLB ;READ COMMAND LINE FROM OPERATOR. BCS 20$ ;BRANCH IF ERROR DETECTED. ; TST G.CMLD(R0) ;IGNORE IF NO DATA BLE MAIN ; HAS BEEN ENTERRED. ; CALL PROCES ;PROCESS THAT COMMAND LINE. BR MAIN ;GO BACK FOR ANOTHER. ; ; ; ; 20$: CMPB #GE.EOF,G.ERR(R0) ;GOT AN ERROR! GO EXIT IF BEQ 40$ ; ONLY END OF INPUT. ; MOV #BADCML,R4 ;BAD ERROR. TYPE MESSAGE MOV #BADCMZ,R5 ; TO TELL OPERATOR, AND CALL TELOPR ; GO BACK TO GIVE ANOTHER BR MAIN ; CHANCE. ; 40$: EXIT$S ;TASK EXIT!! RUN COMPLETE. .PAGE .SBTTL PROCES ;INTERNAL SUBR - PROCESS AN OPERATOR REQUEST. ; ; ; DESCRIPTION: ; AN OPERATOR COMMAND LINE HAS BEEN READ, AND THIS SUBROUTINE CONTROLS ; THE PROCESSING OF THAT REQUEST. THE COMMAND IS CHECKED FOR CORRECT ; SYNTAX, AND A NUMBER OF SUBROUTINES ARE CALLED TO OPEN THE FILES AND ; PERFORM THE COMPARISON. ; ; CALLING SEQUENCE: ; CALL PROCES ; ; INPUT PARAMETERS: ; NONE. ; ; IMPLICIT INPUTS: ; NONE. ; ; OUTPUT PARAMETERS: ; NONE. ; ; IMPLICIT OUTPUTS: ; NONE. ; ; COMPLETION CODES: ; ; PROCES: ; CSI$1 #CSIB,GCMLB+G.CMLD+2,GCMLB+G.CMLD ;CHECK SYNTAX. BCC 20$ ;BRANCH IF OK. CALL SYNTER ;SYNTAX ERROR. TYPE MESSAGE BR 60$ ; AND IGNORE REQUEST. ; 20$: CALL OPNOUT ;OPEN OUTPUT FILE. BCS 60$ ;IGNORE REQUEST IF IN ERROR. BIT #MSKHEL,CSIB+C.MKW1 ; Help switch? BNE 40$ ; If NE yes - ignore input ; CALL SETINP ;SET UP FILE DESCRIPTORS FOR BOTH INPUT FILES. BCS 60$ ;IGNORE REQUEST IF TROUBLE. ; ; ; 40$: ;LOOP TO COMPARE ALL FILES. BIT #MSKHEL,CSIB+C.MKW1 ; Help switch? BEQ 45$ ; If EQ no - process normally DIR$ #HLSPWN ; Yes - ask for help WTSE$S #1 ; Wait for it to finish BR 60$ ; Get next line ; 45$: MOV MAXDIF,GOTDIF ;PREPARE TO COUNT DIFFERENCES. CLR LASTBR ;ENSURE "LAST BLOCKS BEEN READ" FLAG IS OFF. CLR BCOUNT ;CLEAR COUNT OF BLOCKS COMPARED. CALL OPNINP ;OPEN NEXT SET OF INPUT FILES. BCC 50$ ;BRANCH IF OK. TST FINIS ;IF END OF ALL BNE 58$ ; COMPARES, RETURN. BR 55$ ;OPEN ERROR, DO NEXT FILE. 50$: CALL ATTACH ;ATTACH OUTPUT DEVICE IF TERMINAL. CALL PRINTF ;PRINT FILENAMES. CALL CONTIG ;SEE IF FILES ARE CONTIGUOUS. CALL COMPAR ;PERFORM COMPARE. CALL DETACH ;DETACH OUTPUT DEVICE. CALL PRINTD ;PRINT NUMBER OF DIFFERENCES. 55$: CALL CLOSIN ;CLOSE BOTH INPUT FILES. INC FCOUNT ;INCREMENT NUMBER OF COMPARES PERFORMED. BIT #WILDCD,IN1FDB+F.FNB+N.STAT ;IF ANOTHER POSSIBLE FILE (WILD BNE 45$ ; FILENAME), GO BACK AND TRY. ; 58$: CMP FCOUNT,#1 ; Only one file? BEQ 60$ ; If EQ yes - omit Grand Totals MOV TOTDIF,R1 ; Get the total differences ; CLR DF1MSV ;INITIALIZE AREA CLR DF1MSV+2 ; TO GET ASCII CLR DF1MSV+4 ; COUNT. ; MOV #DF1MSV,R0 ;CONVERT NUMBER OF CLR R2 ; DIFFERENCES TO CALL $CBDMG ; ASCII. ; ; CLR DF1MSB ;INITIALIZE AREA CLR DF1MSB+2 ; TO GET ASCII CLR DF1MSB+4 ; BLOCKS. ; MOV #DF1MSB,R0 ;CONVERT NUMBER OF MOV FCOUNT,R1 ; FILES COMPARED CLR R2 ; TO ASCII. CALL $CBDMG ; ; MOV #DF1MSG,R4 ;PRINT MOV #DF1MSZ,R5 ; CALL REPORT ; ; ; ; 60$: CLOSE$ #OUTFDB ;ENSURE OUTPUT FILE IS CLOSED. ; RETURN ;(TO "MAIN") .PAGE .SBTTL OPNOUT ;INTERNAL SUBR - OPEN OUTPUT FILE ; ; ; DESCRIPTION: ; FROM THE OPERATOR'S COMMAND LINE, EXTRACT THE OUTPUT FILENAME STRING, ; OR, IF NOT SPECIFIED BY OPERATOR, USE DEFAULT DEVICE STRING, AND OPEN ; THE OUTPUT FILE. IF ANY ERRORS ARE DETECTED, TYPE A MESSAGE TO THE ; OPERATOR. ; ; TEST IF THE OUTPUT DEVICE IS A TERMINAL DEVICE, SO IT CAN BE ATTACHED ; LATER ON. ; ; CALLING SEQUENCE: ; CALL OPNOUT ; ; INPUT PARAMETERS: ; NONE. ; ; IMPLICIT INPUTS: ; CSIB ;(OPERATOR COMMAND LINE). ; ; OUTPUT PARAMETERS: ; NONE. ; ; IMPLICIT OUTPUTS: ; NONE. ; ; COMPLETION CODES: ; "C" CONDITION CODE = 0 IF OPEN OK, OR, ; = 1 IF AN ERROR DETECTED. ; ; OPNOUT: ; MOV #OUTDEF,R1 ;GET DEFAULT OUTPUT DEVICE STRING. MOVB #CS.OUT,CSIB+C.TYPR ;(TO GET SPECS FROM LEFT OF "=" SIGN). ; BITB #CS.EQU,CSIB+C.STAT ;BRANCH IF NO OUTPUT FILE BEQ 40$ ; WAS SPECIFIED BY OPERATOR. ; CSI$2 #CSIB,,#MAXSW ;EXTRACT OPERATORS SPECIFICATION. BCC 20$ ;BRANCH IF OK. CALL SYNTER ;SYNTAX ERROR, TYPE MESSAGE BR 60$ ; AND GO RETURN. ; 20$: MOV #CSIB+C.DSDS,R1 ;ADDRESS OF OPERATORS SPECIFICATION. MOVB #CS.INP,C.TYPR(R0) ;RESET CSI BLOCK TO GET INPUT FILES. ; 40$: CLR SUICO ;DEFAULT TO NO UIC STRING GIVEN. BITB #CS.DIF,C.STAT(R0) ;IF GIVEN, SAVE BEQ 50$ ; ADDRESS AND MOV C.DIRD(R0),SUICO ; SIZE OF MOV C.DIRD+2(R0),SUICO+2; UIC STRING. ; 50$: OPEN$W #OUTFDB,,R1 ;OPEN THE OUTPUT FILE. BCS 55$ ;BRANCH IF IT FAILED. ; CLR TTYDEV ;DEFAULT TO NON-TERMINAL DEVICE. GLUN$S #LUNOUT,#RECBUF ;GET LUN INFO FOR OUTPUT DEVICE. BIT #FD.TTY,RECBUF+4 ;BRANCH IF NOT A BEQ 53$ ; TERMINAL DEVICE. INC TTYDEV ;IT IS, SET FLAG. 53$: CLC ;RETURN. BR 80$ ; ; 55$: CALL IOEROR ;OPEN ERROR, TYPE MESSAGE. ; 60$: SEC ;SET ERROR FLAG. ; 80$: RETURN ;(TO "PROCES") .PAGE .SBTTL SETINP ;INTERNAL SUBR - SET UP INPUT FILE DESCRIPTORS ; ; ; DESCRIPTION: ; TO SET UP THE INPUT FILES, READY TO BE OPENED, FROM THE COMMAND LINE ; READ FROM THE OPERATOR. IF A UIC STRING WAS SPECIFIED, ITS ADDRESS- ; SIZE IS SAVED. IF NO FILE NAME WAS GIVEN, THEN "*.*;*" IS USED (FOR A ; COMARISON OF ALL FILES IN THAT UIC). THE FIRST INPUT FILE IS PARSED ; READY FOR OPENING. THE SECOND FILE IS EITHER SET UP IN THE DEFAULT ; FILE NAME BLOCK, OR IF WHOLE UIC COMPARE, IS LEFT FOR SUBOUTINE "OPNINP" ; TO USE SAME NAME AS FILE 1. ; ; CALLING SEQUENCE: ; CALL SETINP ; ; INPUT PARAMETERS: ; NONE. ; ; IMPLICIT INPUTS: ; NONE. ; ; OUTPUT PARAMETERS: ; NONE. ; ; IMPLICIT OUTPUTS: ; NONE. ; ; COMPLETION CODES: ; "C" CONDITION CODE = 0 IF OK, OR, ; = 1 IF AN ERROR DETECTED. ; ; SETINP: ; CSI$2 #CSIB,,#MAXSW ;EXTRACT SPECIFICATION FOR FIRST FILE. BCS 40$ ;BRANCH IF SYNTAX ERROR. BIT #MSKHEL,CSIB+C.MKW1 ; Help switch? BNE 60$ ; If NE yes - ignore input ; CLR SUIC1 ;DEFAULT TO NO UIC STRING. BITB #CS.DIF,C.STAT(R0) ;BRANCH IF NO BEQ 10$ ; UIC GIVEN. MOV C.DIRD(R0),SUIC1 ;SAVE ADDRESS/LENGTH MOV C.DIRD+2(R0),SUIC1+2 ; OF ASCII UIC. 10$: BITB #CS.NMF,C.STAT(R0) ;WAS A FILENAME GIVEN?? BNE 20$ ;BRANCH IF YES. MOV #WILDN,C.FILD+2(R0) ;NO, USE WILDCARD MOV #WILDNZ,C.FILD(R0) ; NAME (*.*;*). ; 20$: MOV #IN1FDB,R0 ;GET INPUT FILE 1 FDB ADDRESS. MOV #IN1FDB+F.FNB,R1 ;FILENAME BLOCK IN FDB. MOV F.DSPT(R0),R2 ;DATASET DESCRIPTOR. MOV F.DFNB(R0),R3 ;DEFAULT FILENAME BLOCK. ; CALL .PARSE ;PREPARE TO OPEN INPUT FILE. ; ; ; CSI$2 #CSIB,,#MAXSW ;EXTRACT SPECIFICATION FOR SECOND FILE. BCS 40$ ;BRANCH IF SYNTAX ERROR. CLR SUIC2 ;DEFAULT TO NO UIC GIVEN. BITB #CS.DIF,C.STAT(R0) ;BRANCH IF NO BEQ 30$ ; UIC GIVEN. MOV C.DIRD(R0),SUIC2 ;SAVE ADDRESS/LENGTH MOV C.DIRD+2(R0),SUIC2+2 ; OF ASCII UIC. 30$: CLC ;SET FINAL COMPLETION CODE. BR 60$ ;RETURN. ; 40$: CALL SYNTER ;SYNTAX ERROR. TYPE MESSAGE. SEC ;SET ERROR CODE. ; 60$: RETURN ;(TO "PROCES") .PAGE .SBTTL OPNINP ;INTERNAL SUBR - OPEN NEXT PAIR OF INPUT FILES ; ; ; DESCRIPTION: ; TO OPEN, IF POSSIBLE, THE NEXT PAIR OF INPUT FILES THAT ARE TO BE ; COMPARED. THE FIRST FILE IS OPENED (OR IF NO MORE WILDCARD, JUST RETURN). ; THEN THE SECOND INPUT FILE IS OPENED FROM EITHER THE NAME HELD IN THE ; DEFAULT FILENAME BLOCK (IF OPERATOR HAS ASKED FOR JUST ONE FILE COMPARE) ; OR FROM NAME OF FIRST OPENED INPUT FILE (IF ALL FILES IN UICS BEING ; COMPARED). ; ; UNLESS THE OPERATOR SPECIFIED AN EXPLICIT VERSION NUMBER, OR USED THE ; /VE SWITCH, AN ATTEMPT WILL BE MADE TO OPEN FILE 2 WITH THE SAME VERSION ; NUMBER AS FILE 1. IF THIS ATTEMPT FAILS, ONE MORE OPEN WILL BE ATTEMPTED ; WITH VERSION NUMBER "0" (IE: THE LATEST VERSION). ; ; CALLING SEQUENCE: ; CALL OPNINP ; ; INPUT PARAMETERS: ; NONE. ; ; IMPLICIT INPUTS: ; NONE. ; ; OUTPUT PARAMETERS: ; NONE. ; ; IMPLICIT OUTPUTS: ; NONE. ; ; COMPLETION CODES: ; "C" CONDITION CODE = 0 IF OPEN OK, OR, ; = 1 IF AN ERROR DETECTED, OR NO MORE WILDCARD ; FILES. ; ; OPNINP: ; MOV #IN1FDB,R0 ;FDB FOR FIRST INPUT FILE. MOV #IN1FDB+F.FNB,R1 ;FILENAME BLOCK. CALL .FIND ;FIND THE FILE. BCS 20$ ;BRANCH IF ERROR. OPNS$R ;OPEN THE FILE. BCC 60$ ;BRANCH IF ALL'S WELL. ; 20$: CMPB #IE.NSF,F.ERR(R0) ;BRANCH IF NOT "NO BNE 40$ ; SUCH FILE" ERROR. TST FCOUNT ;WAS "NSF". BRANCH IF IT BEQ 40$ ; WAS THE FIRST FILE. INC FINIS ;NOT REALLY AN ERROR, HAVE BR 100$ ; JUST FINISHED UIC. 40$: CALL IOEROR ;BAD ERROR. TYPE MESSAGE BR 100$ ; AND RETURN. ; 60$: MOV F.EFBK+2(R0),F1END ;SAVE END OF FILE VBN MOV F.FFBY(R0),F1END+2 ;SAVE OFFSET. BGT 70$ ;BRANCH IF WITHIN THAT BLOCK. DEC F1END ;IS END OF LAST MOV #512.,F1END+2 ; BLOCK!! ; ; ; ; 70$: MOV #IN2FDB,R0 ;FDB FOR SECOND INPUT FILE. BIT #WILDCD,IN1FDB+F.FNB+N.STAT ;IS THIS MULTIPLE COMPARES?? BEQ 80$ ;BRANCH IF NOT. CLR CSIB+C.FILD ;YES, FORCE OPEN TO USE NAME CLR CSIB+C.FILD+2 ; AS INPUT FILE 1. MOV IN1FDB+F.FNB+N.FNAM+0,DEFNAM+N.FNAM MOV IN1FDB+F.FNB+N.FNAM+2,DEFNAM+N.FNAM+2 MOV IN1FDB+F.FNB+N.FNAM+4,DEFNAM+N.FNAM+4 MOV IN1FDB+F.FNB+N.FTYP,DEFNAM+N.FTYP ; 80$: MOV #IN2FDB+F.FNB,R1 ;PARSE THE MOV F.DSPT(R0),R2 ; SECOND MOV F.DFNB(R0),R3 ; FILE CALL .PARSE ; NAME. ; BIT #MSKVER,CSIB+C.MKW1 ;WAS /VERSION SWITCH SET?? BNE 85$ ;BRANCH IF YES. ; TST N.FVER(R1) ;DID OPERATOR SPECIFY A VERSION NUMBER?? BNE 90$ ;BRANCH IF YES. ; MOV IN1FDB+F.FNB+N.FVER,N.FVER(R1) ;USE SAME VERSION AS FILE 1. CALL .FIND ;FIND THE FILE. BCC 95$ ;BRANCH IF IT WAS FOUND. ; 85$: CLR N.FVER(R1) ;DEFAULT TO LATEST VERSION. 90$: CALL .FIND ;FIND THE FILE. BCS 98$ ;BRANCH IF NO FILE. ; 95$: OPNS$R ;OPEN INPUT FILE 2. BCS 98$ ;BRANCH IF ERROR. MOV F.EFBK+2(R0),F2END ;SAVE END OF FILE VBN MOV F.FFBY(R0),F2END+2 ; AND OFFSET. BGT 120$ ;BRANCH IF WITHIN THAT BLOCK. DEC F2END ;IS END OF LAST MOV #512.,F2END+2 ; BLOCK!! BR 120$ ; ; 98$: CALL IOEROR ;BAD ERROR. TYPE MESSAGE. ; 100$: CALL CLOSIN ;ENSURE BOTH INPUT FILES ARE CLOSED. SEC ;SET COMPLETION CODE. ; 120$: RETURN ;(TO "PROCES") .PAGE .SBTTL ATTACH/DETACH ;INTERNAL SUBR - ATTACH/DETACH OUTPUT DEVICE. ; ; ; DESCRIPTION: ; ATTACH/DETACH OUTPUT DEVICE IF A TERMINAL DEVICE. ; ; CALLING SEQUENCE: ; CALL ATTACH ; CALL DETACH ; ; INPUT PARAMETERS: ; ; IMPLICIT INPUTS: ; ; OUTPUT PARAMETERS: ; ; IMPLICIT OUTPUTS: ; ; COMPLETION CODES: ; ; ATTACH: ; MOV #IO.ATT,R0 ;GO DO ATTACH. BR ATTCOM ; ; DETACH: ; MOV #IO.DET,R0 ;GO DO DETACH. ; ; ; ; ATTCOM: TST TTYDEV ;IGNORE IF NOT A BEQ 20$ ; TERMINAL DEVICE. ; QIOW$S R0,#LUNOUT ;PERFORM ATTACH/DETACH. ; 20$: RETURN ; .PAGE .SBTTL PRINTF ;INTERNAL SUBR - PRINT NAME OF FILES TO BE COMPARED. ; ; ; DESCRIPTION: ; THIS SUBROUTINE WRITES TO THE REPORT FILE, THE NAME OF BOTH INPUT ; FILES TO BE COMPARED. ; ; CALLING SEQUENCE: ; CALL PRINTF ; ; INPUT PARAMETERS: ; NONE. ; ; IMPLICIT INPUTS: ; NONE. ; ; OUTPUT PARAMETERS: ; NONE. ; ; IMPLICIT OUTPUTS: ; NONE. ; ; COMPLETION CODES: ; NONE. ; ; PRINTF: ; TST FCOUNT ;BRANCH IF NOT BNE 40$ ; FIRST COMPARE. ; MOV #HEADNG+HEADN1,R0 ;INITIALIZE MOV #70.,R1 ; MAIN 10$: MOVB #' ,(R0)+ ; HEADING. SOB R1,10$ ; ; MOV CSIB+C.CMLD+2,R0 ;ADDRESS AND SIZE OF MOV CSIB+C.CMLD,R1 ; COMMAND LINE. MOV #HEADNG+HEADN1,R2 ;PUT COMMAND 20$: MOVB (R0)+,(R2)+ ; LINE INTO SOB R1,20$ ; HEADING. MOV #HEADNG,R4 ;GET ADDRESS MOV #HEADN1,R5 ; AND SIZE ADD CSIB+C.CMLD,R5 ; OF HEADING. CALL REPORT ;PRINT MAIN HEADING. ; 40$: CALL BLANKR ;BLANK OUT REPORT BUFFER. MOV #RECBUF,R5 ;ADDRESS OF BUFFER. MOV #CRLF,(R5)+ ;PUT IN CARRIAGE MOV #LFLF,(R5)+ ; CONTROL. MOV #"FI,(R5)+ ;PUT MOV #"LE,(R5)+ ; IN MOV #"S=,(R5)+ ; "FILES=" INC R5 ;LEAVE A SPACE. MOV #IN1FDB,R0 ;CONVERT FIRST FILE CALL CFNAME ; NAME TO ADD #FNMSIZ,R5 ; ASCII. 60$: CMPB #' ,-(R5) ;GET RID OF BEQ 60$ ; TRAILING INC R5 ; BLANKS. MOVB #CR,(R5)+ ;START A NEW MOVB #LF,(R5)+ ; LINE. ADD #7,R5 ;ALLOW SPACES. MOV #IN2FDB,R0 ;CONVERT IN CALL CFNAME ; SECOND ADD #FNMSIZ,R5 ; FILENAME. 80$: CMPB #' ,-(R5) ;GET RID OF BEQ 80$ ; TRAILING INC R5 ; BLANKS. ; MOV #RECBUF,R4 ;PRINT NAMES OF SUB #RECBUF,R5 ; FILES TO BE CALL REPORT ; COMPARED. ; RETURN ;(TO "PROCES") .PAGE .SBTTL CONTIG ;INTERNAL SUBR - TEST IF FILES ARE CONTIGUOUS. ; ; ; DESCRIPTION: ; READ THE FILE HEADER OF BOTH INPUT FILES, AND DETERMINE IF THEY ARE ; BOTH CONTIGUOUS. IF ONE IS, AND THE OTHER IS NOT, A NON-FATAL WARNING ; MESSAGE IS TYPED. ; ; CALLING SEQUENCE: ; CALL CONTIG ; ; INPUT PARAMETERS: ; ; IMPLICIT INPUTS: ; ; OUTPUT PARAMETERS: ; ; IMPLICIT OUTPUTS: ; ; COMPLETION CODES: ; ; CONTIG: ; CLRB CONTGF ;FILE 1. DEFAULT MOV #"NO,CNTG1C ; TO NON- MOV #"N-,CNTG1C+2 ; CONTIGUOUS. ; ;READ FILE HEADER. QIOW$S #IO.RAT,#LUNIN1,#EF1A,,,,<#IN1FDB+F.FNB+N.FID,#HEDR> BITB #UC.CON,BLOK1A+H.UCHA ;BRANCH IF FILE IS BEQ 20$ ; NON-CONTIGUOUS. ; INCB CONTGF ;FILE IS CLR CNTG1C ; CONTIGUOUS. CLR CNTG1C+2 ; ; ; ; 20$: CLRB CONTGF+1 ;FILE 2. DEFAULT MOV #"NO,CNTG2C ; TO NON- MOV #"N-,CNTG2C+2 ; CONTIGUOUS. ; ;READ FILE HEADER. QIOW$S #IO.RAT,#LUNIN2,#EF2A,,,,<#IN2FDB+F.FNB+N.FID,#HEDR> BITB #UC.CON,BLOK1A+H.UCHA ;BRANCH IF FILE IS BEQ 40$ ; NON-CONTIGUOUS. ; INCB CONTGF+1 ;FILE IS CLR CNTG2C ; CONTIGUOUS. CLR CNTG2C+2 ; ; ; ; 40$: CMPB CONTGF,CONTGF+1 ;BRANCH IF BOTH FILES BEQ 60$ ; ARE THE SAME. ; CLR CONTGF ;DIFFERENT. PROCESS AS NON-CONTIGUOUS. ; MOV #IN1FDB,R0 ;PUT NAME OF FILE MOV #CNTG1F,R5 ; 1 INTO ERROR CALL CFNAME ; MESSAGE. MOV #IN2FDB,R0 ;PUT NAME OF FILE MOV #CNTG2F,R5 ; 2 INTO ERROR CALL CFNAME ; MESSAGE. ; MOV #CNTGER,R4 ;TYPE WARNING MESSAGE MOV #CNTGEZ,R5 ; THAT FILES ARE CALL TELOPR ; NOT SAME STATE. ; ; 60$: RETURN ; .PAGE .SBTTL COMPAR ;INTERNAL SUBR - PERFORM FILE COMPARE. ; ; ; DESCRIPTION: ; BOTH FILES ARE READ USING MULTIPLE BUFFERING BLOCKS SET "A" AND "B". ; WHEN I/O COMPLETE IS DETECTED FOR A EITHER BLOCK SET, THE BLOCK RECORD ; BUFFERS ARE COMPARED, WITH DIFFERENCES BEING REPORTED. ; ; THE COMPARE WILL STOP WHEN EITHER FILE HAS BEEN COMPLETELY READ, AND ; COMPARED. ; ; CALLING SEQUENCE: ; CALL COMPAR ; ; INPUT PARAMETERS: ; NONE. ; ; IMPLICIT INPUTS: ; NONE. ; ; OUTPUT PARAMETERS: ; NONE. ; ; IMPLICIT OUTPUTS: ; NONE. ; ; COMPLETION CODES: ; ; COMPAR: ; ;BLOCK SET "A". TST LASTBR ;HAS LAST BLOCK BEEN READ YET?? BEQ 10$ ;BRANCH IF NOT. TST STATA ;YES. HAVE WE FINISHED WITH BLOCK SET "A"?? BLT 15$ ;BRANCH IF YES, CONTINUE IF NOT. 10$: CALL SETRA ;SETUP REGISTERS FOR BLOCK SET "A" TST (R5) ;WHAT IS STATUS OF BLOCK SET "A"?? BEQ 60$ ;BRANCH IF RECORDS READ READY FOR A COMPARE. BLT 40$ ;BRANCH IF READY FOR A NEW READ TO BE STARTED. ; ;BLOCK SET "B". 15$: TST LASTBR ;HAS LAST BLOCK BEEN READ YET?? BEQ 18$ ;BRANCH IF NOT. TST STATB ;YES. HAVE WE FINISHED WITH BLOCK SET "B"?? BPL 18$ ;NO, GO DECIDE ON IT! TST STATA ;FINISHED WITH BLOCK SET 2, IF BLOCK SET BLT 160$ ; 1 ALSO FINISHED, GO TO JOB COMPLETE. BR 20$ ;HO-HUM, GO WAIT FOR I/O COMPLETE ON SET 1. 18$: CALL SETRB ;SETUP REGISTERS FOR BLOCK SET "B" TST (R5) ;WHAT IS STATUS OF BLOCK SET "B"?? BEQ 60$ ;BRANCH IF RECORDS READ READY FOR A COMPARE. BLT 40$ ;BRANCH IF READY FOR A NEW READ TO BE STARTED. ; 20$: WTLO$S 0,#IOEFS ;WAIT FOR A READ TO COMPLETE. CALL IOCOMP ;PROCESS THAT I/O COMPLETE. CLR LASTBR ;CLEAR LAST BLOCK READ FLAG. BR COMPAR ;GO BACK TO DECISION MAKER. ; ; ; ; 40$: CALL READIN ;START NEW READ ON BOTH FILES FOR BLOCK SET. BR COMPAR ;GO BACK AND MAKE NEXT DECISION. ; ; ; 60$: ;READY TO DO A COMPARISON OF RECORDS IN A BLOCK SET. DEC (R5) ;ADJUST STATUS TO GET NEW READS PERFORMED. SUB 4(R5),R2 ;ADJUST VBN BACK TO FIRST INC R2 ; VBN NOW IN BUFFER. ; 70$: INC BCOUNT ;ADJUST COUNT OF BLOCKS COMPARED. CLR R3 ;PREPARE TO GENERATE OFFSET. ; MOV #512.,R4 ;SET MAXIMUM BYTES IN A BLOCK. CMP R2,F1END ;BRANCH IF THAT WAS NOT LAST BLO 80$ ; BLOCK IN FILE 1. MOV F1END+2,R4 ;WAS LAST, RESET BLOCK SIZE. 80$: CMP R2,F2END ;BRANCH IF THAT WAS NOT LAST BLO 100$ ; BLOCK IN FILE 2. CMP F2END+2,R4 ;IF NEW MINIMUM BGE 100$ ; BLOCK SIZE, MOV F2END+2,R4 ; RESET IT. ; 100$: SUB #2,R4 ;CONVERT BYTES TO NUMBER ASR R4 ; OF WORDS TO BE INC R4 ; COMPARED. BLE COMPAR ;BRANCH IF NOTHING TO BE COMPARED. ; 120$: CMP (R0)+,(R1)+ ;BRANCH IF WORDS BEQ 140$ ; COMPARE OK. TST GOTDIF ;BRANCH IF MAXIMUM DIFFERENCES BGT 130$ ; HAVE NOT BEEN FOUND. MOV #177777,IN1FDB+F.VBN+2 ;MAX DIFFERENCES FOUND, BR COMPAR ; STOP SEARCH. 130$: CALL BADCMP ;GOT A BAD COMPARE, REPORT IT. DEC GOTDIF ;ADJUST NUMBER OF DIFFERENCES. 140$: TST (R3)+ ;ADJUST OFFSET. SOB R4,120$ ;COMPARE WHOLE BLOCK. ; DEC 4(R5) ;ADJUST NUMBER OF VB'S HELD IN BUFFER. BLE COMPAR ;GO BACK IF NO MORE DATA. ; INC R2 ;ANOTHER VB HELD IN BUFFER, GO BR 70$ ; BACK AND COMPARE IT. ; ; ; ; 160$: MOVB #'1,FBIGRA ;DEFAULT TO FILE 1 BEING MOVB #'2,FBIGRB ; BIGGER THAN FILE 2. CMP F1END,F2END ;COMPARE VBN'S IN BOTH FILES. BHI 200$ ;BRANCH IF BLO 180$ ; UNEQUAL. CMP F1END+2,F2END+2 ;COMPARE SIZE OF LAST BLOCK. BEQ 220$ ;BRANCH IF EQUAL. BHI 200$ ;BRANCH IF FILE 1 LARGER. 180$: MOVB #'2,FBIGRA ;FILE 2 IS MOVB #'1,FBIGRB ; LARGER. ; 200$: MOV #FBIGR,R4 ;PRINT MESSAGE THAT FILES MOV #FBIGRZ,R5 ; ARE UNEQUAL SIZES. CALL REPORT ; ; 220$: RETURN ;(TO "PROCES") .PAGE .SBTTL IOCOMP ;INTERNAL SUBR - PROCESS AN I/O READ COMPLETE. ; ; ; DESCRIPTION: ; A READ HAS NOW BEEN COMPLETED, BUT WHERE?? WELL, BY LONG AND LABORIOUS ; PROGRAMMING, THE APPROPRIATE EVENT FLAG IS FOUND AND CLEARED. THE ; BLOCK SET STATUS IS UPDATED. IF A READ ERROR WAS DETECTED, AN ERROR ; MESSAGE IS ISSUED AND THE COMPARE STOPPED BY SETTING THE CURRENT ; VBN IN THE FDB TO ITS MAXIMUM VALUE (DIRTY, BUT IT WORKS!). ; ; CALLING SEQUENCE: ; CALL IOCOMP ; ; INPUT PARAMETERS: ; NONE. ; ; IMPLICIT INPUTS: ; NONE. ; ; OUTPUT PARAMETERS: ; NONE. ; ; IMPLICIT OUTPUTS: ; NONE. ; ; COMPLETION CODES: ; "C" CONDITION CODE = 0 IF READ OK, OR, ; = 1 IF AN ERROR DETECTED. ; ; IOCOMP: ; RDAF$S #EFBUF ;READ ALL EVENT FLAGS. ; CALL SETRA ;SET UP REGISTERS FOR BLOCK SET "A". MOV #IN1FDB,R0 ;GET FDB ADDRESS FOR FILE 1. BIT #EF1AM,EFBUF ;BRANCH IF FILE 1 READ BEQ 20$ ; IS NOT COMPLETE. CLEF$S #EF1A ;FILE 1 READ COMPLETE, MOV R3,R1 ; GET #IOST, AND BR 80$ ; GO ADJUST STATUS. 20$: MOV #IN2FDB,R0 ;GET FDB ADDRESS FOR FILE 2. BIT #EF2AM,EFBUF ;BRANCH IF FILE 2 READ BEQ 40$ ; IS NOT COMPLETE. CLEF$S #EF2A ;FILE 2 READ COMPLETE, MOV R4,R1 ; GET #IOST, AND BR 80$ ; GO ADJUST STATUS. ; 40$: CALL SETRB ;SET UP REGISTERS FOR BLOCK SET "B". MOV #IN1FDB,R0 ;GET FDB ADDRESS FOR FILE 1. BIT #EF1BM,EFBUF ;BRANCH IF FILE 1 READ BEQ 60$ ; IS NOT COMPLETE. CLEF$S #EF1B ;FILE 1 READ COMPLETE, MOV R3,R1 ; GET #IOST, AND BR 80$ ; GO ADJUST STATUS. 60$: MOV #IN2FDB,R0 ;GET FDB ADDRESS FOR FILE 2. BIT #EF2BM,EFBUF ;BRANCH IF FILE 2 READ BEQ 120$ ; IS NOT COMPLETE. CLEF$S #EF2B ;FILE 2 READ COMPLETE, MOV R4,R1 ; GET #IOST, AND ; 80$: MOVB (R1),F.ERR(R0) ;GET COMPLETION CODE. BGE 100$ ;BRANCH IF OK. CALL IOEROR ;I/O ERROR. TYPE MESSAGE, MOV #177777,F.VBN+2(R0); STOP COMPARE, SET SEC ; COMPLETION CODE, BR 120$ ; RETURN. ; 100$: DEC (R5) ;ADJUST STATUS. ; 120$: RETURN ; .PAGE .SBTTL SETRA ;INTERNAL SUBR - SETUP REGISTERS FOR BLOCK SET "A". .SBTTL SETRB ;INTERNAL SUBR - SETUP REGISTERS FOR BLOCK SET "B". ; ; ; DESCRIPTION: ; SET UP REGISTERS FOR EITHER BLOCK SET "A" AR "B". ; ; CALLING SEQUENCE: ; CALL SETRA (OR SETRB) ; ; INPUT PARAMETERS: ; NONE. ; ; IMPLICIT INPUTS: ; NONE. ; ; OUTPUT PARAMETERS: ; R0 = ADDRESS OF RECORD BLOCK FOR FILE 1. ; R1 = ADDRESS OF RECORD BLOCK FOR FILE 2. ; R2 = LAST VBN READ INTO BLOCKS. ; R3 = ADDRESS OF IOST FOR FILE 1. ; R4 = ADDRESS OF IOST FOR FILE 2. ; R5 = ADDRESS OF STATUS BLOCK. ; ; IMPLICIT OUTPUTS: ; NONE. ; ; COMPLETION CODES: ; ; SETRA: ; MOV #BLOK1A,R0 ;BLOCK SET "A". MOV #BLOK2A,R1 ; MOV #IOST1A,R3 ; MOV #IOST2A,R4 ; MOV #STATA,R5 ; MOV 2(R5),R2 ; RETURN ; ; ; ; SETRB: ; MOV #BLOK1B,R0 ;BLOCK SET "A". MOV #BLOK2B,R1 ; MOV #IOST1B,R3 ; MOV #IOST2B,R4 ; MOV #STATB,R5 ; MOV 2(R5),R2 ; ; RETURN ; .PAGE .SBTTL READIN ;INTERNAL SUBR - READ BLOCK FROM INPUT FILE. ; ; ; DESCRIPTION: ; TO READ FOR EITHER BLOCK SET, THE NEXT BLOCK FROM BOTH FILES. I/O ; COMPLETE IS NOT WAITED FOR. IF THE FILE HAS BEEN COMPLETELY READ, ; THEN, OBVIOUSLY, NO READ WILL TAKE PLACE. ; ; CALLING SEQUENCE: ; CALL READIN ; ; INPUT PARAMETERS: ; R0-R5 AS DEFINED IN INTERNAL SUBROUTINE "SETRA" (PREVIOUS PAGE). ; ; IMPLICIT INPUTS: ; NONE. ; ; OUTPUT PARAMETERS: ; ; IMPLICIT OUTPUTS: ; NONE. ; ; COMPLETION CODES: ; "C" CONDITION CODE = 0 IF READ OK, OR, ; = 1 IF ALL BLOCKS HAVE BEEN READ, AND COMPARED. ; ; READIN: ; CMP IN1FDB+F.VBN+2,F1END ;CHECK IF EITHER BHI 20$ ; FILE HAS BEEN CMP IN2FDB+F.VBN+2,F2END ; COMPLETELY BLOS 40$ ; READ. ; 20$: ;A FILE HAS BEEN COMPLETELY READ. INC LASTBR ;SET FLAG THAT LAST BLOCK READ HAS BEEN ISSUED. BR 80$ ;RETURN ; 40$: MOV #NBLOCK,RBSIZ ;DEFAULT READ FOR MAXIMUM NUMBER OF BLOCKS. TST CONTGF ;BRANCH IF FILE IS BNE 50$ ; CONTIGUOUS. MOV #1,RBSIZ ;FILE IS NON-CONTIGUOUS, SO ONLY READ 1 BLOCK. ; 50$: MOV IN1FDB+F.VBN+2,LVBN ;GET VBN ABOUT TO BE READ. ADD RBSIZ,LVBN ;ADD NO. VB'S ABOUT TO BE READ. DEC LVBN ;ADJUST IT TO BE LAST VBN TO BE READ. CMP LVBN,F1END ;BRANCH IF READ WOULD BHI 55$ ; EXCEED END-OF-FILE. CMP LVBN,F2END ;BRANCH IF READ IS WITHIN BLOS 60$ ; BOTH FILES. 55$: DEC RBSIZ ;ADJUST NUMBER OF VB'S TO BE READ, AND BR 50$ ; GO SEE IF IT IS WITHIN FILES. ; 60$: MOV R1,-(SP) ;(SAVE A REGISTER). MOV RBSIZ,R1 ;CALCULATE NO. MUL #512.,R1 ; BYTES TO MOV R1,R2 ; BE READ. MOV (SP)+,R1 ;(RESTORE REGISTER). ; ;ISSUE READS FOR BOTH FILES. NO WAIT FOR I/O COMPLETE. QIO$S #IO.RVB,#LUNIN1,6.(R5),,R3,, QIO$S #IO.RVB,#LUNIN2,8.(R5),,R4,, ; ADD RBSIZ,IN1FDB+F.VBN+2 ;ADJUST VBN OF ADD RBSIZ,IN2FDB+F.VBN+2 ; BOTH FILES. ; MOV LVBN,2(R5) ;SAVE VBN THAT WILL BE LAST READ. MOV RBSIZ,4(R5) ;SAVE NO. VB'S JUST READ. ; MOV #2,(R5) ;SET STATUS = 2 READS IN PROGRESS. ; 80$: RETURN ; .PAGE .SBTTL BADCMP ;INTERNAL SUBR - REPORT ON BAD COMPARE. ; ; ; DESCRIPTION: ; A WORD IN EACH INPUT FILE HAS FAILED THE COMPARE. FORMAT A LINE AND ; REPORT THE FACT GIVING BLOCK, OFFSET, AND DATA OF BOTH WORDS. ; ; CALLING SEQUENCE: ; CALL BADCMP ; ; INPUT PARAMETERS: ; R0 = ADDRESS+2 OF FILE 1 VALUE. ; R1 = ADDRESS+2 OF FILE 2 VALUE. ; R2 = VBN BEING COMPARED. ; R3 = OFFSET IN BLOCK OF BAD COMPARISON ; ; IMPLICIT INPUTS: ; NONE. ; ; OUTPUT PARAMETERS: ; NONE. ; ; IMPLICIT OUTPUTS: ; NONE. ; ; COMPLETION CODES: ; ; NOTE: REGISTERS MUST NOT BE DESTROYED. ; BADCMP: ; MOV R0,-(SP) ;SAVE THOSE REGISTERS. MOV R1,-(SP) ; MOV R2,-(SP) ; MOV R3,-(SP) ; MOV R4,-(SP) ; MOV R5,-(SP) ; ; CMP MAXDIF,GOTDIF ;BRANCH IF NOT THE BNE 20$ ; FIRST DIFFERENCE. MOV #DIFHDN,R4 ;IS FIRST, PRINT MOV #DIFHDZ,R5 ; SUB-HEADINGS CALL REPORT ; FOR DUMP. ; 20$: CALL BLANKR ;BLANK OUT REPORT BUFFER. SUB #2,R1 ;GET BOTH MOV (R1),-(SP) ; VALUES SUB #2,R0 ; THAT MOV (R0),-(SP) ; DIFFER. ; MOV R2,R1 ;GET VBN, AND MOV #RECBUF+DIFBLK,R0 ; CONVERT CLR R2 ; TO CALL $CBOMG ; ASCII. ; MOV R3,R1 ;GET OFFSET MOV #RECBUF+DIFOFF,R0 ; AND CONVERT MOV #1,R2 ; TO ASCII CALL $CBOMG ; BYTE. SUB #6,R0 ;BLANK OUT MOVB #' ,(R0)+ ; FIRST MOVB #' ,(R0)+ ; THREE MOVB #' ,(R0)+ ; CHARACTERS. ; MOV (SP)+,R1 ;GET FILE 1 VALUE CALL CONVRT ; AND REPORT IT. CALL BLANKR ;BLANK OUT REPORT BUFFER. MOV (SP)+,R1 ;GET FILE 2 VALUE CALL CONVRT ; AND REPORT IT. ; MOV (SP)+,R5 ;RESTORE REGISTERS. MOV (SP)+,R4 ; MOV (SP)+,R3 ; MOV (SP)+,R2 MOV (SP)+,R1 ; MOV (SP)+,R0 ; ; RETURN ;(TO "COMPAR") .PAGE .SBTTL CONVRT ;INTERNAL SUBR - CONVERT DATA VALUE OF BAD COMPARE. ; ; ; DESCRIPTION: ; TO CONVERT THE DATA VALUE OF A BAD COMPARE TO THE VARIOUS FORMATS ; IN THE REPORT RECORD, AND TO WRITE THE RECORD TO THE OUTPUT FILE. ; ; CALLING SEQUENCE: ; CALL CONVRT ; ; INPUT PARAMETERS: ; R1 = BINARY VALUE. ; ; IMPLICIT INPUTS: ; NONE. ; ; OUTPUT PARAMETERS: ; NONE. ; ; IMPLICIT OUTPUTS: ; NONE. ; ; COMPLETION CODES: ; ; CONVRT: ; MOV R1,-(SP) ;SAVE THE VALUE. ; MOV #RECBUF+DIFDEC,R0 ;CONVERT TO MOV #1,R2 ; ASCII CALL $CBDSG ; DECIMAL. ; MOV #RECBUF+DIFOCT,R0 ;CONVERT MOV (SP),R1 ; TO MOV #1,R2 ; OCTAL. CALL $CBOMG ; ; MOVB (SP),R1 ;GET FIRST BIC #177400,R1 ; BYTE, MOV R1,R4 ; SAVE. MOV #RECBUF+DIFBYT,R0 ;CONVERT MOV #1,R2 ; TO CALL $CBTMG ; ASCII. MOVB #',,(R0)+ ;DELIMITER. MOVB 1(SP),R1 ;GET SECOND BIC #177400,R1 ; BYTE, MOV R1,R5 ; SAVE. MOV #1,R2 ;CONVERT TO CALL $CBTMG ; ASCII. ; CMP #040,R4 ;IF NOT CONTROL BGT 20$ ; CHARACTER, MOVB R4,RECBUF+DIFASC+3; PUT BOTH 20$: CMP #040,R5 ; BYTES IN BGT 40$ ; AS ASCII MOVB R5,RECBUF+DIFASC+4; CHARACTERS ; 40$: MOV #RECBUF+DIFR50,R0 ;CONVERT TO MOV (SP)+,R1 ; RADIX-50. CALL $C5TA ; ; MOV #RECBUF,R4 ;PRINT VALUES MOV #DIFHDZ,R5 ; FOR THAT CALL REPORT ; REPORT. ; RETURN ;(TO "BADCMP") .PAGE .SBTTL PRINTD ;INTERNAL SUBR - PRINT NUMBER OF DIFFERENCES FOUND ; ; ; DESCRIPTION: ; PRINT, AT THE END OF THE COMPARE, THE NUMBER OF DIFFERENCES FOUND IN ; THE FILE, AND THE FILE SIZE. ; ; CALLING SEQUENCE: ; CALL PRINTD ; ; INPUT PARAMETERS: ; NONE. ; ; IMPLICIT INPUTS: ; NONE. ; ; OUTPUT PARAMETERS: ; NONE. ; ; IMPLICIT OUTPUTS: ; NONE. ; ; COMPLETION CODES: ; ; PRINTD: ; MOV GOTDIF,R1 ;CALCULATE NUMBER SUB MAXDIF,R1 ; OF DIFFERENCES NEG R1 ; FOUND. ADD R1,TOTDIF ; Add to Total Differences ; CLR DIFMSV ;INITIALIZE AREA CLR DIFMSV+2 ; TO GET ASCII CLR DIFMSV+4 ; COUNT. ; MOV #DIFMSV,R0 ;CONVERT NUMBER OF CLR R2 ; DIFFERENCES TO CALL $CBDMG ; ASCII. ; ; CLR DIFMSB ;INITIALIZE AREA CLR DIFMSB+2 ; TO GET ASCII CLR DIFMSB+4 ; BLOCKS. ; MOV #DIFMSB,R0 ;CONVERT NUMBER OF MOV BCOUNT,R1 ; BLOCKS COMPARED CLR R2 ; TO ASCII. CALL $CBDMG ; ; MOV #DIFMSG,R4 ;PRINT MOV #DIFMSZ,R5 ; CALL REPORT ; ; RETURN ;(TO "PROCES") .PAGE .SBTTL CLOSIN ;INTERNAL SUBR - CLOSE BOTH INPUT FILES. ; ; ; DESCRIPTION: ; CLOSE BOTH INPUT FILES. ; ; CALLING SEQUENCE: ; CALL CLOSIN ; ; INPUT PARAMETERS: ; NONE. ; ; IMPLICIT INPUTS: ; NONE. ; ; OUTPUT PARAMETERS: ; NONE. ; ; IMPLICIT OUTPUTS: ; NONE. ; ; COMPLETION CODES: ; ; CLOSIN: ; CLOSE$ #IN1FDB ; CLOSE$ #IN2FDB ; ; RETURN ; .PAGE .SBTTL CFNAME ;INTERNAL SUBR - CONVERT FDB FILENAME TO ASCII ; ; ; DESCRIPTION: ; TO CONVERT THE FILENAME NOW HELD IN THE FNB OF THE FDB TO AN ASCII ; STRING. THE AREA TO GET THE STRING MUST BE AT LEAST "FNMSIZ" BYTES ; IN LENGTH. THE UIC WAS EXTRACTED FROM THE OPERATORS COMMAND LINE. ; ; CALLING SEQUENCE: ; CALL CFNAME ; ; INPUT PARAMETERS: ; R0 = ADDRESS OF FDB. ; R5 = ADDRESS TO GET FILENAME STRING. ; ; IMPLICIT INPUTS: ; NONE. ; ; OUTPUT PARAMETERS: ; NONE. ; ; IMPLICIT OUTPUTS: ; NONE. ; ; COMPLETION CODES: ; ; CFNAME: ; MOV R0,-(SP) ;SAVE REGISTERS. MOV R5,-(SP) ; ; MOV R0,R4 ;GET FNB ADD #F.FNB,R4 ; ADDRESS. ; MOV #FNMSIZ,R3 ;BLANK OUT 20$: MOVB #' ,(R5)+ ; AREA TO SOB R3,20$ ; GET STRING. ; MOV (SP),R0 ;ADDRESS TO GET STRING. ; MOVB N.DVNM(R4),(R0)+ ;PUT IN DEVICE MOVB N.DVNM+1(R4),(R0)+ ; NAME. MOV N.UNIT(R4),R1 ;PUT IN CLR R2 ; THE CALL $CBOMG ; UNIT. MOVB #':,(R0)+ ;PUT DEVICE DELIMETER. ; MOV #SUIC1,R1 ;SET = INPUT FILE 1. CMP #IN1FDB+F.FNB,R4;BRANCH IF THIS IS BEQ 25$ ; INPUT FILE 1. MOV #SUIC2,R1 ;SET = INPUT FILE 2. CMP #IN2FDB+F.FNB,R4;BRANCH IF THIS IS BEQ 25$ ; INPUT FILE 2. MOV #SUICO,R1 ;CAN ONLY BE OUTPUT FILE. 25$: MOV (R1)+,R2 ;GET SIZE OF UIC STRING. BLE 35$ ;BRANCH IF NO UIC. MOV (R1),R1 ;GET ADDRESS OF STRING. 30$: MOVB (R1)+,(R0)+ ;PUT IN SOB R2,30$ ; UIC. ; 35$: ADD #N.FNAM,R4 ;GET ADDRESS OF RAD50 FILENAME.TYP MOV #4,R5 ;4 RAD50 WORDS. 40$: CMP #1,R5 ;IF ABOUT TO DO BNE 60$ ; VERSION, PUT MOVB #'.,(R0)+ ; IN DELIMETER. 60$: MOV (R4)+,R1 ;GET RAD50 WORD. CALL $C5TA ;CONVERT TO ASCII. 80$: CMPB #' ,-(R0) ;STRIP OFF BEQ 80$ ; TRAILING INC R0 ; BLANKS. SOB R5,40$ ; ; MOVB #';,(R0)+ ;FOLLOW LASTLY MOV (R4),R1 ; WITH THE CLR R2 ; VERSION CALL $CBOMG ; NUMBER. ; MOV (SP)+,R5 ;RESTORE REGISTERS. MOV (SP)+,R0 ; ; RETURN ; .PAGE .SBTTL BLANKR ;INTERNAL SUBR - BLANK OUT REPORT BUFFER. ; ; ; DESCRIPTION: ; FILL THE REPORT BUFFER "RECBUF" WITH BLANKS. ; ; CALLING SEQUENCE: ; CALL BLANKR ; ; INPUT PARAMETERS: ; NONE. ; ; IMPLICIT INPUTS: ; NONE. ; ; OUTPUT PARAMETERS: ; NONE. ; ; IMPLICIT OUTPUTS: ; NONE. ; ; COMPLETION CODES: ; ; BLANKR: ; MOV R0,-(SP) ;SAVE REGISTERS. MOV R1,-(SP) ; ; MOV #RECBUF,R0 ;BLANK MOV #RECBUZ/2,R1 ; OUT 20$: MOV #" ,(R0)+ ; REPORT SOB R1,20$ ; BUFFER. ; MOV (SP)+,R1 ;RESTORE REGISTERS. MOV (SP)+,R0 ; ; RETURN ; .PAGE .SBTTL REPORT ;INTERNAL SUBR - PRINT LINE TO REPORT FILE. ; ; ; DESCRIPTION: ; PRINT THE INDICATED LINE TO THE OUTPUT REPORT FILE. ; ; CALLING SEQUENCE: ; CALL REPORT ; ; INPUT PARAMETERS: ; R4 = ADDRESS OF DATA TO BE WRITTEN. ; R5 = SIZE. ; ; IMPLICIT INPUTS: ; NONE. ; ; OUTPUT PARAMETERS: ; NONE. ; ; IMPLICIT OUTPUTS: ; NONE. ; ; COMPLETION CODES: ; "C" CONDITION CODE = 0 IF WRITE OK, OR, ; = 1 IF AN ERROR DETECTED. ; ; REPORT: ; MOV R0,-(SP) ;SAVE REGISTER. ; PUT$ #OUTFDB,R4,R5 ;PRINT. BCC 20$ ;BRANCH IF OK. CALL IOEROR ;ERROR. SEC ;SET ERROR CODE. ; 20$: MOV (SP)+,R0 ;RESTORE REGISTER. ; RETURN ; .PAGE .SBTTL SYNTER ;INTERNAL SUBR - TYPE SYNTAX ERROR MESSAGE. ; ; ; DESCRIPTION: ; TYPE, ON THE OPERATORS CONSOLE, A MESSAGE INDICATING THAT A SYNTAX ; ERROR WAS IN THE COMMAND LINE. ; ; CALLING SEQUENCE: ; CALL SYNTER ; ; INPUT PARAMETERS: ; NONE. ; ; IMPLICIT INPUTS: ; NONE. ; ; OUTPUT PARAMETERS: ; NONE. ; ; IMPLICIT OUTPUTS: ; NONE. ; ; COMPLETION CODES: ; ; SYNTER: ; MOV #SYNERR,R4 ;TYPE MESSAGE. MOV #SYNERZ,R5 ; CALL TELOPR ; ; RETURN ; .PAGE .SBTTL IOEROR ;INTERNAL SUBR - TYPE I/O ERROR MESSAGE ; ; ; DESCRIPTION: ; GET THE NAME OF THE FILE, AND THE ERROR CODE, AND TYPE A MESSAGE ; TO OPERATOR THAT AN I/O ERROR HAS OCCURED. ; ; CALLING SEQUENCE: ; CALL IOEROR ; ; INPUT PARAMETERS: ; R0 = ADDRESS OF FDB. ; ; IMPLICIT INPUTS: ; NONE. ; ; OUTPUT PARAMETERS: ; NONE. ; ; IMPLICIT OUTPUTS: ; NONE. ; ; COMPLETION CODES: ; ; IOEROR: ; MOV R0,-(SP) ;SAVE FDB ADDRESS. ; MOV #IOERRF,R5 ;ADDRESS TO GET FILENAME. CALL CFNAME ;CONVERT FILENAME TO ASCII. ; MOVB F.ERR(R0),R1 ;CONVERT ERROR MOV #IOERRC,R0 ; CODE TO MOV #1,R2 ; ASCII. CALL $CBDSG ; ; MOV #IOERR,R4 ;TYPE ERROR MOV #IOERRZ,R5 ; MESSAGE. CALL TELOPR ; ; MOV (SP)+,R0 ;RESTORE FDB ADDRESS. ; RETURN ; .PAGE .SBTTL TELOPR ;INTERNAL SUBR - TYPE MESSAGE TO OPERATOR. ; ; ; DESCRIPTION: ; TYPE THE MESSAGE. ; ; CALLING SEQUENCE: ; CALL TELOPR ; ; INPUT PARAMETERS: ; R4 = ADDRESS OF MESSAGE ; R5 = SIZE. ; ; IMPLICIT INPUTS: ; NONE. ; ; OUTPUT PARAMETERS: ; NONE. ; ; IMPLICIT OUTPUTS: ; NONE. ; ; COMPLETION CODES: ; ; TELOPR: ; QIOW$S #IO.WLB,#LUNTI,#EFTI,,,, ; RETURN ; .PAGE .END MAIN ;