mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-23 19:58:06 +11:00
shell: handle inputs with interrupts
This commit is contained in:
parent
358c551bcc
commit
ac22a206ae
@ -27,8 +27,10 @@ BUFIDX .equ INPTBUF+BUFSIZE
|
|||||||
; *** CODE ***
|
; *** CODE ***
|
||||||
jr init
|
jr init
|
||||||
|
|
||||||
|
.fill 0x38-$
|
||||||
|
jr handleInterrupt
|
||||||
|
|
||||||
init:
|
init:
|
||||||
; disable interrupts we don't need them
|
|
||||||
di
|
di
|
||||||
|
|
||||||
; setup stack
|
; setup stack
|
||||||
@ -39,12 +41,16 @@ init:
|
|||||||
xor a
|
xor a
|
||||||
ld (BUFIDX), a ; starts at 0
|
ld (BUFIDX), a ; starts at 0
|
||||||
|
|
||||||
|
; RC2014's serial I/O is based on interrupt mode 1. We'd prefer im 2,
|
||||||
|
; but for now, let's go with the simpler im 1.
|
||||||
|
im 1
|
||||||
|
|
||||||
; setup ACIA
|
; setup ACIA
|
||||||
; CR7 (1) - Receive Interrupt disabled
|
; CR7 (1) - Receive Interrupt enabled
|
||||||
; CR6:5 (00) - RTS low, transmit interrupt disabled.
|
; CR6:5 (00) - RTS low, transmit interrupt disabled.
|
||||||
; CR4:2 (101) - 8 bits + 1 stop bit
|
; CR4:2 (101) - 8 bits + 1 stop bit
|
||||||
; CR1:0 (10) - Counter divide: 64
|
; CR1:0 (10) - Counter divide: 64
|
||||||
ld a, 0b00010110
|
ld a, 0b10010110
|
||||||
out (ACIA_CTL), a
|
out (ACIA_CTL), a
|
||||||
|
|
||||||
; print prompt
|
; print prompt
|
||||||
@ -52,11 +58,42 @@ init:
|
|||||||
call printstr
|
call printstr
|
||||||
call printcrlf
|
call printcrlf
|
||||||
|
|
||||||
|
; alright, ready to receive
|
||||||
|
ei
|
||||||
|
|
||||||
mainloop:
|
mainloop:
|
||||||
call readc
|
|
||||||
call chkbuf
|
call chkbuf
|
||||||
jr mainloop
|
jr mainloop
|
||||||
|
|
||||||
|
; read char in the ACIA and put it in the read buffer
|
||||||
|
handleInterrupt:
|
||||||
|
push af
|
||||||
|
push hl
|
||||||
|
|
||||||
|
; Read our character from ACIA into our BUFIDX
|
||||||
|
in a, (ACIA_CTL)
|
||||||
|
bit 0, a ; is our ACIA rcv buffer full?
|
||||||
|
jr z, .end ; no? a interrupt was triggered for nothing.
|
||||||
|
|
||||||
|
call getbufptr ; HL set, A set
|
||||||
|
; is our input buffer full? If yes, we don't read anything. Something
|
||||||
|
; is wrong: we don't process data fast enough.
|
||||||
|
cp BUFSIZE
|
||||||
|
jr z, .end ; if BUFIDX == BUFSIZE, our buffer is full.
|
||||||
|
|
||||||
|
; increase our buf ptr while we still have it in A
|
||||||
|
inc a
|
||||||
|
ld (BUFIDX), a
|
||||||
|
|
||||||
|
in a, (ACIA_IO)
|
||||||
|
ld (hl), a
|
||||||
|
|
||||||
|
.end:
|
||||||
|
pop hl
|
||||||
|
pop af
|
||||||
|
ei
|
||||||
|
reti
|
||||||
|
|
||||||
; spits character in A in port SER_OUT
|
; spits character in A in port SER_OUT
|
||||||
printc:
|
printc:
|
||||||
push af
|
push af
|
||||||
@ -85,43 +122,17 @@ printcrlf:
|
|||||||
call printc
|
call printc
|
||||||
ret
|
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
|
; check if the input buffer is full or ends in CR or LF. If it does, prints it
|
||||||
; back and empty it.
|
; back and empty it.
|
||||||
chkbuf:
|
chkbuf:
|
||||||
ld a, (BUFIDX)
|
call getbufptr
|
||||||
cp 0
|
cp 0
|
||||||
ret z ; BUFIDX is zero? nothing to check.
|
ret z ; BUFIDX is zero? nothing to check.
|
||||||
|
|
||||||
cp BUFSIZE
|
cp BUFSIZE
|
||||||
jr z, .do ; if BUFIDX == BUFSIZE? do!
|
jr z, .do ; if BUFIDX == BUFSIZE? do!
|
||||||
|
|
||||||
call getbufptr
|
|
||||||
; our previous char is in BUFIDX - 1. Fetch this
|
; our previous char is in BUFIDX - 1. Fetch this
|
||||||
dec hl
|
dec hl
|
||||||
ld a, (hl) ; now, that's our char we have in A
|
ld a, (hl) ; now, that's our char we have in A
|
||||||
@ -149,12 +160,17 @@ chkbuf:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
; Set current buffer pointer in HL. The buffer pointer is where our *next* char
|
; Set current buffer pointer in HL. The buffer pointer is where our *next* char
|
||||||
; will be written.
|
; will be written. A is set to the value of (BUFIDX)
|
||||||
getbufptr:
|
getbufptr:
|
||||||
|
push bc
|
||||||
|
|
||||||
|
ld a, (BUFIDX)
|
||||||
ld hl, INPTBUF
|
ld hl, INPTBUF
|
||||||
xor b
|
xor b
|
||||||
ld c, a
|
ld c, a
|
||||||
add hl, bc ; hl now points to INPTBUF + BUFIDX
|
add hl, bc ; hl now points to INPTBUF + BUFIDX
|
||||||
|
|
||||||
|
pop bc
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; *** DATA ***
|
; *** DATA ***
|
||||||
|
Loading…
Reference in New Issue
Block a user