From a823d900823056c2109c4de362c6cbcfcc512b7d Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Fri, 19 Apr 2024 07:57:47 +0200 Subject: [PATCH] Separated versions --- libsrc/common/strcasestr.s | 95 ++++++++++++++++++++++++++++++++++++++ libsrc/common/strstr.s | 33 ++++--------- 2 files changed, 103 insertions(+), 25 deletions(-) create mode 100644 libsrc/common/strcasestr.s diff --git a/libsrc/common/strcasestr.s b/libsrc/common/strcasestr.s new file mode 100644 index 000000000..58364f419 --- /dev/null +++ b/libsrc/common/strcasestr.s @@ -0,0 +1,95 @@ +; +; Ullrich von Bassewitz, 11.12.1998 +; +; char* strcasestr (const char* haystack, const char* needle); +; + + .export _strcasestr + .import popptr1, return0, tolowerdirect + .importzp ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3, tmp4 + .include "ctype.inc" + + .segment "LOWCODE" + +_strcasestr: + sta ptr2 ; Save needle + stx ptr2+1 + sta ptr4 ; Setup temp copy for later + + jsr popptr1 ; Get haystack to ptr1 + +; If needle is empty, return haystack + + ; ldy #$00 Y=0 guaranteed by popptr1 + lda (ptr2),y ; Get first byte of needle + beq @Found ; Needle is empty --> we're done + +; Search for the beginning of the string (this is not an optimal search +; strategy [in fact, it's pretty dumb], but it's simple to implement). + + jsr tolowerdirect ; Lowercase + sta tmp1 ; Save start of needle +@L1: lda (ptr1),y ; Get next char from haystack + beq @NotFound ; Jump if end + + jsr tolowerdirect ; Lowercase + cmp tmp1 ; Start of needle found? + beq @L2 ; Jump if so + iny ; Next char + bne @L1 + inc ptr1+1 ; Bump high byte + bne @L1 ; Branch always + +; We found the start of needle in haystack + +@L2: tya ; Get offset + clc + adc ptr1 + sta ptr1 ; Make ptr1 point to start + bcc @L3 + inc ptr1+1 + +; ptr1 points to the start of needle in haystack now. Setup temporary pointers for the +; search. The low byte of ptr4 is already set. + +@L3: sta ptr3 + lda ptr1+1 + sta ptr3+1 + lda ptr2+1 + sta ptr4+1 + ldy #1 ; First char is identical, so start on second + +; Do the compare + +@L4: lda (ptr4),y ; Get char from needle + beq @Found ; Jump if end of needle (-> found) + + jsr tolowerdirect ; Lowercase + sta tmp2 + + lda (ptr3),y ; Compare with haystack + + jsr tolowerdirect ; Lowercase + cmp tmp2 + bne @L5 ; Jump if not equal + iny ; Next char + bne @L4 + inc ptr3+1 + inc ptr4+1 ; Bump hi byte of pointers + bne @L4 ; Next char (branch always) + +; The strings did not compare equal, search next start of needle + +@L5: ldy #1 ; Start after this char + bne @L1 ; Branch always + +; We found the start of needle + +@Found: lda ptr1 + ldx ptr1+1 + rts + +; We reached end of haystack without finding needle + +@NotFound: + jmp return0 ; return NULL diff --git a/libsrc/common/strstr.s b/libsrc/common/strstr.s index 6ab46148c..691e5ba5c 100644 --- a/libsrc/common/strstr.s +++ b/libsrc/common/strstr.s @@ -4,20 +4,11 @@ ; char* strstr (const char* haystack, const char* needle); ; - .export _strstr, _strcasestr - .import popptr1, return0, tolowerdirect - .importzp ptr1, ptr2, ptr3, ptr4, tmp1, tmp2 - -maybe_lower: ; Lowercase char in A if needed - jmp tolowerdirect ; patched on entry with either JMP or RTS + .export _strstr + .import popptr1 + .importzp ptr1, ptr2, ptr3, ptr4, tmp1 _strstr: - ldy #$60 ; RTS - bne :+ -_strcasestr: - ldy #$4C ; JMP absolute -: sty maybe_lower - sta ptr2 ; Save needle stx ptr2+1 sta ptr4 ; Setup temp copy for later @@ -33,12 +24,9 @@ _strcasestr: ; Search for the beginning of the string (this is not an optimal search ; strategy [in fact, it's pretty dumb], but it's simple to implement). - jsr maybe_lower ; Lowercase if needed sta tmp1 ; Save start of needle @L1: lda (ptr1),y ; Get next char from haystack beq @NotFound ; Jump if end - - jsr maybe_lower ; Lowercase if needed cmp tmp1 ; Start of needle found? beq @L2 ; Jump if so iny ; Next char @@ -55,7 +43,7 @@ _strcasestr: bcc @L3 inc ptr1+1 -; ptr1 points to the start of needle in haystack now. Setup temporary pointers for the +; ptr1 points to the start of needle now. Setup temporary pointers for the ; search. The low byte of ptr4 is already set. @L3: sta ptr3 @@ -69,14 +57,7 @@ _strcasestr: @L4: lda (ptr4),y ; Get char from needle beq @Found ; Jump if end of needle (-> found) - - jsr maybe_lower ; Lowercase if needed - sta tmp2 - - lda (ptr3),y ; Compare with haystack - - jsr maybe_lower ; Lowercase if needed - cmp tmp2 + cmp (ptr3),y ; Compare with haystack bne @L5 ; Jump if not equal iny ; Next char bne @L4 @@ -98,4 +79,6 @@ _strcasestr: ; We reached end of haystack without finding needle @NotFound: - jmp return0 ; return NULL + lda #$00 ; return NULL + tax + rts