Mercurial > hg > index.cgi
changeset 18:6a046bd8107f
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.
author | William Astle <lost@l-w.ca> |
---|---|
date | Tue, 08 Nov 2022 21:24:55 -0700 |
parents | f86967c0bc73 |
children | 20fa3242c6a5 |
files | src/lwbasic.s |
diffstat | 1 files changed, 69 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- 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