A2osX/LIB/LIBSTR.S.txt
2015-03-15 23:00:40 +01:00

784 lines
15 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

PR#3
PREFIX /A2OSX.BUILD
NEW
INC 1
AUTO 6
.LIST OFF
.OP 65C02
.OR $2000
.TF LIB/LIBSTR.O
*--------------------------------------
.INB INC/MACROS.I
.INB INC/A2OSX.I
*--------------------------------------
ZPTmpPtr1 .EQ ZPLIB+2
ZPTmpPtr2 .EQ ZPLIB+4
ZPTmpPtr3 .EQ ZPLIB+6
*--------------------------------------
* Main entry point
* input :
* X = Function
*--------------------------------------
* Code signature and relocation table
*--------------------------------------
* CLD $D8
* JMP (*,x) $7C
* #JMPTABLE
* /JMPTABLE
*--------------------------------------
CS.START cld
jmp (.1,x)
.1 .DA LIB.LOAD
.DA LIB.UNLOAD
.DA PRINTF
.DA PRINTC
.DA PRINTP
.DA STRMATCHP
.DA STRCPYP
.DA STRCATP
.DA UCASEP
.DA LCASEP
.DA PRINTDATE
.DA PRINTTIME
.DA SSCANF
*--------------------------------------
PRINTFJMP1 .DA PRINTFA
.DA PRINTFB,PRINTFBB
.DA PRINTFD,PRINTFDD,PRINTFL
.DA PRINTFE,PRINTFEE
.DA PRINTFH,PRINTFHH
.DA PRINTFI,PRINTFII
.DA PRINTFSC,PRINTFSP
.DA PRINTFT,PRINTFTT
PRINTFJMP2 .DA PRINTFCR,PRINTFBKSLH,PRINTFPERCENT
*--------------------------------------
.DA 0
.DA CS.END-CS.START
.DA 0
*--------------------------------------
LIB.LOAD
LIB.UNLOAD clc
rts
*--------------------------------------
* PRINTF :
* Prints C-Style String
* PULLW Pointer to Sting,Last Byte negative
* %a pull 1 byte to print ATTRIB String
* %b pull 1 byte to print BIN
* %B pull 2 byte to print BIN
* %d pull 1 byte to print unsigned DEC
* %D pull 2 bytes to print unsigned DEC
* %L pull 4 bytes to print unsigned DEC
* %e pull 1 byte to print low Nibble HEX
* %E pull 1 byte to print high Nibble HEX
* %h pull 1 byte to print HEX
* %H pull 2 bytes to print HEX
* %i pull 1 byte to print signed DEC
* %I pull 2 bytes to print signed DEC
* %s pull 2 bytes ptr to C-Style String
* %S pull 2 bytes ptr to P-Style String
* \n print CR=13
* \\ print \
* \% print %
* padding :
* %d '9' '12'
* %2d ' 9' '12'
* %02d '09' '12'
* %16s 'ABCDEFGHIjkl '
* %011s 'ABCDEFGH000'
*--------------------------------------
PRINTF >PULLW ZPTmpPtr1
ldy #0
PRINTFCOUT lda (ZPTmpPtr1),y
beq .1
ora #$80
cmp #"%"
beq PRINTFESC1
cmp #"\"
beq PRINTFESC2
jsr COUT
iny
bne PRINTFCOUT
.1 rts
PRINTFEXIT ply
iny
bne PRINTFCOUT
rts
*--------------------------------------
PRINTFESC1 stz PADLEN
lda #" "
sta PADCHAR
.1 ldx #PRINTFTBL1.END-PRINTFTBL1-1
iny
lda (ZPTmpPtr1),y
beq .9
ora #$80
.2 cmp PRINTFTBL1,x do we have a %x command?
beq .8 yes, jmp to it!
dex
bpl .2 no valid letter...
cmp #"0" ...a 0...mmm... padding char!!
beq .4
bcc .9
cmp #"9"
bcs .9
.3 and #$0F we have a digit
pha save it...
lda PADLEN starts PADLEN * 10
asl times 2
pha save times 2
asl times 4
asl times 8
sta PADLEN
pla get back times 2
clc
adc PADLEN times 8 + times 2 = times 10
sta PADLEN
pla get back current digit
adc PADLEN
sta PADLEN
bra .5
.4 lda PADLEN do we already had met digits to build PADLEN ?
bne .3 yes, continue to build PADLEN
lda #"0"
sta PADCHAR no, this is the first 0, so make it PADCHAR
.5 bra .1
.8 phy
txa
asl
tax
jmp (PRINTFJMP1,x)
.9 rts
*--------------------------------------
PRINTFESC2 ldx #PRINTFTBL2.END-PRINTFTBL2-1
iny
lda (ZPTmpPtr1),y
beq .9
ora #$80
.2 cmp PRINTFTBL2,x
beq .3
dex
bpl .2
rts
.3 phy
txa
asl
tax
jmp (PRINTFJMP2,x)
.9 rts
*--------------------------------------
PRINTFA >PULLA
ldx #0
.1 asl
pha
lda #"-"
bcc .2
lda PRINTF.ATTRIB,x
.2 jsr COUT
pla
inx
cpx #8
bne .1
jmp PRINTFEXIT
PRINTFB ldx #8
>PULLA
.1 asl
pha
lda #$B0
bcc .2
inc
.2 jsr COUT
pla
dex
bne .1
jmp PRINTFEXIT
PRINTFBB >PULLA
>PULLA
jmp PRINTFEXIT
PRINTFD >PULLA
sta HEXBUF
stz HEXBUF+1
stz HEXBUF+2
stz HEXBUF+3
jsr HEX2DEC
jmp PRINTFEXIT
PRINTFDD >PULLA
sta HEXBUF
>PULLA
sta HEXBUF+1
stz HEXBUF+2
stz HEXBUF+3
jsr HEX2DEC
jmp PRINTFEXIT
PRINTFL >PULLA
sta HEXBUF
>PULLA
sta HEXBUF+1
>PULLA
sta HEXBUF+2
>PULLA
sta HEXBUF+3
jsr HEX2DEC
jmp PRINTFEXIT
PRINTFE >PULLA
jsr PRHEX
jmp PRINTFEXIT
PRINTFEE >PULLA
lsr
lsr
lsr
lsr
jsr PRHEX
jmp PRINTFEXIT
PRINTFH >PULLA
jsr PRBYTE
jmp PRINTFEXIT
PRINTFHH >PULLA
pha
>PULLA
jsr PRBYTE
pla
jsr PRBYTE
jmp PRINTFEXIT
PRINTFI >PULLA
jmp PRINTFEXIT
PRINTFII >PULLA
>PULLA
jmp PRINTFEXIT
PRINTFSC >PULLYA
jsr PRINTYA
jmp PRINTFEXIT
PRINTFSP >PULLYA
jsr PRINTYAP
jmp PRINTFEXIT
PRINTFT jsr PRINTTIME
jmp PRINTFEXIT
PRINTFTT jsr PRINTDATE
jmp PRINTFEXIT
PRINTFCR jsr CROUT
jmp PRINTFEXIT
PRINTFBKSLH lda #"\"
jsr COUT
jmp PRINTFEXIT
PRINTFPERCENT lda #"%"
jsr COUT
jmp PRINTFEXIT
*--------------------------------------
PRINTC >PULLW ZPTmpPtr2
ldy #0
.1 lda (ZPTmpPtr2),y
beq .8
ora #$80
jsr COUT
iny
bne .1
.8 rts
*--------------------------------------
PRINTP >PULLW ZPTmpPtr2
ldy #0
lda (ZPTmpPtr2),y
tax
beq .8
.1 iny
lda (ZPTmpPtr2),y
ora #$80
jsr COUT
dex
bne .1
.8 rts
*--------------------------------------
* STRMATCHP : (P-Style Strings)
* pull PTR to Dest String
* pull PTR to Src string
* works with wildcards :
* Dest Str Src str
* message = m?ss*
* = me*ge
* = *ge
* = *
* message = me?sage != me?age
*--------------------------------------
STRMATCHP >PULLW ZPTmpPtr1
>PULLW ZPTmpPtr2
rts
*--------------------------------------
* STRCPYP : (P-Style Strings)
* pull PTR to Dest String
* pull PTR to Src string
*--------------------------------------
STRCPYP >PULLW ZPTmpPtr1
>PULLW ZPTmpPtr2
lda (ZPTmpPtr2)
sta (ZPTmpPtr1)
tay
beq .2
.1 lda (ZPTmpPtr2),y
sta (ZPTmpPtr1),y
dey
bne .1
.2 rts
*--------------------------------------
* STRCATP : (P-Style Strings)
* pull PTR to Dest String
* pull PTR to Src string
*--------------------------------------
STRCATP >PULLW ZPTmpPtr1
>PULLW ZPTmpPtr2
lda (ZPTmpPtr1)
tay
iny
lda (ZPTmpPtr2)
tax
beq .3
.1 inc ZPTmpPtr2
bne .2
inc ZPTmpPtr2+1
.2 lda (ZPTmpPtr2)
sta (ZPTmpPtr1),y
iny
dex
bne .1
dey
tya
sta (ZPTmpPtr1)
.3 rts
*--------------------------------------
UCASEP phx
>PULLW ZPTmpPtr2
ldy #0
lda (ZPTmpPtr2),y
tax
beq .9
.1 iny
lda (ZPTmpPtr2),y
cmp #$61 "a"
bmi .2
cmp #$7B "z"+1
bpl .2
sec
sbc #$20
sta (ZPTmpPtr2),y
.2 dex
bne .1
.9 plx
rts
*--------------------------------------
LCASEP phx
>PULLW ZPTmpPtr2
ldy #0
lda (ZPTmpPtr2),y
tax
beq .9
.1 iny
lda (ZPTmpPtr2),y
cmp #$41 "A"
bmi .2
cmp #$5B "Z"+1
bpl .2
clc
adc #$20
sta (ZPTmpPtr2),y
.2 dex
bne .1
.9 plx
rts
*--------------------------------------
* PULLW = DATE in ProDOS Format
* A = year, Y = month/day
*--------------------------------------
PRINTDATE stz HEXBUF+1
stz HEXBUF+2
stz HEXBUF+3
ldx #"0"
stx PADCHAR
ldx #2
stx PADLEN
>PULLYA
pha save year to get high bit of month later
lsr
pha
cmp #70 are we in the 70s ?
bcc .1
lda #$19
bra .2
.1 lda #$20
.2 jsr PRBYTE
pla
sta HEXBUF
jsr HEX2DEC
lda #"/"
jsr COUT
ldx #"0"
stx PADCHAR
ldx #2
stx PADLEN
pla get back year
lsr get high bit of month in carry
tya get month/day
pha save it for day
ror pick high bit from carry
lsr
lsr
lsr
lsr
sta HEXBUF
jsr HEX2DEC
lda #"/"
jsr COUT
ldx #"0"
stx PADCHAR
ldx #2
stx PADLEN
pla get back month/day
and #$1F
sta HEXBUF
jmp HEX2DEC
*--------------------------------------
* PULLW = TIME in ProDOS Format
* A = hours, Y = minutes
*--------------------------------------
PRINTTIME stz HEXBUF+1
stz HEXBUF+2
stz HEXBUF+3
ldx #"0"
stx PADCHAR
ldx #2
stx PADLEN
>PULLYA
and #$1F
sta HEXBUF
jsr HEX2DEC
lda #":"
jsr COUT
ldx #"0"
stx PADCHAR
ldx #2
stx PADLEN
tya get minutes
and #$3F
sta HEXBUF
jmp HEX2DEC
*--------------------------------------
*
*--------------------------------------
SSCANF >PULLW ZPTmpPtr1 get PString to scan (ex: "192.168.1.5")
>PULLW ZPTmpPtr2 get PString pattern (ex: "%d.%d.%d.%d")
>PULLW ZPTmpPtr3 get target buffer
ldy #0 Y = PTR in pattern
lda (ZPTmpPtr1)
beq .9
tax X = COUNT to scan
inc ZPTmpPtr1
bne .1
inc ZPTmpPtr1+1
.1 txa End Of String?
beq .8
tya
cmp (ZPTmpPtr2) End of pattern?
beq .8
iny
lda (ZPTmpPtr2),y
cmp #'%' Escape?
beq .2
cmp (ZPTmpPtr1) Same char?
bne .9
jsr SSCANF.IncPtr1
bne .1
clc
rts
.2 tya
cmp (ZPTmpPtr2) unexpected End of pattern after "%" ?
beq .9
iny
lda (ZPTmpPtr2),y
cmp #'d' BYTE ?
bne .3
stz ASCBUF
.20 lda (ZPTmpPtr1)
jsr SSCANF.IsDigit
bcs .21
phx
inc ASCBUF
ldx ASCBUF
sta ASCBUF,x
plx
jsr SSCANF.IncPtr1
bne .20 end of string ?
.21 jsr DEC2HEX
lda HEXBUF
sta (ZPTmpPtr3)
inc ZPTmpPtr3
bne .1
inc ZPTmpPtr3+1
bra .1
.3 cmp #'D' WORD ?
bne .4
bra .1
.4 cmp #'s' STRING ?
bne .9
bra .1
.8 clc
rts
.9 sec
rts
*--------------------------------------
SSCANF.IncPtr1 dex
beq .1
inc ZPTmpPtr1
bne .1
inc ZPTmpPtr1+1 never Zero
.1 rts
*--------------------------------------
SSCANF.IsDigit cmp #'0'
bcc .1
cmp #'9'+1
bcs .1
rts
.1 sec
rts
*--------------------------------------
********** PRIVATE FUNCTIONS **********
*--------------------------------------
* PRINTYAC :
* Prints C-Style String
* Y,A=Pointer to Sting, Last Byte 0
*--------------------------------------
PRINTYA >STYA ZPTmpPtr2
ldy #0
.1 lda (ZPTmpPtr2),y
beq .2
ora #$80
jsr COUT
iny
bne .1
.2 rts
*--------------------------------------
* PRINTYAP :
* Prints Pascal-Style String
* Y,A=Pointer to Sting, LEN=1st Byte
*--------------------------------------
PRINTYAP phx
>STYA ZPTmpPtr2
ldy #0
lda (ZPTmpPtr2),y
tax
beq .8
.1 iny
lda (ZPTmpPtr2),y
ora #$80
jsr COUT
lda PADLEN
beq .2
cpy PADLEN
beq .8
.2 dex
bne .1
lda PADLEN
beq .8
.3 lda PADCHAR
jsr COUT
iny
cpy PADLEN
bne .3
.8 plx
rts
*--------------------------------------
* Convert HEXBUF to ASCBUF decimal padded with 0
*--------------------------------------
HEX2DEC phx
phy
ldx #4
.1 stz BCDBUF,x Clear all 5 bytes
dex
bpl .1
ldx #32 let's roll 32 bits
sed
.2 asl HEXBUF
rol HEXBUF+1
rol HEXBUF+2
rol HEXBUF+3
php cpy will disturb carry while BCD adc
ldy #0
.3 plp
lda BCDBUF,y
adc BCDBUF,y
sta BCDBUF,y
php
iny
cpy #5 Last byte of BCDBUF?
bne .3
plp
dex
bne .2
cld
ldy #0
ldx #9
.4 lda BCDBUF,y
pha
and #$0F
ora #$B0
sta ASCBUF,x
dex
pla
lsr
lsr
lsr
lsr
ora #$B0
sta ASCBUF,x
iny
dex
bpl .4
lda PADLEN any Len format ?
beq .5 no
lda #10
sec yes, print only digits starting at pos 10-padlen
sbc PADLEN
.5 tax x=0 if no padlen, or x=10-padlen
.6 lda ASCBUF,x
cmp #$B0 a zero?
beq .7
inc PADLEN found a non zero, print all digits, even if 0, next time
ldy #"0"
sty PADCHAR
bra .8
.7 cpx #9 last digit ?
beq .8 print always
ldy PADLEN no pad to fill, do not print 0
beq .9
lda PADCHAR fill with PADCHAR
.8 jsr COUT
.9 inx
cpx #10
bne .6
ply
plx
rts
*--------------------------------------
* Convert ASCBUF decimal to HEXBUF
*--------------------------------------
DEC2HEX phx
phy
stz HEXBUF
stz HEXBUF+1
stz HEXBUF+2
stz HEXBUF+3
ldx #0
.1 asl HEXBUF HEXBUF * 2 -> HEXBUF
rol HEXBUF+1
rol HEXBUF+2
rol HEXBUF+3
lda HEXBUF HEXBUF * 2 -> HEXBUFTMP
asl
sta HEXBUFTMP
lda HEXBUF+1
rol
sta HEXBUFTMP+1
lda HEXBUF+2
rol
sta HEXBUFTMP+2
lda HEXBUF+3
rol
sta HEXBUFTMP+3
asl HEXBUFTMP HEXBUFTMP * 2 -> HEXBUFTMP
rol HEXBUFTMP+1
rol HEXBUFTMP+2
rol HEXBUFTMP+3
lda HEXBUF HEXBUF + HEXBUFTMP -> HEXBUF
clc
adc HEXBUFTMP
sta HEXBUF
lda HEXBUF+1
adc HEXBUFTMP+1
sta HEXBUF+1
lda HEXBUF+2
adc HEXBUFTMP+2
sta HEXBUF+2
lda HEXBUF+3
adc HEXBUFTMP+3
sta HEXBUF+3
inx
lda ASCBUF,x
and #$0F
clc
adc HEXBUF
sta HEXBUF
bcc .2
inc HEXBUF+1
bne .2
inc HEXBUF+2
bne .2
inc HEXBUF+3
.2 cpx ASCBUF
bne .1
ply
plx
rts
*--------------------------------------
PRBYTE pha
lsr
lsr
lsr
lsr
ora #$B0
cmp #$BA
bcc .1
adc #6
.1 jsr COUT
pla
PRHEX and #$0F
ora #$B0
cmp #$BA
bcc COUT
adc #6
bra COUT
*--------------------------------------
CROUT lda #13
*--------------------------------------
COUT phx
phy
>PUSHA
ldy #S.PS.hOUTDEV
lda (pPsContext),y
>SYSCALL SYS.DevOutA
ply
plx
rts
*--------------------------------------
CS.END
PRINTFTBL1 .AS -"abBdDLeEhHiIsStT"
PRINTFTBL1.END
PRINTFTBL2 .AS -"n\%"
PRINTFTBL2.END
PRINTF.ATTRIB .AS -"dnb+++wr"
*--------------------------------------
PADCHAR .BS 1
PADLEN .BS 1
HEXBUF .BS 4 32 bits max
HEXBUFTMP .BS 4
BCDBUF .BS 5 5, enough to handle 32bits
ASCBUF .BS 11 LEN + 10 digits ($FFFFFFFF=4.294.967.295)
*--------------------------------------
MAN
SAVE LIB/LIBSTR.S
ASM