A2osX/SYS/KERNEL.S.TIME.txt
2019-02-20 16:07:43 +00:00

622 lines
12 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
PREFIX
AUTO 4,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
*--------------------------------------
.DUMMY
.OR ZPTMP
TIME.DWORD .BS 4
TIME.DivDay .BS 2
TIME.ModDay .BS 3
TIME.Div60 .BS 2
TIME.Mod .BS 1
TIME.Div3600 .BS 1
TIME.Century .BS 1
TIME.Year .BS 1
.ED
*/--------------------------------------
* # 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 >STYA ZPPtr2
>MLICALL MLIGETTIME
>LDYAI DATELO
>STYA ZPPtr1
bra TIME.PTime2TimeP1P2
*/--------------------------------------
* # 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 jsr MEM.SPtr1PPtr2
TIME.PTime2TimeP1P2
ldy #1
lda (ZPPtr1),y Get Year
lsr C is high bit of month
ldy #S.Time.YEAR
sta (ZPPtr2),y set year
sta TIME.Year for conputing Century/WDAY later
lda (ZPPtr1) Get Month/day
pha save Day
ror
lsr
lsr
lsr
lsr
ldy #S.Time.MONTH
sta (ZPPtr2),y set month
pla get back day
and #$1F
iny
sta (ZPPtr2),y set day
lda TIME.Year 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 (ZPPtr2) set Century
sta TIME.Century for conputing WDAY later
ldy #2
lda (ZPPtr1),y Get Min
tax
iny
lda (ZPPtr1),y Get Hour
ldy #S.Time.HOUR
sta (ZPPtr2),y set hour
iny
txa
sta (ZPPtr2),y set min
iny
lda #0
sta (ZPPtr2),y set seconds (ProDOS does not provide it)
* 1/1/1970 was Thursday...if not leap, add one, if leap add 2
K.ComputeWDAY lda #3 Thursday : 4 (-1 for mod 7)
pha
lda #19
sta TIME.DWORD
lda #70
sta TIME.DWORD+1
.1 ldy TIME.DWORD
lda TIME.DWORD+1
cpy TIME.Century
bne .2
cmp TIME.Year
beq .4
.2 jsr TIME.IsLeapYearYA CS = Leap
pla
adc #1
cmp #7
bcc .3
sbc #7 MOD 7
.3 pha
inc TIME.DWORD+1
lda TIME.DWORD+1
cmp #100
bne .1
lda #0
sta TIME.DWORD+1
inc TIME.DWORD
bra .1
.4 ldy #S.Time.MONTH
lda (ZPPtr2),y get month
tax
.5 lda K.StrFTime.MDAY-1,x get day count in this month
bne .6 february ?
ldy TIME.Century
lda TIME.Year
jsr TIME.IsLeapYearYA CS = Leap
.6 pla
adc K.StrFTime.MDAY-1,x
cmp #7
bcc .7
sbc #7
.7 pha
dex
bne .5
pla
ldy #S.Time.DAY
adc (ZPPtr2),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 (ZPPtr2),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 MEM.SPtr1PPtr2
ldy #3
.1 lda (ZPPtr1),y
sta TIME.DWORD,y
dey
bpl .1
stz TIME.DivDay
stz TIME.DivDay+1
.2 lda TIME.DWORD
sta TIME.ModDay
sec
sbc #SECSDAY
pha
lda TIME.DWORD+1
sta TIME.ModDay+1
sbc /SECSDAY
pha
lda TIME.DWORD+2
sta TIME.ModDay+2
sbc ^SECSDAY
pha
lda TIME.DWORD+3
sbc #0
bcc .3 end of DIV/MOD ?
sta TIME.DWORD+3
ldx #2
.21 pla
sta TIME.DWORD,x
dex
bpl .21
inc TIME.DivDay
bne .2
inc TIME.DivDay+1
bne .2
.3 pla
pla
pla
stz TIME.Div60
stz TIME.Div60+1
.4 lda TIME.ModDay
sta TIME.Mod
sec
sbc #60
pha
lda TIME.ModDay+1
sbc #0
pha
lda TIME.ModDay+2
sbc #0
bcc .5
sta TIME.ModDay+2
pla
sta TIME.ModDay+1
pla
sta TIME.ModDay
inc TIME.Div60
bne .4
inc TIME.Div60+1
bne .4
.5 pla
pla
lda TIME.Mod
ldy #S.Time.SECOND
sta (ZPPtr2),y
stz TIME.Div3600
.6 lda TIME.Div60
sta TIME.Mod
sec
sbc #60
pha
lda TIME.Div60+1
sbc #0
pha
bcc .7
sta TIME.Div60+1
pla
sta TIME.Div60
inc TIME.Div3600
bne .6
.7 pla
lda TIME.Mod
dey ldy #S.Time.MINUTE
sta (ZPPtr2),y
lda TIME.Div3600
dey ldy #S.Time.HOUR
sta (ZPPtr2),y
lda TIME.DivDay WDAY computation : (DivDay + DAY0) mod 7
clc
adc #DAY0
pha
lda TIME.DivDay+1
adc /DAY0
eor #$ff
tax
pla
.8 sta TIME.Mod
sec
sbc #7
bcs .8
inx
bne .8
lda TIME.Mod
ldy #S.Time.WDAY
sta (ZPPtr2),y
lda #CENTURY0
sta TIME.Century
lda #YEAR0
sta TIME.Year
K.CTime2Time.Year
.1 ldy TIME.Century
lda TIME.Year
jsr TIME.IsLeapYearYA if Leap year CS
lda #0 Toggle Carry
rol
eor #1
lsr
lda TIME.DivDay
sbc #365
pha
lda TIME.DivDay+1
sbc /365
bcc .2
sta TIME.DivDay+1
pla
sta TIME.DivDay
inc TIME.Year
lda TIME.Year
cmp #100
bne .1
stz TIME.Year
inc TIME.Century
bne .1
.2 pla
lda TIME.Century
* ldy #S.Time.CENTURY
sta (ZPPtr2)
ldy #S.Time.YEAR
lda TIME.Year
sta (ZPPtr2),y
clc
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 mod 4 = 0 ?
beq .9 leap year
.8 clc not leap
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 MEM.SPtr1PPtr2
>PULLW ZPPtr3 timeptr
.1 lda (ZPPtr2)
beq .8
jsr MEM.NextCharPtr2
cmp #'%'
beq .2
jsr K.StrFTime.addChar
bra .1
.2 ldx #K.StrFTime.JMP-K.StrFTime.Tbl-1
lda (ZPPtr2)
beq .8
jsr MEM.NextCharPtr2
.3 cmp K.StrFTime.Tbl,x
beq .4
dex
bpl .3
bra .1
.4 txa
asl
tax
jsr .5
bra .1
.5 jmp (K.StrFTime.JMP,x)
.8 lda #0 Terminate C string
sta (ZPPtr1)
clc
rts
*--------------------------------------
K.StrFTime.TBL .AS "aAbBdHImMpSwyY"
K.StrFTime.JMP .DA K.StrFTime.A
.DA K.StrFTime.AA
.DA K.StrFTime.B
.DA K.StrFTime.BB
.DA K.StrFTime.D
.DA K.StrFTime.HH
.DA K.StrFTime.II
.DA K.StrFTime.M
.DA K.StrFTime.MM
.DA K.StrFTime.P
.DA K.StrFTime.SS
.DA K.StrFTime.W
.DA K.StrFTime.Y
.DA K.StrFTime.YY
*--------------------------------------
K.StrFTime.A ldx #3 Short day of week, 3 chars...
.HS 2C Bit abs
K.StrFTime.AA ldx #15 full DoW
>LDYAI K.StrFTime.DAY
>STYA ZPPtr4
ldy #S.Time.WDAY
bra K.StrFTime.STR
K.StrFTime.B ldx #3 Short Month, 3 chars....
.HS 2C Bit abs
K.StrFTime.BB ldx #15 full Month....
>LDYAI K.StrFTime.MON
>STYA ZPPtr4
ldy #S.Time.MONTH
K.StrFTime.STR lda (ZPPtr3),y get required S.Time field value
tay
beq .9 Illegal value
.1 dey range 0..x
beq .2
lda (ZPPtr4)
sec
adc ZPPtr4
sta ZPPtr4
bcc .1
inc ZPPtr4+1
bra .1
.2
* ldy #0 Y is already 0
.3 iny
lda (ZPPtr4),y
jsr K.StrFTime.addChar
tya
cmp (ZPPtr4)
beq .8
dex
bne .3
.8 rts
.9 ldx #3
lda #'?'
.99 jsr K.StrFTime.addChar
dex
bne .99
rts
*--------------------------------------
K.StrFTime.II ldy #S.Time.HOUR
lda (ZPPtr3),y
cmp #12
bcc .1
sbc #12
.1 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 K.StrFTime.addChar
lda #'m'
bra K.StrFTime.addChar
K.StrFTime.YY ldy #S.Time.CENTURY
jsr K.StrFTime.addDecPtr1Y
K.StrFTime.Y ldy #S.Time.YEAR
.HS 2C bit abs
K.StrFTime.D ldy #S.Time.DAY
.HS 2C bit abs
K.StrFTime.HH ldy #S.Time.HOUR
.HS 2C bit abs
K.StrFTime.SS ldy #S.Time.SECOND
.HS 2C bit abs
K.StrFTime.W ldy #S.Time.WDAY
.HS 2C bit abs
K.StrFTime.M ldy #S.Time.MONTH
.HS 2C bit abs
K.StrFTime.MM ldy #S.Time.MINUTE
*--------------------------------------
K.StrFTime.addDecPtr1Y
lda (ZPPtr3),y
K.StrFTime.addDecA
stz .2+1
ldx #8
sed
.1 asl
pha
.2 lda #$ff Self Modified
adc .2+1
sta .2+1
pla
dex
bne .1
cld
lda .2+1
pha
lsr
lsr
lsr
lsr
ora #$30
jsr K.StrFTime.addChar
pla
and #$0f
ora #$30
*--------------------------------------
K.StrFTime.addChar
sta (ZPPtr1)
jmp MEM.NextCharPtr1
*--------------------------------------
K.StrFTime.DAY >PSTR "Monday"
>PSTR "Tuesday"
>PSTR "Wednesday"
>PSTR "Thursday"
>PSTR "Friday"
>PSTR "Saturday"
>PSTR "Sunday"
*--------------------------------------
K.StrFTime.MON >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