]> git.sur5r.net Git - cc65/commitdiff
initial check-in
authorcpg <cpg@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 10 Feb 2009 19:15:21 +0000 (19:15 +0000)
committercpg <cpg@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 10 Feb 2009 19:15:21 +0000 (19:15 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@3923 b7a2c559-68d2-44c3-8de9-860c34a00d81

libsrc/common/strnicmp.s [new file with mode: 0644]

diff --git a/libsrc/common/strnicmp.s b/libsrc/common/strnicmp.s
new file mode 100644 (file)
index 0000000..c3b89e4
--- /dev/null
@@ -0,0 +1,102 @@
+;
+; Christian Groessler, 10.02.2009
+; derived from strncmp.s and stricmp.s
+;
+; int __fastcall__ strnicmp (const char* s1, const char* s2, size_t count);
+; int __fastcall__ strncasecmp (const char* s1, const char* s2, size_t count);
+;
+
+       .export         _strnicmp, _strncasecmp
+       .import         popax, __ctype
+       .importzp       ptr1, ptr2, ptr3, tmp1
+
+
+_strnicmp:
+_strncasecmp:
+
+; Convert the given counter value in a/x from a downward counter into an
+; upward counter, so we can increment the counter in the loop below instead
+; of decrementing it. This adds some overhead now, but is cheaper than
+; executing a more complex test in each iteration of the loop. We do also
+; correct the value by one, so we can do the test on top of the loop.
+
+       eor     #$FF
+       sta     ptr3
+       txa
+       eor     #$FF
+       sta     ptr3+1
+
+; Get the remaining arguments
+
+               jsr     popax           ; get s2
+       sta     ptr2
+       stx     ptr2+1
+       jsr     popax           ; get s1
+       sta     ptr1
+       stx     ptr1+1
+
+; Loop setup
+
+       ldy     #0
+
+; Start of compare loop. Check the counter.
+
+Loop:          inc     ptr3
+       beq     IncHi           ; Increment high byte
+
+; Compare a byte from the strings
+
+Comp:  lda     (ptr2),y
+       tax
+       lda     __ctype,x       ; get character classification
+       and     #$01            ; lower case char?
+       beq     L1              ; jump if no
+       txa                     ; get character back
+       sec
+       sbc     #<('a'-'A')     ; make upper case char
+       tax                     ;
+L1:    stx     tmp1            ; remember upper case equivalent
+
+       lda     (ptr1),y        ; get character from first string
+       tax
+       lda     __ctype,x       ; get character classification
+       and     #$01            ; lower case char?
+               beq     L2              ; jump if no
+       txa                     ; get character back
+       sec
+               sbc     #<('a'-'A')     ; make upper case char
+       tax
+
+L2:    cpx     tmp1            ; compare characters
+               bne     NotEqual        ; Jump if strings different
+       txa                     ; End of strings?
+               beq     Equal1          ; Jump if EOS reached, a/x == 0
+
+; Increment the pointers
+
+       iny
+       bne     Loop
+       inc     ptr1+1
+       inc     ptr2+1
+       bne     Loop            ; Branch always
+
+; Increment hi byte
+
+IncHi: inc     ptr3+1
+               bne     Comp            ; Jump if counter not zero
+
+; Exit code if strings are equal. a/x not set
+
+Equal: lda     #$00
+       tax
+Equal1:        rts
+
+; Exit code if strings not equal
+
+NotEqual:
+       bcs     L3
+       ldx     #$FF            ; Make result negative
+       rts
+
+L3:    ldx     #$01            ; Make result positive
+       rts