.TITLE WFIND .IDENT /V3.00/ .NLIST BEX .ENABL LC ;*********************************************************************** ; ; WFIND.PAT ; ; This patch file implements processing specific to the Cornell ; University/Chemical Engineering Batch System (version 3) for ; RSX-11M V4.0 or V4.1. ; ; This patch is applied to object module WFIND.OBJ extracted from ; the library file QMGCLI.OLB on the distribution disk. ; Its function is to read and analyze the *JOB card on each file ; to be submitted for execution to the batch system. ; ;---------------------------------------------------------------------- ; ; Steve Thompson ; School of Chemical Engineering ; Cornell University ; Ithaca NY 14853 ; ;*********************************************************************** .MCALL QIOW$S,OFNB$R,CLOSE$,GET$,EXST$S .MCALL FDBDF$,FDRC$A,FDOP$A ; ; Specify location of patch in module WFIND. This location is ; different in the RSX-11M V4.0 and V4.1 versions. ; .PSECT .IF EQ, ; .=.+204 ; RSX-11M V4.1 .ENDC ; EQ, .IF EQ, ; .=.+200 ; RSX-11M V4.0 .ENDC ; EQ, CALL JOBCRD ; Call new routine ; ; New stuff, all in P-sections BAPDAT (data) and BAPCOD (code). ; .PSECT BAPDAT,D ; ; Error messages. ; FCSMSG: .ASCIZ /, FCS / QCKMSG: .ASCIZ /SUB - Job may not be submitted into this queue/ OPNMSG: .ASCIZ /SUB - Open error on / GETMSG: .ASCIZ /SUB - Read error on / JOBMSG: .ASCIZ /SUB - Error on *JOB card in file / .IF DF,B3$TIM TIMMSG: .ASCIZ /SUB - Invalid time limit, file / .ENDC ; DF,B3$TIM .IF DF,B3$MEM MEMMSG: .ASCIZ /SUB - Invalid memory requirement, file / .ENDC ; DF,B3$MEM .IF DF,B3$PAG PAGMSG: .ASCIZ /SUB - Invalid page count, file / .ENDC ; DF,B3$PAG .EVEN ; ; Just to make sure that the task is not doing anything fancy with the ; FDB before we got here, another is allocated and the relevant information ; is copied to it (the filename block) before trying to check the *JOB ; card. ; LOCFDB: FDBDF$ ; FDRC$A ,RECBUF,80. ; FDOP$A 4,,,FO.RD ; Open for read on LUN 4 ; ; Other data. ; .IF DF,B3$TIM TIMLIM: .BLKW 1 ; Time limit for current file .ENDC ; DF,B3$TIM .IF DF,B3$MEM MEMLIM: .BLKW 1 ; Memory limit for current file .ENDC ; DF,B3$MEM RECBUF: .BLKB 80. ; *JOB card and message buffer .PSECT BAPCOD,I JOBCRD: CALL $SAVAL ; Save all registers CALL .FIND ;* Intercepted instruction BCC 10$ ; If CC good, keep going RTS PC ; else go back to original code 10$: CMP #3,CMDTYP ; SUBMIT command? BEQ 20$ ; If EQ yes RTS PC ; Do no more if PRINT command ; ; Open the file describing this sub-job. ; 20$: ADD #F.FNB,R0 ; Point to filename block MOV #LOCFDB+F.FNB,R1 ; Point to local filename block MOV #S.FNBW,R2 ; Get size of filename block (words) 30$: MOV (R0)+,(R1)+ ; Copy a word DEC R2 ; Done yet? BGT 30$ ; If GT no, loop OFNB$R #LOCFDB ; Open file by file ID BCC 32$ ; If CC, OK JMP OPNERR ; else open error 32$: ; Ref. label ; ; Read what is hopefully the *JOB card. ; GET$ R0 ; Read the *JOB card BCC 34$ ; If CC good JMP GETERR ; If CS, error 34$: MOV F.NRBD(R0),R2 ; Get record length CLOSE$ R0 ; OK, now close the file ; ; Preprocessing of *JOB card. ; TST R2 ; *JOB card blank? BNE 36$ ; If NE no, good 35$: JMP JOBERR ; If EQ yes, can't be *JOB card 36$: CLRB RECBUF+1(R2) ; Make it ASCIZ MOV #RECBUF,R0 ; Get address of *JOB card buffer MOV R0,R1 ; Copy it CALL $CVTUC ; Make it all upper case ; ; Analyze the *JOB card. The accepted format is as follows: ; ; *JOB TIME=nm,MEMORY=nk,PAGES=np ; ; where "nm" is the jobs' time limit in minutes, "nk" is ; the maximum memory requirement in K-words, and "np" is the ; output limit in pages. All three keywords may be ; omitted if desired, in which case the time limit defaults to ; the value of the global symbol $DFTIM, the memory defaults ; to the value of the global symbol $DFMEM, and the page ; count defaults to the value of $DFPAG (enforced by the ; batch processor only). All three quantities must ; be positive and less than the values of $MXTIM, $MXMEM ; and $MXPAG respectively. The keywords may be specified in ; any order. "nm" may be optionally followed by a letter M, ; and "nk" may optionally be followed by a letter K. Any text ; following a ! or ; character (inclusive) is treated as a ; comment and is ignored. ; MOV #RECBUF,R0 ; Get address of *JOB card buffer CMPB #'*,(R0)+ ; Does it start "*JOB"? BNE 35$ ; If NE no CMPB #'J,(R0)+ ; Maybe BNE 35$ ; If NE no CMPB #'O,(R0)+ ; Maybe BNE 35$ ; If NE no CMPB #'B,(R0)+ ; Maybe BNE 35$ ; If NE no .IF DF,B3$TIM!B3$MEM!B3$PAG .IF DF,B3$TIM MOV #$DFTIM,TIMLIM ; Default the time limit .ENDC ; DF,B3$TIM .IF DF,B3$MEM MOV #$DFMEM,MEMLIM ; Default the memory limit .ENDC ; DF,B3$MEM ; ; Look for keyword on *JOB card. ; 50$: MOVB (R0)+,R1 ; Get next character BEQ 80$ ; If EQ, end of *JOB card CMPB R1,#40 ; Was it a space? BEQ 50$ ; If EQ yes, ignore it CMPB R1,#11 ; Tab? BEQ 50$ ; If EQ yes, ignore it CMPB R1,#'! ; Start of comment? BEQ 80$ ; If EQ yes CMPB R1,#'; ; Comment? BEQ 80$ ; If EQ yes .IF DF,B3$TIM CMPB R1,#'T ; Time limit? BEQ 60$ ; If EQ yes .ENDC ; DF,B3$TIM .IF DF,B3$MEM CMPB R1,#'M ; Memory limit? BEQ 70$ ; If EQ yes .ENDC ; DF,B3$MEM .IF DF,B3$PAG CMPB R1,#'P ; Page limit? BEQ 75$ ; .ENDC ; DF,B3$PAG BR JOBERR ; Otherwise error on *JOB card ; ; Extract time limit. ; .IF DF,B3$TIM 60$: MOVB (R0)+,R1 ; Get next character BEQ TIMERR ; We were looking for "=" CMPB R1,#'= ; Equals sign? BNE 60$ ; If NE no, keep looking CALL $CDTB ; Get time limit TST R1 ; Sensible value? BLE TIMERR ; Not if it's negative CMP R1,#$MXTIM ; Maybe BGT TIMERR ; No MOV R1,TIMLIM ; Save it CMPB #'M,R2 ; "minutes" unit? BNE 62$ ; If NE no MOVB (R0)+,R2 ; Yes, skip it 62$: TSTB R2 ; End of *JOB card? BEQ 80$ ; If EQ yes CMPB R2,#40 ; End of keyword (space)? BEQ 50$ ; If EQ yes CMPB R2,#11 ; End of keyword (tab)? BEQ 50$ ; If EQ yes CMPB #',,R2 ; End of keyword (comma)? BNE TIMERR ; If not, error BR 50$ ; Look for more keywords .ENDC ; DF,B3$TIM ; ; Extract memory limit ; .IF DF,B3$MEM 70$: MOVB (R0)+,R1 ; Get next character BEQ MEMERR ; We were looking for "=" CMPB R1,#'= ; Equals sign? BNE 70$ ; If NE no, keep looking CALL $CDTB ; Get memory limit TST R1 ; Sensible value? BLE MEMERR ; Not if it's negative CMP R1,#$MXMEM ; Maybe BGT MEMERR ; No MOV R1,MEMLIM ; Save it CMPB #'K,R2 ; "Kwords" unit? BNE 72$ ; If NE no MOVB (R0)+,R2 ; Yes, skip it 72$: TSTB R2 ; End of *JOB card? BEQ 80$ ; If EQ yes CMPB R2,#40 ; End of keyword (space)? BEQ 50$ ; If EQ yes CMPB R2,#11 ; End of keyword (tab)? BEQ 50$ ; If EQ yes CMPB #',,R2 ; End of keyword (comma)? BNE MEMERR ; If NE no, error BR 50$ ; Keep scanning .ENDC ; DF,B3$MEM ; ; Validate page count. ; .IF DF,B3$PAG 75$: MOVB (R0)+,R1 ; Get next character BEQ PAGERR ; We were looking for "=" CMPB R1,#'= ; Equals sign? BNE 75$ ; If NE no, keep looking CALL $CDTB ; Get page limit TST R1 ; Sensible value? BLE PAGERR ; Not if it's negative CMP R1,#$MXPAG ; Maybe BGT PAGERR ; No TSTB R2 ; End of *JOB card? BEQ 80$ ; If EQ yes CMPB R2,#40 ; End of keyword (space)? BEQ 50$ ; If EQ yes CMPB R2,#11 ; End of keyword (tab)? BEQ 50$ ; If EQ yes CMPB #',,R2 ; End of keyword (comma)? BNE PAGERR ; If NE no, error BR 50$ ; Keep scanning .ENDC ; DF,B3$PAG ; ; Check that time limit sum so far does not exceed the maximum. ; 80$: ; Ref. label .IF DF,B3$TIM ADD TIMLIM,TIMSUM ; Accumulate sum CMP TIMLIM,#$MXTIM ; Too big? BGT TIMERR ; If GT yes .ENDC ; DF,B3$TIM ; ; Check that job may be submitted to this queue. ; CALL QCHK ; Check job/queue compatability BCC 81$ ; If CC, OK JMP QCKERR ; If CS, mismatch found 81$: ; Ref. label ; ; *JOB card has been checked. Increment TIME*MEMORY sum. ; .IF DF,B3$TIM & B3$MEM MOV TIMLIM,R0 ; Get time limit MOV MEMLIM,R1 ; Get memory limit CALL $MUL ; Multiply them ADD R1,TIMMEM+2 ; Update sum ADC TIMMEM ; ADD R0,TIMMEM ; .IFF .IF DF,B3$TIM ADD TIMLIM,TIMMEM+2 ; Add just time limit ADC TIMMEM ; (not really necessary) .ENDC ; DF,B3$TIM .IF DF,B3$MEM ADD MEMLIM,TIMMEM+2 ; Add just memory limit ADC TIMMEM ; (not really necessary) .ENDC ; DF,B3$MEM .ENDC ; DF,B3$TIM & B3$MEM ; ; That's it for this file. ; .ENDC ; DF,B3$TIM ! B3$MEM ! B3$PAG RTS PC ; Return to normal QMGCLI code ; ; Error processing. ; OPNERR: MOV #OPNMSG,R1 ; Get open error message address MOV R1,-(SP) ; Filespec required BR COMMON ; Continue in common code GETERR: CLOSE$ ; Close the file MOV #GETMSG,R1 ; Get GET$ error message address MOV R1,-(SP) ; Filespec required BR COMMON ; Continue in common code JOBERR: MOV #JOBMSG,R1 ; Error on *JOB card MOV R1,-(SP) ; Filespec required BR NOFCS ; .IF DF,B3$TIM TIMERR: MOV #TIMMSG,R1 ; Invalid time limit MOV R1,-(SP) ; Filespec required BR NOFCS ; .ENDC ; DF,B3$TIM .IF DF,B3$MEM MEMERR: MOV #MEMMSG,R1 ; Invalid memory requirement MOV R1,-(SP) ; Filespec required BR NOFCS ; .ENDC ; DF,B3$MEM .IF DF,B3$PAG PAGERR: MOV #PAGMSG,R1 ; Invalid page count MOV R1,-(SP) ; Filespec required BR NOFCS ; .ENDC ; DF,B3$PAG QCKERR: MOV #QCKMSG,R1 ; Job/queue mismatch CLR -(SP) ; Filespec not required ; Fall through to NOFCS NOFCS: CLR R5 ; Show no FCS error BR COMMN1 ; COMMON: MOVB F.ERR(R0),R5 ; Save FCS error code COMMN1: MOV #RECBUF,R0 ; Get output buffer address 10$: MOVB (R1)+,(R0)+ ; Move a character BNE 10$ ; If not at end, loop DEC R0 ; Remove null byte TST (SP)+ ; Filespec required? BEQ 30$ ; If EQ no MOV #LOCFDB,R1 ; Get FDB address CLR R2 ; Fill in filename CALL .EXPFN ; MOV R5,R1 ; Get FCS error code in R1 BEQ 30$ ; If EQ, no FCS error MOV #FCSMSG,R2 ; Get address of FCS error text 20$: MOVB (R2)+,(R0)+ ; move it in BNE 20$ ; DEC R0 ; CLR R2 ; No leading zeroes CALL $CBDSG ; Convert to signed decimal 30$: SUB #RECBUF,R0 ; Calculate length QIOW$S #IO.WVB,#2,#2,,,,<#RECBUF,R0,#40> ; Print it EXST$S #EX$SEV ; and exit with severe error .END