|
|
@@ -27,8 +27,10 @@ BUFIDX .equ INPTBUF+BUFSIZE |
|
|
|
; *** CODE *** |
|
|
|
jr init |
|
|
|
|
|
|
|
.fill 0x38-$ |
|
|
|
jr handleInterrupt |
|
|
|
|
|
|
|
init: |
|
|
|
; disable interrupts we don't need them |
|
|
|
di |
|
|
|
|
|
|
|
; setup stack |
|
|
@@ -39,12 +41,16 @@ init: |
|
|
|
xor a |
|
|
|
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 |
|
|
|
; CR7 (1) - Receive Interrupt disabled |
|
|
|
; CR7 (1) - Receive Interrupt enabled |
|
|
|
; CR6:5 (00) - RTS low, transmit interrupt disabled. |
|
|
|
; CR4:2 (101) - 8 bits + 1 stop bit |
|
|
|
; CR1:0 (10) - Counter divide: 64 |
|
|
|
ld a, 0b00010110 |
|
|
|
ld a, 0b10010110 |
|
|
|
out (ACIA_CTL), a |
|
|
|
|
|
|
|
; print prompt |
|
|
@@ -52,11 +58,42 @@ init: |
|
|
|
call printstr |
|
|
|
call printcrlf |
|
|
|
|
|
|
|
; alright, ready to receive |
|
|
|
ei |
|
|
|
|
|
|
|
mainloop: |
|
|
|
call readc |
|
|
|
call chkbuf |
|
|
|
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 |
|
|
|
printc: |
|
|
|
push af |
|
|
@@ -85,43 +122,17 @@ printcrlf: |
|
|
|
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) |
|
|
|
call getbufptr |
|
|
|
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 |
|
|
@@ -149,12 +160,17 @@ chkbuf: |
|
|
|
ret |
|
|
|
|
|
|
|
; 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: |
|
|
|
push bc |
|
|
|
|
|
|
|
ld a, (BUFIDX) |
|
|
|
ld hl, INPTBUF |
|
|
|
xor b |
|
|
|
ld c, a |
|
|
|
add hl, bc ; hl now points to INPTBUF + BUFIDX |
|
|
|
|
|
|
|
pop bc |
|
|
|
ret |
|
|
|
|
|
|
|
; *** DATA *** |
|
|
|