.importzp sreg, ptr1, ptr2 .import popptr1, popax .import _msg_text .export _streq, _streq_i, _strneq_i, _lcase, _find_nick ; 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); ; extern __fastcall__ char find_nick(void); ; 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. ; find_nick() does a case-insensitive search of msg_text for ; config.nick. returns 1 if found, 0 if not. NOTE: only searches the ; first 256 bytes of msg_text! this is a minor infelicity, but people ; rarely type that much text in one message... 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 :) temp2 = sreg+2 NICK = $0480 ; aka config.nick _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 _find_nick: lda _msg_text sta ptr1 lda _msg_text+1 sta ptr1+1 ldy #0 ; loop over _msg_text, looking for the first character of NICK, ; but convert both to lowercase before comparing. @l: lda (ptr1),y beq ret0 ; if we hit the end of _msg_text, we're done, no match. jsr _lcase sta temp ; temp = lcase(A) lda NICK ; compare to lcase(NICK[0]) jsr _lcase cmp temp beq @found1 ; found a match for the first char, see if the rest matches. @next: iny bne @l beq ret0 @found1: ; found a case-insensitive match for the first char of NICL... sty temp2 ; save Y so we can pick back up in the @l loop if this isn't a match. iny ; start with _msg_text char after the initial match. ldx #1 ; start with 2nd char of NICK @l2: lda (ptr1),y jsr _lcase sta temp lda NICK,x beq ret1 ; if we hit the null terminator of NICK, we have a successful match! jsr _lcase cmp temp bne @nope ; no match, get out of @l2 iny inx bne @l2 ; matched a char, look at the next @nope: ldy temp2 ; restore Y jmp @next ; jump to the bottom of the @l loop.