summaryrefslogtreecommitdiff
path: root/programs/sub-suite/libc.s
diff options
context:
space:
mode:
Diffstat (limited to 'programs/sub-suite/libc.s')
-rw-r--r--programs/sub-suite/libc.s201
1 files changed, 201 insertions, 0 deletions
diff --git a/programs/sub-suite/libc.s b/programs/sub-suite/libc.s
new file mode 100644
index 0000000..bd55f9c
--- /dev/null
+++ b/programs/sub-suite/libc.s
@@ -0,0 +1,201 @@
+; 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.
+ aab ; 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.
+ cab ; 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.