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