diff --git a/src/cpmio.asm b/src/cpmio.asm index fdef0be..0693b16 100644 --- a/src/cpmio.asm +++ b/src/cpmio.asm @@ -52,6 +52,7 @@ FCBRC .equ FCB+15 ; file's record count (0 to 128) FCBCR .equ FCB+32 ; current (next) record FCBLN .equ FCB+33 ; FCB length FTYPE .db "TBA" ; tasty basic file type +lastnum .dw 0 ; last line number the loader read haschar: push bc @@ -98,8 +99,6 @@ lo1: ld hl,(textunfilled) lo2: ld a,(de) ; get char from buffer - cp 1ah ; is it EOF? - jr z,lo3 ; yes, all done ld (hl),a ; copy char to text area inc hl ; and update pointers inc de @@ -107,7 +106,56 @@ lo2: dec b ; end of record? jr z,lo1 ; yes, so try next record jr lo2 ; no, copy next char +; The whole file is in memory now. Walk the lines to find where the program +; ends: only at a line's first byte can 1ah be the end of file marker, and +; even there it is only the marker when the two bytes do not read as a line +; number after the one before it. Line numbers ascend; what follows the +; marker does not. lo3: + ld de,(textunfilled) ; de -> past the last byte read + ld hl,0 + ld (lastnum),hl ; no line read yet + ld hl,textbegin +lo4: + push hl ; hl -> a line's first byte + or a + sbc hl,de + pop hl + jr nc,lo7 ; nothing left: no marker in the file + ld a,(hl) + cp EOF + jr nz,lo5 ; not the marker, so a line: read it + push hl ; the marker, where a line could begin: + ld a,(hl) ; does it read as the next number? + inc hl + ld h,(hl) + ld l,a + ld bc,(lastnum) + or a + sbc hl,bc + pop hl + jr z,lo7 ; not greater than the last: the end + jr c,lo7 +lo5: + ld a,(hl) ; this line's number is the one the + ld (lastnum),a ; next one has to beat + inc hl + ld a,(hl) + ld (lastnum+1),a + inc hl +lo6: + push hl + or a + sbc hl,de + pop hl + jr nc,lo7 ; ran off the end mid line + ld a,(hl) + inc hl + cp cr ; a line ends at its first cr + jr nz,lo6 + jr lo4 +lo7: + ld (textunfilled),hl jp rstart save: call fname ; ** save **