123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- ; String library
- ;
- #include once <free.asm>
- ;
- __STR_ISNULL: ; Returns A = FF if HL is 0, 0 otherwise
- lda z80_h ;- ld a,h
- sta z80_a
- ;- or l
- ;- sub 1 ; Only CARRY if HL is NULL
- ;- sbc a, a ; Only FF if HL is NULL (0 otherwise)
- rts ;- ret
- __STRCMP: ; Compares strings at HL, DE: Returns 0 if EQual, -1 if HL < DE, +1 if HL > DE
- ; A register is preserved and returned in A'
- ;- PROC ; __FASTCALL__
- ;- LOCAL __STRCMPZERO
- ;- LOCAL __STRCMPEXIT
- ;- LOCAL __STRCMPLOOP
- ;- LOCAL __NOPRESERVEBC
- ;- LOCAL __EQULEN
- ;- LOCAL __EQULEN1
- ;- LOCAL __HLZERO
- ;- ex af, af' ; Saves current A register in A' (it's used by STRXX comparison functions)
- lda z80_h ;- ld a,h
- sta z80_a
- ;- or l
- ;- jr z, __HLZERO
- lda z80_d ;- ld a,d
- sta z80_a
- ;- or e
- ;- ld a, 1
- ;- ret z ; Returns +1 if HL is not NULL and DE is NULL
- ;- ld c, (hl)
- ;- inc hl
- ;- ld b, (hl)
- ;- inc hl ; BC = LEN(a$)
- ;- push hl ; HL = &a$, saves it
- ;- ex de, hl
- ;- ld e, (hl)
- ;- inc hl
- ;- ld d, (hl)
- ;- inc hl
- ;- ex de, hl ; HL = LEN(b$), de = &b$
- ; At this point Carry is cleared, and A reg. = 1
- ;- sbc hl, bc ; Carry if len(b$) > len(a$)
- ;- jr z, __EQULEN ; Jump if they have the same length so A reg. = 0
- ;- jr c, __EQULEN1 ; Jump if len(b$) > len(a$) so A reg. = 1
- __NOPRESERVEBC:
- ;- add hl, bc ; Restore HL (original length)
- ;- ld b, h ; len(b$) <= len(a$)
- ;- ld c, l ; so BC = hl
- ;- dec a ; At this point A register = 0, it must be -1 since len(a$) > len(b$)
- __EQULEN:
- ;- dec a ; A = 0 if len(a$) = len(b$), -1 otherwise
- __EQULEN1:
- ;- pop hl ; Recovers A$ pointer
- ;- push af ; Saves A for later (Value to return if strings reach the end)
- ;- ld a, b
- ;- or c
- ;- jr z, __STRCMPZERO ; empty string being compared
- ; At this point: BC = lesser length, DE and HL points to b$ and a$ chars respectively
- __STRCMPLOOP:
- ;- ld a, (de)
- ;- cpi
- ;- jr nz, __STRCMPEXIT ; (HL) != (DE). Examine carry
- ;- jp po, __STRCMPZERO ; END of string (both are equal)
- ;- inc de
- ;- jp __STRCMPLOOP
- __STRCMPZERO:
- ;- pop af ; This is -1 if len(a$) < len(b$), +1 if len(b$) > len(a$), 0 otherwise
- rts ;- ret
- __STRCMPEXIT: ; Sets A with the following value
- ;- dec hl ; Get back to the last char
- ;- cp (hl)
- ;- sbc a, a ; A = -1 if carry => (DE) < (HL); 0 otherwise (DE) > (HL)
- ;- cpl ; A = -1 if (HL) < (DE), 0 otherwise
- ;- add a, a ; A = A * 2 (thus -2 or 0)
- ;- inc a ; A = A + 1 (thus -1 or 1)
- pla ;- pop bc ; Discard top of the stack
- sta z80_b
- pla
- sta z80_c
- rts ;- ret
- __HLZERO:
- ora z80_d ;- or d
- ora z80_e ;- or e
- ;- ret z ; Returns 0 (EQ) if HL == DE == NULL
- ;- ld a, -1
- rts ;- ret ; Returns -1 if HL is NULL and DE is not NULL
- ;- ENDP
- ; The following routines perform string comparison operations (<, >, ==, etc...)
- ; On return, A will contain 0 for False, other value for True
- ; Register A' will determine whether the incoming strings (HL, DE) will be freed
- ; from dynamic memory on exit:
- ; Bit 0 => 1 means HL will be freed.
- ; Bit 1 => 1 means DE will be freed.
- __STREQ: ; Compares a$ == b$ (HL = ptr a$, DE = ptr b$). Returns FF (True) or 0 (False)
- lda z80_l ;- push hl
- pha
- lda z80_h
- pha
- lda z80_e ;- push de
- pha
- lda z80_d
- pha
- jsr __STRCMP ;- call __STRCMP
- pla ;- pop de
- sta z80_d
- pla
- sta z80_e
- pla ;- pop hl
- sta z80_h
- pla
- sta z80_l
- ;inc a ; If A == -1, return 0
- ;jp z, __FREE_STR
- ;dec a ;
- ;dec a ; Return -1 if a = 0 (True), returns 0 if A == 1 (False)
- ;- sub 1
- ;- sbc a, a
- jmp __FREE_STR ;- jp __FREE_STR
- __STRNE: ; Compares a$ != b$ (HL = ptr a$, DE = ptr b$). Returns FF (True) or 0 (False)
- lda z80_l ;- push hl
- pha
- lda z80_h
- pha
- lda z80_e ;- push de
- pha
- lda z80_d
- pha
- jsr __STRCMP ;- call __STRCMP
- pla ;- pop de
- sta z80_d
- pla
- sta z80_e
- pla ;- pop hl
- sta z80_h
- pla
- sta z80_l
- ;jp z, __FREE_STR
- ;ld a, 0FFh ; Returns 0xFFh (True)
- jmp __FREE_STR ;- jp __FREE_STR
- __STRLT: ; Compares a$ < b$ (HL = ptr a$, DE = ptr b$). Returns FF (True) or 0 (False)
- lda z80_l ;- push hl
- pha
- lda z80_h
- pha
- lda z80_e ;- push de
- pha
- lda z80_d
- pha
- jsr __STRCMP ;- call __STRCMP
- pla ;- pop de
- sta z80_d
- pla
- sta z80_e
- pla ;- pop hl
- sta z80_h
- pla
- sta z80_l
- jeq __FREE_STR ;- jp z, __FREE_STR ; Returns 0 if A == B
- ;- dec a ; Returns 0 if A == 1 => a$ > b$
- ;jp z, __FREE_STR
- ;inc a ; A = FE now (-2). Set it to FF and return
- jmp __FREE_STR ;- jp __FREE_STR
- __STRLE: ; Compares a$ <= b$ (HL = ptr a$, DE = ptr b$). Returns FF (True) or 0 (False)
- lda z80_l ;- push hl
- pha
- lda z80_h
- pha
- lda z80_e ;- push de
- pha
- lda z80_d
- pha
- jsr __STRCMP ;- call __STRCMP
- pla ;- pop de
- sta z80_d
- pla
- sta z80_e
- pla ;- pop hl
- sta z80_h
- pla
- sta z80_l
- ;- dec a ; Returns 0 if A == 1 => a$ < b$
- ;jp z, __FREE_STR
- ;ld a, 0FFh ; A = FE now (-2). Set it to FF and return
- jmp __FREE_STR ;- jp __FREE_STR
- __STRGT: ; Compares a$ > b$ (HL = ptr a$, DE = ptr b$). Returns FF (True) or 0 (False)
- lda z80_l ;- push hl
- pha
- lda z80_h
- pha
- lda z80_e ;- push de
- pha
- lda z80_d
- pha
- jsr __STRCMP ;- call __STRCMP
- pla ;- pop de
- sta z80_d
- pla
- sta z80_e
- ;- pop hl
- jeq __FREE_STR ;- jp z, __FREE_STR ; Returns 0 if A == B
- ;- inc a ; Returns 0 if A == -1 => a$ < b$
- ;jp z, __FREE_STR ; Returns 0 if A == B
- ;ld a, 0FFh ; A = FE now (-2). Set it to FF and return
- jmp __FREE_STR ;- jp __FREE_STR
- __STRGE: ; Compares a$ >= b$ (HL = ptr a$, DE = ptr b$). Returns FF (True) or 0 (False)
- lda z80_l ;- push hl
- pha
- lda z80_h
- pha
- lda z80_e ;- push de
- pha
- lda z80_d
- pha
- jsr __STRCMP ;- call __STRCMP
- pla ;- pop de
- sta z80_d
- pla
- sta z80_e
- pla ;- pop hl
- sta z80_h
- pla
- sta z80_l
- clc ;- inc a ; Returns 0 if A == -1 => a$ < b$
- adc #$01
- ;jr z, __FREE_STR
- ;ld a, 0FFh ; A = FE now (-2). Set it to FF and return
- __FREE_STR: ; This exit point will test A' for bits 0 and 1
- ; If bit 0 is 1 => Free memory from HL pointer
- ; If bit 1 is 1 => Free memory from DE pointer
- ; Finally recovers A, to return the result
- ;- PROC
- ;- LOCAL __FREE_STR2
- ;- LOCAL __FREE_END
- ldx z80_ap ;- ex af,af'
- sta z80_ap
- txa
- lda z80_a ;- bit 0,a
- bit 0
- jeq __FREE_STR2 ;- jr z, __FREE_STR2
- pha ;- push af
- php
- lda z80_e ;- push de
- pha
- lda z80_d
- pha
- jsr __MEM_FREE ;- call __MEM_FREE
- pla ;- pop de
- sta z80_d
- pla
- sta z80_e
- plp ;- pop af
- pha
- __FREE_STR2:
- lda z80_a ;- bit 1,a
- bit 1
- jeq __FREE_END ;- jr z, __FREE_END
- lda z80_e ;- ex de,hl
- ldx z80_l
- stx z80_e
- sta z80_l
- lda z80_d
- ldx z80_h
- stx z80_d
- sta z80_h
- jsr __MEM_FREE ;- call __MEM_FREE
- __FREE_END:
- ldx z80_ap ;- ex af,af'
- sta z80_ap
- txa
- rts ;- ret
- ;- ENDP
|