.TITLE TIMREC - DECnet Time Setter .IDENT /Y01.10/ ; In-house version .NLIST BEX ; Don't list binary extensions .ENABL LC ; Enable lower case .SBTTL Introduction ; ; TIMREC - DECnet Network Master Time Requester/Setter Task ; ; Companion file to TIMSND, network time server/sender task ; Author: ; Bruce R. Mitchell ; Source Site: ; Machine Intelligence and Industrial Magic ; PO Box 601, Hudson, Wisconsin 54016 ; Source Hardware and Operating System: ; DEC PDP-11/70 under RSX-11M-Plus V2.0 Autopatch A ; Target Site: ; Same ; Target Hardware and Operating System: ; Same ; Revision History: ; 1-Sep-82 First version coded ; 17-Nov-82 Modified error reporting messages ; 28-Sep-83 Upgrade to support old versions of RSX .PAGE .SBTTL .SBTTL TIMREC Structure ; TIMREC is quite simply structured. It opens the network and ; establishes a connection to the master network node. In the ; connection "mailbox" area, it receives the current time on the ; network master node. It then issues an RSX STIM$ set system ; time directive to set the requesting node's time and exits. ; (If the task is running under an old version of RSX, a SPWN$ ; of an MCR command line to set the time is done instead.) .PAGE .SBTTL Caveats - READ THESE! ; This task will emphatically NOT work unless (1) the TIMSND ; companion task is installed on the host node, (2) an alias ; for NETTIM is defined. ; ; This is SEMI-SUPPORTED and EXPERIMENTAL software which may ; do any number of foul things to the system on which it runs. ; Don't come bitching about anything this task does to you. ; Caveat user. .PAGE .SBTTL .SBTTL Local Definitions ; Define O$$LDM for old versions of RSX (where STIM$ nonexistent) .IF NDF S$$NM1 ; If an old version of RSX O$$LDM = 1 ; This is an old version of RSX .ENDC ; NDF S$$NM1 ; Logical unit numbers LUN1 = 1 ; Network mailbox LUN LUN2 = 2 ; Network logical link LUN LUN3 = 3 ; Owning terminal LUN LUN4 = 4 ; Console LUN ; Event flag numbers EFN1 = 1 ; Network mailbox EFN EFN2 = 2 ; Network logical link EFN TIEFN = 3 ; Owning terminal EFN COEFN = 4 ; Console terminal EFN SPNEFN = 5 ; Spawn command EFN ; Common ASCII codes LF = 12 ; ASCII linefeed CR = 15 ; ASCII carriage return .PAGE .SBTTL Macro Calls and Definitions ; Macros from LB:[1,1]NETLIB.MLB .MCALL CLSW$ ; Close the network and wait .MCALL CONB$$ ; Define a connect block .MCALL CONW$ ; Connect to object and wait .MCALL DSCW$ ; Disconnect from object and wait .MCALL NETDF$ ; Network definitions .MCALL OPNW$ ; Open network and wait NETDF$ ; Define the network symbols ; Macros from LB:[1,1]RSXMAC.SML .MCALL ALUN$ ; Assign logical unit number .MCALL DIR$ ; Execute system directive .MCALL EXST$ ; Exit with status .MCALL QIOW$ ; Queue I/O and wait .MCALL QIOSY$ ; Define QIO symbols .IF DF O$$LDM ; If an old version of RSX .MCALL SPWN$ ; Spawn a task .IFF ; If not an old version of RSX .MCALL STIM$ ; Set system time .ENDC ; DF O$$LDM QIOSY$ ; Define the QIO symbols .PAGE .SBTTL Directive Parameter Blocks ; DPBs for assigning LUNs to the network ALUN1: ALUN$ LUN1, NS, 0 ; Assign LUN 1 to NS: unit 0 ALUN2: ALUN$ LUN2, NS, 0 ; Assign LUN 2 to NS: unit 0 ALUN3: ALUN$ LUN3, TI, 0 ; Assign LUN 3 to TI: unit 0 ALUN4: ALUN$ LUN4, CO, 0 ; Assign LUN 3 to system console ; DPB for closing the network CLSNET: CLSW$ LUN1, EFN1 ; Close all activity on LUN 1 ; Waiting event flag is EFN 1 ; Connect block for connecting to network master and server object CONBLK: CONB$$ NETTIM, 201., 0 ; Connect to node/alias NETTIM ; Connect to object type 201 ; Connect by object type ; DPB for connecting to server object on network master CONNET: CONW$ LUN2, EFN2, NSTBLK,, ; Connect to server on LUN 2 ; Waiting event flag is EFN 2 ; NSTBLK is the connect status block ; CONBLK is the connect block ; TIMRET is the returned time buffer ; Returned time buffer is 16. bytes ; DPB for disconnecting from server object on network master DISNET: DSCW$ LUN2, EFN2 ; Disconnect from server on LUN 2 ; Waiting event flag is EFN 2 ; DPB for exiting with status EXSTAT: EXST$ EX$SUC ; For exiting with success status EXSTER: EXST$ EX$ERR ; For exiting with error status EXSTWA: EXST$ EX$WAR ; For exiting with warning status ; DPB for opening the network OPENET: OPNW$ LUN1, EFN1, NSTBLK,, <1, 0> ; Open network on LUN 1 ; Waiting event flag is EFN 1 ; NSTBLK is the open status block ; Maximum of 1 logical link open ; Abort log. link on phys. link failure ; DPB for setting system time .IF DF O$$LDM ; If an old version of RSX SETTIM: SPWN$ MCR...,,,,, SPNEFN,,, MS6, MS6LEN .IFF ; If a new version of RSX SETTIM: STIM$ TIMRET ; Time block address is TIMRET .ENDC ; DF O$$LDM ; DPBs for printing a message on the console or invoking terminal COQBLK: QIOW$ IO.WVB, LUN4, COEFN,,,, TIQBLK: QIOW$ IO.WBT, LUN3, TIEFN,,,, < , , 40> .PAGE .SBTTL Message Storage MESG01: .ASCII \TIMREC-F-NOF, Network open failed\ MS1LEN = . - MESG01 MESG02: .ASCII \TIMREC-F-NCF, Network connect failed\ MS2LEN = . - MESG02 MESG03: .ASCII \TIMREC-F-OUM, Network connect failed\ .ASCII \ Object unknown at master\ MS3LEN = . - MESG03 MESG04: .ASCII \ I/O status code = \ MS4A: .BLKB 3 .ASCII \, $DSW = \ MS4B: .BLKB 3 MS4LEN = . - MESG04 MESG05: .BLKB 8. ; 8 bytes for storing time .ASCII \ TIMREC - Time set via DECnet on \ MS5A: .BLKB 9. ; Storage for date MS5LEN = . - MESG05 MS6: .ASCII \TIME \ MS6A: .BLKB 8. ; Storage for time .ASCII \ \ MS6B: .BLKB 9. ; Storage for date MS6LEN = . - MS6 .EVEN .PAGE .SBTTL Variable Storage NSTBLK: .BLKW 2 ; 2 words for network status block TIMRET: .BLKW 8. ; 8 words for returned time .PAGE .SBTTL .SBTTL Code TIMREC: DIR$ #ALUN1 ; Assign first network LUN DIR$ #ALUN2 ; Assign second network LUN DIR$ #ALUN3 ; Assign LUN to TI: DIR$ #ALUN4 ; Assign LUN to CO: DIR$ #OPENET ; Open the network CMPB NSTBLK, #IS.SUC ; Was the open successful? BEQ 10$ ; If so, continue ; Network open failed; print message stating same and exit w/status MOV #MESG01, R3 ; "TIMREC-F-NOF, Network open failure" MOV #MS1LEN, R4 ; Load message length into R4 MOV NSTBLK, R5 ; Load error code into R5 CALL ERREXT ; Print the error code and message DIR$ #EXSTER ; Exit with error status ; The network is opened; connect to the time object on the master node 10$: DIR$ #CONNET ; Try to connect to time server CMPB NSTBLK, #IS.SUC ; Was the connect successful? BEQ 50$ ; If so, continue ; Connect failed; see if it was because master node wasn't up CMPB NSTBLK, #IE.NRJ ; Failed because of DECnet reject? BEQ 30$ ; If so, continue ; Connect failed for obscure reason; print message stating same and exit MOV #MESG02, R3 ; "TIMREC-F-NCF, Network connect failed" MOV #MS2LEN, R4 ; Load message length into R4 MOV NSTBLK, R5 ; Load error code into R5 CALL ERREXT ; Print the error code and message DIR$ #CLSNET ; Close the network DIR$ #EXSTER ; Exit with error status ; Connect failed due to net rejection; see if because object not there 30$: CMPB NSTBLK+2, #NE$UOB ; Failed because object unknown? BNE 40$ ; If not, go reschedule self ; Connect failed because object unknown at remote node; exit MOV #MESG03, TIQBLK+Q.IOPL ; Move object fail message into DPB MOV #MS3LEN, TIQBLK+Q.IOPL+2 ; Move message length into DPB DIR$ #TIQBLK ; Print error message on TI: DIR$ #CLSNET ; Close the network DIR$ #EXSTER ; Exit with error status ; Connect failed for non-fatal reason; exit w/status 40$: MOV #MESG02, R3 ; "TIMREC-F-NCF, Network connect failed" MOV #MS2LEN, R4 ; Load message length into R4 MOV NSTBLK, R5 ; Load error code into R5 CALL ERREXT ; Print the error code and message DIR$ #CLSNET ; Close the network ; In some cases, it might be desirable for the task to spawn a ; request to MCR to run again after 1 minute and try to get the ; time again. This is optional and debatable, so the code has ; not been included. This is where it would go, though. DIR$ #EXSTWA ; Exit with warning status ; Connect was successful; disconnect from server and close the network 50$: DIR$ #DISNET ; Disconnect from the server DIR$ #CLSNET ; Close the network ; Pick up the received time and set this system's time from it MOV #-1, TIMRET+S.TICP ; Default the clock frequency .IF DF O$$LDM ; If this is an old version of RSX ; Load up the command line to be spawned with the received time and date MOV #MS6A, R0 ; Load ASCII time field address in R0 MOV #TIMRET+G.TIHR, R1 ; Load binary time field address in R1 MOV #3, R2 ; Specify HH:MM:SS format CALL $TIM ; Convert time to ASCII MOV #MS6B, R0 ; Load ASCII date field address in R0 MOV #TIMRET+G.TIYR, R1 ; Load binary date field address in R1 CALL $DAT ; Convert date to ASCII .ENDC ; DF O$$LDM DIR$ #SETTIM ; Set system time ; Print a message logging the time set on the system console MOV #MESG05, R0 ; Load ASCII time field address in R0 MOV #TIMRET+G.TIHR, R1 ; Load binary time field address in R1 MOV #3, R2 ; Specify HH:MM:SS format CALL $TIM ; Convert time to ASCII MOV #MS5A, R0 ; Load ASCII date field address in R0 MOV #TIMRET+G.TIYR, R1 ; Load binary date field address in R1 CALL $DAT ; Convert date to ASCII DIR$ #COQBLK ; Print the time set message ; Exit to RSX with success status DIR$ #EXSTAT ; Exit with success status .PAGE .SBTTL .SBTTL Subroutines .SBTTL .SBTTL ERREXT Print Error and Exit ; ; ERREXT - Print FCS Error, DSW Error, and Exit to RSX ; ; This subroutine ; ; Inputs: R3 - Address of preceding error message ; R4 - Length of preceding error message ; R5 - Directive I/O error code value ; ; Outputs: None ; ; Register dispositions: All registers used are saved and restored ; ; Variable dispositions: None modified ; ERREXT: CALL $SAVAL ; Save registers 0 - 5 MOV $DSW, -(SP) ; Save the DSW on the stack MOV R3, TIQBLK+Q.IOPL ; Punch in the message address MOV R4, TIQBLK+Q.IOPL+2 ; Punch in the message length DIR$ #TIQBLK ; Print the preceding error message MOV #MS4A, R0 ; R0 points at the target storage area MOVB R5, R1 ; R1 contains the source byte CLR R2 ; Specify suppression of leading zeroes CALL $CBTMG ; Convert binary byte to octal magnitude MOV #MS4B, R0 ; R0 points at the target storage area MOV (SP)+, R1 ; Restore the DSW into R1 CLR R2 ; Specify suppression of leading zeroes CALL $CBTMG ; Convert binary byte to octal magnitude MOV #MESG04, TIQBLK+Q.IOPL ; Punch in the message address MOV #MS4LEN, TIQBLK+Q.IOPL+2 ; Punch in the message length DIR$ #TIQBLK ; Print the preceding error message RETURN ; Return to the caller .END TIMREC