X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp-cpm3.git/blobdiff_plain/2f8aa307bd467d1ba6dd282bc4fb1a67e614a179..80873aa27c7a3eccbd3858fdd5c39925ea7a2fcf:/cbios/ascii.180 diff --git a/cbios/ascii.180 b/cbios/ascii.180 index fbe193d..d3f6b20 100644 --- a/cbios/ascii.180 +++ b/cbios/ascii.180 @@ -42,9 +42,14 @@ o.fflags equ 3 o.cflags equ 4 db 0 +o.stat equ 5 + b2m SXOFF,0 + b2m TDC1,1 + b2m TDC3,2 db 0 oint.iflags equ as0_dev+o.iflags-s0.inbuf oint.fflags equ as0_dev+o.fflags-s0.inbuf +oint.stat equ as0_dev+o.stat-s0.inbuf mkbuf s0.rx_id, s0.inbuf, s0.rx_len mkbuf s0.tx_id, s0.outbuf,s0.tx_len @@ -58,7 +63,7 @@ as1_dev: db 0 ;absolute device # db 1 ;relative device db 0 ;iflags - db M_CREAD ;fflags + db M_CREAD+M_IXOFF ;fflags db M_CS8 ;cflags db 0 @@ -108,9 +113,8 @@ asci_ioctl: ld a,b cp 1 jr nz,asioc_1 - ld a,(INIDONE) - and 80h - cp INIDONEVAL + ld a,(inidone) + cp inidoneval ret z asioc_1: push hl @@ -546,18 +550,28 @@ asci0_inp: push ix ld ix,s0.inbuf ; call ff_gech - ld a,b - cp s0.rx_len/4 - jr nc,a0i_1 - bit CRTS_IFLOW,(ix+oint.fflags) - jr z,a0i_1 - di + ld a,b ;remaining chrs in buffer + cp s0.rx_len/4 ; < 32? + jr nc,a0i_2 ; no, just get char + ld b,(ix+oint.fflags) ; yes, enable RTS if needed + bit CRTS_IFLOW,b ; yes, enable RTS if needed + jr z,a0i_1 ; no needed + di ; needed, enable in0 a,(cntla0) and ~M_RTS0 ;assert RTS or M_EFR ;don't reset error flags ei out0 (cntla0),a a0i_1: + bit IXOFF,b ; XON/XOFF on input? + jr z,a0i_2 ; no + di + set TDC1,(ix+oint.stat) ; + in0 a,(stat0) ; + or M_TIE ; + ei + out0 (stat0),a ; +a0i_2: ld a,c pop ix ret @@ -569,6 +583,19 @@ asci1_inp: push ix ld ix,s1.inbuf ; call ff_gech + ld a,b ; remaining chars in buffer + cp s0.rx_len/4 ; == 25% full? + jr nz,a1i_2 ; no, just get char + bit IXOFF,(ix+oint.fflags) ; XON/XOFF on input? + jr z,a1i_2 ; no + di + set TDC1,(ix+oint.stat) ; + in0 a,(stat1) ; + or M_TIE ; + out0 (stat1),a ; + ei +a1i_2: + ld a,c ; get back the char pop ix ret @@ -595,7 +622,6 @@ asci1_osta: ;-------------------------------------------------------------- ; put character in c in buffer ; destroys hl, bc -; returns output char in a asci0_out: push ix ; @@ -603,16 +629,15 @@ asci0_out: call ff_puth pop ix ; di ; - in0 c,(stat0) ; - set TIE,c ; - out0 (stat0),c ; + in0 a,(stat0) ; + or M_TIE ; + out0 (stat0),a ; ei ; ret ;-------------------------------------------------------------- ; put character in c in buffer ; destroys hl, bc -; returns output char in a asci1_out: push ix ; @@ -620,9 +645,9 @@ asci1_out: call ff_puth pop ix ; di ; - in0 c,(stat1) ; - set TIE,c ; - out0 (stat1),c ; + in0 a,(stat1) ; + or M_TIE ; + out0 (stat1),a ; ei ; ret @@ -643,41 +668,40 @@ rtxisvjmp1: .lall asci_int macro dev - local rxi_2,rxi_4 + local rxi_2,rxi_3 push ix -rxtxi&dev&_lp0: ld ix,s&dev&.inbuf ; + ld d,(ix+oint.fflags) rxtxi&dev&_lp1: - in0 a,(stat&dev) ;receive flag set? + in0 e,(stat&dev) ;get asci status jp p,txi&dev ;RDRF == Bit 7 - and M_OVRN+M_PERR+M_FE - ld e,a - in0 a,(asext&dev) + ; RX Interrupt + + res BREAK,e + in0 a,(asext&dev) ;get break status and M_BREAK - or e + or e ;merge to other error flags ld e,a - in0 d,(cntla&dev) ; - res EFR,d ; - out0 (cntla&dev),d + in0 a,(cntla&dev) ;reset all error flags + and ~M_EFR ; + out0 (cntla&dev),a ; - ld c,(ix+o.in_idx) ; + ld c,(ix+o.in_idx) ;input buffer pointer ld b,0 ld hl,s&dev&.inbuf ; add hl,bc - in0 a,(rdr&dev) ; - ld (hl),a + in0 b,(rdr&dev) ;get char ;todo: break detection - ;todo: parity, framing overrun error + ;todo: parity, framing, overrun error + ld (hl),b - ld e,(ix+oint.fflags) - bit IXON,e - jr z,rxi_2 +; bit IXON,d +; jr z,rxi_2 ;todo: test XON/XOFF - rxi_2: ld a,c ;increment buffer in pointer @@ -686,42 +710,53 @@ rxi_2: and b ; ld c,a - sub (ix+o.out_idx) ; - jr z,rxtxi&dev&_lp1 ;skip if buffer is full - - ld (ix+o.in_idx),c ; - - jr nc,$+3 ; - adc b ; + sub (ix+o.out_idx) ;number of free places in buffer + jr z,rxtxi&dev&_lp1 ;buffer full? + and b ; + ld (ix+o.in_idx),c ; no, update input index - cp s&dev&.tx_len*3/4 - jr c,rxi&dev&_noflow + cp s&dev&.tx_len*3/4 ;buffer now 75% full? + jr nz,rxtxi&dev&_lp1 - if dev=0 - bit CRTS_IFLOW,e - jr z,rxi_4 + if dev=0 ; only channel 0 has rts line + bit CRTS_IFLOW,d + jr z,rxi0_nocrts - set EFR,d - set RTS0,d ;RTS inactive - out0 (cntla&dev),d ; + in0 a,(cntla&dev) ;reset all error flags + or M_RTS0+M_EFR ;RTS inactive + out0 (cntla0),a ; +rxi0_nocrts: endif -rxi_4: - bit IXOFF,e + bit IXOFF,d jr z,rxtxi&dev&_lp1 - ;todo: send XOFF - -rxi&dev&_noflow: + ;send XOFF + set TDC3,(ix+oint.stat) + set TIE,e ; + out0 (stat&dev),e ; jr rxtxi&dev&_lp1 - txi&dev: - ld e,a bit TDRE,e ;TX int? jr z,rxtxi&dev&_exit - ;todo: xon/xoff + ; TX Interrupt + + ld a,(ix+oint.stat) ;check if xon/xoff should be sent + tst M_TDC1+M_TDC3 ; + jr z,txi&dev&_char ; no + + ld l,DC3 ;prepare for xoff + bit TDC1,a ;request for xon (also) set? + jr z,txi&dev&_cch ; + ld l,DC1 ; +txi&dev&_cch: + out0 (tdr&dev),l ; + and ~(M_TDC1+M_TDC3) ;reset request flags + ld (ix+oint.stat),a ; + jp rxtxi&dev&_lp1 ; +txi&dev&_char: ld hl,s&dev&.outbuf+o.in_idx ;[in] ld a,(hl) ; inc hl ;[out] @@ -738,7 +773,7 @@ txi&dev: and c ; ld (s&dev&.outbuf+o.out_idx),a ; - jr rxtxi&dev&_lp0 + jp rxtxi&dev&_lp1 txi&dev&_empty: res TIE,e ;disable tx-int