# HG changeset patch # User William Astle # Date 1667967895 25200 # Node ID 6a046bd8107f3c8408b1964e2227e14d3da9fd1a # Parent f86967c0bc7396cf3175842a2da204d648210231 Add line input routine It seems useful to be able to accept lines from the user. So implement a read line routine that also handles echoing properly. None of this blindly writing the input back out to whatever device it came in on. This is not useful behaviour for read/write files. diff -r f86967c0bc73 -r 6a046bd8107f src/lwbasic.s --- a/src/lwbasic.s Sun Nov 06 22:09:33 2022 -0700 +++ b/src/lwbasic.s Tue Nov 08 21:24:55 2022 -0700 @@ -39,6 +39,7 @@ keyb_alt equ 0x04 ; alt pressed keyb_ctrl equ 0x02 ; ctrl pressed keyb_shift equ 0x01 ; shift pressed +linebuffsize equ 0x100 ; the line input buffer (256 bytes) ifdef COCO3 ; GIME INIT0 GIME_COCO equ 0x80 ; Set for coco2 compatible mode (video display) @@ -193,6 +194,7 @@ ; Start of memory which has the direct page and other data. org 0 dpstart equ * ; start of direct page +readlinenoecho rmb 1 ; if nonzero, the readline routine won't echo its input rmb 0x71-* ; align RSTFLG/RSTVEC for stock ROM compatibility RSTFLG rmb 1 ; 0x55 if RSTVEC is valid RSTVEC rmb 2 ; points to warm start routine (must start with NOP) @@ -217,6 +219,7 @@ keyb_buff rmb keyb_bufflen ; the keyboard ring buffer rmb 0x200-* ; unused textscreen rmb 0x200 ; the actual text screen (must be on 512 byte alignment) +linebuff rmb linebuffsize ; the line input buffer org 0x8000 ; the hardware puts the ROMs here; it's not negotiable START orcc #0x50 ; make sure interrupts are disabled if we come here in an unusual way ifdef COCO3 @@ -795,6 +798,70 @@ ; ; 0: keyboard/screen console ; +; Read a line from the active file into linebuff. The resulting line will be NUL terminated leading to at most +; linbuffsize-1 character input. The trailing CR/LF will not be included. The input will be echoed if linebuffecho is +; enabled. Exit with the length of the input line in B. +readline ldx #linebuff ; point to line input buffer + clr ,x ; make sure buffer is NUL terminated +readline0 bsr readchr ; read an input character + bcs readline1 ; brif not EOF + cmpa #0x0d ; CR (carriage return) + beq readline1 ; brif so - return + cmpa #0x03 ; BREAK? + bne readline3 ; brif not + coma ; set carry for irregular exit + skip1 +readline1 clra ; clear carry for regular exit + pshs cc ; save carry state + lda readlinenoecho ; are we echoing? + bne readline2 ; brif not + lda #0x0d ; echo carriage return + line feed + bsr writechr +readline2 tfr x,d ; get end address after input + subd #linebuff ; subtract start of buffer; D is now length and C is clear + clr ,x ; make sure line is NUL terminated + puls cc,pc ; restore BREAK flag (C) and return +readline3 cmpa #0x08 ; backspace? + bne readline4 ; brif not + cmpx #linebuff ; at start of buffer? + beq readline0 ; brif so - do nothing + leax -1,x ; move back buffer pointer + bsr readlinee ; write a BS + lda #0x20 ; write a space + bsr readlinee + lda #0x08 ; and finally a BS + bsr readlinee + bra readline0 ; go process more characters +readline4 cmpa #0x0c ; form feed? + bne readline5 ; brif not + bsr readlinee ; go echo character if needed + bra readline ; go restart line entry +readline5 cmpa #0x20 ; is it non-printing? + blo readline0 ; brif so - don't store it and continue + bsr readlines ; stash character in buffer and echo if necessary + bra readline0 ; go get another character +readlines cmpx #linebuff+linebuffsize-1 ; is the line buffer full? + bhi readlinee0 ; brif so - don't store character OR echo it + sta ,x+ ; stash character +readlinee ldb readlinenoecho ; are we echoing? + bne readlinee0 ; brif not + bsr writechr ; echo the character +readlinee0 rts +; Write a character to the active file; all registers preserved but C will be set if the output file cannot handle +; an output character (doesn't exist, etc.) +writechr tst filenum ; is it screen? + beq writechr_scr ; brif writing to screen + orcc #1 ; unknown device flag + rts +; Handle output to the screen. This is where we convert CR to CRLF +writechr_scr jsr console_outchr ; output the character + cmpa #0x0d ; was it CR? + bne writechr_scr0 ; brif not + lda #0x0a ; ouptut an LF + jsr console_outchr + lda #0x0d ; restore original value +writechr_scr0 andcc #0xfe ; clear error flag + rts ; Read a character from the active file and return it in A; in the event that EOF is detected, readeof will be nonzero ; and the call will return with carry set. readchr clr fileeof ; flag not end of file (and clear carry) @@ -819,9 +886,8 @@ prompt fcn 'OK' immediate ldx #prompt ; point to prompt string jsr console_outstrn - jsr readchr - bra * -immediate0 +immediate0 jsr readline ; read input line + bcs immediate0 ; brif ended with BREAK ; handle line bra immediate ifndef COCO3