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
CENT0			.EQ 19
YEAR0			.EQ 70
DAY0			.EQ 4					day 0 was a thursday
*--------------------------------------
* ZPPtr3 *S.TIME
* FORPNT str
* TXTPTR format
*--------------------------------------
TIMEX.StrFTime
.1				jsr SHARED.TXTPTRgn
				beq .8

				cmp #'%'
				beq .2

				jsr SHARED.FORPNTpn
				bra .1
				
.2				ldx #K.StrFTime.Cnt-1
				jsr SHARED.TXTPTRgn
				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
				jsr SHARED.FORPNTpn
				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 #TIMEX.DAY
				ldx /TIMEX.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 #TIMEX.MON
				ldx /TIMEX.MON
				ldy #S.Time.MONTH
K.StrFTime.STR	sta ZPPtr4
				stx ZPPtr4+1

				ldx #15
				bcc .10
				ldx #3
				
.10				jsr SHARED.P3gY			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.FORPNTpn
				tya
				cmp (ZPPtr4)
				beq .8
				dex
				bne .3

.8				rts
*--------------------------------------
K.StrFTime.II	ldy #S.Time.HOUR
				jsr SHARED.P3gY
				cmp #12
				bcc K.StrFTime.addDecA
				sbc #12
				bra K.StrFTime.addDecA
				
K.StrFTime.P	ldy #S.Time.HOUR
				jsr SHARED.P3gY
				cmp #12
				bcc .1
				lda #'p'
				.HS 2C					bit abs
.1				lda #'a'
				jsr SHARED.FORPNTpn
				lda #'m'
				jmp SHARED.FORPNTpn
t
K.StrFTime.YY	ldy #S.Time.CENTURY
				jsr K.StrFTime.addDecPtr3Y
				ldx #7					"y"
K.StrFTime.AtX	ldy K.StrFTime.OfsX-7,x
*--------------------------------------
K.StrFTime.addDecPtr3Y
				jsr SHARED.P3gY
K.StrFTime.addDecA
				ldx #2
				ldy #'0'
				clc
				jsr MATH.A2STR10
				lda FOUTBuf
				jsr SHARED.FORPNTpn
				lda FOUTBuf+1
				jmp SHARED.FORPNTpn
*--------------------------------------
TIMEX.DAY		>PSTR "???"
				>PSTR "Monday"
				>PSTR "Tuesday"
				>PSTR "Wednesday"
				>PSTR "Thursday"
				>PSTR "Friday"
				>PSTR "Saturday"
				>PSTR "Sunday"
*--------------------------------------
TIMEX.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"
*--------------------------------------
TIMEX.PTime2Time.BAD
				lda #E.OOB
				sec
				rts
TIMEX.PTime2Time
				ldy #3
				jsr SHARED.TXTPTRgY
				and #%11100000
				bne TIMEX.PTime2Time.BAD
				
				dey
				jsr SHARED.TXTPTRgY
				and #%11000000
				bne TIMEX.PTime2Time.BAD
				
				dey						ldy #1
				
				jsr SHARED.TXTPTRgY	Get Year
				lsr						C is high bit of month
				ldy #S.Time.YEAR
				jsr SHARED.FORPNTpY	set year
				sta ARG32+3				for computing Century/WDAY later

				ldy #0
				jsr SHARED.TXTPTRgY	Get Month/day

				tax						save Day
				ror						C is high bit of month
				lsr
				lsr
				lsr
				lsr
				beq TIMEX.PTime2Time.BAD

				cmp #13
				bcs TIMEX.PTime2Time.BAD
				
				ldy #S.Time.MONTH
				jsr SHARED.FORPNTpY	set month
				sta K.ComputeWDAY.1+1
				
				txa						get back day
				beq TIMEX.PTime2Time.BAD

				and #$1F
				cmp #32
				bcs TIMEX.PTime2Time.BAD

				iny
				jsr SHARED.FORPNTpY	set day

				dec						adjust range 0.30 for MOD 7
				sta ARG32.Sign			For later...

				lda ARG32+3				get back year
				cmp #100
				bcs TIMEX.PTime2Time.BAD
				
				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
				ldy #0
				jsr SHARED.FORPNTpY	set Century
				sta ARG32+2				for computing WDAY later

				ldy #2
				jsr SHARED.TXTPTRgY	Get Min
				tax
				iny
				jsr SHARED.TXTPTRgY	Get Hour
				ldy #S.Time.HOUR
				jsr SHARED.FORPNTpY	set hour
				iny
				txa
				jsr SHARED.FORPNTpY	set min
				iny
				lda #0
				jsr SHARED.FORPNTpY	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 #CENT0				Starts at 1970
				sta ARG32
				lda #YEAR0
				sta ARG32+1

.1				ldy ARG32
				lda ARG32+1

				cpy ARG32+2
				bne .2

				cmp ARG32+3	
				beq K.ComputeWDAY.1

.2				jsr TIMEX.IsLeap		CS = Leap			

				pla
				adc #1					365 mod 7
				cmp #7
				bcc .3
				sbc #7					MOD 7

.3				pha
				inc ARG32+1
				lda ARG32+1
				cmp #100
				bne .1

				stz ARG32+1
				inc ARG32
				bra .1
*--------------------------------------
K.ComputeWDAY.1	ldx #$ff				SELF MODIFIED : month

				dex						don't include actual month
				beq .71

.5				clc						assume NO leap

				lda TIMEX.MDAY-1,x		get day count in this month
				bne	.6					february ?

				ldy ARG32+2
				lda ARG32+3	
				jsr TIMEX.IsLeap		CS = Leap			

.6				pla
				adc TIMEX.MDAY-1,x

				cmp #7
				bcc .7
				sbc #7
				
.7				pha
				dex
				bne .5
				
.71				pla
				clc

				adc ARG32.Sign			get day in month (0..30)

.8				cmp #7					MOD 7
				bcc .80
				sbc #7
				bra .8

.80				inc						adjust range 1..7
				ldy #S.Time.WDAY

*				clc
				jmp SHARED.FORPNTpY
*--------------------------------------
* TXTPTR ctime
* FORPNT S.TIME
*--------------------------------------
TIMEX.CTime2Time
				ldy #3

.1				jsr SHARED.TXTPTRgY
				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 M32.DIVMOD  		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
				jsr SHARED.FORPNTpY	

				ldy #CENT0
				sty ZPPtr3
				lda #YEAR0
				sta ZPPtr3+1
K.CTime2Time.Y
.1				ldy ZPPtr3
				lda ZPPtr3+1
				jsr TIMEX.IsLeap 		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+1
				lda ZPPtr3+1
				cmp #100
				bne .1

				stz ZPPtr3+1
				inc ZPPtr3
				bra .1

.2				pla

				lda ZPPtr3
				ldy #S.Time.CENTURY
				jsr SHARED.FORPNTpY

				ldy #S.Time.YEAR
				lda ZPPtr3+1
				jsr SHARED.FORPNTpY
K.CTime2Time.MD
				ldx #1					X = January

.1				clc
				txa
				eor #2
				
				bne .2

				>LDYA ZPPtr3			Current Year
				jsr TIMEX.IsLeap

.2				lda TIMEX.MDAY-1,x
				adc #28					A = days of X
				
				sta .3+1

				lda ARG32				ARG32/ARG32+1 = 0 .. 364 or 365
				sec

.3				sbc #$ff				SELF MODIFIED
				pha
				lda ARG32+1
				sbc #0
				bcc .4
				
				sta ARG32+1
				pla
				sta ARG32
				inx
				bra .1
				
.4				pla
				ldy #S.TIME.MONTH
				txa
				jsr SHARED.FORPNTpY

				iny						S.TIME.DAY
				
				lda ARG32
				inc
				jsr SHARED.FORPNTpY
				
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
				jsr SHARED.FORPNTpY

				clc
				rts

.2				phy

				lda #60
				jsr M32.A2ACC32
				jsr M32.DIVMOD
				ply
				lda TMP32
				jsr SHARED.FORPNTpY
				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
*--------------------------------------
TIMEX.IsLeap	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
*--------------------------------------
TIMEX.MDAY		.DA #3,#0,#3,#2,#3,#2,#3,#3,#2,#3,#2,#3
*--------------------------------------
MAN
SAVE usr/src/sys/kernel.s.timex
LOAD usr/src/sys/kernel.s
ASM
