collapseos/apps/lib/util.asm

108 lines
2.0 KiB
NASM

; Sets Z is A is ' ' or '\t' (whitespace)
isWS:
cp ' '
ret z
cp 0x09
ret
; Advance HL to next WS.
; Set Z if WS found, unset if end-of-string.
toWS:
ld a, (hl)
call isWS
ret z
cp 0x01 ; if a is null, carries and unsets z
ret c
inc hl
jr toWS
; Consume following whitespaces in HL until a non-WS is hit.
; Set Z if non-WS found, unset if end-of-string.
rdWS:
ld a, (hl)
call isWS
jr nz, .ok
cp 0x01 ; if a is null, carries and unsets z
ret c
inc hl
jr rdWS
.ok:
cp a ; ensure Z
ret
; Copy string from (HL) in (DE), that is, copy bytes until a null char is
; encountered. The null char is also copied.
; HL and DE point to the char right after the null char.
strcpyM:
ld a, (hl)
ld (de), a
inc hl
inc de
or a
jr nz, strcpyM
ret
; Like strcpyM, but preserve HL and DE
strcpy:
push hl
push de
call strcpyM
pop de
pop hl
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 caller
or a ; If our chars are null, stop the cmp
inc hl
inc de
jr nz, .loop ; Z is carried through
.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
; Given a string at (HL), move HL until it points to the end of that string.
strskip:
push bc
ex af, af'
xor a ; look for null char
ld b, a
ld c, a
cpir ; advances HL regardless of comparison, so goes one too far
dec hl
ex af, af'
pop bc
ret
; Returns length of string at (HL) in A.
; Doesn't include null termination.
strlen:
push bc
xor a ; look for null char
ld b, a
ld c, a
cpir ; advances HL to the char after the null
.found:
; How many char do we have? We have strlen=(NEG BC)-1, since BC started
; at 0 and decreased at each CPIR loop. In this routine,
; we stay in the 8-bit realm, so C only.
add hl, bc
sub c
dec a
pop bc
ret