fix diskio.f_readline() that skipped first char. It also doesn't leave the end of line char in the string now.

This commit is contained in:
Irmen de Jong 2021-01-10 16:00:22 +01:00
parent 72b4198301
commit 506ac8014c
3 changed files with 92 additions and 68 deletions

View File

@ -293,23 +293,32 @@ _in_buffer sta $ffff
asmsub f_readline(uword bufptr @AY) clobbers(X) -> ubyte @Y {
; Routine to read text lines from a text file. Lines must be less than 255 characters.
; Reads characters from the input file until (and including) a newline or return character (or EOF).
; The line read will be 0-terminated in the buffer. The length of the line is returned in Y.
; Reads characters from the input file UNTIL a newline or return character (or EOF).
; The line read will be 0-terminated in the buffer (and not contain the end of line character).
; The length of the line is returned in Y.
%asm {{
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
ldx #11
jsr c64.CHKIN ; use channel 11 again for input
ldy #0
lda have_first_byte
beq _loop
lda #0
sta have_first_byte
lda first_byte
sta (P8ZP_SCRATCH_W1),y
iny
_loop jsr c64.CHRIN
sta (P8ZP_SCRATCH_W1),y
beq _end
iny
cmp #$0a
beq _zero_end
beq _line_end
cmp #$0d
bne _loop
_zero_end lda #0
_line_end dey ; get rid of the trailing end-of-line char
lda #0
sta (P8ZP_SCRATCH_W1),y
_end rts
}}

View File

@ -1,23 +1,62 @@
%target cx16
%import test_stack
%import textio
%import diskio
%import string
%zeropage basicsafe
%option no_sysinit
; TODO : NOTE: treat $0a (10 - line feed) and $0c (13 - normal petscii Return) both as line separators
main {
sub start() {
txt.lowercase()
txt.print("\nAssembler.\nEmpty line to stop.\n")
textparse.user_input()
; user_input()
file_input()
; test_stack.test()
}
sub user_input() {
repeat {
ubyte input_length = 0
txt.chrout('A')
txt.print_uwhex(textparse.program_counter, 1)
txt.print(": ")
; simulate user always having at least one space at the start
textparse.input_line[0] = ' '
input_length = txt.input_chars(&textparse.input_line+1)
txt.nl()
if not input_length {
txt.print("exit\n")
return
}
textparse.process_line()
}
}
sub file_input() {
if diskio.f_open(8, "romdis.asm") {
uword line=0
repeat 5 {
if diskio.f_readline(textparse.input_line) {
line++
txt.print_uw(line)
txt.chrout(':')
txt.print(textparse.input_line)
txt.nl()
textparse.process_line()
if c64.READST() ; TODO also check STOP key
break
} else
break
}
diskio.f_close()
}
}
}
textparse {
@ -28,31 +67,16 @@ textparse {
uword[3] word_addrs
uword program_counter = $4000
sub user_input() {
repeat {
ubyte input_length = 0
txt.chrout('A')
txt.print_uwhex(program_counter, 1)
txt.print(": ")
; simulate user always having at least one space at the start
input_line[0] = ' '
input_length = txt.input_chars(&input_line+1)
txt.nl()
if not input_length {
txt.print("exit\n")
return
}
sub process_line() {
string.lower(input_line)
preprocess_assignment_spacing()
split_input()
; debug_print_words()
debug_print_words()
if word_addrs[1] and @(word_addrs[1])=='='
do_assign()
else
do_label_or_instr()
}
}
sub do_assign() {
@ -71,7 +95,12 @@ textparse {
}
return
}
txt.print("?invalid operand\n")
txt.print("?invalid operand (assign)\n")
txt.print(" nlen=")
txt.print_ub(nlen)
txt.print(" word=")
txt.print(word_addrs[2])
txt.nl()
}
sub do_label_or_instr() {
@ -84,12 +113,10 @@ textparse {
label_ptr = word_addrs[0]
instr_ptr = word_addrs[1]
operand_ptr = word_addrs[2]
lowercase(operand_ptr)
} else if word_addrs[1] {
if starts_with_whitespace {
instr_ptr = word_addrs[0]
operand_ptr = word_addrs[1]
lowercase(operand_ptr)
} else {
label_ptr = word_addrs[0]
instr_ptr = word_addrs[1]
@ -154,7 +181,7 @@ textparse {
}
return
}
txt.print("?invalid operand\n")
txt.print("?invalid operand (instr)\n")
return
}
txt.print("?invalid instruction\n")
@ -216,9 +243,6 @@ textparse {
parsed_len = conv.any2uword(operand_ptr)
if parsed_len {
operand_ptr += parsed_len
txt.print("abs-restoperand=")
txt.print(operand_ptr)
txt.nl()
if msb(cx16.r15) {
; absolute or abs indirects
if @(operand_ptr)==0
@ -307,16 +331,6 @@ _is_2_entry
txt.nl()
}
sub lowercase(uword st) {
; TODO optimize in asm
ubyte char = @(st)
while char {
@(st) = char & 127
st++
char = @(st)
}
}
sub dummy(uword operand_ptr) -> uword {
uword a1=rndw()
uword a6=a1+operand_ptr
@ -396,7 +410,7 @@ _is_2_entry
}
if changed {
@(dest)=0
string.copy(input_line2, src)
void string.copy(input_line2, src)
}
}
}

View File

@ -8,32 +8,33 @@
main {
sub start() {
str s1 = "12345 abcdef..uvwxyz ()!@#$%;:&*()-=[]<>\xff\xfa\xeb\xc0\n"
str s2 = "12345 ABCDEF..UVWXYZ ()!@#$%;:&*()-=[]<>\xff\xfa\xeb\xc0\n"
str s3 = "12345 \x61\x62\x63\x64\x65\x66..\x75\x76\x77\x78\x79\x7a ()!@#$%;:&*()-=[]<>\xff\xfa\xeb\xc0\n"
ubyte[40] input_line
txt.lowercase()
txt.print(s1)
txt.print(s2)
txt.print(s3)
string.lower(s1)
string.lower(s2)
string.lower(s3)
txt.print(s1)
txt.print(s2)
txt.print(s3)
string.upper(s1)
string.upper(s2)
string.upper(s3)
txt.print(s1)
txt.print(s2)
txt.print(s3)
txt.nl()
if diskio.f_open(8, "romdis.asm") {
uword line=0
repeat 5 {
ubyte length = diskio.f_readline(input_line)
if length {
line++
txt.print_uw(line)
txt.chrout(':')
txt.print_ub(length)
txt.print(":[")
ubyte xx
for xx in 0 to length-1 {
txt.print_ubhex(input_line[xx], 1)
txt.chrout(' ')
}
; txt.print(&input_line)
txt.print("]\n")
; textparse.process_line()
if c64.READST() ; TODO also check STOP key
break
} else
break
}
diskio.f_close()
}
}