NEW PREFIX AUTO 4,1 */-------------------------------------- * # strtof * Convert String to 40 bits Float * ## C * `float strtof (const char* str, char** endptr);` * ## ASM * **In:** * `>PUSHWI EndPtr` * `>LDYA str` * `>SYSCALL strtof` * ## RETURN VALUE * On stack (float) *\-------------------------------------- K.strtof >STYA TXTPTR Ptr to source string >PULLW ZPPtr1 jsr K.AToF.I lda TXTPTR sta (ZPPtr1) ldy #1 lda TXTPTR+1 sta (ZPPtr1),y rts */-------------------------------------- * # AToF * Convert String to 40 bits Float * ## C * `float atof (const char* str);` * ## ASM * **In:** * `>LDYA str` * `>SYSCALL atof` * ## RETURN VALUE * On stack (float) *\-------------------------------------- K.AToF >STYA TXTPTR Ptr to source string K.AToF.I jsr CHARGOT ldx #ROM.FIN **** DUP code in MATH.Go **** jsr GP.ROMCALL lda pStack sec sbc #5 sta pStack sta FORPNT Ptr to dst buffer lda pStack+1 sta FORPNT+1 ldx #ROM.GETFAC jsr GP.ROMCALL clc rts */-------------------------------------- * # StrToL/StrToUL * Convert String to 32 bits (unsigned) int * ## C * `long strtol (const char* str, char** endptr, int base);` * `unsigned long strtoul (const char* str, char** endptr, int base);` * ## ASM * **In:** * `>PUSHB Base` * `>PUSHWI EndPtr` * `>LDYAI str` * `>SYSCALL strtol` * ## RETURN VALUE * On stack (long) *\-------------------------------------- K.StrToL sec Signed .HS 90 BCC K.StrToUL clc Unsigned >STYA ZPPtr2 >PULLW ZPPtr1 >PULLA Base jsr K.AToL.I bcs K.StrToUL.rts * clc K.StrToUL.Exit adc ZPPtr2 sta (ZPPtr1) lda #0 adc ZPPtr2+1 ldy #1 sta (ZPPtr1),y K.StrToUL.rts rts */-------------------------------------- * # atol * Convert String to 32 bits long * ## C * `long atol ( const char * str );` * ## ASM * **In:** * `>LDYA str` * `>SYSCALL atol` * ## RETURN VALUE * On stack (long) *\-------------------------------------- *STDLIB.32 .BS 4 32 bits max STDLIB.32 .EQ FAC 32 bits max *-------------------------------------- K.AToL >STYA ZPPtr2 C-String in Ptr2, Dst buffer in Ptr1 lda #10 base 10 sec signed K.AToL.I jsr STDLIB.GetDec bcs .9 phy Save Count processed ldy #3 .3 lda STDLIB.32,y >PUSHA dey bpl .3 pla * clc .9 rts */-------------------------------------- * # atoi * Convert String to 16 bits int * ## C * `int atoi ( const char * str );` * ## ASM * **In:** * `>LDYAI str` * `>SYSCALL atoi` * ## RETURN VALUE * Y,A = int *\-------------------------------------- K.atoi >STYA ZPPtr2 lda #10 base 10 sec signed jsr STDLIB.GetDec bcs .9 >LDYA STDLIB.32 .9 rts *-------------------------------------- * Convert Hex int at ZPPtr2 to STDLIB.32 *-------------------------------------- STDLIB.GetHex lda (ZPPtr2) beq .9 jsr MEM.IsHexDigit bcs .9 jsr STDLIB.32.Clear sta STDLIB.32 ldy #$ff .1 iny lda (ZPPtr2),y beq .8 jsr MEM.IsHexDigit bcs .8 pha ldx #4 .2 jsr STDLIB.32.T2 bcs .99 overflow!!! dex bne .2 pla ora STDLIB.32 sta STDLIB.32 bra .1 .8 clc rts .99 pla .9 sec rts *-------------------------------------- * Convert Decimal int at ZPPtr2 to STDLIB.32 *-------------------------------------- STDLIB.GetDec jsr STDLIB.32.Clear ldy #$ff .1 iny lda (ZPPtr2),y beq .8 jsr MEM.IsDigit bcs .8 phy Save Y, pointing to next char jsr STDLIB.32.T10 ply bcs .9 lda (ZPPtr2),y and #$0F * clc adc STDLIB.32 sta STDLIB.32 bcc .1 inc STDLIB.32+1 bne .1 inc STDLIB.32+2 bne .1 inc STDLIB.32+3 bne .1 overflow!!! * sec rts .8 tya sec beq .9 clc .9 rts *-------------------------------------- STDLIB.32.T10 ldx #3 .1 lda STDLIB.32,x save STDLIB.32 for 4+1 pha dex bpl .1 jsr STDLIB.32.T2 STDLIB.32 * 2 -> STDLIB.32 bcs STDLIB.32.9 overflow!!! jsr STDLIB.32.T2 STDLIB.32 * 4 -> STDLIB.32 bcs STDLIB.32.9 overflow!!! ldx #0 ldy #4 * clc .2 pla STDLIB.32 * 4 + STDLIB.32 -> STDLIB.32 adc STDLIB.32,x sta STDLIB.32,x inx dey bne .2 bcs STDLIB.32.RTS overflow!!! * STDLIB.32 * 2 -> STDLIB.32 STDLIB.32.T2 asl STDLIB.32 rol STDLIB.32+1 rol STDLIB.32+2 rol STDLIB.32+3 rts if CS, overflow!!! STDLIB.32.9 pla discard saved STDLIB.32 pla pla pla STDLIB.32.RTS rts *-------------------------------------- STDLIB.32.Clear ldx #3 .1 stz STDLIB.32,x dex bpl .1 rts */-------------------------------------- * # RealPath * Return the canonicalized absolute pathname * ## C * `unsigned short int realpath (const char* str);` * ## ASM * **In:** * `>LDYA str` * `>SYSCALL realpath` * ## RETURN VALUE * CC : success * Y,A = Ptr to Full Path (C-String) * X = hMem of Full Path * CS : A = Error Code *\-------------------------------------- K.realpath sec .HS 90 BCC K.realpath.I clc ror .89+1 >STYA ZPPtr1 ldx #$ff lda (ZPPtr1) beq .1 cmp #'/' full path starting with '/'? beq .3 yes, do not append to current prefix .1 ldy #S.PS.hPREFIX lda (pPs),y jsr K.GetMemPtr >STYA ZPPtr2 ldy #$ff .2 iny inx lda (ZPPtr2),y sta K.Buf256,x bne .2 dex .3 ldy #$ff .4 iny inx lda (ZPPtr1),y sta K.Buf256,x bne .4 dex beq .89 we have '/'....nothing to do... lda K.Buf256,x cmp #'/' bne .50 stz K.Buf256,x remove ending / if any *-------------------------------------- * X=LEN, K.Buf256 = /dir1/./../file\0 *-------------------------------------- .50 ldx #1 lda K.Buf256,x beq .89 .5 ldy #0 dot counter=0 .6 cmp #'/' beq .8 cmp #'.' bne .7 iny .HS 2C BIT ABS, skip "LDY #0" .7 ldy #0 not a dot....reset dot counter inx lda K.Buf256,x bne .6 always, should end with a '/' .8 tya beq .80 Y was 0....nothing to do... dey "./" ? bne .9 no.. lda K.Buf256-2,x cmp #'/' "/./" ? bne .80 dex dex jsr K.RealPath.RemoveAtX we found "/./", remove,useless.... bra .80 .9 dey "../" ? bne .90 ".../" ??!!...mmm...syntax error lda K.Buf256-3,x cmp #'/' "/../" ? bne .80 dex dex dex txa we found "/../" beq .90 at the beginning of string...cannot remove /dir/.. jsr K.RealPath.RemoveAtX remove "/.." .10 dex lda K.Buf256,x go to "/dir" cmp #'/' bne .10 jsr K.RealPath.RemoveAtX ...remove "/dir" .80 inx lda K.Buf256,x bne .5 *-------------------------------------- .89 lda #$ff SELF MODIFIED bpl .98 >LDYAI K.Buf256 jmp K.NewStr .90 lda #E.BADPATH sec rts .98 clc rts *-------------------------------------- K.RealPath.RemoveAtX txa X = "/something" tay .1 iny lda K.Buf256,y beq .2 cmp #'/' bne .1 .2 phx .3 lda K.Buf256,y sta K.Buf256,x beq .4 iny inx bne .3 .4 txa bne .8 lda #'/' Make sure we have a least '/' in the buffer sta K.Buf256 stz K.Buf256+1 .8 plx rts */-------------------------------------- * # StrMatch * Compare a String against pattern (e.g. '*test?.txt') * ## C * `int * strmatch ( char * s, const char * pattern );` * ## ASM * **In:** * `>PUSHWI pattern` * `>LDYAI s` * `>SYSCALL strmatch` * ## RETURN VALUE * CC : match * CS : no match *\-------------------------------------- K.StrMatch jsr MEM.SPtr1PPtr2 lda (ZPPtr2) Get pattern 1st byte beq .8 Match always if empty ldy #0 bra .21 .1 inc ZPPtr2 Make PTR2 (pattern) advance to next char bne .2 inc ZPPtr2+1 .2 lda (ZPPtr2) get pattern char beq .41 end of pattern... .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 .4 iny advance to next char to compare bra .1 continue if remaining char in pattern .41 lda (ZPPtr1),y end of pattern, but end of string ? beq .8 yes, string matched entirely * no, remaining char in string, no match .9 sec rts .5 inc ZPPtr2 Make PTR2 advance to next char bne .6 inc ZPPtr2+1 .6 lda (ZPPtr2) we have '*', last char of pattern ? beq .8 yes, match everything, including empty string 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 iny bra .1 go check remaining char in pattern... .8 clc rts *-------------------------------------- MAN SAVE USR/SRC/SYS/KERNEL.S.STDLIB LOAD USR/SRC/SYS/KERNEL.S ASM