From: Alan Cox Date: Wed, 16 Jan 2019 14:54:34 +0000 (+0000) Subject: linc80: switch to the new SIO macros and buffering X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=f1c8cff5d5647579725618b8fae74edf7a8857d4;p=FUZIX.git linc80: switch to the new SIO macros and buffering --- diff --git a/Kernel/platform-linc80/crt0.s b/Kernel/platform-linc80/crt0.s index d8883c49..ba2ebf87 100644 --- a/Kernel/platform-linc80/crt0.s +++ b/Kernel/platform-linc80/crt0.s @@ -21,7 +21,8 @@ .area _GSFINAL ; unused .area _DISCARD .area _COMMONMEM - .area _CONSOLE + .area _SERIAL + .area _BOOT ; patch the jp init over it .area _PAGE0 ; unused but stops binman changing us ; exported symbols diff --git a/Kernel/platform-linc80/devtty.c b/Kernel/platform-linc80/devtty.c index f3b745c2..21b57348 100644 --- a/Kernel/platform-linc80/devtty.c +++ b/Kernel/platform-linc80/devtty.c @@ -95,7 +95,7 @@ void tty_drain_sio(void) if (((old_ca[1] ^ sio_state[1]) & sio_state[1]) & 8) tty_carrier_raise(1); old_ca[1] = sio_state[1]; - if (sio_txl[1] < 128 && (sleeping & 2)) { + if (sio_txl[1] < 64 && (sleeping & 2)) { sleeping &= ~2; tty_outproc(1); } @@ -111,7 +111,7 @@ void tty_drain_sio(void) if (((old_ca[0] ^ sio_state[0]) & sio_state[0]) & 8) tty_carrier_raise(2); old_ca[0] = sio_state[0]; - if (sio_txl[0] < 128 && (sleeping & 4)) { + if (sio_txl[0] < 64 && (sleeping & 4)) { sleeping &= ~4; tty_outproc(2); } diff --git a/Kernel/platform-linc80/fuzix.lnk b/Kernel/platform-linc80/fuzix.lnk index 4d0056fc..10a84328 100644 --- a/Kernel/platform-linc80/fuzix.lnk +++ b/Kernel/platform-linc80/fuzix.lnk @@ -1,8 +1,9 @@ -mwxuy -i fuzix.ihx --b _CONSOLE=0x0100 +-b _SERIAL=0x0100 -b _COMMONMEM=0x0300 --b _CODE=0x0E00 +-b _CODE=0x0F00 +-b _BOOT=0x0100 -l z80 platform-linc80/crt0.rel platform-linc80/commonmem.rel diff --git a/Kernel/platform-linc80/linc80.s b/Kernel/platform-linc80/linc80.s index ae72a4f3..c75b60b1 100644 --- a/Kernel/platform-linc80/linc80.s +++ b/Kernel/platform-linc80/linc80.s @@ -258,6 +258,10 @@ _sio2_otir: ld hl,#_sio_r otir ret + + + .area _COMMONMEM + ; ; outchar: Wait for UART TX idle, then print the char in A ; destroys: AF @@ -278,308 +282,6 @@ ocloop_sio: out (SIOA_D),a ret -; -; SIO2 IM2 console driver -; -; The buffers are 256 bytes per channel and page aligned. The lower -; half is used for receive the upper for transmit. Both are rings. - -; -; Transmit data from the queue. We need a stop system for this but -; actually the logical one might be to just turn that IRQ off, so long -; as we remember to kickstart it again properly. Check if it's enough -; to just unmask the IRQ bit ? -; -; All of this lives in common space so we don't bank switch so much. - - .area _CONSOLE - -sioa_rx: - jp init ; for boot only - .ds 128-3 ; we wrote a JP init in the first 3 -sioa_tx: ; that will be recycled - .ds 128 -siob_rx: - .ds 128 -siob_tx: - .ds 128 - - .area _COMMONMEM -sioa_error: - .db 0 -sioa_rxover: - .db 0 -sioa_stat: - .db 0 -sioa_txp: - .dw sioa_tx -sioa_txe: - .dw sioa_tx -sioa_rxp: - .dw sioa_rx -sioa_rxe: - .dw sioa_rx - -siob_error: - .db 0 -siob_rxover: - .db 0 -siob_stat: - .db 0 -siob_txp: - .dw sioa_tx -siob_txe: - .dw sioa_tx -siob_rxp: - .dw sioa_rx -siob_rxe: - .dw sioa_rx - -; -; Interrupt vector handler for port A transmit empty -; -sioa_txd: - push af - ld a,(_sioa_txl) - or a - jr z, tx_a_none - push hl - dec a - ld (_sioa_txl),a - ld hl,(sioa_txp) - ld a,(hl) - out (SIOA_D),a - inc hl - set 7,l - ld (sioa_txp),hl - pop hl -tx_a_none: - ld a,#0x28 - out (SIOA_C),a ; silence tx interrupt - pop af - ei - reti -; -; Interrupt vector handler for port A receive ready -; -sioa_rx_ring: - push af - push hl -sioa_rx_next: - in a,(SIOA_D) ; read ASAP - ld l,a - ld a,(_sioa_rxl) - inc a - jp m, a_rx_over - ld (_sioa_rxl),a - ; should we check bit 5/6 and if appropriate flow control on bit 5/6 - ; high ? - cp #0x60 ; flow control threshold - call z, _sioa_flow_control_on - ld a,l - ld hl,(sioa_rxp) - ld (hl),a - inc l - res 7,l - ld (sioa_rxp),hl - ; - ; The chip has a small FIFO and bytes can also arrive as we - ; read. To maximise performance try and empty it each time. - ; - ; This is bounded as worst case at high data rate and low - ; CPU speed we will overrun and bail out. - ; - in a,(SIOA_C) ; RR 0 - rra - jr c, sioa_rx_next - pop hl - pop af - ei - reti -a_rx_over: - ld a,(sioa_error) - or #0x20 ; Fake an RX overflow bit - ld (sioa_rxover),a - pop af - ei - reti -; -; Interrupt vector for a port A status change -; -; FIXME: -; log the or of changes seem (dcd down, up) and last state -; of both CTS and DCD. The CTS last state is sufficient for flow -; and we can use thw two edges of DCD to work out if we had a hangup -; and if we are now open. -; -sioa_status: - ; CTS or DCD change - push af - push hl - ; RR0 - in a,(SIOA_C) - ld (_sioa_state),a - and #8 - jr z, no_dcd_drop_a - ; \DCD went high - ld (_sioa_dropdcd),a ; Set the dcdflag -no_dcd_drop_a: - ; Clear the latched values - ld a,#0x10 - out (SIOA_C),a - pop hl - pop af - ei - reti - -; -; Interrupt vector for a port A error -; -sioa_special: - ; Parity, RX Overrun, Framing - ; Probably want to record them, but we at least must clean up - push af - ld a,#1 - out (SIOA_C),a ; RR1 please - in a,(SIOA_C) ; clear events - ld (sioa_error),a ; Save error bits - ; Clear the latched values - ld a,#0x30 - out (SIOA_C),a - pop af - ei - reti - -; -; Interrupt vector handler for port B transmit empty -; -siob_txd: - push af - ld a,(_siob_txl) - or a - jr z, tx_b_none - push hl - dec a - ld (_siob_txl),a - ld hl,(siob_txp) - ld a,(hl) - out (SIOB_D),a - inc hl - set 7,l - ld (siob_txp),hl - pop hl -tx_b_none: - ld a,#0x28 - out (SIOB_C),a ; silence tx interrupt - pop af - ei - reti -; -; Interrupt vector handler for port B receive ready -; -siob_rx_ring: - push af - push hl -siob_rx_next: - in a,(SIOB_D) ; read ASAP - ld l,a - ld a,(_siob_rxl) - inc a - jp m, b_rx_over - ld (_siob_rxl),a - ; should we check bit 5/6 and if appropriate flow control on bit 5/6 - ; high ? - cp #0x60 ; flow control threshold - call z, _siob_flow_control_on - ld a,l - ld hl,(siob_rxp) - ld (hl),a - inc l - res 7,l - ld (siob_rxp),hl - ; - ; The chip has a small FIFO and bytes can also arrive as we - ; read. To maximise performance try and empty it each time. - ; - ; This is bounded as worst case at high data rate and low - ; CPU speed we will overrun and bail out. - ; - in a,(SIOB_C) ; RR 0 - rra - jr c, siob_rx_next - pop hl - pop af - ei - reti -b_rx_over: - ld a,(siob_error) - or #0x20 ; Fake an RX overflow bit - ld (siob_rxover),a - pop af - ei - reti -; -; Interrupt vector for a port B status change -; -; FIXME: -; log the or of changes seem (dcd down, up) and last state -; of both CTS and DCD. The CTS last state is sufficient for flow -; and we can use thw two edges of DCD to work out if we had a hangup -; and if we are now open. -; -siob_status: - ; CTS or DCD change - push af - push hl - ; RR0 - in a,(SIOB_C) - ld (_siob_state),a - and #8 - jr z, no_dcd_drop_b - ; \DCD went high - ld (_siob_dropdcd),a ; Set the dcdflag -no_dcd_drop_b: - ; Clear the latched values - ld a,#0x10 - out (SIOB_C),a - pop hl - pop af - ei - reti - -; -; Interrupt vector for a port B error -; -siob_special: - ; Parity, RX Overrun, Framing - ; Probably want to record them, but we at least must clean up - push af - ld a,#1 - out (SIOB_C),a ; RR1 please - in a,(SIOB_C) ; clear events - ld (siob_error),a ; Save error bits - ; Clear the latched values - ld a,#0x30 - out (SIOB_C),a - pop af - ei - reti - -; -; C interface methods -; - .globl _sioa_txqueue - .globl _sioa_flow_control_off - .globl _sioa_flow_control_on - .globl _sioa_rx_get - .globl _sioa_error_get - - .globl _siob_txqueue - .globl _siob_flow_control_off - .globl _siob_flow_control_on - .globl _siob_rx_get - .globl _siob_error_get - .globl _sio_dropdcd .globl _sio_flow .globl _sio_rxl @@ -587,7 +289,7 @@ siob_special: .globl _sio_txl .globl _sio_wr5 -; These are paid and exposed as arrays to C +; These are laid out and exposed as arrays to C _sio_wr5: _sioa_wr5: .db 0xEA ; DTR, 8bit, tx enabled @@ -619,178 +321,12 @@ _sioa_txl: _siob_txl: .db 0 -; -; Queue a byte to be sent (DI required) -; -; l = byte -; -; Need a way to halt processing somewhere here or a_tx ? -; (or can we use hardware ?) -; 128 byte ring buffer aligned to upper half (rx is in lower) -; -_sioa_txqueue: - ld a,(_sioa_txl) - or a - jr z, sioa_direct_maybe ; if can tx now then do - inc a - jp m, txa_overflow -sioa_queue: - ld (_sioa_txl),a - ld a,l - ld hl,(sioa_txe) - ld (hl),a - inc l - set 7,l - ld (sioa_txe),hl - ld l,#0 - ret -txa_overflow: - ; some kind of flag for error - ld l,#1 - ret -sioa_direct_maybe: - ; check RR - in a,(SIOA_C) - and #0x04 ; RX space ? - ; if space - ld a,#1 - jr nz, sioa_queue - ; bypass the queue and kickstart the interrupt machine - ld a,l - out (SIOA_D),a - ld l,#0 - ret - ; Call with DI - -_sioa_flow_control_off: - ld a,#5 - out(SIOA_C),a ; WR 5 - ld a,(_sioa_wr5) - out (SIOA_C),a ; Turn off RTS - ret - -_sioa_flow_control_on: - ld a,#5 - out(SIOA_C),a ; WR 5 - ld a,(_sioa_wr5) - and #0xFD - out (SIOA_C),a ; Turn off RTS - ret - - ; DI required - ; Returns char in L - ; - ; Caller responsible for making post buffer fetch decisions about - ; RTS -_sioa_rx_get: - ld a,(_sioa_rxl) - or a - ret z - dec a - ld (_sioa_rxl),a - ld hl,(sioa_rxe) - ld a,(hl) - inc l - res 7,l - ld (sioa_rxe),hl - scf - ld l,a - ret - - ; DI required -_sioa_error_get: - ld hl,#sioa_error - ld a,(hl) - ld (hl),#0 - ld l,a - ret - -; -; Queue a byte to be sent (DI required) -; -; l = byte -; -; Need a way to halt processing somewhere here or a_tx ? -; (or can we use hardware ?) -; 128 byte ring buffer aligned to upper half (rx is in lower) -; -_siob_txqueue: - ld a,(_siob_txl) - or a - jr z, siob_direct_maybe ; if can tx now then do - inc a - jp m, txb_overflow -siob_queue: - ld (_siob_txl),a - ld a,l - ld hl,(siob_txe) - ld (hl),a - inc l - set 7,l - ld (siob_txe),hl - ld l,#0 - ret -txb_overflow: - ; some kind of flag for error - ld l,#1 - ret -siob_direct_maybe: - ; check RR - in a,(SIOB_C) - and #0x04 ; RX space ? - ; if space - ld a,#1 - jr z, siob_queue - ; bypass the queue and kickstart the interrupt machine - ld a,l - out (SIOB_D),a - ld l,#0 - ret - ; Call with DI - -_siob_flow_control_off: - ld a,#5 - out(SIOB_C),a ; WR 5 - ld a,(_siob_wr5) - out (SIOB_C),a ; Turn off RTS - ret - -_siob_flow_control_on: - ld a, (_siob_flow) - or a - ret z - ld a,#5 - out(SIOB_C),a ; WR 5 - ld a,(_siob_wr5) - and #0xFD - out (SIOB_C),a ; Turn off RTS - ret + .include "../dev/z80sio.s" - ; DI required - ; Returns char in L - ; - ; Caller responsible for making post buffer fetch decisions about - ; RTS -_siob_rx_get: - ld a,(_siob_rxl) - or a - ret z - dec a - ld (_siob_rxl),a - ld hl,(siob_rxe) - ld a,(hl) - inc l - res 7,l - ld (siob_rxe),hl - scf - ld l,a - ret - - ; DI required -_siob_error_get: - ld hl,#siob_error - ld a,(hl) - ld (hl),#0 - ld l,a - ret +sio_ports a +sio_ports b +sio_handler_im2 a, SIOA_C, SIOA_D, reti +sio_handler_im2 b, SIOB_C, SIOB_D, reti + .area _BOOT + jp init