Sfoglia il codice sorgente

shell: add input routine

pull/10/head
Virgil Dupras 5 anni fa
parent
commit
358c551bcc
2 ha cambiato i file con 112 aggiunte e 8 eliminazioni
  1. +3
    -1
      parts/platforms/rc2014.inc
  2. +109
    -7
      parts/shell/shell.asm

+ 3
- 1
parts/platforms/rc2014.inc Vedi File

@@ -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.

+ 109
- 7
parts/shell/shell.asm Vedi File

@@ -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…
Annulla
Salva