aboutsummaryrefslogtreecommitdiff
path: root/src/streq.s
diff options
context:
space:
mode:
Diffstat (limited to 'src/streq.s')
-rw-r--r--src/streq.s84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/streq.s b/src/streq.s
new file mode 100644
index 0000000..2116203
--- /dev/null
+++ b/src/streq.s
@@ -0,0 +1,84 @@
+
+ .importzp sreg, ptr1, ptr2
+ .import popptr1, popax
+ .export _streq, _streq_i, _strneq_i, _lcase
+
+ ; extern __fastcall__ char lcase(char c);
+ ; extern __fastcall__ char streq(char *s1, char *s2);
+ ; extern __fastcall__ char streq_i(char *s1, char *s2);
+ ; extern __fastcall__ char strneq_i(char *s1, char *s2, char len);
+
+ ; these are fast and small replacements for standard C library functions.
+ ; lcase() is a drop-in replacement for tolower().
+ ; streq() is basically strcmp() except it returns true for equality,
+ ; false for inequality (so you can't e.g. use it for sorting).
+ ; also, it only supports strings up to 256 bytes long.
+ ; streq_i() is the case-insensitive verson of streq().
+ ; strneq_i() is case-insensitive and stops after 'len' characters.
+
+ limit = sreg+3 ; number of characters to compare (0 = 256)
+ insens = sreg ; bit 7 set = case insensitive, otherwise not
+ temp = sreg+1 ; nothing to see here, move along :)
+
+_lcase:
+ cmp #'Z'+1
+ bcs lcret
+ cmp #'A'
+ bcc lcret
+ ora #$20
+lcret:
+ rts
+
+_strneq_i:
+ sta limit
+ jsr popax
+ ldy #$80
+ sty insens
+ jmp doit
+
+_streq_i:
+ ldy #$80
+ .byte $2c ; BIT abs, skip next
+_streq:
+ ldy #0
+ sty insens
+ ldy #0
+ sty limit
+
+doit:
+ sta ptr2
+ stx ptr2+1
+ jsr popptr1 ; returns with Y=0
+
+cmploop:
+ lda (ptr2),y
+ bit insens
+ bpl no_case_1
+ jsr _lcase
+
+no_case_1:
+ sta temp
+ lda (ptr1),y
+ tax
+ bit insens
+ bpl no_case_2
+ jsr _lcase
+
+no_case_2:
+ sec
+ sbc temp
+ bne ret0
+ txa
+ beq ret1
+
+ iny
+ cpy limit
+ bne cmploop
+
+ret1:
+ lda #1
+ .byte $2c
+ret0:
+ lda #0
+ tax
+ rts