ZP is definitely your friend here. The 6502 is nearly crippled without it, unless you resort to self-modifying code. When I ported VTL-2 from the 6800 to the 6502 I observed that Frank always stored the mandatory space between the line number and the associated program text. My optimization was to store the line length in that spot so I could quickly find the next line without searching byte by byte for the end-of-line marker. I then slightly modified the LIST routine to print a space instead of the length byte. I don't know what your interpreter expects from FNDLIN, but I do my best to describe my entry and exit conditions in my code, which I've revised a couple of times in the last 11 years:
Code:
;-----------------------------------------------------;
; Find the first/next stored program line >= {#}
; entry: (cc): start search at program beginning
; (cs): start search at next line
; ({@} -> beginning of current line)
; used by: edit:, findln:
; uses: prgm, {@ # & (}
; exit: (cs): {@} = {&}, x:a and {(} invalid, y = 2
; (cc): {@} -> beginning of found line, y = 2,
; x:a = {(} = actual found line number
; 52 bytes
find:
lda #<prgm ;
ldx #>prgm ;
ldy #2 ;
bcc find1st ; (cc): search begins at first line
ldx at+1 ;
clc ;
findnxt:
lda at ; {@} -> next line (or {&} if
adc (at),y ; there is no next line ...)
bcc find5 ;
inx ;
find1st:
stx at+1 ;
find5:
sta at ;
cpx ampr+1 ; {@} >= {&} (end of program)?
bcc find6 ;
cmp ampr ;
bcs findrts ; yes: line not found (cs)
find6:
lda (at) ;
sta lparen ; {(} = current line number
cmp pound ;
dey ;
lda (at),y ;
iny ;
sta lparen+1 ;
sbc pound+1 ; if {(} < {#} then try the next
bcc findnxt ; program line
clc ; found line (cc)
lda lparen ;
ldx lparen+1 ;
findrts:
rts ;
at, pound, ampr and lparen are all 16-bit ZP variables. It is highly unlikely that this will transfer cleanly to your use case (I just noticed that lda (at) is a 'c02 instruction), but it might help nudge you in the right direction.
[Edit: I tracked down the older NMOS version of the same. It's not as tight:
Code:
;-----------------------------------------------------;
; Find the first/next stored program line >= {#}
; entry: (cc): start search at program beginning
; (cs): start search at next line
; ({@} -> beginning of current line)
; used by: skp2:, findln:
; uses: prgm, {@ # & (}
; exit: (cs): {@}, x:a and {(} undefined, y = 2
; (cc): {@} -> beginning of found line, y = 2,
; x:a = {(} = actual found line number
; 62 bytes
find:
ldx /prgm
lda #prgm
bcc find1st ; cc: search begins at first line
ldx at+1
ldy #2
findnxt:
lda at
cmp ampr
lda at+1
sbc ampr+1 ; {@} >= {&} (end of program)?
bcs findrts ; yes: search failed (cs)
find3:
lda at
adc (at),y ; no: {@} -> next line
bcc find5
inx
find1st:
stx at+1
find5:
sta at
ldy #0
lda (at),y
sta lparen ; {(} = current line number
cmp pound ; (invalid if {@} >= {&}, but
iny ; we'll catch that later...)
lda (at),y
sta lparen+1
sbc pound+1 ; if {(} < {#} then try the next
iny ; program line
bcc findnxt
lda at ; {@} >= {&} (end of program)?
cmp ampr ; yes: search failed (cs)
lda at+1 ; no: search succeeded (cc)
sbc ampr+1
lda lparen
ldx lparen+1
findrts:
rts
]
_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some
VTL02C on it and see how it grows on you!
Mike B.
(about me) (learning how to github)