1 ;;; Copyright (c) 1999 Massachusetts Institute of Technology
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 2 of the
6 ;;; License, or (at your option) any later version.
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.
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.
17 ;I T S .OPERS RELEVANT TO REAL TIME
19 ;.PDTIME AC, ;RETURNS PDUPS*<# SECS SINCE BEGINNING OF YEAR>
21 APDTIM: PUSHJ P,GPDTIM
22 JRST RETM1 ;-1 IF NOT KNOWN
25 ;.RDATE AC, ;RETURNS SIXBIT YYMMDD IN AC
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
33 ;.RTIME AC, ;RETURNS SIXBIT HHMMSS (24 HOUR TIME) IN AC
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
41 ;.RDATIM AC, ;DOES .RTIME TO AC, .RDATE TO AC+1
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
53 ;.RYEAR AC, ;PUSHJ'S TO RYEAR AND MOVEM'S E TO AC
55 ARYEAR: PUSHJ P,RYEAR ;GET THE CRUFT
56 UMOVEM E,(J) ;STORE YEAR AND CRUD
59 ;.RLPDT AC, ;DOES .RYEAR AC+1, AND ALSO MOVEM'S A TO AC
61 ARLPDT: PUSHJ P,RYEAR ;GET THE CRUFT
62 UMOVEM E,1(J) ;STORE YEAR AND CRUD
63 JRST APTUAJ ;STORE TIME AND RETURN
65 ;ROUTINE TO RETURN -1 ON AN OPER
67 RETM1: XCTR XRW,[SETOM (J)]
70 ;GET THE CORRECTED PDUPS*<# SECS SINCE BEGINNING OF YEAR> IN A
71 ;SKIP IF OFFSET AVAILABLE AND CLOCK ON
75 SKIPN A,PDTIME ;GET THE OFFSET
76 JRST GPDTM2 ;NOT AVAILABLE
77 DATAI PDCLK,B ;GET WHAT THE CLOCK IS SAYING
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)
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?)
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
102 ;GET SIXBIT YYMMDD (DATE) IN A (LOCALIZED PDTIME/SPD IN A, YEAR IN RH(E))
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
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
115 ;GET MONTH (1 => JAN) IN B, DAY (1 => THE FIRST) IN C
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
124 LMNTBL: MNIRP [<M 1>] ;TABLE OF DAYS GONE BY AT BEGINNING OF MONTH
126 ;GET THE SIXBIT TIME IN A (# SECS SINCE MIDNIGHT IN B)
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
136 ;DEPOSIT C(C) AS TWO SIX BIT (AS OPPOSED TO SIXBIT) DECIMAL DIGITS
137 ; VIA T (INTO A) THEN DECREMENT T
139 RDATM1: IDIVI C,10. ;SEPARATE DIGITS
140 DPB C,[60600,,D] ;DEPOSIT FIRST DIGIT TO GIVE 12 BITS
142 ADD T,[140000,,] ;DECREMENT BYTE POINTER
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
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
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
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
167 ;NOTE: THE SYMS JAN, FEB, MAR, ETC. ARE DEFINED AFTER (AND BY) MNIRP (A MACRO)
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
178 AOS FYEAR ;INCREMENT YEAR
180 ;INSERT OTHER CRUFT HERE IF DESIRED
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.)
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
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
213 AOS (P) ;CAUSE RETURN TO SKIP
215 ;IF DAYLIGHT SAVINGS TIME THEN ADD 3600. TO A AND SET BIT 4.7 IN E
217 GLPDT2: JFCL ;POPJ FOR STD TIME
218 ;JRST CRDDST FOR DAY LIGHT TIME
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
230 ;IT IS NOW SOMETIME DURING THE WEEKS IN APR AND OCTOBER
231 ;WHEN IT MAY BE EITHER STANDARD OR DAYLIGHT SAVINGS TIME
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...
243 ADD A,C ;ADD TO NUMBER OF DAYS
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
254 CRDSB: 7200. ;IN APR CHANGES AT 2AM EST
255 3600. ;IN OCTOBER CHANGES AT 1AM EST
257 CRDTST: CAIGE A,<APR 1>
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
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,
267 TLO E,400000 ;365 DAY YEAR AFTER FEB 28, SET BIT 4.9 OF E
268 ADDI A,SPD ;INCREMENT A ONE DAY
271 ;GET DAY OF WEEK OF BEGINNING OF YEAR (IN E) (0 => SUNDAY) IN B
272 ;FOLLOWING ROUTINE HAS BEEN EXHAUSTIVELY CHECKED
274 GDWOBY: MOVEI A,-1(E)
284 ;SLOW CLOCK ROUTINE TO CHECK ON REAL-TIME CLOCK SYSTEM
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,
290 AOS A,TIMOFF ;UPDATE TIMOFF
291 CAMGE A,[2*SPD] ;Incremented beyond length of day?
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.
299 SKIPN A,PDTIME ;MAYBE UPDATE BACKUP SYSTEM
300 JRST INITM2 ;PDTIME NOT AVAILABLE, DON'T
303 JUMPE B,INITM2 ;JUMP IF CLOCK OFF
306 IDIVI A,30. ;CONVERT TO HALF-SECONDS SINCE BEGINNING OF YEAR
307 MOVEM A,PDYTIM ;STORE RE-CALCULATED BACKUP TIME
310 SKIPN PDTIME ; Update backup system?
311 JRST INITM2 ; Not without offset
315 JRST INITM2 ; Not if clock reset
317 SUB A,PDTIME ; 60ths since Jan 1
319 IDIVI A,30. ; halfs since Jan 1
320 MOVEM A,PDYTIM ; Store backup
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
342 JRST UTCONJ ;THAT'S ALL
344 CLCQDT: PUSHJ P,RDATE1 ;GET DAY OF MONTH IN C, MONTH IN B
345 SETZM QDATE ;INITIALIZE FOR FOLLOWING
350 DPB E,[330700,,QDATE] ;YEAR
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.
358 MOVEM C,QDATEI ;MECHANISM IS, SET QDATEI UNLESS ALREADY SET.