basic: keep line index ordered and line numbers unique
This commit is contained in:
parent
62138b12cf
commit
9d1003e7a2
@ -33,16 +33,7 @@ bufInit:
|
||||
; * not enough space in the pool
|
||||
; * not enough space in the line index
|
||||
bufAdd:
|
||||
exx ; preserve HL and DE
|
||||
; 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
|
||||
; Check whether we have enough pool space. This is done in all cases.
|
||||
call strlen
|
||||
inc a ; strlen doesn't include line termination
|
||||
exx ; preserve HL and DE
|
||||
@ -53,31 +44,81 @@ bufAdd:
|
||||
exx ; restore
|
||||
; no carry? HL >= BUF_RAMEND, error. Z already unset
|
||||
ret nc
|
||||
; We have enough space.
|
||||
; Third step: set line index data
|
||||
push de ; --> lvl 1
|
||||
push hl ; --> lvl 2
|
||||
|
||||
; Check the kind of operation we make: add, insert or replace?
|
||||
call bufFind
|
||||
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), e
|
||||
inc hl
|
||||
ld (hl), d
|
||||
inc hl
|
||||
ld de, BUF_POOL-4
|
||||
or a ; reset carry
|
||||
sbc hl, de
|
||||
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 (hl), e
|
||||
inc hl
|
||||
ld (hl), d
|
||||
inc hl
|
||||
ld (BUF_LFREE), hl
|
||||
pop hl \ push hl ; <-- lvl 2, restore and preserve
|
||||
ld (ix+2), e
|
||||
ld (ix+3), d
|
||||
|
||||
; Increase line index size
|
||||
ld de, (BUF_LFREE)
|
||||
inc de \ inc de \ inc de \ inc de
|
||||
ld (BUF_LFREE), de
|
||||
|
||||
; Fourth step: copy string to pool
|
||||
ld de, (BUF_PFREE)
|
||||
call strcpyM
|
||||
ld (BUF_PFREE), de
|
||||
pop hl ; <-- lvl 2
|
||||
pop de ; <-- lvl 1
|
||||
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.
|
||||
; Z set if (IX) is a valid line, unset if the pool is empty.
|
||||
bufFirst:
|
||||
@ -98,6 +139,7 @@ bufEOF:
|
||||
push hl
|
||||
push de
|
||||
push ix \ pop hl
|
||||
or a ; clear carry
|
||||
ld de, (BUF_LFREE)
|
||||
sbc hl, de
|
||||
jr z, .empty
|
||||
@ -115,3 +157,25 @@ bufStr:
|
||||
ld l, (ix+2)
|
||||
ld h, (ix+3)
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user