RosettaCodeData/Task/String-case/Z80-Assembly/string-case.z80

77 lines
2.0 KiB
Z80 Assembly

ToUpperCase:
;INPUT:
;HL = BASE ADDRESS OF A NULL-TERMINATED STRING
;OVERWRITES THE STRING YOU INPUT WITH THE UPPERCASE VERSION
ld bc,&617A ;lower case ascii range
loop_toUpperCase:
ld a,(hl)
or a
ret z
call CompareRange_Inclusive ;is this a lower case letter?
jr c,skipUpperCase ;if not, don't change it!
and %11011111 ;change to upper case
ld (hl),a ;store back in string
skipUpperCase:
inc hl
jr loop_toUpperCase
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ToLowerCase:
;INPUT:
;HL = BASE ADDRESS OF A NULL-TERMINATED STRING
;OVERWRITES THE STRING YOU INPUT WITH THE LOWERCASE VERSION
ld bc,&415A ;upper case ascii range
loop_toLowerCase:
ld a,(hl)
or a
ret z
call CompareRange_Inclusive
jr c,skipLowerCase
or %00100000
ld (hl),a
skipLowerCase:
inc hl
jr loop_toLowerCase
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ToggleCase:
;INPUT:
;HL = BASE ADDRESS OF A NULL-TERMINATED STRING
;INVERTS THE CASE OF ALL ALPHABET CHARACTERS IN THE STRING
ld bc,&415A
loop_toggleCase:
ld a,(hl)
or a
ret z
call CompareRange_Inclusive
jr nc,toggle
push bc
ld bc,&617A
call CompareRange_Inclusive
pop bc
jr c, skipToggleCase
toggle:
xor %00100000
ld (hl),a
skipToggleCase:
inc hl
jr loop_toggleCase
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CompareRange_Inclusive:
;returns CF CLEAR if B <= A <= C, and CF SET otherwise.
cp b
ret c ;if carry set, A < B thus out of range.
push de
ld e,a
ld a,c
ld c,e ;swap A with C
cp c ;compare C to A. Signs are reversed.
;if carry set, "A" < "C" which means original C < original A. Thus out of range.
;if carry clear, we are in range.
ld e,a ;now put A and C back where they belong.
ld a,c
ld c,e ;none of this affects the flags, so the compare is still valid.
pop de
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;