From ac22a206ae5bc349c26051ec4bf742e514a1afc9 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Sat, 13 Apr 2019 15:02:29 -0400 Subject: [PATCH] shell: handle inputs with interrupts --- parts/shell/shell.asm | 80 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 32 deletions(-) diff --git a/parts/shell/shell.asm b/parts/shell/shell.asm index a44939b..27b0882 100644 --- a/parts/shell/shell.asm +++ b/parts/shell/shell.asm @@ -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 ***