; Simple libc implementation for the SuB Suite strtoull: phy.w ; Preserve Y. and #0 ; Reset A. tay ; Reset Y. pha.q ; Reset the value buffer. @loop: lda (sp+20), y ; Get a character from the string. pha ; Preserve the character. jsr isdigit ; Is this character, a digit? pla ; Get the character back. bne @digit ; Yes, so extract the value from it. jsr tolower ; No, so convert the character to lowercase. pha ; Preserve the character. jsr islower ; Is this an alphabetical character? pla ; Get the character back. beq @end ; No, so we're done. @alpha: sec ; Yes, so prepare for a non borrowing subtract. sbc #'a'-10 ; Get the numeric value from this digit. bra @chkbase ; Check if the value matches the base. @digit: sec ; Prepare for a non borrowing subtract. sbc #'0' ; Get the numeric value from this digit. @chkbase: cmp sp+19 ; Does the value match the base? bcs @end ; No, so we're done. @addval: tab ; Save the digit value. lda.q sp+1 ; Get the value from the value buffer. mul sp+19 ; Multiply the value by the base. clc ; Prepare for a non carrying add. adc b ; Add the digit value to the total value. sta.q sp+1 ; Place the value in the value buffer. iny ; Increment the string index. and #0 ; Reset A. bra @loop ; Keep looping. @end: pla.q ; Get the value buffer back. ply.w ; Get Y back. ldb #0 ; Reset B. rts ; End of strtoull. strlen: pha.q ; Set the temp variable to the argument. ldb #0 ; Reset B. tba ; Reset A. tax ; Reset X. phy.w ; Preserve Y. txy ; Reset Y. @loop: lda (sp+3), y ; Are we at the end of the string? beq @end ; Yes, so we're done. iny ; No, so increment the index. bra @loop ; Keep looping. @end: tyx ; Return the length in X. ply.w ; Get the preserved value back. pla.q ; Get the argument back. txa ; Get the return value. rts ; End of strlen. strcmp: ldb #0 ; Reset B. tba ; Reset A. phy.w ; Preserve Y. tay ; Reset Y. @loop: ldb #0 ; Set the islong flag to false. lda (sp+19), y ; Are we at the end of the first string? beq cmpr ; Yes, so check if we're too short, or too long. ldb #1 ; No, so set the islong flag to true. cmp (sp+11), y ; Is the character of both strings, the same? bne cmpr ; No, so check if we're too short, or too long. iny ; Yes, so increment the index. bra @loop ; Keep looping. strccmp: strcasecmp: ldb #0 ; Reset B. tba ; Reset A. phy.w ; Preserve Y. tay ; Reset Y. @loop: ldb #0 ; Set the islong flag to false. lda (sp+19), y ; Are we at the end of the first string? beq cmpr ; Yes, so check if we're too short, or too long. ldb #1 ; No, so set the islong flag to true. jsr tolower ; Convert the character of string 1 to lowercase. phb ; Preserve the islong flag. pha ; Preserve the converted character. lda (sp+13), y ; Get the character of the second string. jsr tolower ; Convert the character of string 2 to lowercase. tab ; Place it in B. pla ; Get the character of string 1 back. cmp b ; Is the character of both strings, the same? plb ; Get the islong flag back. bne cmpr ; No, so check if we're too short, or too long. iny ; Yes, so increment the index. bra @loop ; Keep looping. cmpr: lda (sp+11), y ; Are we at the end of the second string? beq @islong ; Yes, so check the islong flag. @isshort: lda (sp+19), y ; No, but are we at the end of the first string? beq @short ; Yes, so return -1. @islong: cpb #1 ; Is the islong flag true? bne @equ ; No, so return 0. @long: lda #1 ; Yes, so return 1. bra @end ; We are done. @equ: lda #0 ; Return 0. bra @end ; We are done. @short: lda #$FF ; Return -1. @end: ply.w ; Get the preserved value back. rts ; End of cmpr. isdigit: sec ; Prepare for a non carrying subtraction. sbc #'0' ; Subtract $30 from the passed character. and #$FF ; Make sure that we have only one byte. cmp #10 ; Is the subtracted value, less than 10? bcs @false ; No, so return false. @true: lda #1 ; Yes, so return true. bra @end ; We are done. @false: lda #0 ; Return false. @end: rts ; End of isdigit. isxdigit: pha ; Preserve the character. jsr isdigit ; Is this character, a decimal digit? pla ; Get the character back. bne @true ; Yes, so return true. @alpha: sec ; No, so prepare for a non carrying subtract. ora #$20 ; Convert it to lowercase. sbc #'a' ; Subtract $61 from the character. and #$FF ; Make sure that we have only one byte. cmp #6 ; Is the subtracted value, less than 6? bcs @false ; No, so return false. @true: lda #1 ; Yes, so return true. bra @end ; We are done. @false: lda #0 ; Return false. @end: rts ; End of isxdigit. isupper: sec ; Prepare for a non carrying subtraction. sbc #'A' ; Subtract $41 from the passed character. bra isletter ; Check if it's less than 26. islower: sec ; Prepare for a non carrying subtraction. sbc #'a' ; Subtract $61 from the passed character. isletter: and #$FF ; Make sure that we have only one byte. cmp #26 ; Is the subtracted value, less than 26? bcs @false ; No, so return false. @true: lda #1 ; Yes, so return true. bra @end ; We are done. @false: lda #0 ; Return false. @end: rts ; End of isletter. tolower: pha ; Preserve the character. jsr isupper ; Is this character, an uppercase character? pla ; Get the character back. beq @end ; No, so we're done. @lower: ora #$20 ; Yes, so convert it to lowercase. @end: rts ; End of tolower. toupper: pha ; Preserve the character. jsr islower ; Is this character, a lowercase character? pla ; Get the character back. beq @end ; No, so we're done. @upper: and #$5F ; Yes, so convert it to uppercase. @end: rts ; End of toupper.