|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- ; 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
-
- ; HL - DE -> HL
- subDEFromHL:
- push af
- ld a, l
- sub e
- ld l, a
- ld a, h
- sbc a, d
- ld h, a
- pop af
- ret
-
- ; make Z the opposite of what it is now
- toggleZ:
- jp z, unsetZ
- cp a
- ret
-
- ; Returns length of string at (HL) in A.
- ; Doesn't include null termination.
- 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
-
- ; Sets Z if string at (HL) is one character long
- strIs1L:
- xor a
- cp (hl)
- jp z, unsetZ ; empty string
- inc hl
- cp (hl) ; Z has proper value
- dec hl ; doesn't touch Z
- 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 upcase
- ld c, a
- ld a, (hl)
- call 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
-
- ; Compares strings pointed to by HL and DE until one of them hits its null char.
- ; If equal, Z is set. If not equal, Z is reset.
- strcmp:
- push hl
- push de
-
- .loop:
- ld a, (de)
- cp (hl)
- jr nz, .end ; not equal? break early. NZ is carried out
- ; to the called
- 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
- jr .loop
-
- .end:
- pop de
- pop hl
- ; 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 unsetZ
- ret
-
- ; Scans (HL) and sets Z according to whether the string is double quoted, that
- ; is, starts with a " and ends with a ". If it is double quoted, "enter" them,
- ; that is, advance HL by one and transform the ending quote into a null char.
- ; If the string isn't double-enquoted, HL isn't changed.
- enterDoubleQuotes:
- ld a, (hl)
- cp '"'
- ret nz
- push hl
- inc hl
- ld a, (hl)
- or a ; already end of string?
- jr z, .nomatch
- xor a
- call findchar ; go to end of string
- dec hl
- ld a, (hl)
- cp '"'
- jr nz, .nomatch
- ; We have a match, replace ending quote with null char
- xor a
- ld (hl), a
- ; Good, let's go back
- pop hl
- ; ... but one char further
- inc hl
- cp a ; ensure Z
- ret
- .nomatch:
- call unsetZ
- pop hl
- 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 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
-
-
- ; DE * BC -> DE (high) and HL (low)
- multDEBC:
- ld hl, 0
- ld a, 0x10
- .loop:
- add hl, hl
- rl e
- rl d
- jr nc, .noinc
- add hl, bc
- jr nc, .noinc
- inc de
- .noinc:
- dec a
- jr nz, .loop
- ret
|