From 9d1003e7a250179d61eb87b72983f5cad6844dd9 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Tue, 19 Nov 2019 21:55:26 -0500 Subject: [PATCH] basic: keep line index ordered and line numbers unique --- apps/basic/buf.asm | 114 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 89 insertions(+), 25 deletions(-) diff --git a/apps/basic/buf.asm b/apps/basic/buf.asm index a44224a..010c2d2 100644 --- a/apps/basic/buf.asm +++ b/apps/basic/buf.asm @@ -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