1
0
mirror of https://github.com/PDP-10/its.git synced 2026-04-07 06:16:30 +00:00

Add KLH's TIMRTS library, needed by GUNNER 6.

This commit is contained in:
Lars Brinkhoff
2023-07-13 15:07:59 +02:00
parent c9ed641d1b
commit bb10ad46ff
2 changed files with 483 additions and 0 deletions

View File

@@ -1041,6 +1041,7 @@ ksc/nscan.8 197709130702.35
ksc/pagser.49 198510290114.12
ksc/qmail.614 198808140012.29
ksc/timer.115 198712180208.41
ksc/timrts.42 198504142018.45
ksc/zotz.12 198712150308.01
kshack/1proc.bugs 198605312354.25
kshack/ainote.8 198610240402.35

482
src/ksc/timrts.42 Executable file
View File

@@ -0,0 +1,482 @@
SUBTTL Time routines - readin', ritin', & rithmetic for dates/times
IFN $$OUT*$$OTIM, .FATAL OUT pkg now uses DATIME library
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; These routines will work fine unless dumped after
;;; execution. To ensure complete winnage, call PUSHJ P,TIMINI
;;; to initialize words such as TMDSTF and TMSYST.
;;;
;;; Internal format time word: a single word serves to define date/time
;;; as follows. This is identical to ITS DSK format date, except
;;; for the use of bit 1.1 as Daylight Saving Time indicator. (ugh!)
; Mask Field Bits Range Var. Variable range
TM%DST== 1 ; 1.1 0-1 half-sec or DST indicator.
TM%SEC== 777776 ; 2.9-1.2 0-131K seconds 0-86399.
TM%DAY== 37,,0 ; 3.5-3.1 0-31 days 1-31
TM%MON== 740,,0 ; 3.9-3.6 0-15 months 1-12
TM%YR== 177000,,0 ; 4.7-4.1 0-127 years 0-127 relative to 1900 (1900-2027)
TM$SEC==(.BP TM%SEC,) ; Define BP LH's into each field.
TM$DAY==(.BP TM%DAY,)
TM$MON==(.BP TM%MON,)
TM$YR== (.BP TM%YR,)
GMTDIF==5 ; # hours difference of local zone from GMT.
; Table for printing day-of-week, indexed by 1-7.
; Use TIMADY to find abs time in days; divide by 7 and
; remainder (plus 1) is index into DOW tables.
DOWTB: ; preferred label.
TDAYTB: 0
IRP D,,[MON,TUE,WED,THU,FRI,SAT,SUN]
3,,[ASCIZ /D/] ; All strings of length 3.
TERMIN
; Table for long-form Day-Of-Week, indexed by 1-7.
LDOWTB: 0
IRP D,,[Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday]
.LENGTH "D",,[ASCIZ "D"]
TERMIN
; Table for printing month, indexed by 1-12.
MONTAB: 0
IRP M,,[JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC]
3,,[ASCIZ /M/] ; All strings length 3.
TERMIN
; Table for printing month, indexed by 1-12.
LMNTAB: 0
IRP M,,[January,February,March,April,May,June,July,August,September,October,November,December]
.LENGTH "M",,[ASCIZ "M"]
TERMIN
; Table containing # of days in each month, assuming non-leap year.
TMONLN: 0 ; no 0'th month.
;JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC
31. ? 28. ? 31. ? 30. ? 31. ? 30. ? 31. ? 31. ? 30. ? 31. ? 30. ? 31.
; Special table to allow figuring how many days so far
; in this year. Indexed by month # (1-12) gives # days
; taken up by months preceding it. Assumes non-leap year.
TMONTB: 0
0
31. ;+jan
59. ;+jan+feb
90. ;+jan+feb+mar...
120. ;...+apr
151. ;...+may
181. ;...+jun
212. ;...+jul
243. ;...+aug
273. ;...+sep
304. ;...+oct
334. ;...+nov
LVAR TMBUF: BLOCK 8. ; Various composed strings stored here.
; TIMINI - Initializes time routines and makes sure system knows the
; time; fails to skip if it doesn't.
TIMINI: PUSH P,A
SETZM TMDSTF ; Clear DST flag
SETZM TMSYST ; and time system started.
SYSCAL RQDATE,[CRET A] ; Try to get time.
JSR SYSLOS
CAME A,[-1] ; Skip if don't know time.
AOS -1(P) ; Else skip on return!
POP P,A
POPJ P,
; TIMGET - Returns internal time word in A.
; TIMGT - Similar but doesn't bother to hack DST bit.
TIMGT: SYSCAL RQDATE,[CRET A] ; Get DSK format date.
JSR SYSLOS
CAMN A,[-1]
JSR AUTPSY ; Ugh, system doesn't know time.
POPJ P,
TIMGET: SYSCAL RQDATE,[CRET A]
JSR SYSLOS
CAMN A,[-1] ; Make sure system knows time.
JSR AUTPSY
TRZ A,TM%DST ; Assume Standard Time in effect.
SKIPN TMDSTF ; Skip if Standard/Savings flag known.
PUSHJ P,TMDSTG ; If not, get it.
SKIPGE TMDSTF ; Now if Daylight Savings in effect,
TRO A,TM%DST ; set flag.
POPJ P,
LVAR TMDSTF: 0 ; Flag for Daylight Savings Time. + Standard, - Savings, 0 don't know.
TMDSTG: PUSH P,A ; Routine to set TMDSTF.
.RYEAR A,
CAMN A,[-1]
JSR AUTPSY
SETOM TMDSTF ; Assume DST in effect.
TLNN A,100000 ; If bit is set, that's right.
MOVMS TMDSTF ; Else Standard, make flag positive.
POP P,A
POPJ P,
LVAR TLZONP: 0 ; Local Timezone, standard (BP to ASCIZ)
LVAR TLZONQ: 0 ; Local Timezone, Daylite Savings (BP to ASCIZ)
; TMZONG - Get Local Time-Zone strings.
; At moment simply sets, since ITS has no way of asking for
; time-zone... TNX version could win though.
TMZONG: PUSH P,A
MOVE A,[440700,,[ASCIZ /EST/]]
MOVEM A,TLZONP
MOVE A,[440700,,[ASCIZ /EDT/]]
MOVEM A,TLZONQ
POP P,A
RET
; TIMGTN - Gets 32-bit "Network time" in A. This is GMT in # seconds since
; 1/1/00.
TIMGTN: PUSHAE P,[B,C]
.RLPDTM A, ; Get in A, # secs since beg of year.
CAME A,[-1] ; in B, the year
CAMN B,[-1]
JSR AUTPSY ; If either is -1, time not known.
CAIGE B, ; If 4.9 on, it's past Feb 28 and non-leap-yr
SUBI A,24.*3600. ; so subtract one day from .RLPDTM misfeature.
TLNE B,100000 ; Bit 4.7 = Daylight Savings time?
SUBI A,3600. ; If on, subtract one hour to get Standard.
MOVEI B,-1900.(B) ; Get year, relative to 1900.
MOVEI C,-1(B) ; Adjust and
LSH C,-2 ; Get # leap years since 1900 not including this year.
IMULI B,365. ; Find # days in years thus far
ADDI B,(C) ; Plus # LY's, to get total days in years past.
IMULI B,86400. ; Now get # seconds in all them days.
ADD A,B ; and produce total seconds since 1/1/00 !
ADD A,[GMTDIF*3600.] ; Adjust to GMT.
POPAE P,[C,B]
POPJ P,
IFNDEF $$OUT,$$OUT==0 ? $$OTIM==0
IFE $$OUT*$$OTIM,[
; Don't need following cruft any more if using OUT.
; TIMDAT - Takes time word in A, returns ASCNT ptr in A to string
; at TMBUF of format <MM/DD/YY>.
TIMDAT: PUSHAE P,[B,C,D]
MOVE D,[440700,,TMBUF] ; Set up BP for date composer.
PUSHJ P,TMDAT
MOVE A,[8.,,TMBUF]
POPAE P,[D,C,B]
POPJ P,
; TIMTIM - Like TIMDAT, but string is time in format <HH:MM:SS>.
TIMTIM: PUSHAE P,[B,C,D]
MOVE D,[440700,,TMBUF]
PUSHJ P,TMTIM
MOVE A,[8.,,TMBUF]
POPAE P,[D,C,B]
POPJ P,
; TIMDTM - Combination of TIMDAT and TIMTIM, produces <MM/DD/YY HH:MM:SS>.
TIMDTM: PUSHAE P,[B,C,D]
MOVE D,[440700,,TMBUF]
PUSHJ P,TMDAT
MOVEI B,40 ; Put in a spacer.
IDPB B,D
PUSHJ P,TMTIM
MOVE A,[17.,,TMBUF]
POPAE P,[D,C,B]
POPJ P,
; TMDAT - Internal rtn to deposit MM/DD/YY using BP in D.
; Takes time wd in A, clobbers B and C.
TMDAT: PUSH P,E
SKIPA E,[-3,,[ TM$MON,,A
TM$DAY,,A
TM$YR,,A ] ]
TMDT2: IDPB B,D
LDB B,(E) ; Get numerical value into B.
IDIVI B,10. ; Divide into 2 digits.
MOVEI B,"0(B)
IDPB B,D ; Output first,
MOVEI B,"0(C)
IDPB B,D ; and second.
MOVEI B,"/ ; Set up separator, in case looping again.
AOBJN E,TMDT2
POP P,E
POPJ P,
; TMTIM - Internal rtn to deposit HH:MM:SS using BP in D.
; Takes time wd in A, clobbers B and C.
TMTIM: PUSH P,E
HRRZ B,A ; For storage of hr, min, sec.
LSH B,-1
IDIVI B,60. ; Get secs
PUSH P,C ; save
IDIVI B,60. ; Get hr and mins
PUSH P,C ; Save mins too.
MOVSI E,-3
JRST TMTM3
TMTM2: IDPB B,D
POP P,B ; Get numerical value into B.
TMTM3: IDIVI B,10. ; Divide into 2 digits.
MOVEI B,"0(B)
IDPB B,D ; Output first,
MOVEI B,"0(C)
IDPB B,D ; and second.
MOVEI B,": ; Set up separator, in case looping again.
AOBJN E,TMTM2
POP P,E
POPJ P,
; TIMEXP - Takes time wd in A, returns ASCNT ptr to string in TMBUF
; of the form <7 AUG 1976 0831-EDT>.
; TIMENG - similar but uses current time and takes no arg.
TIMENG: PUSHJ P,TIMGET
TIMEXP: PUSHAE P,[B,C]
PUSH P,[19.,,TMBUF] ; Save probable result on stack.
PUSH P,A ; Save time wd.
MOVE C,[440700,,TMBUF] ; Put string in special location.
LDB A,[TM$DAY,,(P)] ;get day
IDIVI A,10.
JUMPN A,[MOVEI A,"0(A)
IDPB A,C
MOVSI A,1
ADDM A,-1(P) ; increment length of ASCNT ptr to return.
JRST .+1]
MOVEI A,"0(B)
IDPB A,C
MOVEI A,40
IDPB A,C ;space out
LDB A,[TM$MON,,(P)] ;get month
MOVE A,MONTAB(A) ;get ptr to string for it
HRLI A,440700
ILDB B,A
IDPB B,C
ILDB B,A
IDPB B,C
ILDB B,A
IDPB B,C ;3 chars
MOVEI A,40
IDPB A,C ;space out
LDB A,[TM$YR,,(P)] ;get year
ADDI A,1900. ;get real year
PUSHJ P,TIMCVT
MOVEI A,40 ;space out
IDPB A,C
HRRZ A,(P) ;get half-sec since midnight
IDIVI A,60.*2 ; get mins
IDIVI A,60. ; Get hrs in A, mins in B
IMULI A,100. ; space hrs out 2 digits
ADD A,B ;get total 'time'
MOVEI B,"0 ;crock to add (!) zeros so stupid
CAIGE A,1000. ;parsers will be happy (4 digits total)
IDPB B,C
CAIGE A,100.
IDPB B,C
CAIGE A,10.
IDPB B,C
PUSHJ P,TIMCVT
POP P,A ; Restore to test DST bit.
MOVE B,[440700,,[ASCIZ /-EST/]]
TRNE A,TM%DST
MOVE B,[440700,,[ASCIZ /-EDT/]] ; Use EDT if DST in effect.
ILDB A,B
IDPB A,C ;note nice hack..makes asciz when done.
JUMPN A,.-2
POP P,A ; Return ASCNT ptr to result
POPAE P,[C,B]
POPJ P,
TIMCVT: IDIVI A,10.
JUMPE A,TIMCV1
PUSH P,B
PUSHJ P,TIMCVT
POP P,B
TIMCV1: ADDI B,"0
IDPB B,C
POPJ P,
; LTMEXP - Takes time wd in A, returns ASCNT ptr to string in TMBUF
; of the form <7 August 1976 08:31 EDT>.
; LTMENG - similar but uses current time and takes no arg.
LTMENG: PUSHJ P,TIMGET
LTMEXP: PUSHAE P,[B,C,D]
PUSH P,A ; Save time wd.
MOVE C,[440700,,TMBUF] ; Put string in special location.
MOVEI D,17.
LDB A,[TM$DAY,,(P)] ;get day
IDIVI A,10.
JUMPN A,[MOVEI A,"0(A)
IDPB A,C
AOJA D,.+1 ]
MOVEI A,"0(B)
IDPB A,C
MOVEI A,40
IDPB A,C ;space out
LDB A,[TM$MON,,(P)] ;get month
MOVE A,LMNTAB(A) ;get ptr to string for it
HRLI A,440700
ILDB B,A
LTME1: IDPB B,C
ADDI D,1
ILDB B,A
JUMPN B,LTME1
MOVEI A,40
IDPB A,C ;space out
LDB A,[TM$YR,,(P)] ;get year
ADDI A,1900. ;get real year
PUSHJ P,TIMCVT
MOVEI A,40 ;space out
IDPB A,C
HRRZ A,(P) ;get half-sec since midnight
IDIVI A,60.*2 ; get mins
IDIVI A,60. ; Get hrs in A, mins in B
PUSH P,B
IDIVI A,10.
ADDI A,"0
IDPB A,C
ADDI B,"0
IDPB B,C
MOVEI A,":
IDPB A,C
POP P,A
IDIVI A,10.
ADDI A,"0
IDPB A,C
ADDI B,"0
IDPB B,C
POP P,A ; Restore to test DST bit.
MOVE B,[440700,,[ASCIZ / EST/]]
TRNE A,TM%DST
MOVE B,[440700,,[ASCIZ / EDT/]] ; Use EDT if DST in effect.
ILDB A,B
IDPB A,C ;note nice hack..makes asciz when done.
JUMPN A,.-2
MOVS A,D ; Return ASCNT ptr to result
HRRI A,TMBUF
POPAE P,[D,C,B]
POPJ P,
] ;IFE $$OUT*$$OTIM
; TIMADY - Time in Absolute Days. Converts time wd in A to absolute
; # of days since Jan 1 1900, returns value in same.
TIMADY: PUSHAE P,[B,C]
LDB B,[TM$MON,,A] ;get month #
LDB C,[TM$DAY,,A] ;get day #
ADD C,TMONTB(B) ;add days in months thus far to # days thus far in month
LDB A,[TM$YR,,A] ;get year
JUMPE A,TIMAD7 ; Avoid 1900 lossage.
TRNE A,3 ;is this a leap yr? (only works until 2000)
JRST .+3 ;no, skip additional day
CAIL B,3 ;leap yr... is it after feb?
ADDI C,1 ;yes, add extra day.
MOVEI B,-1(A) ;adjust, and
LSH B,-2 ;get # of l.y. since 1900, not incl. this yr
IMULI A,365. ;# yrs times 365
ADDI A,(B) ;plus # prior l.y.'s (# extra days)
TIMAD7: ADDI A,-1(C) ;plus days so far this yr (-1 because day 1 of month
POPAE P,[C,B] ; is really 0)
POPJ P,
; TIMASC - Similar to TIMADY, but returns value in seconds.
; Value is 31,536,000. per yr (32 bits for 136 yrs).
TIMASC: PUSH P,B
HRRZ B,A ; Get # half-secs
LSH B,-1 ; # secs.
PUSHJ P,TIMADY ; Get # days.
IMULI A,24.*60.*60.
ADDI A,(B) ; Add # secs for today to # secs of days past.
POP P,B
POPJ P,
; TIMCAD - Convert Absolute Days to time word. Inverse of TIMADY.
; Takes # days since 1/1/00 in A, returns time wd in same.
TIMCAD: PUSHAE P,[B,C]
IDIVI A,365. ;find # "normal" years.
JUMPE A,TIMCA2 ; Avoid 1900 lossage.
MOVEI C,-1(A) ;now see how many leap years covered (not incl current)
LSH C,-2 ;divide by 4 to get # leap yrs
SUBI B,(C) ;adjust cnt of remaining days
JUMPL B,[SUBI A,1 ;backed past year boundary? bump down # yrs
ADDI B,365. ;if negative, must adjust again
TRNN A,3 ;if in leap year,
ADDI B,1 ;add one more since 366. days in LY
JRST .+1]
TIMCA2: MOVEI C,12.
CAMGE B,TMONTB(C) ;compare # days in year with # days after each month
SOJG C,.-1 ;loop (#1 index has 0 value, so it will stop)
TRNN A,3 ;leap year?
JRST [ CAIGE C,3 ;ugh, yes. but if in jan or feb,
JRST .+1 ;saved. else it's after feb and must hack it.
SUBI B,1 ;lower value
CAMGE B,TMONTB(C) ;still wins?
SUBI C,1 ;if not, bump month down.
CAIN C,2 ;if now in Feb,
AOJA B,.+1 ;restore value so subtracting TMONTB gives 29, not 28.
JRST .+1]
SUB B,TMONTB(C) ;get # of day within month
DPB A,[TM$YR,,A] ;deposit year
DPB C,[TM$MON,,A] ;and month
MOVEI B,1(B) ; First day of month is day 1, not day 0.
DPB B,[TM$DAY,,A] ;and day.
ANDCMI A,-1 ;Zap RH to start of day.
POPAE P,[C,B]
POPJ P,
; TIMCAS - Converts Absolute Seconds to time word.
; Argument in A (# secs since 1/1/00), returns time wd in A.
TIMCAS: PUSH P,B
IDIVI A,24.*60.*60. ; Get remainder of # secs in day
PUSHJ P,TIMCAD ; Find time wd given # days.
LSH B,1
ADDI A,(B) ; Add in # half secs.
POP P,B
POPJ P,
; TIMASY - Converts internal time wd. to system time
; ( 30'ths of second since system startup). Will return
; negative value if time specified is BEFORE system startup.
TIMASY: PUSHJ P,TIMASC ; Convert given time to absolute # secs.
SKIPN TMSYST ; If don't already have system startup time,
PUSHJ P,TMSYSG ; must get it.
SUB A,TMSYST ; Find difference in secs.
IMULI A,30. ; Turn into 30'ths.
POPJ P,
LVAR TMSYST: 0 ; Holds time of system startup in absolute # secs.
TMSYSG: PUSHAE P,[A,B,C]
PUSHJ P,TIMGT ; Get current date/time in internal format
.RDTIME B, ; And time since system startup.
PUSHJ P,TIMASC ; Convert date/time to abs # seconds.
IDIVI B,30. ; Similarly get # secs since system startup.
SUB A,B ; Now get abs # secs at which system started.
MOVEM A,TMSYST ; Store it.
POPAE P,[C,B,A]
POPJ P,