mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-26 18:29:56 +00:00
4325cdcc78
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
225 lines
6.5 KiB
Plaintext
225 lines
6.5 KiB
Plaintext
;EASE$$$ READ ONLY COPY of file Òsexydate.aÓ
|
|
; 1.1 CCH 11/10/1988 Fixed Header.
|
|
; 1.0 CCH 11/ 9/1988 Adding to EASE.
|
|
; OLD REVISIONS BELOW
|
|
; 1.0 BBM 2/11/88 Adding file for the first time into EASEÉ
|
|
; END EASE MODIFICATION HISTORY
|
|
; File SexyDate.TEXT
|
|
;
|
|
; Routines to convert between number of seconds elapsed since 1904 Jan 1 00:00:00 am
|
|
; and date: year / month / day / hour / min / sec / (day of week).
|
|
; Written by Jerome T. Coonen 2 July 1983
|
|
;
|
|
; Seconds: unsigned 32-bit integer passed in D0.
|
|
;
|
|
; Date: array of 7 16-bit integers pointed to by A0.
|
|
; 0: year -- 1904, 1905, ...
|
|
; 1: month -- 1, 2, ..., 12
|
|
; 2: day -- 1, 2, ..., 31
|
|
; 3: hour -- 0, 1, ..., 24
|
|
; 4: minute -- 0, 1, ..., 59
|
|
; 5: second -- 0, 1, ..., 59
|
|
; 6: weekday -- 1, 2, ..., 7 corresponding to Sun, Mon, ..., Sat
|
|
;
|
|
|
|
BLANKS ON
|
|
STRING ASIS
|
|
|
|
SEXYDATE PROC EXPORT
|
|
EXPORT SECS2DATE, DATE2SECS
|
|
|
|
SECS2DATE
|
|
MOVEM.L D0-D4/A0,-(SP) ; SAVE WORKING REGISTERS
|
|
|
|
;
|
|
; Have number of seconds N 1904 in D0. Compute
|
|
; DN = number of days elapsed = N div 86400 where 86400 = 24 * 60 * 60
|
|
; HMS = number of seconds in last day = N mod 86400.
|
|
; Since 86400 > 2^31-1 cannot use 68000 DIVU directly. Instead, divide halved number
|
|
; of seconds by 43200. To get HMS, must double computed mod (with 43200) and add in the
|
|
; low order bit of the input N.
|
|
;
|
|
MOVEQ #0,D1 ; INIT HMS
|
|
LSR.L #1,D0 ; N DIV 2, WITH ODD BIT TO X
|
|
ROXR.L #1,D1 ; GET X BIT IN HI SLOT, FOR LATER ROTATE
|
|
DIVU #43200,D0
|
|
SWAP D0 ; GET MOD 43200 IN D0.W
|
|
MOVE.W D0,D1 ; HALF THE MOD IN D1.W
|
|
ROL.L #1,D1
|
|
CLR.W D0 ; WANT LONG DN
|
|
SWAP D0 ; DN
|
|
|
|
;
|
|
; YearsGone = (DN * 4) div 1461 where 1461 is 4*365+1
|
|
; Formula depends on leap year being the first of the four.
|
|
;
|
|
MOVE.L D0,D2 ; COPY DN
|
|
ASL.L #2,D2 ; DN * 4
|
|
DIVU #1461,D2 ; YEARSGONE = (DN * 4) DIV 1461
|
|
ADDI.W #1904,D2 ; YEAR
|
|
MOVE.W D2,(A0)+
|
|
|
|
;
|
|
; Need number of days in Jan+Feb just below. So take YEAR mod 3 before clearing year.
|
|
;
|
|
MOVEQ #59,D3 ; ASSUME NOT LEAP YEAR
|
|
ANDI.W #3,D2 ; YEAR MOD 3
|
|
BNE.S SDNOTLEAP
|
|
ADDQ.W #1,D3
|
|
SDNOTLEAP
|
|
CLR.W D2 ; LEAVE 4 * DOY = DAY OF YEAR IN HI WORD
|
|
SWAP D2
|
|
LSR.W #2,D2 ; D0Y
|
|
|
|
;
|
|
; Computing Month/Day from DOY is an exercise in interpolation. As a function of DOY,
|
|
; MONTH is a step function. Because of the leap year glitch, convenient to restart
|
|
; function at March.
|
|
;
|
|
; DOY MONTH
|
|
;-------------------------------------------------------------------
|
|
; 0-30 1 -- January
|
|
; 31-58/59 2 -- February (depends on whether leap year)
|
|
;
|
|
; 0-30 3 -- March
|
|
; 31-60 4 -- April
|
|
; 61-91 5 -- May
|
|
; 92-121 6 -- June
|
|
; 122-152 7 -- July
|
|
; 153-183 8 -- August
|
|
; 184-213 9 -- September
|
|
; 214-244 10 -- October
|
|
; 244-274 11 -- November
|
|
; 275-305 12 -- December
|
|
;
|
|
; The linear interpolator is ((DOY * 128) + 71) div 3919.
|
|
;
|
|
MOVEQ #1,D4 ; MONTH OFFSET, 1 OR 3
|
|
CMP.W D3,D2 ; 59/60 VERSUS DOY
|
|
BLT.S SDJANORFEB ; LESS THAN MEANS JAN OR FEB
|
|
ADDQ.W #2,D4 ; ADJUST MONTH OFFSET
|
|
SUB.W D3,D2 ; START DOY AT MARCH
|
|
SDJANORFEB
|
|
LSL.L #7,D2 ; DOY * 128
|
|
MOVEQ #71,D3
|
|
ADD.L D3,D2 ; (DOY * 128) + 71
|
|
DIVU #3919,D2 ; ((DOY * 128) + 71) DIV 3919
|
|
ADD.W D4,D2 ; ADJUST MONTH 1..12
|
|
SWAP D2 ; HAVE MONTH | DAY-1
|
|
LSR.W #7,D2 ; DIVIDE BY 128 TO GET DAY OF MONTH
|
|
ADDQ.W #1,D2 ; DAY 1..31
|
|
MOVE.L D2,(A0)+
|
|
|
|
;
|
|
; HOURS = HMS div 3600
|
|
; MS = HMS mod 3600 = minutes/seconds
|
|
; MINUTES = MS div 60
|
|
; SECONDS = MS mod 60
|
|
;
|
|
DIVU #3600,D1 ; HMS DIV 3600
|
|
MOVE.W D1,(A0)+ ; HOURS
|
|
CLR.W D1
|
|
SWAP D1 ; MS
|
|
DIVU #60,D1 ; SECONDS | MINUTES
|
|
SWAP D1
|
|
MOVE.L D1,(A0)+ ; MINUTES | SECONDS
|
|
|
|
;
|
|
; Finally get the day of week = ((DN + 5) mod 7) + 1
|
|
; The 5 is added since 1 Jan 1904 was a Friday.
|
|
;
|
|
ADDQ.W #5,D0
|
|
DIVU #7,D0
|
|
SWAP D0
|
|
ADDQ.W #1,D0
|
|
MOVE.W D0,(A0)
|
|
|
|
;
|
|
; Clean up stack and return.
|
|
;
|
|
MOVEM.L (SP)+,D0-D4/A0
|
|
RTS
|
|
|
|
|
|
;
|
|
; Have year / month / day / hours / min / sec in a sequence of words pointed to by A0.
|
|
; Deduce number of seconds since 1904, and return in D0.
|
|
;
|
|
; Since a date is no more than a representation of time in a bizarre mixed radix,
|
|
; the computation reduces to:
|
|
; DAYSGONE * 86400 + HOURS * 3600 + MINUTES * 60 + SECONDS
|
|
; The hard part is deducing the DAYSGONE from the YEAR / MONTH / DAY.
|
|
;
|
|
DATE2SECS
|
|
MOVEM.L D1-D4,-(SP) ; WORKING REGISTERS
|
|
|
|
;
|
|
; Do the easy part with HOURS, MINUTES, and SECONDS.
|
|
;
|
|
MOVEQ #0,D0 ; INIT SECOND COUNT
|
|
ADDQ.L #8,A0 ; POINT TO MINUTES/SECONDS
|
|
MOVE.L (A0),D1 ; MINUTES | SECONDS
|
|
MOVE.W D1,D0 ; SECONDS
|
|
SWAP D1 ; MINUTES
|
|
MOVE.W -(A0),D2 ; HOURS
|
|
MOVEQ #60,D3
|
|
MULU D3,D2 ; HOURS * 60
|
|
ADD.W D1,D2 ; (HOURS * 60) + MINUTES
|
|
MULU D3,D2 ; ((HOURS * 60) + MINUTES) * 60
|
|
ADD.L D2,D0
|
|
|
|
;
|
|
; Compute DAYSGONE in D1.
|
|
;
|
|
MOVE.W -(A0),D1 ; DAYS
|
|
SUBQ.W #1,D1
|
|
MOVE.W -(A0),D2 ; MONTH
|
|
MOVE.W -(A0),D3 ; YEAR, AND A0 IS BACK TO INPUT VALUE
|
|
|
|
MOVE.W D3,D4 ; COPY YEAR FOR LEAP TEST
|
|
|
|
;
|
|
; To find number of days in elapsed years use ((YEARSGONE * 1461) + 3) div 4.
|
|
; Formula depends on leap year being the first of a quartet.
|
|
;
|
|
SUBI.W #1904,D3 ; YEARSGONE
|
|
MULU #1461,D3 ; YEARSGONE * 1461
|
|
ADDQ.L #3,D3 ; (YEARSGONE * 1461) + 3
|
|
LSR.L #2,D3 ; ((YEARSGONE * 1461) + 3) DIV 4
|
|
ADD.W D3,D1 ; ACCUMULATE DAYSGONE
|
|
|
|
;
|
|
; As above, the tough part is finding the number of days in the elapsed months.
|
|
; The function to be interpolated is in a sense the inverse of the step function above.
|
|
; The interpolating function is ((MONTHSGONE * 3917) + 52) div 128.
|
|
;
|
|
SUBQ.W #1,D2 ; MONTH-1 RANGES 0..11
|
|
CMPI.W #1,D2 ; 2 OR MORE IS MARCH...
|
|
BLE.S DSJANORFEB
|
|
|
|
SUBQ.W #2,D2 ; MONTH-3, RESTART INTERP AT MARCH
|
|
MOVEQ #59,D3 ; DAYS IN JAN AND FEB
|
|
ANDI.W #3,D4 ; CHECK FOR LEAP YEAR, MOD 3
|
|
BNE.S DSNOTLEAP
|
|
ADDQ.W #1,D3
|
|
DSNOTLEAP
|
|
ADD.W D3,D1 ; SOME MORE ELAPSED DAYS
|
|
DSJANORFEB
|
|
MULU #3917,D2 ; (MONTHSGONE * 3917)
|
|
ADDI.W #52,D2 ; (MONTHSGONE * 3917) + 52
|
|
LSR.W #7,D2 ; ((MONTHSGONE * 3917) + 52) DIV 128
|
|
ADD.W D2,D1 ; MORE ELAPSED DAYS
|
|
|
|
;
|
|
; Finally multiply the number of days elapsed by 24*60*60 = 86400 = 43200*2
|
|
;
|
|
MULU #43200,D1
|
|
ADD.L D1,D1
|
|
ADD.L D1,D0
|
|
|
|
MOVEM.L (SP)+,D1-D4
|
|
RTS
|
|
|
|
END
|
|
|