PR#3 PREFIX /A2OSX.SRC NEW INC 1 AUTO 6 .LIST OFF .OP 65C02 .OR $2000 .TF /A2OSX.BOOT/LIB/LIBSTR.O *-------------------------------------- .INB INC/MACROS.I .INB INC/A2OSX.I *-------------------------------------- ZPTmpPtr1 .EQ ZPLIB+2 ZPTmpPtr2 .EQ ZPLIB+4 ZPTmpPtr3 .EQ ZPLIB+6 *-------------------------------------- * File Header (16 Bytes) *-------------------------------------- CS.START cld jmp (.1,x) .DA #$61 6502,Level 1 (65c02) .DA #1 BIN Layout Version 1 .DA 0 .DA CS.END-CS.START .DA 0 .DA 0 .DA 0 *-------------------------------------- * Relocation Table *-------------------------------------- .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 PRINTFESC,PRINTFCR,PRINTFBKSLH,PRINTFPERCENT *-------------------------------------- .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 * %n pull 1 byte to print low Nibble HEX * %N 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 * \e print 'ESC' ($1B,27) * \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 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 .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 .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 #'0' 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 *-------------------------------------- PRINTFESC lda #$1B ESC jsr COUT 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 jsr COUT iny bne .1 .8 rts *-------------------------------------- PRINTP >PULLW ZPTmpPtr2 ldy #0 lda (ZPTmpPtr2),y tax beq .8 .1 iny lda (ZPTmpPtr2),y 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 #'a' bmi .2 cmp #'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 #'A' bmi .2 cmp #'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 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 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 #$30 sta ASCBUF,x dex pla lsr lsr lsr lsr ora #$30 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 #'0' 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 #$30 cmp #'9'+1 bcc .1 adc #6 .1 jsr COUT pla PRHEX and #$0F ora #$30 cmp #'9'+1 bcc COUT adc #6 bra COUT *-------------------------------------- CROUT lda #13 *-------------------------------------- COUT phx phy cmp #13 bne .1 ldx #DEVMGR.COUT jsr pDevJmp bcs .9 lda #10 .1 ldx #DEVMGR.COUT jsr pDevJmp ply plx .9 rts *-------------------------------------- CS.END PRINTFTBL1 .AS "abBdDLnNhHiIsStT" PRINTFTBL1.END PRINTFTBL2 .AS "en\%" 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