; run RLA the number of times specified in B rlaX: ; first, see if B == 0 to see if we need to bail out inc b dec b ret z ; Z flag means we had B = 0 .loop: rla djnz .loop ret callHL: jp (hl) ret ; Compare HL with DE and sets Z and C in the same way as a regular cp X where ; HL is A and DE is X. cpHLDE: ld a, h cp d ret nz ; if not equal, flags are correct ld a, l cp e ret ; flags are correct ; HL - DE -> HL subDEFromHL: push af ld a, l sub e ld l, a ld a, h sbc d ld h, a pop af ret ; Returns length of string at (HL) in A. strlen: push bc push hl ld bc, 0 ld a, 0 ; look for null char .loop: cpi jp z, .found jr .loop .found: ; How many char do we have? the (NEG BC)-1, which started at 0 and ; decreased at each CPI call. In this routine, we stay in the 8-bit ; realm, so C only. ld a, c neg dec a pop hl pop bc ret ; Compares strings pointed to by HL and DE up to A count of characters in a ; case-insensitive manner. ; If equal, Z is set. If not equal, Z is reset. strncmpI: push bc push hl push de ld b, a .loop: ld a, (de) call JUMP_UPCASE ld c, a ld a, (hl) call JUMP_UPCASE cp c jr nz, .end ; not equal? break early. NZ is carried out ; to the called or a ; cp 0. If our chars are null, stop the cmp jr z, .end ; The positive result will be carried to the ; caller inc hl inc de djnz .loop ; Success ; We went through all chars with success. Ensure Z cp a .end: pop de pop hl pop bc ; Because we don't call anything else than CP that modify the Z flag, ; our Z value will be that of the last cp (reset if we broke the loop ; early, set otherwise) ret ; If string at (HL) starts with ( and ends with ), "enter" into the parens ; (advance HL and put a null char at the end of the string) and set Z. ; Otherwise, do nothing and reset Z. enterParens: ld a, (hl) cp '(' ret nz ; nothing to do push hl ld a, 0 ; look for null char ; advance until we get null .loop: cpi jp z, .found jr .loop .found: dec hl ; cpi over-advances. go back to null-char dec hl ; looking at the last char before null ld a, (hl) cp ')' jr nz, .doNotEnter ; We have parens. While we're here, let's put a null xor a ld (hl), a pop hl ; back at the beginning. Let's advance. inc hl cp a ; ensure Z ret ; we're good! .doNotEnter: pop hl call JUMP_UNSETZ ret ; Find string (HL) in string list (DE) of size B, in a case-insensitive manner. ; Each string is C bytes wide. ; Returns the index of the found string. Sets Z if found, unsets Z if not found. findStringInList: push de push bc .loop: ld a, c call strncmpI ld a, c call JUMP_ADDDE jr z, .match djnz .loop ; no match, Z is unset pop bc pop de ret .match: ; Now, we want the index of our string, which is equal to our initial B ; minus our current B. To get this, we have to play with our registers ; and stack a bit. ld d, b pop bc ld a, b sub d pop de cp a ; ensure Z ret