o.cflags equ 4\r
\r
db 0\r
+o.stat equ 5\r
+ b2m SXOFF,0\r
+ b2m TDC1,1\r
+ b2m TDC3,2\r
db 0\r
oint.iflags equ as0_dev+o.iflags-s0.inbuf\r
oint.fflags equ as0_dev+o.fflags-s0.inbuf\r
+oint.stat equ as0_dev+o.stat-s0.inbuf\r
mkbuf s0.rx_id, s0.inbuf, s0.rx_len\r
mkbuf s0.tx_id, s0.outbuf,s0.tx_len\r
\r
db 0 ;absolute device #\r
db 1 ;relative device\r
db 0 ;iflags\r
- db M_CREAD ;fflags\r
+ db M_CREAD+M_IXOFF ;fflags\r
db M_CS8 ;cflags\r
\r
db 0\r
ld a,b\r
cp 1\r
jr nz,asioc_1\r
- ld a,(INIDONE)\r
- and 80h\r
- cp INIDONEVAL\r
+ ld a,(inidone)\r
+ cp inidoneval\r
ret z\r
asioc_1:\r
push hl\r
push ix\r
ld ix,s0.inbuf ;\r
call ff_gech\r
- ld a,b\r
- cp s0.rx_len/4\r
- jr nc,a0i_1\r
- bit CRTS_IFLOW,(ix+oint.fflags)\r
- jr z,a0i_1\r
- di\r
+ ld a,b ;remaining chrs in buffer\r
+ cp s0.rx_len/4 ; < 32?\r
+ jr nc,a0i_2 ; no, just get char\r
+ ld b,(ix+oint.fflags) ; yes, enable RTS if needed\r
+ bit CRTS_IFLOW,b ; yes, enable RTS if needed\r
+ jr z,a0i_1 ; no needed\r
+ di ; needed, enable\r
in0 a,(cntla0)\r
and ~M_RTS0 ;assert RTS\r
or M_EFR ;don't reset error flags\r
ei\r
out0 (cntla0),a\r
a0i_1:\r
+ bit IXOFF,b ; XON/XOFF on input?\r
+ jr z,a0i_2 ; no\r
+ di\r
+ set TDC1,(ix+oint.stat) ;\r
+ in0 a,(stat0) ;\r
+ or M_TIE ;\r
+ ei\r
+ out0 (stat0),a ;\r
+a0i_2:\r
ld a,c\r
pop ix\r
ret\r
push ix\r
ld ix,s1.inbuf ;\r
call ff_gech\r
+ ld a,b ; remaining chars in buffer\r
+ cp s0.rx_len/4 ; == 25% full?\r
+ jr nz,a1i_2 ; no, just get char\r
+ bit IXOFF,(ix+oint.fflags) ; XON/XOFF on input?\r
+ jr z,a1i_2 ; no\r
+ di\r
+ set TDC1,(ix+oint.stat) ;\r
+ in0 a,(stat1) ;\r
+ or M_TIE ;\r
+ out0 (stat1),a ;\r
+ ei\r
+a1i_2:\r
+ ld a,c ; get back the char\r
pop ix\r
ret\r
\r
;--------------------------------------------------------------\r
; put character in c in buffer\r
; destroys hl, bc\r
-; returns output char in a\r
\r
asci0_out:\r
push ix ;\r
call ff_puth\r
pop ix ;\r
di ;\r
- in0 c,(stat0) ;\r
- set TIE,c ;\r
- out0 (stat0),c ;\r
+ in0 a,(stat0) ;\r
+ or M_TIE ;\r
+ out0 (stat0),a ;\r
ei ;\r
ret\r
\r
;--------------------------------------------------------------\r
; put character in c in buffer\r
; destroys hl, bc\r
-; returns output char in a\r
\r
asci1_out:\r
push ix ;\r
call ff_puth\r
pop ix ;\r
di ;\r
- in0 c,(stat1) ;\r
- set TIE,c ;\r
- out0 (stat1),c ;\r
+ in0 a,(stat1) ;\r
+ or M_TIE ;\r
+ out0 (stat1),a ;\r
ei ;\r
ret\r
\r
\r
.lall\r
asci_int macro dev\r
- local rxi_2,rxi_4\r
+ local rxi_2,rxi_3\r
\r
push ix\r
-rxtxi&dev&_lp0:\r
ld ix,s&dev&.inbuf ;\r
+ ld d,(ix+oint.fflags)\r
rxtxi&dev&_lp1:\r
- in0 a,(stat&dev) ;receive flag set?\r
+ in0 e,(stat&dev) ;get asci status\r
jp p,txi&dev ;RDRF == Bit 7\r
- and M_OVRN+M_PERR+M_FE\r
- ld e,a\r
\r
- in0 a,(asext&dev)\r
+ ; RX Interrupt\r
+\r
+ res BREAK,e\r
+ in0 a,(asext&dev) ;get break status\r
and M_BREAK\r
- or e\r
+ or e ;merge to other error flags\r
ld e,a\r
\r
- in0 d,(cntla&dev) ;\r
- res EFR,d ;\r
- out0 (cntla&dev),d\r
+ in0 a,(cntla&dev) ;reset all error flags\r
+ and ~M_EFR ;\r
+ out0 (cntla&dev),a ;\r
\r
- ld c,(ix+o.in_idx) ;\r
+ ld c,(ix+o.in_idx) ;input buffer pointer\r
ld b,0\r
ld hl,s&dev&.inbuf ;\r
add hl,bc\r
\r
- in0 a,(rdr&dev) ;\r
- ld (hl),a\r
+ in0 b,(rdr&dev) ;get char\r
;todo: break detection\r
- ;todo: parity, framing overrun error\r
+ ;todo: parity, framing, overrun error\r
+ ld (hl),b\r
\r
- ld e,(ix+oint.fflags)\r
- bit IXON,e\r
- jr z,rxi_2\r
+; bit IXON,d\r
+; jr z,rxi_2\r
;todo: test XON/XOFF\r
-\r
rxi_2:\r
\r
ld a,c ;increment buffer in pointer\r
and b ;\r
ld c,a\r
\r
- sub (ix+o.out_idx) ;\r
- jr z,rxtxi&dev&_lp1 ;skip if buffer is full\r
-\r
- ld (ix+o.in_idx),c ;\r
-\r
- jr nc,$+3 ;\r
- adc b ;\r
+ sub (ix+o.out_idx) ;number of free places in buffer\r
+ jr z,rxtxi&dev&_lp1 ;buffer full?\r
+ and b ;\r
+ ld (ix+o.in_idx),c ; no, update input index\r
\r
- cp s&dev&.tx_len*3/4\r
- jr c,rxi&dev&_noflow\r
+ cp s&dev&.tx_len*3/4 ;buffer now 75% full?\r
+ jr nz,rxtxi&dev&_lp1\r
\r
- if dev=0\r
- bit CRTS_IFLOW,e\r
- jr z,rxi_4\r
+ if dev=0 ; only channel 0 has rts line\r
+ bit CRTS_IFLOW,d\r
+ jr z,rxi0_nocrts\r
\r
- set EFR,d\r
- set RTS0,d ;RTS inactive\r
- out0 (cntla&dev),d ;\r
+ in0 a,(cntla&dev) ;reset all error flags\r
+ or M_RTS0+M_EFR ;RTS inactive\r
+ out0 (cntla0),a ;\r
+rxi0_nocrts:\r
endif\r
\r
-rxi_4:\r
- bit IXOFF,e\r
+ bit IXOFF,d\r
jr z,rxtxi&dev&_lp1\r
- ;todo: send XOFF\r
-\r
-rxi&dev&_noflow:\r
+ ;send XOFF\r
+ set TDC3,(ix+oint.stat)\r
+ set TIE,e ;\r
+ out0 (stat&dev),e ;\r
jr rxtxi&dev&_lp1\r
\r
-\r
txi&dev:\r
- ld e,a\r
bit TDRE,e ;TX int?\r
jr z,rxtxi&dev&_exit\r
\r
- ;todo: xon/xoff\r
+ ; TX Interrupt\r
+\r
+ ld a,(ix+oint.stat) ;check if xon/xoff should be sent\r
+ tst M_TDC1+M_TDC3 ;\r
+ jr z,txi&dev&_char ; no\r
+\r
+ ld l,DC3 ;prepare for xoff\r
+ bit TDC1,a ;request for xon (also) set?\r
+ jr z,txi&dev&_cch ;\r
+ ld l,DC1 ;\r
+txi&dev&_cch:\r
+ out0 (tdr&dev),l ;\r
+ and ~(M_TDC1+M_TDC3) ;reset request flags\r
+ ld (ix+oint.stat),a ;\r
+ jp rxtxi&dev&_lp1 ;\r
\r
+txi&dev&_char:\r
ld hl,s&dev&.outbuf+o.in_idx ;[in]\r
ld a,(hl) ;\r
inc hl ;[out]\r
and c ;\r
ld (s&dev&.outbuf+o.out_idx),a ;\r
\r
- jr rxtxi&dev&_lp0\r
+ jp rxtxi&dev&_lp1\r
\r
txi&dev&_empty:\r
res TIE,e ;disable tx-int\r