X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp-cpm3.git/blobdiff_plain/99b8d89e09c2c5303d3cbec39c9dc288cc3a3233..e8b62d9ac855de6439580c15ee12f496a94c5e5d:/cbios/ascii.180 diff --git a/cbios/ascii.180 b/cbios/ascii.180 index 3ea64a7..3ffa931 100644 --- a/cbios/ascii.180 +++ b/cbios/ascii.180 @@ -42,9 +42,15 @@ o.fflags equ 3 o.cflags equ 4 db 0 +o.stat equ 5 + b2m SXOFF,0 + b2m TDC1,1 + b2m TDC3,2 + b2m TOFF,7 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 +64,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 @@ -105,14 +111,6 @@ IOCTL_MAX equ ($-ioctl_ftab)/2 ; asci_ioctl: - ld a,b - cp 1 - jr nz,asioc_1 - ld a,(INIDONE) - and 80h - cp INIDONEVAL - ret z -asioc_1: push hl ex (sp),ix ld (ix+o.absdev),b @@ -151,8 +149,13 @@ init_st: ld b,(ix+o.absdev) ld c,8 ; mlt bc ; - ld hl,@ctbl+7 ; + ld hl,@ctbl+6 ; add hl,bc ; + res IXON,(ix+o.fflags) + bit mbxon_bit,(hl) ;get cpm3 xon flag + jr z,$+6 + set IXON,(ix+o.fflags) + inc hl ld a,(hl) ;get baudrate index call as_br_div ld c,astc0l @@ -174,8 +177,8 @@ init_st: or a,M_RE+M_TE+M_RTS0+M_EFR ;Rx/Tx enable call out_asci_reg - push ix bit 0,(ix+o.reldev) + push ix jr nz,init_1 ld hl,rtxisvjmp0 ;rx/tx int vector ld (ivtab + IV$ASCI0),hl ; @@ -214,18 +217,22 @@ mod_tab: func_tcgeta: call chk_ptr + ld b,(ix+o.absdev) + ld c,8 ; + mlt bc ; + ld hl,@ctbl+6 ; + add hl,bc ; + res IXON,(ix+o.fflags) + bit mbxon_bit,(hl) ;get cpm3 xon flag + jr z,$+6 + set IXON,(ix+o.fflags) + inc hl ld a,(ix+o.iflags) call b_st_a inc de ld a,(ix+o.fflags) call b_st_a inc de - - ld b,(ix+o.absdev) - ld c,8 ; - mlt bc ; - ld hl,@ctbl+7 ; - add hl,bc ; ld a,(hl) ;get baudrate index and M_CBAUD ld b,a @@ -256,8 +263,13 @@ func_tcseta: ld b,(ix+o.absdev) ld c,8 ; mlt bc ; - ld hl,@ctbl+7 ; + ld hl,@ctbl+6 ; add hl,bc ; + res mbxon_bit,(hl) + bit IXON,a + jr z,$+4 + set mbxon_bit,(hl) + inc hl call b_ld_a ld (ix+o.cflags),a and M_CBAUD @@ -377,6 +389,13 @@ asci_stop: ;-------------------------------------------------------------- asci_start: + bit 0,(ix+o.reldev) + jr nz,asci_st1 + in0 a,cntla0 ;asci0 + and ~M_RTS0 ;Activate RTS + or M_EFR + out0 (cntla0),a +asci_st1: ld c,stat0 ; ld a,M_RIE jr out_asci_reg @@ -515,22 +534,52 @@ asci1_ista: ;-------------------------------------------------------------- ; Get an input character +if 0 asci0_inp: push ix ld ix,s0.inbuf ; - call ff_gech - ld a,b - cp s0.rx_len/4 + call ff_cnt + cp 32 jr nc,a0i_1 - bit CRTS_IFLOW,(ix+oint.fflags) - jr z,a0i_1 di in0 a,(cntla0) + res RTS0,a + set EFR,a + out0 (cntla0),a + ei +a0i_1: + call ff_get + pop ix + ret +endif + + +asci0_inp: + push ix + ld ix,s0.inbuf ; + call ff_gech + 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 @@ -542,6 +591,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 @@ -568,34 +630,38 @@ asci1_osta: ;-------------------------------------------------------------- ; put character in c in buffer ; destroys hl, bc -; returns output char in a asci0_out: push ix ; ld ix,s0.outbuf ; call ff_puth pop ix ; + ld a,(as0_dev+o.stat) ;Transmitter stopped? + bit TOFF,a ; + ret nz ; yes 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 ; ld ix,s1.outbuf ; call ff_puth pop ix ; + ld a,(as1_dev+o.stat) ;Transmitter stopped? + bit TOFF,a ; + ret nz ; yes di ; - in0 c,(stat1) ; - set TIE,c ; - out0 (stat1),c ; + in0 a,(stat1) ; + or M_TIE ; + out0 (stat1),a ; ei ; ret @@ -616,86 +682,111 @@ rtxisvjmp1: .lall asci_int macro dev - local rxi_2,rxi_4 - 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 b,0 - ld hl,s&dev&.inbuf ; - add hl,bc + ld c,(ix+o.in_idx) ;get input index + ld b,0 ; + ld hl,s&dev&.inbuf ; + base = input buffer pointer + add hl,bc ; - in0 a,(rdr&dev) ; - ld (hl),a + in0 b,(rdr&dev) ;get char ;todo: break detection - ;todo: parity, framing overrun error - - ld e,(ix+oint.fflags) - bit IXON,e - jr z,rxi_2 - ;todo: test XON/XOFF - -rxi_2: - - ld a,c ;increment buffer in pointer + ;todo: parity, framing, overrun error + ld (hl),b + bit IXON,d + jr z,rxi&dev&_x3 + ;test XON/XOFF + ld a,DC3 + cp b + jr nz,rxi&dev&_x1 + set TOFF,(ix+oint.stat) ;Stop transmitter + jr rxtxi&dev&_lp1 +rxi&dev&_x1: + ld a,DC1 + cp b + jr nz,rxi&dev&_x2 + res TOFF,(ix+oint.stat) ;Enable transmitter + jr rxi&dev&_txen +rxi&dev&_x2: + bit IXANY,d + jr z,rxi&dev&_x3 + res TOFF,(ix+oint.stat) ;Enable transmitter +rxi&dev&_x3: + + ld a,c ;increment input index inc a ; ld b,(ix+o.mask) ; 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 ; - - cp s&dev&.tx_len*3/4 - jr c,rxi&dev&_noflow - - if dev=0 - bit CRTS_IFLOW,e - jr z,rxi_4 - - set EFR,d - set RTS0,d ;RTS inactive - out0 (cntla&dev),d ; + 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 ;buffer now 75% full? + jr nz,rxtxi&dev&_lp1 + + if dev=0 ;only channel 0 has rts line + bit CRTS_IFLOW,d + jr z,rxi0_nocrts + in0 a,(cntla&dev) ; + 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) +rxi&dev&_txen: + 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 whether 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: + bit TOFF,(ix+oint.stat) + jr nz,txi&dev&_empty ; - ld hl,s&dev&.outbuf+o.in_idx ;[in] + ld hl,s&dev&.outbuf+o.in_idx ;[in] ld a,(hl) ; inc hl ;[out] ld c,(hl) ; @@ -707,15 +798,15 @@ txi&dev: ld a,(hl) ; out0 (tdr&dev),a ; inc c ; - ld a,(s&dev&.outbuf+o.mask) ; + ld a,(s&dev&.outbuf+o.mask); and c ; - ld (s&dev&.outbuf+o.out_idx),a ; + 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 - out0 (stat&dev),e ; 5 + out0 (stat&dev),e ; rxtxi&dev&_exit: pop ix