A2osX/SYS/KERNEL.S.TIME.txt

625 lines
12 KiB
Plaintext
Raw Normal View History

2017-12-22 21:24:30 +00:00
NEW
PREFIX /A2OSX.BUILD
2017-12-22 21:24:30 +00:00
AUTO 4,1
*--------------------------------------
2016-08-31 15:38:48 +00:00
* https://www.cise.ufl.edu/~cop4600/cgi-bin/lxr/http/source.cgi/lib/ansi/gmtime.c
*--------------------------------------
2016-08-31 15:38:48 +00:00
SECSDAY .EQ 86400 60*60*24
CENTURY0 .EQ 19
YEAR0 .EQ 70
DAY0 .EQ 4 day 0 was a thursday
*/--------------------------------------
2018-06-18 06:22:50 +00:00
* # Time
* Get System Time in Buffer
* ## In :
2018-06-18 06:22:50 +00:00
* Y,A = PTR to S.TIME
* ## Out :
2018-06-18 06:22:50 +00:00
* S.TIME filled with System date/time
*\--------------------------------------
2018-06-18 06:22:50 +00:00
K.Time >STYA ZPPtr2
>MLICALL MLIGETTIME
>LDYAI DATELO
2017-01-12 17:43:45 +00:00
>STYA ZPPtr1
bra TIME.PTime2TimeP1P2
*/--------------------------------------
* # PTime2Time
* Convert ProDOS Time To S.TIME
* ## In :
* PUSHW = Dst PTR To S.TIME
* PUSHW = Src PTR to ProDOS DATE/TIME (DWORD)
*\--------------------------------------
K.PTime2Time jsr MEM.PullP1P2
TIME.PTime2TimeP1P2
ldy #1
lda (ZPPtr1),y Get Year
lsr C is high bit of month
2016-09-21 15:20:37 +00:00
ldy #S.Time.YEAR
sta (ZPPtr2),y set year
2016-09-21 15:20:37 +00:00
sta K.CTime.Year for conputing Century/WDAY later
lda (ZPPtr1) Get Month/day
pha save Day
ror
lsr
lsr
lsr
lsr
2016-09-21 15:20:37 +00:00
ldy #S.Time.MONTH
sta (ZPPtr2),y set month
pla get back day
and #$1F
iny
sta (ZPPtr2),y set day
2016-09-21 15:20:37 +00:00
lda K.CTime.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
2016-09-21 15:20:37 +00:00
sta K.CTime.Century for conputing WDAY later
ldy #2
lda (ZPPtr1),y Get Min
tax
iny
lda (ZPPtr1),y Get Hour
2016-09-21 15:20:37 +00:00
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
2016-09-21 15:20:37 +00:00
K.ComputeWDAY lda #3 Thursday : 4 (-1 for mod 7)
pha
lda #19
2016-09-21 15:20:37 +00:00
sta K.CTime.DWORD
lda #70
2016-09-21 15:20:37 +00:00
sta K.CTime.DWORD+1
2016-09-21 15:20:37 +00:00
.1 ldy K.CTime.DWORD
lda K.CTime.DWORD+1
2016-09-21 15:20:37 +00:00
cpy K.CTime.Century
bne .2
2016-09-21 15:20:37 +00:00
cmp K.CTime.Year
beq .4
.2 jsr TIME.IsLeapYearYA CS = Leap
pla
adc #1
cmp #7
bcc .3
sbc #7 MOD 7
.3 pha
2016-09-21 15:20:37 +00:00
inc K.CTime.DWORD+1
lda K.CTime.DWORD+1
cmp #100
bne .1
lda #0
2016-09-21 15:20:37 +00:00
sta K.CTime.DWORD+1
inc K.CTime.DWORD
bra .1
2016-09-21 15:20:37 +00:00
.4 ldy #S.Time.MONTH
lda (ZPPtr2),y get month
tax
2016-09-21 15:20:37 +00:00
.5 lda K.StrFTime.MDAY-1,x get day count in this month
bne .6 february ?
2016-09-21 15:20:37 +00:00
ldy K.CTime.Century
lda K.CTime.Year
jsr TIME.IsLeapYearYA CS = Leap
.6 pla
2016-09-21 15:20:37 +00:00
adc K.StrFTime.MDAY-1,x
cmp #7
bcc .7
sbc #7
.7 pha
dex
bne .5
pla
2016-09-21 15:20:37 +00:00
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
2016-09-21 15:20:37 +00:00
ldy #S.Time.WDAY
2017-01-12 17:43:45 +00:00
sta (ZPPtr2),y
clc
rts
*/--------------------------------------
* # CTime2Time
* Convert CTIME to S.TIME
* ## In :
* PUSHW = Dst PTR To S.TIME
* PUSHW = Src CTIME DWORD
*\--------------------------------------
K.CTime2Time jsr MEM.PullP1P2
2016-08-31 15:38:48 +00:00
ldy #3
2017-01-12 17:43:45 +00:00
.1 lda (ZPPtr1),y
2016-09-21 15:20:37 +00:00
sta K.CTime.DWORD,y
2016-08-31 15:38:48 +00:00
dey
bpl .1
2016-09-21 15:20:37 +00:00
stz K.CTime.DivDay
stz K.CTime.DivDay+1
2016-08-31 15:38:48 +00:00
2016-09-21 15:20:37 +00:00
.2 lda K.CTime.DWORD
sta K.CTime.ModDay
2016-08-31 15:38:48 +00:00
sec
sbc #SECSDAY
pha
2016-09-21 15:20:37 +00:00
lda K.CTime.DWORD+1
sta K.CTime.ModDay+1
2016-08-31 15:38:48 +00:00
sbc /SECSDAY
pha
2016-09-21 15:20:37 +00:00
lda K.CTime.DWORD+2
sta K.CTime.ModDay+2
2016-08-31 15:38:48 +00:00
sbc #0
pha
2016-09-21 15:20:37 +00:00
lda K.CTime.DWORD+3
2016-08-31 15:38:48 +00:00
sbc #0
bcc .3 end of DIV/MOD ?
2016-09-21 15:20:37 +00:00
sta K.CTime.DWORD+3
ldx #2
.21 pla
sta K.CTime.DWORD,x
dex
bpl .21
2016-08-31 15:38:48 +00:00
2016-09-21 15:20:37 +00:00
inc K.CTime.DivDay
2016-08-31 15:38:48 +00:00
bne .2
2016-09-21 15:20:37 +00:00
inc K.CTime.DivDay+1
2016-08-31 15:38:48 +00:00
bne .2
.3 pla
pla
pla
2016-09-21 15:20:37 +00:00
stz K.CTime.Div60
stz K.CTime.Div60+1
2016-08-31 15:38:48 +00:00
2016-09-21 15:20:37 +00:00
.4 lda K.CTime.ModDay
sta K.CTime.Mod
2016-08-31 15:38:48 +00:00
sec
sbc #60
pha
2016-09-21 15:20:37 +00:00
lda K.CTime.ModDay+1
2016-08-31 15:38:48 +00:00
sbc #0
pha
2016-09-21 15:20:37 +00:00
lda K.CTime.ModDay+2
2016-08-31 15:38:48 +00:00
sbc #0
bcc .5
2016-09-21 15:20:37 +00:00
sta K.CTime.ModDay+2
2016-08-31 15:38:48 +00:00
pla
2016-09-21 15:20:37 +00:00
sta K.CTime.ModDay+1
2016-08-31 15:38:48 +00:00
pla
2016-09-21 15:20:37 +00:00
sta K.CTime.ModDay
2016-08-31 15:38:48 +00:00
2016-09-21 15:20:37 +00:00
inc K.CTime.Div60
2016-08-31 15:38:48 +00:00
bne .4
2016-09-21 15:20:37 +00:00
inc K.CTime.Div60+1
2016-08-31 15:38:48 +00:00
bne .4
.5 pla
pla
2016-09-21 15:20:37 +00:00
lda K.CTime.Mod
ldy #S.Time.SECOND
2017-01-12 17:43:45 +00:00
sta (ZPPtr2),y
2016-08-31 15:38:48 +00:00
2016-09-21 15:20:37 +00:00
stz K.CTime.Div3600
2016-08-31 15:38:48 +00:00
2016-09-21 15:20:37 +00:00
.6 lda K.CTime.Div60
sta K.CTime.Mod
2016-08-31 15:38:48 +00:00
sec
sbc #60
pha
2016-09-21 15:20:37 +00:00
lda K.CTime.Div60+1
2016-08-31 15:38:48 +00:00
sbc #0
pha
bcc .7
2016-09-21 15:20:37 +00:00
sta K.CTime.Div60+1
2016-08-31 15:38:48 +00:00
pla
2016-09-21 15:20:37 +00:00
sta K.CTime.Div60
2016-08-31 15:38:48 +00:00
2016-09-21 15:20:37 +00:00
inc K.CTime.Div3600
2016-08-31 15:38:48 +00:00
bne .6
.7 pla
2016-09-21 15:20:37 +00:00
lda K.CTime.Mod
dey ldy #S.Time.MINUTE
2017-01-12 17:43:45 +00:00
sta (ZPPtr2),y
2016-08-31 15:38:48 +00:00
2016-09-21 15:20:37 +00:00
lda K.CTime.Div3600
dey ldy #S.Time.HOUR
2017-01-12 17:43:45 +00:00
sta (ZPPtr2),y
2016-08-31 15:38:48 +00:00
2016-09-21 15:20:37 +00:00
lda K.CTime.DivDay WDAY computation : (DivDay + DAY0) mod 7
clc
2016-08-31 15:38:48 +00:00
adc #DAY0
pha
2016-09-21 15:20:37 +00:00
lda K.CTime.DivDay+1
2016-08-31 15:38:48 +00:00
adc /DAY0
eor #$ff
tax
pla
2016-09-21 15:20:37 +00:00
.8 sta K.CTime.Mod
2016-08-31 15:38:48 +00:00
sec
sbc #7
bcs .8
inx
bne .8
2016-09-21 15:20:37 +00:00
lda K.CTime.Mod
ldy #S.Time.WDAY
2017-01-12 17:43:45 +00:00
sta (ZPPtr2),y
2016-08-31 15:38:48 +00:00
lda #CENTURY0
2016-09-21 15:20:37 +00:00
sta K.CTime.Century
2016-08-31 15:38:48 +00:00
lda #YEAR0
2016-09-21 15:20:37 +00:00
sta K.CTime.Year
2016-09-02 06:09:44 +00:00
2016-09-21 15:20:37 +00:00
K.CTime2Time.Year
.1 ldy K.CTime.Century
lda K.CTime.Year
jsr TIME.IsLeapYearYA if Leap year CS
lda #0 Toggle Carry
rol
eor #1
lsr
2016-09-21 15:20:37 +00:00
lda K.CTime.DivDay
2016-09-01 05:42:28 +00:00
sbc #365
pha
2016-09-21 15:20:37 +00:00
lda K.CTime.DivDay+1
2016-09-01 05:42:28 +00:00
sbc /365
2016-09-02 06:09:44 +00:00
bcc .2
2016-08-31 15:38:48 +00:00
2016-09-21 15:20:37 +00:00
sta K.CTime.DivDay+1
2016-09-01 05:42:28 +00:00
pla
2016-09-21 15:20:37 +00:00
sta K.CTime.DivDay
2016-09-01 05:42:28 +00:00
2016-09-21 15:20:37 +00:00
inc K.CTime.Year
lda K.CTime.Year
2016-09-01 05:42:28 +00:00
cmp #100
2016-09-02 06:09:44 +00:00
bne .1
2016-09-21 15:20:37 +00:00
stz K.CTime.Year
inc K.CTime.Century
2016-09-02 06:09:44 +00:00
bne .1
2016-09-01 05:42:28 +00:00
2016-09-02 06:09:44 +00:00
.2 pla
2016-09-21 15:20:37 +00:00
lda K.CTime.Century
* ldy #S.Time.CENTURY
2017-01-12 17:43:45 +00:00
sta (ZPPtr2)
2016-09-21 15:20:37 +00:00
ldy #S.Time.YEAR
lda K.CTime.Year
2017-01-12 17:43:45 +00:00
sta (ZPPtr2),y
2016-09-01 05:42:28 +00:00
2016-09-02 06:09:44 +00:00
clc
rts
2016-09-01 05:42:28 +00:00
*--------------------------------------
* In :
* Y = Century
* A = Year (0..99)
2016-09-01 05:42:28 +00:00
* if (year mod 400 = 0)
* or
* if not (year mod 100 = 0) and (year mod 4 = 0)
* Out :
* CS = Leap
* CC = Not Leap
2016-08-31 15:38:48 +00:00
*--------------------------------------
TIME.IsLeapYearYA
cmp #0 Year = 00 ?
2016-09-01 05:42:28 +00:00
bne .1 no
tya year = 00, get century in a
and #$3 mod 4 = 0 ?
beq .9 leap year
.8 clc not leap
2016-09-01 05:42:28 +00:00
rts
2016-08-31 15:38:48 +00:00
2016-09-01 05:42:28 +00:00
.1 and #$3 mod 4 = 0 ?
bne .8
.9 sec Leap
2016-08-31 15:38:48 +00:00
rts
*--------------------------------------
K.StrFTime.MDAY .DA #3,#0,#3,#2,#3,#2,#3,#3,#2,#3,#2,#3
2016-09-21 15:20:37 +00:00
K.CTime.DWORD .BS 4
K.CTime.DivDay .BS 2
K.CTime.ModDay .BS 3
K.CTime.Div60 .BS 2
K.CTime.Div3600 .BS 1
K.CTime.Mod .BS 1
K.CTime.Century .BS 1
K.CTime.Year .BS 1
*/--------------------------------------
* # StrFTime
2018-06-18 06:22:50 +00:00
* ## C
* Convert S.TIME struct to CSTR
2018-06-18 06:22:50 +00:00
* `size_t strftime (char* ptr, size_t maxsize, const char* format, const struct tm* timeptr );`
* ## ASM
* **In:**
* PUSHW = Dst PTR To CSTR Buf
* PUSHW = Src PTR To Format String
* %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
* PUSHW = Src PTR To S.Time
2018-06-14 15:31:36 +00:00
* **Out:**
* none. always succeed.
*\--------------------------------------
K.StrFTime jsr MEM.PullP1P2P3
ldy #0
.1 lda (ZPPtr2),y
beq .8
iny
cmp #'%'
beq .2
jsr K.StrFTime.addChar
bra .1
.2 ldx #K.StrFTime.JMPL-K.StrFTime.Tbl-1
lda (ZPPtr2),y
beq .8
iny
.3 cmp K.StrFTime.Tbl,x
beq .4
dex
bpl .3
bra .1
.4 lda K.StrFTime.JMPL,x
sta .5+1
lda K.StrFTime.JMPH,x
sta .5+2
phy
.5 jsr $ffff
ply
bra .1
.8 lda #0 Terminate C string
sta (ZPPtr3)
rts
*--------------------------------------
K.StrFTime.TBL .AS "aAbBdHImMpSwyY"
K.StrFTime.JMPL .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.JMPH .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 (ZPPtr1),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.D ldy #S.Time.DAY
bra K.StrFTime.addDecPtr1Y
K.StrFTime.HH ldy #S.Time.HOUR
bra K.StrFTime.addDecPtr1Y
K.StrFTime.II ldy #S.Time.HOUR
lda (ZPPtr1),y
cmp #12
bcc .1
sbc #12
.1 bra K.StrFTime.addDecA
K.StrFTime.M ldy #S.Time.MONTH
bra K.StrFTime.addDecPtr1Y
K.StrFTime.MM ldy #S.Time.MINUTE
bra K.StrFTime.addDecPtr1Y
K.StrFTime.P ldy #S.Time.HOUR
lda (ZPPtr1),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.SS ldy #S.Time.SECOND
bra K.StrFTime.addDecPtr1Y
K.StrFTime.W ldy #S.Time.WDAY
bra K.StrFTime.addDecPtr1Y
K.StrFTime.YY ldy #S.Time.CENTURY
jsr K.StrFTime.addDecPtr1Y
K.StrFTime.Y ldy #S.Time.YEAR
*--------------------------------------
K.StrFTime.addDecPtr1Y
lda (ZPPtr1),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 (ZPPtr3)
inc ZPPtr3
bne .8
inc ZPPtr3+1
.8 rts
*--------------------------------------
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 /A2OSX.SRC/SYS/KERNEL.S.TIME
LOAD /A2OSX.SRC/SYS/KERNEL.S
ASM