NEW PREFIX /A2OSX.BUILD 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 */-------------------------------------- * # Time * Get System Time in Buffer * ## C * `time_t time (S.TIME* timer);` * ##ASM * **In:** * Y,A = PTR to S.TIME * **Out:** * 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 * **In :** * `>PUSHW timer` * `>LDYA ptime` * `>SYSCALL PTime2Time` * **Out:** *\-------------------------------------- K.PTime2Time >STYA ZPPtr1 >PULLW ZPPtr2 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 K.CTime.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 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 sta K.CTime.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 K.CTime.DWORD lda #70 sta K.CTime.DWORD+1 .1 ldy K.CTime.DWORD lda K.CTime.DWORD+1 cpy K.CTime.Century bne .2 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 inc K.CTime.DWORD+1 lda K.CTime.DWORD+1 cmp #100 bne .1 lda #0 sta K.CTime.DWORD+1 inc K.CTime.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 K.CTime.Century lda K.CTime.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 * **In :** * `>PUSHW timer` * `>LDYA ctime` * `>SYSCALL CTime2Time` * **Out:** *\-------------------------------------- K.CTime2Time >STYA ZPPtr1 >PULLW ZPPtr2 ldy #3 .1 lda (ZPPtr1),y sta K.CTime.DWORD,y dey bpl .1 stz K.CTime.DivDay stz K.CTime.DivDay+1 .2 lda K.CTime.DWORD sta K.CTime.ModDay sec sbc #SECSDAY pha lda K.CTime.DWORD+1 sta K.CTime.ModDay+1 sbc /SECSDAY pha lda K.CTime.DWORD+2 sta K.CTime.ModDay+2 sbc #0 pha lda K.CTime.DWORD+3 sbc #0 bcc .3 end of DIV/MOD ? sta K.CTime.DWORD+3 ldx #2 .21 pla sta K.CTime.DWORD,x dex bpl .21 inc K.CTime.DivDay bne .2 inc K.CTime.DivDay+1 bne .2 .3 pla pla pla stz K.CTime.Div60 stz K.CTime.Div60+1 .4 lda K.CTime.ModDay sta K.CTime.Mod sec sbc #60 pha lda K.CTime.ModDay+1 sbc #0 pha lda K.CTime.ModDay+2 sbc #0 bcc .5 sta K.CTime.ModDay+2 pla sta K.CTime.ModDay+1 pla sta K.CTime.ModDay inc K.CTime.Div60 bne .4 inc K.CTime.Div60+1 bne .4 .5 pla pla lda K.CTime.Mod ldy #S.Time.SECOND sta (ZPPtr2),y stz K.CTime.Div3600 .6 lda K.CTime.Div60 sta K.CTime.Mod sec sbc #60 pha lda K.CTime.Div60+1 sbc #0 pha bcc .7 sta K.CTime.Div60+1 pla sta K.CTime.Div60 inc K.CTime.Div3600 bne .6 .7 pla lda K.CTime.Mod dey ldy #S.Time.MINUTE sta (ZPPtr2),y lda K.CTime.Div3600 dey ldy #S.Time.HOUR sta (ZPPtr2),y lda K.CTime.DivDay WDAY computation : (DivDay + DAY0) mod 7 clc adc #DAY0 pha lda K.CTime.DivDay+1 adc /DAY0 eor #$ff tax pla .8 sta K.CTime.Mod sec sbc #7 bcs .8 inx bne .8 lda K.CTime.Mod ldy #S.Time.WDAY sta (ZPPtr2),y lda #CENTURY0 sta K.CTime.Century lda #YEAR0 sta K.CTime.Year 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 lda K.CTime.DivDay sbc #365 pha lda K.CTime.DivDay+1 sbc /365 bcc .2 sta K.CTime.DivDay+1 pla sta K.CTime.DivDay inc K.CTime.Year lda K.CTime.Year cmp #100 bne .1 stz K.CTime.Year inc K.CTime.Century bne .1 .2 pla lda K.CTime.Century * ldy #S.Time.CENTURY sta (ZPPtr2) ldy #S.Time.YEAR lda K.CTime.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 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 * ## C * Convert S.TIME struct to CSTR * `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 * **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