basic: keep line index ordered and line numbers unique

This commit is contained in:
Virgil Dupras 2019-11-19 21:55:26 -05:00
parent 62138b12cf
commit 9d1003e7a2

View File

@ -33,16 +33,7 @@ bufInit:
; * not enough space in the pool ; * not enough space in the pool
; * not enough space in the line index ; * not enough space in the line index
bufAdd: bufAdd:
exx ; preserve HL and DE ; Check whether we have enough pool space. This is done in all cases.
; First step: do we have index space?
ld hl, (BUF_LFREE)
ld de, BUF_POOL
or a ; reset carry
sbc hl, de
exx ; restore
; no carry? HL >= BUF_POOL, error. Z already unset
ret nc
; Second step: see if we're within the pool's bounds
call strlen call strlen
inc a ; strlen doesn't include line termination inc a ; strlen doesn't include line termination
exx ; preserve HL and DE exx ; preserve HL and DE
@ -53,31 +44,81 @@ bufAdd:
exx ; restore exx ; restore
; no carry? HL >= BUF_RAMEND, error. Z already unset ; no carry? HL >= BUF_RAMEND, error. Z already unset
ret nc ret nc
; We have enough space.
; Third step: set line index data ; Check the kind of operation we make: add, insert or replace?
push de ; --> lvl 1 call bufFind
push hl ; --> lvl 2 jr z, .replace ; exact match, replace
call c, .insert ; near match, insert
; do we have enough index space?
exx ; preserve HL and DE
ld hl, (BUF_LFREE) ld hl, (BUF_LFREE)
ld (hl), e ld de, BUF_POOL-4
inc hl or a ; reset carry
ld (hl), d sbc hl, de
inc hl exx ; restore
; no carry? HL >= BUF_POOL, error. Z already unset
ret nc
; We have enough space.
; set line index data
push de ; --> lvl 1
ld (ix), e
ld (ix+1), d
ld de, (BUF_PFREE) ld de, (BUF_PFREE)
ld (hl), e ld (ix+2), e
inc hl ld (ix+3), d
ld (hl), d
inc hl ; Increase line index size
ld (BUF_LFREE), hl ld de, (BUF_LFREE)
pop hl \ push hl ; <-- lvl 2, restore and preserve inc de \ inc de \ inc de \ inc de
ld (BUF_LFREE), de
; Fourth step: copy string to pool ; Fourth step: copy string to pool
ld de, (BUF_PFREE) ld de, (BUF_PFREE)
call strcpyM call strcpyM
ld (BUF_PFREE), de ld (BUF_PFREE), de
pop hl ; <-- lvl 2
pop de ; <-- lvl 1 pop de ; <-- lvl 1
ret ret
; No need to add a new line, just replace the current one.
.replace:
ld (ix), e
ld (ix+1), d
push de
ld de, (BUF_PFREE)
ld (ix+2), e
ld (ix+3), d
call strcpyM
ld (BUF_PFREE), de
pop de
ret
; An insert is exactly like an add, except that lines following insertion point
; first.
.insert:
push hl
push de
push bc
; We want a LDDR that moves from (BUF_LFREE)-1 to (BUF_LFREE)+3
; for a count of (BUF_LFREE)-BUF_LINES
ld hl, (BUF_LFREE)
ld de, BUF_LINES
or a ; clear carry
sbc hl, de
ld b, h
ld c, l
ld hl, (BUF_LFREE)
ld d, h
ld e, l
dec hl
inc de \ inc de \ inc de
lddr
pop bc
pop de
pop hl
ret
; Set IX to point to the beginning of the pool. ; Set IX to point to the beginning of the pool.
; Z set if (IX) is a valid line, unset if the pool is empty. ; Z set if (IX) is a valid line, unset if the pool is empty.
bufFirst: bufFirst:
@ -98,6 +139,7 @@ bufEOF:
push hl push hl
push de push de
push ix \ pop hl push ix \ pop hl
or a ; clear carry
ld de, (BUF_LFREE) ld de, (BUF_LFREE)
sbc hl, de sbc hl, de
jr z, .empty jr z, .empty
@ -115,3 +157,25 @@ bufStr:
ld l, (ix+2) ld l, (ix+2)
ld h, (ix+3) ld h, (ix+3)
ret ret
; Browse lines looking for number DE. Set IX to point to one of these :
; 1 - an exact match
; 2 - the first found line to have a higher line number
; 3 - EOF
; Set Z on an exact match, C on a near match, NZ and NC on EOF.
bufFind:
call bufFirst
ret nz
.loop:
ld a, d
cp (ix+1)
ret c ; D < (IX+1), situation 2
jr nz, .next
ld a, e
cp (ix)
ret c ; E < (IX), situation 2
ret z ; exact match!
.next:
call bufNext
ret nz
jr .loop