A2osX/SYS/KERNEL.S.TIME.txt
2019-12-04 14:46:58 +01:00

480 lines
9.8 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.

NEW
AUTO 3,1
*--------------------------------------
* https://www.cise.ufl.edu/~cop4600/cgi-bin/lxr/http/source.cgi/lib/ansi/gmtime.c
*--------------------------------------
SECSDAY .EQ 86400 60*60*24
CENTURY0 .EQ 19
YEAR0 .EQ 70
DAY0 .EQ 4 day 0 was a thursday
*/--------------------------------------
* # Time
* Get System Time in Buffer
* ## C
* `time_t time (S.TIME* timer);`
* ## ASM
* `>LDYA timer`
* `>SYSCALL time`
* ## RETURN VALUE
* S.TIME filled with System date/time
*\--------------------------------------
K.Time >PUSHYA
>MLICALL MLIGETTIME
>LDYAI DATELO
*/--------------------------------------
* # PTime2Time
* Convert ProDOS Time To S.TIME
* ## C
* `int PTime2Time (long* ptime, S.TIME* timer);`
* ## ASM
* `>PUSHW timer`
* `>LDYA ptime`
* `>SYSCALL PTime2Time`
* ## RETURN VALUE
*\--------------------------------------
K.PTime2Time >STYA ARG32
>PULLW ARG32+2
* jsr SHARED.SPtr1PPtr2
ldy #1
lda (ARG32),y Get Year
lsr C is high bit of month
ldy #S.Time.YEAR
sta (ARG32+2),y set year
sta ACC32+3 for computing Century/WDAY later
lda (ARG32) Get Month/day
pha save Day
ror
lsr
lsr
lsr
lsr
ldy #S.Time.MONTH
sta (ARG32+2),y set month
pla get back day
and #$1F
iny
sta (ARG32+2),y set day
lda ACC32+3 get back year
cmp #69 if before 70 CC,if > 70, CS
lda #0
rol get back C in bit 0
eor #1 toggle C
adc #19 set date before 1970 -> 20xx
sta (ARG32+2) set Century
sta ACC32+2 for computing WDAY later
ldy #2
lda (ARG32),y Get Min
tax
iny
lda (ARG32),y Get Hour
ldy #S.Time.HOUR
sta (ARG32+2),y set hour
iny
txa
sta (ARG32+2),y set min
iny
lda #0
sta (ARG32+2),y set seconds (ProDOS does not provide it)
*--------------------------------------
* 1/1/1970 was Thursday...if not leap, add one, if leap add 2
*--------------------------------------
clc
rts
K.ComputeWDAY lda #DAY0-1 Thursday : 4 (-1 for mod 7)
pha
lda #CENTURY0
sta ACC32
lda #YEAR0
sta ACC32+1
.1 ldy ACC32
lda ACC32+1
cpy ACC32+2
bne .2
cmp ACC32+3
beq .4
.2 jsr TIME.IsLeapYearYA CS = Leap
pla
adc #1 365 mod 7
cmp #7
bcc .3
sbc #7 MOD 7
.3 pha
inc ACC32+1
lda ACC32+1
cmp #100
bne .1
stz ACC32+1
inc ACC32
bra .1
*--------------------------------------
.4 ldy #S.Time.MONTH
lda (ARG32+2),y get month
tax
dex don't include actual month
beq .71
.5 clc assume NO leap
lda K.StrFTime.MDAY-1,x get day count in this month
bne .6 february ?
ldy ACC32+2
lda ACC32+3
jsr TIME.IsLeapYearYA CS = Leap
.6 pla
adc K.StrFTime.MDAY-1,x
cmp #7
bcc .7
sbc #7
.7 pha
dex
bne .5
.71 pla
ldy #S.Time.DAY
clc
adc (ARG32+2),y get day in month (1..31)
dec adjust range 0.30 for MOD 7
.8 cmp #7 MOD 7
bcc .80
sbc #7
bra .8
.80 inc adjust range 1..7
ldy #S.Time.WDAY
sta (ARG32+2),y
clc
rts
*/--------------------------------------
* # CTime2Time
* Convert CTime Time To S.TIME
* ## C
* `int CTime2Time (long* ctime, S.TIME* timer);`
* ## ASM
* `>PUSHW timer`
* `>LDYA ctime`
* `>SYSCALL CTime2Time`
* ## RETURN VALUE
*\--------------------------------------
K.CTime2Time jsr SHARED.SPtr1PPtr2
ldy #3
.1 lda (ZPPtr1),y
sta ARG32,y ARG = ctime
dey
bpl .1
lda #SECSDAY ACC = SECSDAY
sta ACC32
lda /SECSDAY
sta ACC32+1
lda ^SECSDAY
sta ACC32+2
stz ACC32+3
jsr MATH.DIVMOD32 ARG32 = Days, TMP32 = remaining secs
lda ARG32 WDAY computation : (ARG32 + DAY0) mod 7
clc
adc #DAY0
pha
lda ARG32+1 65535 days = 179 years
adc /DAY0
eor #$ff
tax
pla
.2 tay
sec
sbc #7
bcs .2
inx
bne .2
tya
ldy #S.Time.WDAY
sta (ZPPtr2),y
ldy #CENTURY0
sty ZPPtr3
lda #YEAR0
sta ZPPtr3+1
K.CTime2Time.Year
.1 ldy ZPPtr3
lda ZPPtr3+1
jsr TIME.IsLeapYearYA if Leap year CS
rol Toggle Carry
eor #1
lsr
lda ARG32
sbc #365
pha
lda ARG32+1
sbc /365
bcc .2
sta ARG32+1
pla
sta ARG32
inc ZPPtr3
lda ZPPtr3
cmp #100
bne .1
stz ZPPtr3
inc ZPPtr3+1
bne .1
.2 pla
lda ZPPtr3+1
* ldy #S.Time.CENTURY
sta (ZPPtr2)
ldy #S.Time.YEAR
lda ZPPtr3
sta (ZPPtr2),y
K.CTime2Time.HMS
ldx #3
.1 lda TMP32,x
sta ARG32,x
dex
bpl .1
ldy #S.TIME.SECOND
jsr .2
dey #S.TIME.MINUTE
jsr .2
dey #S.TIME.HOUR
lda ARG32
sta (ZPPtr2),y
clc
rts
.2 phy
lda #60
jsr MATH.A2ACC32
jsr MATH.DIVMOD32
ply
lda TMP32
sta (ZPPtr2),y
rts
*--------------------------------------
* In :
* Y = Century
* A = Year (0..99)
* if (year mod 400 = 0)
* or
* if not (year mod 100 = 0) and (year mod 4 = 0)
* Out :
* CS = Leap
* CC = Not Leap
*--------------------------------------
TIME.IsLeapYearYA
cmp #0 Year = 00 ?
bne .1 no
tya year = 00, get century in A
and #$3 Century mod 4 = 0 ?
beq .9 leap year (2000)
.8 clc not leap (1900)
rts
.1 and #$3 mod 4 = 0 ?
bne .8
.9 sec Leap
rts
*--------------------------------------
K.StrFTime.MDAY .DA #3,#0,#3,#2,#3,#2,#3,#3,#2,#3,#2,#3
*/--------------------------------------
* # StrFTime
* ## C
* Convert S.TIME struct to CSTR
* `void strftime (char* ptr, const char* format, const struct S.TIME* timeptr );`
* ## ASM
* `PUSHW timeptr`
* `PUSHW format`
* + %a : Abbreviated weekday name : Thu
* + %A : Full weekday name : Thursday
* + %b : Abbreviated month name : Aug
* + %B : Full month name : August
* + %d : Day of the month, zero-padded (01-31)
* + %H : Hour in 24h format (00-23) 14
* + %I : Hour in 12h format (01-12) 02
* + %m : Month as a decimal number (01-12) 08
* + %M : Minute (00-59) 55
* + %p : AM or PM designation PM
* + %S : Second (00-61) 02
* + %w : Weekday as a decimal number with Sunday as 0 (0-6)
* + %y : Year, last two digits (00-99)
* + %Y : Year four digits 2001
* `>LDYA ptr`
* `>SYSCALL strftime`
* ## RETURN VALUE
* none. always succeed.
*\--------------------------------------
K.StrFTime jsr SHARED.SPtr1PPtr2
>PULLW ZPPtr3 timeptr
.1 jsr SHARED.GetCharPtr2
beq .8
cmp #'%'
beq .2
jsr SHARED.PutCharPtr1
bra .1
.2 ldx #K.StrFTime.Cnt-1
jsr SHARED.GetCharPtr2
beq .8
.3 cmp K.StrFTime.Tbl,x
beq .4
dex
bpl .3
bra .1
.4 cpx #7
bcc .5
jsr K.StrFTime.AtX
bra .1
.5 txa
asl
tax
jsr .7
bra .1
.7 jmp (K.StrFTime.JMP,x)
.8 lda #0 Terminate C string
sta (ZPPtr1)
clc
rts
*--------------------------------------
K.StrFTime.Tbl .AS "aAbBIpYydHSwmM"
K.StrFTime.Cnt .EQ *-K.StrFTime.TBL
K.StrFTime.OfsX .DA #S.Time.YEAR,#S.Time.DAY,#S.Time.HOUR,#S.Time.SECOND,#S.Time.WDAY,#S.Time.MONTH,#S.Time.MINUTE
K.StrFTime.JMP .DA K.StrFTime.A
.DA K.StrFTime.AA
.DA K.StrFTime.B
.DA K.StrFTime.BB
.DA K.StrFTime.II
.DA K.StrFTime.P
.DA K.StrFTime.YY
*--------------------------------------
K.StrFTime.A sec Short day of week, 3 chars...
.HS 90 BCC
K.StrFTime.AA clc full DoW
lda #K.StrFTime.DAY
ldx /K.StrFTime.DAY
ldy #S.Time.WDAY
bra K.StrFTime.STR
K.StrFTime.B sec Short Month, 3 chars....
.HS 90 BCC
K.StrFTime.BB clc full Month....
lda #K.StrFTime.MON
ldx /K.StrFTime.MON
ldy #S.Time.MONTH
K.StrFTime.STR sta ZPPtr4
stx ZPPtr4+1
ldx #15
bcc .10
ldx #3
.10 lda (ZPPtr3),y get required S.Time field value
tay
beq .2 Illegal value, print ???
.1 lda (ZPPtr4)
sec
adc ZPPtr4
sta ZPPtr4
bcc .11
inc ZPPtr4+1
.11 dey
bne .1
.2
* ldy #0 Y is already 0
.3 iny
lda (ZPPtr4),y
jsr SHARED.PutCharPtr1
tya
cmp (ZPPtr4)
beq .8
dex
bne .3
.8 rts
*--------------------------------------
K.StrFTime.II ldy #S.Time.HOUR
lda (ZPPtr3),y
cmp #12
bcc K.StrFTime.addDecA
sbc #12
bra K.StrFTime.addDecA
K.StrFTime.P ldy #S.Time.HOUR
lda (ZPPtr3),y
cmp #12
bcc .1
lda #'p'
.HS 2C bit abs
.1 lda #'a'
jsr SHARED.PutCharPtr1
lda #'m'
jmp SHARED.PutCharPtr1
K.StrFTime.YY ldy #S.Time.CENTURY
jsr K.StrFTime.addDecPtr1Y
ldx #7 "y"
K.StrFTime.AtX ldy K.StrFTime.OfsX-7,x
*--------------------------------------
K.StrFTime.addDecPtr1Y
lda (ZPPtr3),y
K.StrFTime.addDecA
ldx #2
ldy #'0'
clc
jsr MATH.A2STR10
lda A2osX.NumStrBuf
jsr SHARED.PutCharPtr1
lda A2osX.NumStrBuf+1
jmp SHARED.PutCharPtr1
*--------------------------------------
K.StrFTime.DAY >PSTR "???"
>PSTR "Monday"
>PSTR "Tuesday"
>PSTR "Wednesday"
>PSTR "Thursday"
>PSTR "Friday"
>PSTR "Saturday"
>PSTR "Sunday"
*--------------------------------------
K.StrFTime.MON >PSTR "???"
>PSTR "January"
>PSTR "February"
>PSTR "March"
>PSTR "April"
>PSTR "May"
>PSTR "June"
>PSTR "July"
>PSTR "August"
>PSTR "September"
>PSTR "October"
>PSTR "November"
>PSTR "December"
*--------------------------------------
MAN
SAVE USR/SRC/SYS/KERNEL.S.TIME
LOAD USR/SRC/SYS/KERNEL.S
ASM