1
0
mirror of https://github.com/PDP-10/its.git synced 2026-01-18 17:16:59 +00:00
PDP-10.its/src/system/time.951

345 lines
12 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;;; Copyright (c) 1999 Massachusetts Institute of Technology
;;; See the COPYING file at the top-level directory of this project.
;I T S .OPERS RELEVANT TO REAL TIME
;.PDTIME AC, ;RETURNS PDUPS*<# SECS SINCE BEGINNING OF YEAR>
APDTIM: PUSHJ P,GPDTIM
JRST RETM1 ;-1 IF NOT KNOWN
JRST APTUAJ
;.RDATE AC, ;RETURNS SIXBIT YYMMDD IN AC
ARDATE: PUSHJ P,GLPDTM ;GET LOCALIZED PDTIME
JRST RETM1 ;NOT AVAILABLE
IDIVI A,SPD ;GET # DAYS SINCE BEGINNING OF YEAR
PUSHJ P,RDATE ;GET THE ANSWER
JRST APTUAJ ;RETURN IT
;.RTIME AC, ;RETURNS SIXBIT HHMMSS (24 HOUR TIME) IN AC
ARTIME: PUSHJ P,GLPDTM ;GET LOCALIZED PDTIME
JRST RETM1 ;NOT AVAILABLE
IDIVI A,SPD ;GET # SECS SINCE MIDNIGHT IN B
PUSHJ P,RTIME ;CONVERT TO SIXBIT HHMMSS
JRST APTUAJ ;RETURN IT
;.RDATIM AC, ;DOES .RTIME TO AC, .RDATE TO AC+1
ARDATI: PUSHJ P,GLPDTM ;GET CRUD
JRST RETM1 ;NO LUCK (THIS IS GETTING BORING)
IDIVI A,SPD ;CONVERT TO DAYS AND SECONDS
HRLM A,(P) ;SAVE DAYS ON PDL
PUSHJ P,RTIME ;GET TIME (HHMMSS)
UMOVEM A,(J) ;GIVE TO USER
HLRZ A,(P) ;GET DAYS AGAIN
PUSHJ P,RDATE ;CONVERT TO SIXBIT
AOJA J,APTUAJ ;GIVE TO USER AND RETURN
;.RYEAR AC, ;PUSHJ'S TO RYEAR AND MOVEM'S E TO AC
ARYEAR: PUSHJ P,RYEAR ;GET THE CRUFT
UMOVEM E,(J) ;STORE YEAR AND CRUD
POPJ P,
;.RLPDT AC, ;DOES .RYEAR AC+1, AND ALSO MOVEM'S A TO AC
ARLPDT: PUSHJ P,RYEAR ;GET THE CRUFT
UMOVEM E,1(J) ;STORE YEAR AND CRUD
JRST APTUAJ ;STORE TIME AND RETURN
;ROUTINE TO RETURN -1 ON AN OPER
RETM1: XCTR XRW,[SETOM (J)]
POPJ P,
;GET THE CORRECTED PDUPS*<# SECS SINCE BEGINNING OF YEAR> IN A
;SKIP IF OFFSET AVAILABLE AND CLOCK ON
GPDTIM:
IFN PDCLKP,[
SKIPN A,PDTIME ;GET THE OFFSET
JRST GPDTM2 ;NOT AVAILABLE
DATAI PDCLK,B ;GET WHAT THE CLOCK IS SAYING
TLZ B,600000
JUMPE B,GPDTM2 ;POWER PROBABLY (BUT NOT NECESSARILY) TURNED OFF
SUBM B,A ;DO THE CORRECTION
JUMPL A,CPOPJ ;LOST, DON'T RETURN A NEGATIVE NUMBER!
JRST POPJ1 ;EXIT SKIPPING (SUCCESS)
] ;PDCLKP
IFN KS10P,[
SKIPN PDTIME ; Offset available?
JRST GPDTM2 ; No: Try backup
RDTIM A ; Read clock into A!B
TLC A,1729. ; "A most interesting number"
TLNE A,-1 ; Does the clock look like it has been set?
JRST GPDTM2 ; Must have been reset
DIVI A,KSFREQ ; Convert to 60ths
SUB A,PDTIME ; Subtract offset
JUMPL A,CPOPJ ; Wooops, don't return a negative number! (Why
; don't we use the backup in this case?)
JRST POPJ1
] ;KS10P
GPDTM2: SKIPGE A,PDYTIM ;CLOCK NOT ON, TRY BACKUP
POPJ P, ;SORRY, NOT AVAILABLE
IMULI A,30. ;CONVERT TO SIXTIETHS OF A SECOND
JRST POPJ1 ;CALL IT CORRECT AND AVAILABLE
;GET SIXBIT YYMMDD (DATE) IN A (LOCALIZED PDTIME/SPD IN A, YEAR IN RH(E))
RDATE: PUSHJ P,RDATE1 ;GET DAY IN C, MONTH IN B
MOVE T,[1400,,A];SET UP BYTE POINTER FOR OUTPUT
PUSHJ P,RDATM1 ;DEPOSIT DAY
MOVE C,B ;GET MONTH
PUSHJ P,RDATM1 ;DEPOSIT MONTH
MOVEI B,(E) ;GET YEAR
IDIVI B,100. ;GET LAST TWO DIGITS IN C
ARTIMX: PUSHJ P,RDATM1 ;DEPOSIT YEAR (ENTRY FROM RTIME TO DEPOSIT HOUR)
IOR A,[SIXBIT /000000/] ;CONVERT TO REAL SIXBIT
POPJ P,
;GET MONTH (1 => JAN) IN B, DAY (1 => THE FIRST) IN C
RDATE1: AOS C,A ;GET DAY OF YEAR (LOCALIZED) (1 => THE FIRST)
MOVEI B,12. ;INITIALLY ASSUME DECEMBER FOR MONTH
CAMG C,LMNTBL-1(B) ;IF DAY IN YEAR .LE. DAY IN YEAR AT BEGINNING OF THIS MONTH,
SOJA B,.-1 ;THEN DECREMENT TO PREVIOUS MONTH AND TRY AGAIN
SUB C,LMNTBL-1(B) ;C(C) := DAY OF MONTH
POPJ P,
LMNTBL: MNIRP [<M 1>] ;TABLE OF DAYS GONE BY AT BEGINNING OF MONTH
;GET THE SIXBIT TIME IN A (# SECS SINCE MIDNIGHT IN B)
RTIME: MOVE T,[1400,,A];SET UP BYTE POINTER FOR OUTPUT
IDIVI B,60. ;GET SECONDS IN C
PUSHJ P,RDATM1 ;DEPOSIT INTO A
IDIVI B,60. ;GET HOURS IN B, MINUTES IN C
PUSHJ P,RDATM1 ;DEPOSIT MINUTES
MOVE C,B ;GET HOURS IN C
JRST ARTIMX ;DEPOSIT HOURS, CONVERT TO SIXBIT, AND RETURN
;DEPOSIT C(C) AS TWO SIX BIT (AS OPPOSED TO SIXBIT) DECIMAL DIGITS
; VIA T (INTO A) THEN DECREMENT T
RDATM1: IDIVI C,10. ;SEPARATE DIGITS
DPB C,[60600,,D] ;DEPOSIT FIRST DIGIT TO GIVE 12 BITS
DPB D,T ;OUTPUT BYTE
ADD T,[140000,,] ;DECREMENT BYTE POINTER
POPJ P, ;THAT'S ALL
;DO A PUSHJ P,GLPDTM THEN HACK AROUND
;DO THOSE THINGS TO E COMMENTED IN GLPDTM AS BEING DONE BY RYEAR
;TRY TO GET YEAR EVEN IF GLPDTM DOESN'T SKIP, BUT IN THAT CASE CLOBBER A TO -1
RYEAR: PUSHJ P,GLPDTM ;GET THE CRUFT
JRST RYEAR2 ;DIDN'T SKIP, SEE WHAT CAN BE SALVAGED
RYEAR1: PUSH P,A ;PROTECT A FROM FUTURE CLOBBERAGE
IDIVI A,SPD ;GET LOCALIZED # DAYS SINCE BEGINNING OF YEAR
JUMPL E,[SOJA A,.+1] ;DE-LOCALIZE
LDB B,[270300,,E] ;DAY OF WEEK OF BEGINNING OF YEAR
ADD A,B ;ADD IN
IDIVI A,7 ;GET TODAY'S DAY OF WEEK (0 => SUNDAY) IN B
DPB B,[320300,,E] ;DEPOSIT IN E
TLO E,40000 ;DOCUMENT FACT THAT TIME OF YEAR KNOWN
JRST POPAJ ;RESTORE A AND RETURN
RYEAR2: PUSHJ P,GDWOBY ;GLPDTM DIDN'T SKIP, TRY TO SALVAGE CRUFT: FIRST DOWOBY
MOVNI A,1 ;DOCUMENT FACT THAT TIME OF YEAR NOT KNOWN
JUMPE E,CPOPJ ;RETURN IF YEAR NOT KNOWN EITHER
DPB B,[270300,,E] ;DAY OF WEEK OF BEGINNING OF YEAR
JRST CMPF29 ;SEE IF LEAP YEAR, AND RETURN
;NOTE: THE SYMS JAN, FEB, MAR, ETC. ARE DEFINED AFTER (AND BY) MNIRP (A MACRO)
;INCREMENT YEAR
NUPDT: TLNN E,200000 ;SEE IF LEAP YEAR
SKIPA A,[<365.*SPD*PDUPS>] ;NORMAL YEAR
MOVE A,[<366.*SPD*PDUPS>] ;LEAP YEAR
ADDM A,PDTIME ;UPDATE PDCLK OFFSET
IDIVI A,30. ;CONVERT TO HALF-SECONDS
EXCH A,PDYTIM ;ALSO UPDATE BACKUP SYSTEM
SUBM A,PDYTIM
AOS FYEAR ;INCREMENT YEAR
;INSERT OTHER CRUFT HERE IF DESIRED
;DROPS THROUGH
;CODING DROPS THROUGH FROM PREVIOUS PAGE
;GET "LOCALIZED" NUMBER OF SECONDS SINCE BEGINNING OF YEAR IN A
;IF DIVIDED BY # SECONDS IN A DAY,
;GIVES REMAINDER OF # SECONDS SINCE MIDNIGHT LOCAL TIME
;QUOTIENT WHEN FED TO DATE GENERATOR ROUTINE ASSUMING LEAP YEAR GIVES CORRECT DATE
;ALSO GET YEAR AND FLAGS (AS RETURNED BY .RYEAR) IN E
;1.1-2.9 => YEAR (E.G. 1969.)
;3.1-3.5 ZERO
;3.6-3.8 => DAY OF WEEK OF BEGINNING OF YEAR (0 => SUNDAY)
;3.9-4.2 ZERO (RYEAR SETS THIS BYTE TO TODAY'S DAY OF WEEK IF TIME OF YEAR KNOWN)
;4.6 ZERO (RYEAR SETS IT TO 1 IF TIME OF YEAR KNOWN)
;4.7 ONE => DAYLIGHT SAVINGS TIME IN EFFECT
;4.8 ONE => LEAP YEAR
;4.9 ONE => 365 DAY YEAR AND AFTER FEB 28
;SKIPS IF PDCLK ON AND BOTH PDTIME AND FYEAR NON-ZERO (IN OTHER WORDS IF SUCCESSFUL)
;PREVIOUS CODING DROPS THROUGH ON YEAR INCREMENT
GLPDTM: CONO PI,CLKOFF ;AVOID DOUBLE YEAR INCREMENT
SKIPE E,FYEAR ;GET YEAR IN E, SKIP IF NOT AVAILABLE
PUSHJ P,GPDTIM ;GET PDTIME, SHOULD SKIP
JRST CLKONJ ;SOMETHING NOT AVAILABLE, DON'T SKIP
IDIVI A,60. ;CONVERT TO SECONDS
PUSHJ P,CMPF29 ;MAYBE SET BIT 4.8 OR 4.9 OF E, IF 4.9 SET THEN ADD SPD TO A
CAML A,[366.*SPD] ;IF MORE THAN A YEAR HAS GONE,
JRST NUPDT ;THEN INCREMENT YEAR
CONO PI,CLKON ;TIMIMG ERROR PROBLEM GONE
PUSH P,A ;SAVE # SECONDS DURING NEXT CALL
PUSHJ P,GDWOBY ;GET DAY OF WEEK OF BEGINNING OF YEAR (0 => SUNDAY)
DPB B,[270300,,E] ;DEPOSIT IN RIGHT PLACE
POP P,A ;RESTORE A
AOS (P) ;CAUSE RETURN TO SKIP
;IF DAYLIGHT SAVINGS TIME THEN ADD 3600. TO A AND SET BIT 4.7 IN E
GLPDT2: JFCL ;POPJ FOR STD TIME
;JRST CRDDST FOR DAY LIGHT TIME
;JFCL "NORMAL"
CAML A,[<APR 1>*SPD+7200.] ;IF BEFORE 2AM APR 1,
CAML A,[<OCT 31.>*SPD+3600.] ;OR IF AFTER 1AM STANDARD TIME OCT 31,
POPJ P, ;THEN OBVIOUSLY STANDARD TIME IS IN EFFECT
CAML A,[<APR 7>*SPD+7200.] ;IF BEFORE 2AM APR 7 STANDARD TIME,
CAML A,[<OCT 25.>*SPD+3600.] ;OR IF AFTER 1AM STANDARD TIME OCTOBER 25,
JRST GLPDT3 ;THEN NOT OBVIOUS
CRDDST: TLO E,100000 ;DAYLIGHT SAVINGS TIME, SET BIT IN E
ADDI A,3600. ;CONTINUE TO LOCALIZE THE TIME THAT WILL BE RETURNED
POPJ P,
;IT IS NOW SOMETIME DURING THE WEEKS IN APR AND OCTOBER
;WHEN IT MAY BE EITHER STANDARD OR DAYLIGHT SAVINGS TIME
GLPDT3: PUSH P,A ;SAVE # SECS
CAMG A,[JUL*SPD] ;IF NOT YET JULY,
TDZA D,D ;THEN IT MUST BE APR, SET INDEX
MOVEI D,1 ;OCTOBER, SET INDEX
SUB A,CRDSB(D) ;COMPENSATE FOR 2AM OR 1AM
IDIVI A,SPD ;FLUSH SECONDS, LEAVE ONLY DAYS (IT LOOKS LIKE A LEAP YEAR, REMEMBER)
LDB C,[270300,,E] ;GET DAY OF WEEK OF BEGINNING OF YEAR IN C
JUMPGE E,.+3 ;IF REGULAR YEAR,
SOJGE C,.+2 ;THEN DE-LOCALIZE SO IT WILL RE-LOCALIZE LATER...
MOVEI C,6 ;MOD 7
ADD A,C ;ADD TO NUMBER OF DAYS
IDIVI A,7
IMULI A,7
SUB A,C ;C(A) := NUMBER OF DAYS IN YEAR BEFORE LAST SUNDAY (MAYBE TODAY)
;IF LAST SUNDAY (AS DEFINED ABOVE) IS BELOW THE "REGION OF AMBIGUITY",
;THEN IT HAS NOT YET CHANGED TO THE LATER TIME
XCT CRDTST(D) ;SKIP IF DAYLIGHT SAVINGS TIME
JRST POPAJ ;STANDARD TIME, NO CHANGES NECESSARY
POP P,A ;DAYLIGHT SAVINGS TIME, RESTORE A
JRST CRDDST ;MUNG A AND E AND RETURN
CRDSB: 7200. ;IN APR CHANGES AT 2AM EST
3600. ;IN OCTOBER CHANGES AT 1AM EST
CRDTST: CAIGE A,<APR 1>
CAIL A,<OCT 25.>
;IF LEAP YEAR THEN SET BIT 4.8 OF E
;IF NOT LEAP YEAR THEN IF AFTER FEB 28 THEN SET BIT 4.9 OF E AND ADD SPD TO A
CMPF29: TRNN E,3 ;IF LEAP YEAR, (HOPEFULLY THIS ONLY PLACE WHERE DIRECTLY CHECKED FOR LEAP YEAR)
TLOA E,200000 ;THEN SET BIT 4.8 OF E AND RETURN
CAMGE A,[<<MAR 1>-1>*SPD] ;365 DAY YEAR, IF BEFORE MARCH FIRST,
POPJ P, ;THEN RETURN
TLO E,400000 ;365 DAY YEAR AFTER FEB 28, SET BIT 4.9 OF E
ADDI A,SPD ;INCREMENT A ONE DAY
POPJ P,
;GET DAY OF WEEK OF BEGINNING OF YEAR (IN E) (0 => SUNDAY) IN B
;FOLLOWING ROUTINE HAS BEEN EXHAUSTIVELY CHECKED
GDWOBY: MOVEI A,-1(E)
IDIVI A,400.
MOVEI A,1(B)
IDIVI B,4
ADD A,B
IDIVI B,25.
SUB A,B
IDIVI A,7
POPJ P,
;SLOW CLOCK ROUTINE TO CHECK ON REAL-TIME CLOCK SYSTEM
PDCCHK: SKIPL PDYTIM ;IF BACKUP TIME (SINCE BEGINNING OF YEAR) CALCULATED,
AOS PDYTIM ;THEN UPDATE IT
SKIPGE TIMOFF ;IF TIMOFF NOT CALCULATED,
POPJ P, ;THEN RETURN
AOS A,TIMOFF ;UPDATE TIMOFF
CAMGE A,[2*SPD] ;Incremented beyond length of day?
JRST PDCCH1
SETZB A,TIMOFF ;Yes - reset it.
MOVEM A,RSWTIM ;Also reset last-resource-warning timestamp.
PDCCH1: TRNE A,64.*2-1 ;Is this a 64. second (based on TIMOFF) clock break?
POPJ P, ; No, so return.
INITIM:
IFN PDCLKP,[
SKIPN A,PDTIME ;MAYBE UPDATE BACKUP SYSTEM
JRST INITM2 ;PDTIME NOT AVAILABLE, DON'T
DATAI PDCLK,B
TLZ B,600000
JUMPE B,INITM2 ;JUMP IF CLOCK OFF
SUBM B,A
JUMPL A,CPOPJ
IDIVI A,30. ;CONVERT TO HALF-SECONDS SINCE BEGINNING OF YEAR
MOVEM A,PDYTIM ;STORE RE-CALCULATED BACKUP TIME
] ;PDCLKP
IFN KS10P,[
SKIPN PDTIME ; Update backup system?
JRST INITM2 ; Not without offset
RDTIM A
TLC A,1729.
TLNE A,-1
JRST INITM2 ; Not if clock reset
DIVI A,KSFREQ
SUB A,PDTIME ; 60ths since Jan 1
JUMPL A,CPOPJ
IDIVI A,30. ; halfs since Jan 1
MOVEM A,PDYTIM ; Store backup
] ;KS10P
INITM2: PUSHJ P,GLPDTM ;GET LOCALIZED PDTIME
POPJ P, ;SOMETHING'S MISSING
IDIVI A,SPD ;SEPARATE INTO DAYS AND SECONDS
LSH B,1 ;CONVERT TIME SINCE MIDNIGHT TO HALF-SECONDS
MOVEM B,TIMOFF ;STORE RE-CALCULATED NUMBER OF HALF-SECONDS SINCE MIDNIGHT
PUSHJ P,CLCQDT ;GET QDATE,,TIMOFF IN A
CONO PI,UTCOFF ;INHIBIT INTERRUPTS DURING THIS RITUAL
SKIPGE A,QMDRO ;GET ORIGIN OF MASTER DSK DIRECTORY
JRST UTCONJ ;DIRECTORY LOCKED
MOVE B,QACTB ;DIRECTORY CHANGED BIT FOR DSK DIRECTORY
SKIPE T,PDTIME ;GET OFFSET FOR DECORIOLIS CLOCK
CAMN T,MPDOFF(A) ;SEE IF IT MATCHES RELEVANT WORD IN DSKDIR
JRST .+3 ;MATCHES OR PDTIME NOT AVAILABLE
MOVEM T,MPDOFF(A) ;NO MATCH, CORRECT THE DSKDIR ONE
IORM B,QMDRO ;SET DIRECTORY CHANGED BIT
SKIPE T,FYEAR ;NOW DO THE SAME FOR THE YEAR,
CAMN T,MDYEAR(A) ;AND THE RELEVANT WORD IN DSKDIR
JRST .+3
MOVEM T,MDYEAR(A)
IORM B,QMDRO
JRST UTCONJ ;THAT'S ALL
CLCQDT: PUSHJ P,RDATE1 ;GET DAY OF MONTH IN C, MONTH IN B
SETZM QDATE ;INITIALIZE FOR FOLLOWING
PUSH P,E
MOVE E,FYEAR
SUBI E,1900.
DPB E,[331000,,QDATE] ;YEAR
POP P,E
DPB B,[270400,,QDATE] ;MONTH
DPB C,[220500,,QDATE] ;DAY
MOVE C,QDATE ;THE FIRST TIME QDATE IS SET UP,
HRR C,TIMOFF ;SET UP QDATEI = TIME SYSTEM CAME UP.
SKIPGE QDATEI
MOVEM C,QDATEI ;MECHANISM IS, SET QDATEI UNLESS ALREADY SET.
POPJ P,