;COPYRIGHT GENERAL SCIENTIFIC CORPORATION ;ROCKVILLE, MD. ; ;THIS SOFTWARE MAY BE FREELY DISTRIBUTED BY DECUS FOR NON-COMMERCIAL PURPOSES ;SUBJECT TO GSC COPYRIGHT AND DECUS REGULATIONS. ; .TITLE TSX-PLUS WATCH DOG PROGRAM .ENABL LC .NLIST BEX ; ; This routine runs as a detached job or as a virtual ; or even main job. Its function is to schedule detached ; jobs at times and dates stored in the file WAT:WATCHD.DAT. ; ; The data file must be set-up as follows on a line-by-line basis: ; ; 12345678901234567890123456789012 ; 14:00 03-MAY-82 DEV:FILNAM.COM time and date fully specified ; 16:00 **-***-** DEV:FILNAM.COM run every day at certain time ; 18:00 **-JUN-82 DEV:FILNAM.COM run every day of June 82 at time ; 19:00 01-***-** DEV:FILNAM.COM run on date every month ; ; Some assumptions: ; ; 1. The time must always be fully specified ; ; 2. The day, month or year can be wild carded ; ; 3. The data file must be in ascending order by time ; ; 4. Data file has fixed length records of 32 bytes and can ; a maximum of two blocks (or 32 entries) ; ; 5. The file name specified must be a command file for TSX-Plus ; ; 6. The system must be generated so that there are enough detached ; lines in the system. The total number required will depend upon ; how many simultaneous jobs will be executing on the system. At ; a minimum, two lines are required. ; ; Ned W. Rhodes September 1982 ; Modified by Paul Lustgraaf, April 1985 ; .MCALL .PRINT,.EXIT,.CLOSE,.READW,.LOOKUP,.DATE WILD = '* ;WILD CARD SYMBOL CR = 15 ;CARRIAGE RETURN LF = 12 ;LINE FEED BELL = 7 ;A BELL CAR = 15 ;CARRIAGE RETURN TIME = 0 ;TIME FIELD OFFSET HOURS = 0 ;HOURS FIELD OFFSET MINUTE = 3 ;MINUTES FIELD OFFSET DAY = 6 ;DAY FIELD OFFSET MONTH = 9. ;MONTH FIELD OFFSET YEAR = 13. ;YEAR FIELD OFFSET .PAGE ; Open file and read in information ; WATCH:: .LOOKUP #LAREA,#1,#FILEN ;WHERE IS FILE?? BCC 1$ ;CONTINUE .PRINT #LOOK ;ERROR MESSAGE .EXIT 1$: .READW #LAREA,#1,#BUFFER,#512.,#0 ;READ IT BCC 2$ ;CONTINUE .PRINT #REED ;ERROR MESSAGE .EXIT 2$: .CLOSE #1 ;RELEASE FILE MOV #BUFFER,R4 ;POINT TO BUFFER ; ; Get the current date in JDAY, JMONTH, JYEAR ; .DATE ;MOVE DATE TO R0 MOV R0,R1 ;MAKE COPY OF DATE BIC #^C37,R1 ;MASK OFF YEAR ADD #72.,R1 ;ADD BIAS TO YEAR MOV R1,JYEAR ;SAVE YEAR ASR R0 ASR R0 ;PUT MONTH ON BYTE BOUNDARY MOV R0,R1 ;COPY IT SWAB R1 ;PUT MONTH IN LOW BYTE BIC #^C37,R1 ;MASK OFF MONTH MOV R1,JMONTH ;SAVE MONTH ASR R0 ASR R0 ASR R0 ;PUT DAY ON BYTE BOUNDARY BIC #^C37,R0 ;MASK OFF DAY MOV R0,JDAY ;SAVE DAY ; ; Loop here until we have done all the entries ; MLOOP: TST (R4) ;ARE WE DONE?? BEQ DONE ;YES CMP #BUFEND,R4 ;AT END OF BUFFER?? BLE DONE ;YES ; ; Convert the date and time to binary ; MOV R4,R1 ;ADDRESS OF STRING CALL ASCBIN ;CONVERT HOURS MOV R0,IHR ;AND SAVE IT MOV R4,R1 ;ADDRESS OF STRING ADD #MINUTE,R1 ;POINT TO MINUTES CALL ASCBIN ;CONVERT IT MOV R0,IMIN ;SAVE IT MOV R4,R1 ;ADDRESS OF STRING ADD #DAY,R1 ;POINT TO DAY CALL ASCBIN ;CONVERT IT MOV R0,IDAY ;SAVE IT MOV R4,R1 ;ADDRESS OF STRING ADD #YEAR,R1 ;POINT TO YEAR CALL ASCBIN ;CONVERT IT MOV R0,IYEAR ;SAVE IT ; ; Convert the month to binary. ; MOV R4,-(SP) ;SAVE R4 CLR R0 ;R0=NUMERIC MONTH MOV #MTAB-3,R2 ;R2=TABLE PTR MOV #12.,R3 ;R3=LOOP CTR 1$: INC R0 ;R0=NEXT MONTH MOV (SP),R1 ;R1=ADDRESS OF STRING ADD #MONTH,R1 ;POINT R1 TO MONTH MOV #3,R5 ;R5=3 ADD R5,R2 ;POINT R2 TO NEXT ASCII MONTH MOV R2,R4 ;R4->ASCII FOR MONTH 2$: CMPB (R1)+,(R4)+ ;COMPARE ONE BYTE AT A TIME BNE 3$ ;IF NOT EQUAL, BRANCH SOB R5,2$ ;COUNT LOOP MOV R0,IMONTH ;SAVE MONTH BR 10$ 3$: SOB R3,1$ ;COUNT LOOP MOV #-1,IMONTH ;ASSUME INVALID MONTH=WILD MONTH 10$: MOV (SP)+,R4 ;RESTORE R4 ; ; Check the years for a match ; TST IYEAR ;WILD YEAR? BMI TSTMO ;IF SO, BRANCH CMP IYEAR,JYEAR ;DO YEARS MATCH? BNE RECYC ;IF NOT, BRANCH ; ; Check the months for a match ; TSTMO: TST IMONTH ;WILD MONTH? BMI TSTDAY ;IF SO, BRANCH CMP IMONTH,JMONTH ;DO MONTHS MATCH? BNE RECYC ;IF NOT, BRANCH ; ; Check the days for a match ; TSTDAY: TST IDAY ;WILD DAY? BMI TSTTIM ;IF SO, BRANCH CMP IDAY,JDAY ;DO DAYS MATCH? BNE RECYC ;IF NOT, BRANCH ; ; Check the time ; TSTTIM: CALL TIMDIF ;TODAY OR TOMORROW ; ; Check here for an interval of < 1 minute as that ; means that we want to schedule something right away. ; TST IFLG ;TODAY OR TOMORROW BEQ SCHED ;TODAY -- SCHEDULE IT TST R2 ;CHECK HIGH ORDER BITS BNE RECYC ;NOT SAME MINUTE CMP #3600.,R3 ;LESS THAN ONE MINUTE?? BHI DETAT ;YES, DETACH THE JOB NOW BR RECYC ;NOPE, MORE ; ; Now we sleep a while and when we wake-up ; we schedule our little detached job ; SCHED: MOV R3,-(SP) ;SAVE TIME MOV R2,-(SP) ;SAVE TIME MOV SP,R0 ;EMT POINTER MOV R0,-(SP) ;STACK IT MOV #24*400,-(SP) ;SET .TWAIT CODE MOV SP,R0 ;R0 -> ARG BLOCK EMT 375 ;.TWAIT BIC R0,R0 ;R0=0 ADC R0 ;C=1 IF ERROR ADD #10,SP ;POP ARGS ; ; Here is where we actually detach the job to TSX ; DETAT: MOV R4,R0 ;GET BUFFER ADDRESS ADD #16.,R0 ;POINT TO FILE NAME MOV #JOBER,R2 ;POINT TO STORAGE AREA 1$: MOVB (R0)+,(R2)+ ;SAVE IT CMPB #CAR,(R0) ;DID WE HIT WE A CR? BNE 1$ ;NOPE CLRB (R0) ;INSURE A ZERO .PRINT #JOBER ;PRINT THE FILE NAME FOR NOW MOV #EMTTER,R0 ;POINT TO EMT BLOCK EMT 375 ;DETACH IT BCC RECYC ;BRANCH IF NO ERROR MOV #MSGEMT,R0 ;SEND A MESSAGE EMT 375 ;SEND A MESSAGE TO OPERATOR ; ; Point to the next line of the buffer ; RECYC: ADD #32.,R4 ;POINT TO NEXT ONE JMP MLOOP ;TRY AGAIN ; ; Sleep until midnight and start this all over again ; DONE: MOV #24.,IHR ;MIDNIGHT MOV #1.,IMIN ;PLUS 1 CALL TIMDIF ;COMPUTE DIFFERENCE MOV R3,-(SP) ;SAVE TIME MOV R2,-(SP) ;SAVE TIME MOV SP,R0 ;EMT POINTER MOV R0,-(SP) ;STACK IT MOV #24*400,-(SP) ;SET .TWAIT CODE MOV SP,R0 ;R0 -> ARG BLOCK EMT 375 ;.TWAIT BIC R0,R0 ;R0=0 ADC R0 ;C=1 IF ERROR ADD #10,SP ;POP ARGS JMP WATCH ;AND RECYCLE .PAGE ; This routine starts at the address in R1 and ignores spaces ; until it reaches a valid character. It will then convert ; to decimal until it reaches a non-digit. It will return ; the number in R0. If it finds any characters other than ; a digit or a space, it will return -1. ; ASCBIN: CLR R0 ;RESULT=0 MOV R2,-(SP) ;SAVE R2 2$: CMPB #' ,(R1)+ ;IS IT A SPACE?? BEQ 2$ ;IF SO, IGNORE MOV R1,-(SP) ;SAVE R1 DEC R1 ;TRY LAST CHARACTER AGAIN 1$: MOVB (R1)+,R2 ;GET A BYTE SUB #'0,R2 ;CONVERT TO NUMBER BMI 10$ ;IF MINUS, WE ARE DONE CMP R2,#9. ;> 9?? BHI 10$ ;IF YES, EXIT ASL R0 ;RESULT TIMES 2 MOV R0,-(SP) ;AND SAVE IT ASL R0 ;RESULT TIMES 4 ASL R0 ;RESULT TIMES 8 ADD (SP)+,R0 ;RESULT * 8 + RESULT * 2 ADD R2,R0 ;ADD IN CURRENT COUNT BR 1$ ;AND CONTINUE 10$: CMP (SP)+,R1 ;IS THIS THE FIRST NON-BLANK CHARACTER? BNE 9$ ;IF NOT, RETURN THE RESULT DEC R0 ;ELSE RETURN -1 9$: MOV (SP)+,R2 ;RESTORE R2 RETURN .PAGE ; CALCULATES THE TWO-WORD INTEGER TIME BETWEEN THE CURRENT TIME ; AND A SPECIFIED TIME-OF-DAY. ; ; OUTPUTS: ; (R2,R3) = TIME INTERVAL DESIRED IN TICKS ; TIMDIF: CLR IFLG ;CLEAR FLAG WORD CLR R0 CLR R1 MOV IHR,R3 ;R3=HOURS MOV #60.,R5 ;R5=60 MINS/HR 1$: DEC R3 ;COUNT THE HOURS BMI 2$ ;IF DONE, BRANCH ADD R5,R1 ;R1=HOURS*60 BR 1$ 2$: ADD IMIN,R1 ;R1=HOURS*60 + MINUTES MOV #3600.,R5 ;R5=# OF TICKS IN A MINUTE CLR R2 ;HIGH ORDER OF DESIRED TIME CLR R3 ;LOW ORDER OF DESIRED TIME 3$: ROR R5 ;CHECK NEXT BIT BCC 4$ ;IF A ZERO, BRANCH ADD R1,R3 ;ADD (R0,R1) TO (R2,R3) ADC R2 ADD R0,R2 TST R5 ;DONE YET? 4$: BEQ 5$ ;IF DONE, BRANCH ASL R1 ;SHIFT (R0,R1) LEFT FOR EACH BIT ROL R0 BR 3$ 5$: CMP -(SP),-(SP) ;ALLOCATE SPACE FOR CURRENT TIME-OF-DAY MOV SP,R0 MOV R0,-(SP) ;MACHINE-INDEPENDENCE MOV #21*400,-(SP) ;SET .GTIM CODE MOV SP,R0 ;R0 -> ARG BLOCK EMT 375 ;.GTIM CMP (SP)+,(SP)+ ;DISCARD ARG BLOCK MOV (SP)+,R0 ;(R0,R1) = CURRENT TIME MOV (SP)+,R1 SUB R1,R3 ;HANDLE LOW ORDER BITS SBC R2 ;DOUBLE WORD MAGIC SUB R0,R2 ;CALCULATE INTERVAL -- HIGH ORDER BPL 9$ ;IF IT ISN'T REALLY TOMORROW ; ; If we get here, then the time requested has already ; passed and so we set the flag and compute the absolute ; magnitude of the difference for the calling program. ; MOV #-1,IFLG ;IT IS FOR TOMORROW COM R3 ;ONES COMPLEMENT COM R2 ;ONES COMPLEMENT ADD #1,R3 ;COMPUTE THE TWOS COMPLEMENT ADC R2 ;ADD IN THE CARRY 9$: RETURN .PAGE BUFFER: .BLKW 512. ;WHAT TO DO BUFFER BUFEND = . ;END OF BUFFER LAREA: .BLKW 10. ;EMT AREA IHR: .WORD 0 ;HOURS IMIN: .WORD 0 ;MINUTES IFLG: .WORD 0 ;TODAY/TOMORROW FLAG IMONTH: .WORD 0 ;SPECIFIED MONTH JMONTH: .WORD 0 ;CURRENT MONTH IDAY: .WORD 0 ;SPECIFIED DAY JDAY: .WORD 0 ;CURRENT DAY IYEAR: .WORD 0 ;SPECIFIED YEAR JYEAR: .WORD 0 ;CURRENT YEAR EMTTER: .BYTE 0,132 ;TSX EMT BLOCK .WORD JOBER ;THE FILE NAME ADDRESS MSGEMT: .BYTE 0,127 ;SEND MSG EMT .WORD 1 ;DESTINATION LINE .WORD MSG ;THE MESSAGE MSG: .ASCII /?WATCH-I-Unable to start detached job -- / JOBER: .BLKW 8. ;FILE NAME FILEN: .RAD50 /WATWATCHDDAT/ ;DATA FILE LOOK: .ASCIZ /?WATCH-F-File WAT:WATCHD.DAT not found/ REED: .ASCIZ /?WATCH-F-Read error on WAT:WATCHD.DAT/ MTAB: .ASCII /JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC/ .END WATCH