Consolidate license copies
[its.git] / system / time.950
1 ;;; Copyright (c) 1999 Massachusetts Institute of Technology
2 ;;;
3 ;;; This program is free software; you can redistribute it and/or
4 ;;; modify it under the terms of the GNU General Public License as
5 ;;; published by the Free Software Foundation; either version 3 of the
6 ;;; License, or (at your option) any later version.
7 ;;;
8 ;;; This program is distributed in the hope that it will be useful,
9 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
10 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 ;;; General Public License for more details.
12 ;;;
13 ;;; You should have received a copy of the GNU General Public License
14 ;;; along with this program; if not, write to the Free Software
15 ;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16
17 ;I T S .OPERS RELEVANT TO REAL TIME
18
19                 ;.PDTIME AC,    ;RETURNS PDUPS*<# SECS SINCE BEGINNING OF YEAR>
20
21 APDTIM: PUSHJ P,GPDTIM
22          JRST RETM1             ;-1 IF NOT KNOWN
23         JRST APTUAJ
24
25                 ;.RDATE AC,     ;RETURNS SIXBIT YYMMDD IN AC
26
27 ARDATE: PUSHJ P,GLPDTM  ;GET LOCALIZED PDTIME
28          JRST RETM1     ;NOT AVAILABLE
29         IDIVI A,SPD     ;GET # DAYS SINCE BEGINNING OF YEAR
30         PUSHJ P,RDATE   ;GET THE ANSWER
31         JRST APTUAJ     ;RETURN IT
32
33                 ;.RTIME AC,     ;RETURNS SIXBIT HHMMSS (24 HOUR TIME) IN AC
34
35 ARTIME: PUSHJ P,GLPDTM  ;GET LOCALIZED PDTIME
36          JRST RETM1     ;NOT AVAILABLE
37         IDIVI A,SPD     ;GET # SECS SINCE MIDNIGHT IN B
38         PUSHJ P,RTIME   ;CONVERT TO SIXBIT HHMMSS
39         JRST APTUAJ     ;RETURN IT
40
41                 ;.RDATIM AC,    ;DOES .RTIME TO AC, .RDATE TO AC+1
42
43 ARDATI: PUSHJ P,GLPDTM  ;GET CRUD
44          JRST RETM1     ;NO LUCK (THIS IS GETTING BORING)
45         IDIVI A,SPD     ;CONVERT TO DAYS AND SECONDS
46         HRLM A,(P)      ;SAVE DAYS ON PDL
47         PUSHJ P,RTIME   ;GET TIME (HHMMSS)
48         UMOVEM A,(J)    ;GIVE TO USER
49         HLRZ A,(P)      ;GET DAYS AGAIN
50         PUSHJ P,RDATE   ;CONVERT TO SIXBIT
51         AOJA J,APTUAJ   ;GIVE TO USER AND RETURN
52
53                 ;.RYEAR AC,     ;PUSHJ'S TO RYEAR AND MOVEM'S E TO AC
54
55 ARYEAR: PUSHJ P,RYEAR   ;GET THE CRUFT
56         UMOVEM E,(J)    ;STORE YEAR AND CRUD
57         POPJ P,
58
59                 ;.RLPDT AC,     ;DOES .RYEAR AC+1, AND ALSO MOVEM'S A TO AC
60
61 ARLPDT: PUSHJ P,RYEAR   ;GET THE CRUFT
62         UMOVEM E,1(J)   ;STORE YEAR AND CRUD
63         JRST APTUAJ     ;STORE TIME AND RETURN
64
65                 ;ROUTINE TO RETURN -1 ON AN OPER
66
67 RETM1:  XCTR XRW,[SETOM (J)]
68         POPJ P,
69 \f
70                 ;GET THE CORRECTED PDUPS*<# SECS SINCE BEGINNING OF YEAR> IN A
71                 ;SKIP IF OFFSET AVAILABLE AND CLOCK ON
72
73 GPDTIM:
74 IFN PDCLKP,[
75         SKIPN A,PDTIME  ;GET THE OFFSET
76          JRST GPDTM2    ;NOT AVAILABLE
77         DATAI PDCLK,B   ;GET WHAT THE CLOCK IS SAYING
78         TLZ B,600000
79         JUMPE B,GPDTM2  ;POWER PROBABLY (BUT NOT NECESSARILY) TURNED OFF
80         SUBM B,A        ;DO THE CORRECTION
81         JUMPL A,CPOPJ   ;LOST, DON'T RETURN A NEGATIVE NUMBER!
82         JRST POPJ1      ;EXIT SKIPPING (SUCCESS)
83 ] ;PDCLKP
84 IFN KS10P,[
85         SKIPN PDTIME    ; Offset available?
86          JRST GPDTM2    ; No:  Try backup
87         RDTIM A         ; Read clock into A!B
88         TLC A,1729.     ; "A most interesting number"
89         TLNE A,-1       ; Does the clock look like it has been set?
90          JRST GPDTM2    ; Must have been reset
91         DIVI A,KSFREQ   ; Convert to 60ths
92         SUB A,PDTIME    ; Subtract offset
93         JUMPL A,CPOPJ   ; Wooops, don't return a negative number!  (Why
94                         ; don't we use the backup in this case?)
95         JRST POPJ1
96 ] ;KS10P
97 GPDTM2: SKIPGE A,PDYTIM ;CLOCK NOT ON, TRY BACKUP
98          POPJ P,        ;SORRY, NOT AVAILABLE
99         IMULI A,30.     ;CONVERT TO SIXTIETHS OF A SECOND
100         JRST POPJ1      ;CALL IT CORRECT AND AVAILABLE
101
102                 ;GET SIXBIT YYMMDD (DATE) IN A (LOCALIZED PDTIME/SPD IN A, YEAR IN RH(E))
103
104 RDATE:  PUSHJ P,RDATE1  ;GET DAY IN C, MONTH IN B
105         MOVE T,[1400,,A];SET UP BYTE POINTER FOR OUTPUT
106         PUSHJ P,RDATM1  ;DEPOSIT DAY
107         MOVE C,B        ;GET MONTH
108         PUSHJ P,RDATM1  ;DEPOSIT MONTH
109         MOVEI B,(E)     ;GET YEAR
110         IDIVI B,100.    ;GET LAST TWO DIGITS IN C
111 ARTIMX: PUSHJ P,RDATM1  ;DEPOSIT YEAR (ENTRY FROM RTIME TO DEPOSIT HOUR)
112         IOR A,[SIXBIT /000000/] ;CONVERT TO REAL SIXBIT
113         POPJ P,
114
115                 ;GET MONTH (1 => JAN) IN B, DAY (1 => THE FIRST) IN C
116
117 RDATE1: AOS C,A         ;GET DAY OF YEAR (LOCALIZED) (1 => THE FIRST)
118         MOVEI B,12.     ;INITIALLY ASSUME DECEMBER FOR MONTH
119         CAMG C,LMNTBL-1(B)      ;IF DAY IN YEAR .LE. DAY IN YEAR AT BEGINNING OF THIS MONTH,
120          SOJA B,.-1     ;THEN DECREMENT TO PREVIOUS MONTH AND TRY AGAIN
121         SUB C,LMNTBL-1(B)       ;C(C) := DAY OF MONTH
122         POPJ P,
123
124 LMNTBL: MNIRP [<M 1>]   ;TABLE OF DAYS GONE BY AT BEGINNING OF MONTH
125
126                 ;GET THE SIXBIT TIME IN A (# SECS SINCE MIDNIGHT IN B)
127
128 RTIME:  MOVE T,[1400,,A];SET UP BYTE POINTER FOR OUTPUT
129         IDIVI B,60.     ;GET SECONDS IN C
130         PUSHJ P,RDATM1  ;DEPOSIT INTO A
131         IDIVI B,60.     ;GET HOURS IN B, MINUTES IN C
132         PUSHJ P,RDATM1  ;DEPOSIT MINUTES
133         MOVE C,B        ;GET HOURS IN C
134         JRST ARTIMX     ;DEPOSIT HOURS, CONVERT TO SIXBIT, AND RETURN
135
136                 ;DEPOSIT C(C) AS TWO SIX BIT (AS OPPOSED TO SIXBIT) DECIMAL DIGITS
137                 ; VIA T (INTO A) THEN DECREMENT T
138
139 RDATM1: IDIVI C,10.     ;SEPARATE DIGITS
140         DPB C,[60600,,D]        ;DEPOSIT FIRST DIGIT TO GIVE 12 BITS
141         DPB D,T                 ;OUTPUT BYTE
142         ADD T,[140000,,]        ;DECREMENT BYTE POINTER
143         POPJ P,         ;THAT'S ALL
144 \f
145                 ;DO A PUSHJ P,GLPDTM THEN HACK AROUND
146                 ;DO THOSE THINGS TO E COMMENTED IN GLPDTM AS BEING DONE BY RYEAR
147                 ;TRY TO GET YEAR EVEN IF GLPDTM DOESN'T SKIP, BUT IN THAT CASE CLOBBER A TO -1
148
149 RYEAR:  PUSHJ P,GLPDTM  ;GET THE CRUFT
150          JRST RYEAR2    ;DIDN'T SKIP, SEE WHAT CAN BE SALVAGED
151 RYEAR1: PUSH P,A        ;PROTECT A FROM FUTURE CLOBBERAGE
152         IDIVI A,SPD     ;GET LOCALIZED # DAYS SINCE BEGINNING OF YEAR
153         JUMPL E,[SOJA A,.+1]    ;DE-LOCALIZE
154         LDB B,[270300,,E]       ;DAY OF WEEK OF BEGINNING OF YEAR
155         ADD A,B         ;ADD IN
156         IDIVI A,7       ;GET TODAY'S DAY OF WEEK (0 => SUNDAY) IN B
157         DPB B,[320300,,E]       ;DEPOSIT IN E
158         TLO E,40000     ;DOCUMENT FACT THAT TIME OF YEAR KNOWN
159         JRST POPAJ      ;RESTORE A AND RETURN
160
161 RYEAR2: PUSHJ P,GDWOBY  ;GLPDTM DIDN'T SKIP, TRY TO SALVAGE CRUFT: FIRST DOWOBY
162         MOVNI A,1       ;DOCUMENT FACT THAT TIME OF YEAR NOT KNOWN
163         JUMPE E,CPOPJ   ;RETURN IF YEAR NOT KNOWN EITHER
164         DPB B,[270300,,E]       ;DAY OF WEEK OF BEGINNING OF YEAR
165         JRST CMPF29     ;SEE IF LEAP YEAR, AND RETURN
166
167         ;NOTE: THE SYMS JAN, FEB, MAR, ETC. ARE DEFINED AFTER (AND BY) MNIRP (A MACRO)
168
169                 ;INCREMENT YEAR
170
171 NUPDT:  TLNN E,200000                   ;SEE IF LEAP YEAR
172          SKIPA A,[<365.*SPD*PDUPS>]     ;NORMAL YEAR
173           MOVE A,[<366.*SPD*PDUPS>]     ;LEAP YEAR
174         ADDM A,PDTIME   ;UPDATE PDCLK OFFSET
175         IDIVI A,30.     ;CONVERT TO HALF-SECONDS
176         EXCH A,PDYTIM   ;ALSO UPDATE BACKUP SYSTEM
177         SUBM A,PDYTIM
178         AOS FYEAR       ;INCREMENT YEAR
179
180                 ;INSERT OTHER CRUFT HERE IF DESIRED
181                 ;DROPS THROUGH
182 \f
183                 ;CODING DROPS THROUGH FROM PREVIOUS PAGE
184 ;GET "LOCALIZED" NUMBER OF SECONDS SINCE BEGINNING OF YEAR IN A
185         ;IF DIVIDED BY # SECONDS IN A DAY,
186         ;GIVES REMAINDER OF # SECONDS SINCE MIDNIGHT LOCAL TIME
187         ;QUOTIENT WHEN FED TO DATE GENERATOR ROUTINE ASSUMING LEAP YEAR GIVES CORRECT DATE
188 ;ALSO GET YEAR AND FLAGS (AS RETURNED BY .RYEAR) IN E
189         ;1.1-2.9 => YEAR (E.G. 1969.)
190         ;3.1-3.5 ZERO
191         ;3.6-3.8 => DAY OF WEEK OF BEGINNING OF YEAR (0 => SUNDAY)
192         ;3.9-4.2 ZERO (RYEAR SETS THIS BYTE TO TODAY'S DAY OF WEEK IF TIME OF YEAR KNOWN)
193         ;4.6 ZERO (RYEAR SETS IT TO 1 IF TIME OF YEAR KNOWN)
194         ;4.7 ONE => DAYLIGHT SAVINGS TIME IN EFFECT
195         ;4.8 ONE => LEAP YEAR
196         ;4.9 ONE => 365 DAY YEAR AND AFTER FEB 28
197 ;SKIPS IF PDCLK ON AND BOTH PDTIME AND FYEAR NON-ZERO (IN OTHER WORDS IF SUCCESSFUL)
198 ;PREVIOUS CODING DROPS THROUGH ON YEAR INCREMENT
199
200 GLPDTM: CONO PI,CLKOFF  ;AVOID DOUBLE YEAR INCREMENT
201         SKIPE E,FYEAR   ;GET YEAR IN E, SKIP IF NOT AVAILABLE
202          PUSHJ P,GPDTIM ;GET PDTIME, SHOULD SKIP
203           JRST CLKONJ   ;SOMETHING NOT AVAILABLE, DON'T SKIP
204         IDIVI A,60.     ;CONVERT TO SECONDS
205         PUSHJ P,CMPF29  ;MAYBE SET BIT 4.8 OR 4.9 OF E, IF 4.9 SET THEN ADD SPD TO A
206         CAML A,[366.*SPD]       ;IF MORE THAN A YEAR HAS GONE,
207          JRST NUPDT     ;THEN INCREMENT YEAR
208         CONO PI,CLKON   ;TIMIMG ERROR PROBLEM GONE
209         PUSH P,A        ;SAVE # SECONDS DURING NEXT CALL
210         PUSHJ P,GDWOBY  ;GET DAY OF WEEK OF BEGINNING OF YEAR (0 => SUNDAY)
211         DPB B,[270300,,E]       ;DEPOSIT IN RIGHT PLACE
212         POP P,A         ;RESTORE A
213         AOS (P)         ;CAUSE RETURN TO SKIP
214
215                 ;IF DAYLIGHT SAVINGS TIME THEN ADD 3600. TO A AND SET BIT 4.7 IN E
216
217 GLPDT2: JFCL            ;POPJ FOR STD TIME
218                         ;JRST CRDDST FOR DAY LIGHT TIME
219                         ;JFCL "NORMAL"
220         CAML A,[<APR 1>*SPD+7200.]      ;IF BEFORE 2AM APR 1,
221         CAML A,[<OCT 31.>*SPD+3600.]    ;OR IF AFTER 1AM STANDARD TIME OCT 31,
222          POPJ P,                        ;THEN OBVIOUSLY STANDARD TIME IS IN EFFECT
223         CAML A,[<APR 7>*SPD+7200.]      ;IF BEFORE 2AM APR 7 STANDARD TIME,
224         CAML A,[<OCT 25.>*SPD+3600.]    ;OR IF AFTER 1AM STANDARD TIME OCTOBER 25,
225          JRST GLPDT3                    ;THEN NOT OBVIOUS
226 CRDDST: TLO E,100000    ;DAYLIGHT SAVINGS TIME, SET BIT IN E
227         ADDI A,3600.    ;CONTINUE TO LOCALIZE THE TIME THAT WILL BE RETURNED
228         POPJ P,
229 \f
230                 ;IT IS NOW SOMETIME DURING THE WEEKS IN APR AND OCTOBER
231                 ;WHEN IT MAY BE EITHER STANDARD OR DAYLIGHT SAVINGS TIME
232
233 GLPDT3: PUSH P,A        ;SAVE # SECS
234         CAMG A,[JUL*SPD]        ;IF NOT YET JULY,
235          TDZA D,D       ;THEN IT MUST BE APR, SET INDEX
236           MOVEI D,1     ;OCTOBER, SET INDEX
237         SUB A,CRDSB(D)  ;COMPENSATE FOR 2AM OR 1AM
238         IDIVI A,SPD     ;FLUSH SECONDS, LEAVE ONLY DAYS (IT LOOKS LIKE A LEAP YEAR, REMEMBER)
239         LDB C,[270300,,E]       ;GET DAY OF WEEK OF BEGINNING OF YEAR IN C
240         JUMPGE E,.+3    ;IF REGULAR YEAR,
241          SOJGE C,.+2    ;THEN DE-LOCALIZE SO IT WILL RE-LOCALIZE LATER...
242          MOVEI C,6      ;MOD 7
243         ADD A,C         ;ADD TO NUMBER OF DAYS
244         IDIVI A,7
245         IMULI A,7
246         SUB A,C         ;C(A) := NUMBER OF DAYS IN YEAR BEFORE LAST SUNDAY (MAYBE TODAY)
247                 ;IF LAST SUNDAY (AS DEFINED ABOVE) IS BELOW THE "REGION OF AMBIGUITY",
248                 ;THEN IT HAS NOT YET CHANGED TO THE LATER TIME
249         XCT CRDTST(D)   ;SKIP IF DAYLIGHT SAVINGS TIME
250          JRST POPAJ     ;STANDARD TIME, NO CHANGES NECESSARY
251         POP P,A         ;DAYLIGHT SAVINGS TIME, RESTORE A
252         JRST CRDDST     ;MUNG A AND E AND RETURN
253
254 CRDSB:  7200.           ;IN APR CHANGES AT 2AM EST
255         3600.           ;IN OCTOBER CHANGES AT 1AM EST
256
257 CRDTST: CAIGE A,<APR 1>
258         CAIL A,<OCT 25.>
259
260                 ;IF LEAP YEAR THEN SET BIT 4.8 OF E
261                 ;IF NOT LEAP YEAR THEN IF AFTER FEB 28 THEN SET BIT 4.9 OF E AND ADD SPD TO A
262
263 CMPF29: TRNN E,3        ;IF LEAP YEAR, (HOPEFULLY THIS ONLY PLACE WHERE DIRECTLY CHECKED FOR LEAP YEAR)
264          TLOA E,200000  ;THEN SET BIT 4.8 OF E AND RETURN
265           CAMGE A,[<<MAR 1>-1>*SPD]     ;365 DAY YEAR, IF BEFORE MARCH FIRST,
266            POPJ P,      ;THEN RETURN
267         TLO E,400000    ;365 DAY YEAR AFTER FEB 28, SET BIT 4.9 OF E
268         ADDI A,SPD      ;INCREMENT A ONE DAY
269         POPJ P,
270
271                 ;GET DAY OF WEEK OF BEGINNING OF YEAR (IN E) (0 => SUNDAY) IN B
272                 ;FOLLOWING ROUTINE HAS BEEN EXHAUSTIVELY CHECKED
273
274 GDWOBY: MOVEI A,-1(E)
275         IDIVI A,400.
276         MOVEI A,1(B)
277         IDIVI B,4
278         ADD A,B
279         IDIVI B,25.
280         SUB A,B
281         IDIVI A,7
282         POPJ P,
283 \f
284                 ;SLOW CLOCK ROUTINE TO CHECK ON REAL-TIME CLOCK SYSTEM
285
286 PDCCHK: SKIPL PDYTIM    ;IF BACKUP TIME (SINCE BEGINNING OF YEAR) CALCULATED,
287          AOS PDYTIM     ;THEN UPDATE IT
288         SKIPGE TIMOFF   ;IF TIMOFF NOT CALCULATED,
289          POPJ P,        ;THEN RETURN
290         AOS A,TIMOFF    ;UPDATE TIMOFF
291         CAMGE A,[2*SPD] ;Incremented beyond length of day?
292          JRST PDCCH1
293         SETZB A,TIMOFF  ;Yes - reset it.
294         MOVEM A,RSWTIM  ;Also reset last-resource-warning timestamp.
295 PDCCH1: TRNE A,64.*2-1  ;Is this a 64. second (based on TIMOFF) clock break?
296          POPJ P,        ;  No, so return.
297 INITIM:
298 IFN PDCLKP,[
299         SKIPN A,PDTIME  ;MAYBE UPDATE BACKUP SYSTEM
300          JRST INITM2    ;PDTIME NOT AVAILABLE, DON'T
301         DATAI PDCLK,B
302         TLZ B,600000
303         JUMPE B,INITM2  ;JUMP IF CLOCK OFF
304         SUBM B,A
305         JUMPL A,CPOPJ
306         IDIVI A,30.     ;CONVERT TO HALF-SECONDS SINCE BEGINNING OF YEAR
307         MOVEM A,PDYTIM  ;STORE RE-CALCULATED BACKUP TIME
308 ] ;PDCLKP
309 IFN KS10P,[
310         SKIPN PDTIME    ; Update backup system?
311          JRST INITM2    ; Not without offset
312         RDTIM A
313         TLC A,1729.
314         TLNE A,-1
315          JRST INITM2    ; Not if clock reset
316         DIVI A,KSFREQ
317         SUB A,PDTIME    ; 60ths since Jan 1
318         JUMPL A,CPOPJ
319         IDIVI A,30.     ; halfs since Jan 1
320         MOVEM A,PDYTIM  ; Store backup
321 ] ;KS10P
322 INITM2: PUSHJ P,GLPDTM  ;GET LOCALIZED PDTIME
323          POPJ P,        ;SOMETHING'S MISSING
324         IDIVI A,SPD     ;SEPARATE INTO DAYS AND SECONDS
325         LSH B,1         ;CONVERT TIME SINCE MIDNIGHT TO HALF-SECONDS
326         MOVEM B,TIMOFF  ;STORE RE-CALCULATED NUMBER OF HALF-SECONDS SINCE MIDNIGHT
327         PUSHJ P,CLCQDT  ;GET QDATE,,TIMOFF IN A
328         CONO PI,UTCOFF  ;INHIBIT INTERRUPTS DURING THIS RITUAL
329         SKIPGE A,QMDRO  ;GET ORIGIN OF MASTER DSK DIRECTORY
330          JRST UTCONJ    ;DIRECTORY LOCKED
331         MOVE B,QACTB    ;DIRECTORY CHANGED BIT FOR DSK DIRECTORY
332         SKIPE T,PDTIME  ;GET OFFSET FOR DECORIOLIS CLOCK
333          CAMN T,MPDOFF(A)       ;SEE IF IT MATCHES RELEVANT WORD IN DSKDIR
334           JRST .+3              ;MATCHES OR PDTIME NOT AVAILABLE
335             MOVEM T,MPDOFF(A)   ;NO MATCH, CORRECT THE DSKDIR ONE
336             IORM B,QMDRO        ;SET DIRECTORY CHANGED BIT
337         SKIPE T,FYEAR   ;NOW DO THE SAME FOR THE YEAR,
338          CAMN T,MDYEAR(A)       ;AND THE RELEVANT WORD IN DSKDIR
339           JRST .+3
340             MOVEM T,MDYEAR(A)
341             IORM B,QMDRO
342         JRST UTCONJ     ;THAT'S ALL
343 \f
344 CLCQDT: PUSHJ P,RDATE1  ;GET DAY OF MONTH IN C, MONTH IN B
345         SETZM QDATE     ;INITIALIZE FOR FOLLOWING
346         PUSH P,E-1
347         PUSH P,E
348         MOVE E-1,FYEAR
349         IDIVI E-1,100.
350         DPB E,[330700,,QDATE]   ;YEAR
351         POP P,E
352         POP P,E-1
353         DPB B,[270400,,QDATE]   ;MONTH
354         DPB C,[220500,,QDATE]   ;DAY
355         MOVE C,QDATE            ;THE FIRST TIME QDATE IS SET UP,
356         HRR C,TIMOFF            ;SET UP QDATEI = TIME SYSTEM CAME UP.
357         SKIPGE QDATEI
358          MOVEM C,QDATEI         ;MECHANISM IS, SET QDATEI UNLESS ALREADY SET.
359         POPJ P,