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 *-------------------------------------- .DUMMY .OR ZPTMP TIME.DWORD .BS 4 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 >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 jsr MEM.SPtr1PPtr2 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 #DAY0-1 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 stz 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 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 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 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 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 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 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 jsr MEM.GetCharPtr2 beq .8 cmp #'%' beq .2 jsr MEM.PutCharPtr1 bra .1 .2 ldx #K.StrFTime.Cnt-1 jsr MEM.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 MEM.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 MEM.PutCharPtr1 lda #'m' jmp MEM.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 MEM.PutCharPtr1 lda A2osX.NumStrBuf+1 jmp MEM.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