A2osX/SYS/KERNEL.S.STRING.txt

406 lines
9.3 KiB
Plaintext
Raw Normal View History

PR#3
PREFIX /A2OSX.BUILD
LOMEM $A00
INC 1
AUTO 6
*/--------------------------------------
* # StrCat
* Append SRC to DST
* ## In:
* PUSHW = Ptr to SRC (CSTR)
* PUSHW = Ptr to DST (CSTR)
* ## Out:
* DST = DST+SRC
*\--------------------------------------
K.StrCat jsr PullPtr1Ptr2
.1 lda (ZPPtr1)
beq K.StrCpy.I
inc ZPPtr1
bne .1
inc ZPPtr1+1
bra .1
*/--------------------------------------
* # StrCpy
* Copy string
* ## In:
* PUSHW = Ptr to SRC (CSTR)
* PUSHW = Ptr to DST (CSTR)
* ## Out:
* DST = SRC
*\--------------------------------------
K.StrCpy jsr PullPtr1Ptr2
K.StrCpy.I ldy #0
.1 lda (ZPPtr2),y
sta (ZPPtr1),y
beq .8
iny
bne .1
inc ZPPtr2+1
inc ZPPtr1+1
bra .1
.8 rts
*/--------------------------------------
* # StrMatch
* Compare a String against pattern
* ## In:
* PUSHW = PTR to Pattern (e.g. '*test?.txt')
* PUSHW = PTR to Src String
* ## Out:
* CC : match
* CS : no match
*\--------------------------------------
K.StrMatch jsr PullPtr1Ptr2
lda (ZPPtr2) Get pattern 1st byte
beq .8 Match always if empty
ldy #0
bra .21
.1 inc ZPPtr2 Make PTR2 advance to next char
bne .2
inc ZPPtr2+1
.2 lda (ZPPtr2) get pattern char
beq .41
.21 cmp #'*'
beq .5
.3 lda (ZPPtr1) we must match ? or regular char, check if at end of string
beq .9 no char left, exit with error
lda (ZPPtr2) get back pattern char
cmp #'?'
beq .4 no need to compare, any char will match
cmp (ZPPtr1),y Regular Char, compare with string at Y
bne .9 no match, exit
iny advance to next char to compare
.4 dex char matched, check if end of pattern
bne .1 continue if remaining char in pattern
.41 lda (ZPPtr1),y end of pattern, but end of string ?
beq .8 yes, string matched entirely
bra .9 no, remaining char in string, no match
.5 inc ZPPtr2 Make PTR2 advance to next char
bne .6
inc ZPPtr2+1
lda (ZPPtr2) we have '*', last char of pattern ?
beq .8 yes, match everything, including empty string
.6 lda (ZPPtr2) get next char of pattern
cmp #'*' another '*' ?
beq .5 yes, '**' = '*', go next char
cmp #'?' '*?' ??? we must match a least one char
beq .3
.7 lda (ZPPtr1),y we need at least one remaining char in string, check if at end of string
beq .9 no chance to match ? or regular char
iny
lda (ZPPtr2) get again char in pattern
cmp (ZPPtr1),y compare with char in string
bne .7 not equal to next non wildcard in pattern
bra .4 go check remaining char in pattern...
.8 clc
rts
.9 sec
rts
*/--------------------------------------
* # StrUprYA/StrLwrYA
* Convert string to UPPERCASE/lowercase
* ## In:
* Y,A = PTR to String (CSTR)
* ## Out:
* Uppercased/lowercased String in Buffer
*\--------------------------------------
K.StrUprYA ldx #0
.HS 2C bit abs
K.StrLwrYA ldx #2
>STYA ZPPtr1
pha save Y,A to restore them at exit
phy
ldy #0
.1 lda (ZPPtr1),y
beq .8
cmp K.PStrUprLwr,x
bcc .2
cmp K.PStrUprLwr+1,x
bcs .2
eor #$20
sta (ZPPtr1),y
.2 iny
bne .1
inc ZPPtr1+1
bra .1
.8 ply
pla
rts
*--------------------------------------
K.PStrUprLwr .AS "azAZ"
*/--------------------------------------
* # StrFTime
* Convert S.TIME struct to CSTR
* ## 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 PullPtr1Ptr2Ptr3
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
.3 iny
lda (ZPPtr4),y
phy
jsr K.StrFTime.addChar
pla
cmp (ZPPtr4)
beq .8
tay
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
sta K.StrFTime.BIN
stz K.StrFTime.DEC
sed
ldx #8
.1 asl K.StrFTime.BIN
lda K.StrFTime.DEC
adc K.StrFTime.DEC
sta K.StrFTime.DEC
dex
bne .1
cld
* lda K.StrFTime.DEC already in A
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"
*--------------------------------------
K.StrFTime.BIN .BS 1
K.StrFTime.DEC .BS 1 always < 100
*--------------------------------------
MAN
SAVE /A2OSX.SRC/SYS/KERNEL.S.STRING
LOAD /A2OSX.SRC/SYS/KERNEL.S
ASM