shell: add input routine
This commit is contained in:
parent
89e4edfa52
commit
358c551bcc
@ -1,5 +1,7 @@
|
||||
; classic RC2014 setup (8K ROM + 32K RAM) and a stock Serial I/O module
|
||||
|
||||
RAMEND .equ 0xa000
|
||||
; The RAM module is selected on A15, so it has the range 0x8000-0xffff
|
||||
RAMSTART .equ 0x8000
|
||||
RAMEND .equ 0xffff
|
||||
ACIA_CTL .equ 0x80 ; Control and status. RS off.
|
||||
ACIA_IO .equ 0x81 ; Transmit. RS on.
|
||||
|
@ -2,8 +2,9 @@
|
||||
;
|
||||
; Runs a shell over an asynchronous communication interface adapter (ACIA).
|
||||
|
||||
; *** STATUS ***
|
||||
; Incomplete. This just outputs the welcome prompt then halts
|
||||
; Incomplete. For now, this outputs a welcome prompt and then waits for input.
|
||||
; Whenever input is CR or LF, we echo back what we've received and empty the
|
||||
; input buffer. This also happen when the buffer is full.
|
||||
|
||||
#include "platform.inc"
|
||||
|
||||
@ -11,28 +12,50 @@
|
||||
CR .equ 0x0d
|
||||
LF .equ 0x0a
|
||||
|
||||
; size of the input buffer. If our input goes over this size, we echo
|
||||
; immediately.
|
||||
BUFSIZE .equ 0x20
|
||||
|
||||
; *** VARIABLES ***
|
||||
; Our input buffer starts there
|
||||
INPTBUF .equ RAMSTART
|
||||
|
||||
; index, in the buffer, where our next character will go. 0 when the buffer is
|
||||
; empty, BUFSIZE-1 when it's almost full.
|
||||
BUFIDX .equ INPTBUF+BUFSIZE
|
||||
|
||||
; *** CODE ***
|
||||
jr init
|
||||
|
||||
init:
|
||||
di ; no need for interrupts yet
|
||||
; disable interrupts we don't need them
|
||||
di
|
||||
|
||||
; setup stack
|
||||
ld hl, RAMEND
|
||||
ld sp, hl
|
||||
|
||||
; initialize variables
|
||||
xor a
|
||||
ld (BUFIDX), a ; starts at 0
|
||||
|
||||
; setup ACIA
|
||||
; CR7 (1) - Receive Interrupt enabled
|
||||
; CR7 (1) - Receive Interrupt disabled
|
||||
; CR6:5 (00) - RTS low, transmit interrupt disabled.
|
||||
; CR4:2 (101) - 8 bits + 1 stop bit
|
||||
; CR1:0 (10) - Counter divide: 64
|
||||
ld a, 0b10010110
|
||||
ld a, 0b00010110
|
||||
out (ACIA_CTL), a
|
||||
|
||||
; print prompt
|
||||
ld hl, d_welcome
|
||||
call printstr
|
||||
halt
|
||||
call printcrlf
|
||||
|
||||
mainloop:
|
||||
call readc
|
||||
call chkbuf
|
||||
jr mainloop
|
||||
|
||||
; spits character in A in port SER_OUT
|
||||
printc:
|
||||
@ -55,5 +78,84 @@ printstr:
|
||||
jr printstr
|
||||
; no ret because our only way out is ret z above
|
||||
|
||||
printcrlf:
|
||||
ld a, CR
|
||||
call printc
|
||||
ld a, LF
|
||||
call printc
|
||||
ret
|
||||
|
||||
; wait until a char is read in the ACIA and put it in the read buffer
|
||||
readc:
|
||||
; first thing first: is our input buffer full? If yes, we don't even
|
||||
; bother reading the ACIA. Something is wrong: we don't process data
|
||||
; fast enough.
|
||||
ld a, (BUFIDX)
|
||||
cp BUFSIZE
|
||||
ret z ; if BUFIDX == BUFSIZE, our buffer is full.
|
||||
|
||||
call getbufptr
|
||||
|
||||
; increase our buf ptr while we still have it in A
|
||||
inc a
|
||||
ld (BUFIDX), a
|
||||
|
||||
.loop:
|
||||
; Read our character from ACIA into our BUFIDX
|
||||
in a, (ACIA_CTL)
|
||||
bit 0, a ; is our ACIA rcv buffer full?
|
||||
jr z, .loop ; no? loop
|
||||
|
||||
in a, (ACIA_IO)
|
||||
ld (hl), a
|
||||
|
||||
ret
|
||||
|
||||
; check if the input buffer is full or ends in CR or LF. If it does, prints it
|
||||
; back and empty it.
|
||||
chkbuf:
|
||||
ld a, (BUFIDX)
|
||||
cp 0
|
||||
ret z ; BUFIDX is zero? nothing to check.
|
||||
|
||||
cp BUFSIZE
|
||||
jr z, .do ; if BUFIDX == BUFSIZE? do!
|
||||
|
||||
call getbufptr
|
||||
; our previous char is in BUFIDX - 1. Fetch this
|
||||
dec hl
|
||||
ld a, (hl) ; now, that's our char we have in A
|
||||
inc hl ; put HL back where it was
|
||||
|
||||
cp CR
|
||||
jr z, .do ; char is CR? do!
|
||||
cp LF
|
||||
jr z, .do ; char is LF? do!
|
||||
|
||||
; nothing matched? don't do anything
|
||||
ret
|
||||
|
||||
.do:
|
||||
; terminate our string with 0
|
||||
xor a
|
||||
ld (hl), a
|
||||
; reset buffer index
|
||||
ld (BUFIDX), a
|
||||
|
||||
; alright, let's go!
|
||||
ld hl, INPTBUF
|
||||
call printstr
|
||||
call printcrlf
|
||||
ret
|
||||
|
||||
; Set current buffer pointer in HL. The buffer pointer is where our *next* char
|
||||
; will be written.
|
||||
getbufptr:
|
||||
ld hl, INPTBUF
|
||||
xor b
|
||||
ld c, a
|
||||
add hl, bc ; hl now points to INPTBUF + BUFIDX
|
||||
ret
|
||||
|
||||
; *** DATA ***
|
||||
d_welcome: .byte "Welcome to Collapse OS", CR, LF, 0
|
||||
d_welcome: .byte "Welcome to Collapse OS", 0
|
||||
|
Loading…
Reference in New Issue
Block a user