diff --git a/compiler/res/prog8lib/diskio.p8 b/compiler/res/prog8lib/diskio.p8 index ed5ce686c..d243d508a 100644 --- a/compiler/res/prog8lib/diskio.p8 +++ b/compiler/res/prog8lib/diskio.p8 @@ -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 }} diff --git a/examples/cx16/assembler/assem.p8 b/examples/cx16/assembler/assem.p8 index 5085e1b3b..bf92bf01d 100644 --- a/examples/cx16/assembler/assem.p8 +++ b/examples/cx16/assembler/assem.p8 @@ -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) } } } diff --git a/examples/test.p8 b/examples/test.p8 index 6ec24835e..68c69e2f9 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -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() + } }