X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp-cpm3.git/blobdiff_plain/72ba373765af20594a45142cc9bb3c5fe5bb14e6..80873aa27c7a3eccbd3858fdd5c39925ea7a2fcf:/cbios/ascii.180 diff --git a/cbios/ascii.180 b/cbios/ascii.180 index d329de4..d3f6b20 100644 --- a/cbios/ascii.180 +++ b/cbios/ascii.180 @@ -33,7 +33,7 @@ as0_dev: db 0 ;absolute device # db 0 ;relative device db 0 ;iflags - db 0 ;fflags + db M_CREAD+M_CRTS_IFLOW+M_CCTS_OFLOW ;fflags db M_CS8 ;cflags o.absdev equ 0 o.reldev equ 1 @@ -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 0 ;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 @@ -156,12 +160,7 @@ init_st: ld a,(hl) ;get baudrate index call as_br_div ld c,astc0l - ld a,l - call out_asci_reg - inc c - ld a,h - call out_asci_reg - + call out_asci_reg_hl ld c,cntlb0 ld a,M_MPBT ;No MP Mode, X16 @@ -179,8 +178,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 ; @@ -217,10 +216,7 @@ mod_tab: ; Get the current serial port settings. func_tcgeta: - ld a,d - or e - ld a,0ffh - jr z,fgeta_e + call chk_ptr ld a,(ix+o.iflags) call b_st_a @@ -244,18 +240,13 @@ func_tcgeta: dec de dec de xor a -fgeta_e: ret - ;-------------------------------------------------------------- ; Set the current serial port settings. func_tcseta: - ld a,d - or e - ld a,0ffh - jr z,fseta_e + call chk_ptr call asci_stop @@ -281,10 +272,8 @@ func_tcseta: call init_st pop de xor a -fseta_e: ret - ;-------------------------------------------------------------- ; Allow the output buffer to drain @@ -370,6 +359,16 @@ func_tiocssoftcar: ;-------------------------------------------------------------- +chk_ptr: + ld a,e + or d + ret nz + cpl + pop hl + ret + +;-------------------------------------------------------------- + asci_stop: ld c,stat0 ;Disable rx/tx interrupts xor a ; @@ -382,6 +381,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 @@ -395,19 +401,34 @@ asci_start: out_asci_reg: push bc - ld b,a - ld a,c - cp astc0l ;astc0/1 are 16 bit - jr c,$+5 - add a,(ix+o.reldev) - add a,(ix+o.reldev) - ld c,a - ld a,b + bit 0,(ix+o.reldev) + jr z,$+3 + inc c ld b,0 out (c),a pop bc ret +;-------------------------------------------------------------- +; output 16 bit value to asci0/1 register +; +; c: register address +; hl: value +; a destroyed + +out_asci_reg_hl: + ld a,b ;save b + bit 0,(ix+o.reldev) + jr z,$+4 + inc c + inc c + ld b,0 + out (c),l + inc c + out (c),h + ld b,a + ret + ;-------------------------------------------------------------- ; baud rate divider ; @@ -505,20 +526,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 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 @@ -530,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 @@ -556,7 +622,6 @@ asci1_osta: ;-------------------------------------------------------------- ; put character in c in buffer ; destroys hl, bc -; returns output char in a asci0_out: push ix ; @@ -564,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 ; @@ -581,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 @@ -593,54 +657,52 @@ asci1_out: cseg rtxisvjmp0: call isv_sw - dw rxtxi0 + dw asci0_int + rtxisvjmp1: call isv_sw - dw rxtxi1 + dw asci1_int ;-------------------------------------------------------------- -; ASCI 0 Transmit/Receive interupt routines +; ASCI 0/1 Transmit/Receive interupt routines + + .lall +asci_int macro dev + local rxi_2,rxi_3 - dseg -rxtxi0: push ix -rxtxi0_lp0: - ld ix,s0.inbuf ; -rxtxi0_lp1: - in0 a,(stat0) ;receive flag set? - jp p,rxtxi0_1 ;RDRF == Bit 7 - and M_OVRN+M_PERR+M_FE - ld e,a + ld ix,s&dev&.inbuf ; + ld d,(ix+oint.fflags) +rxtxi&dev&_lp1: + in0 e,(stat&dev) ;get asci status + jp p,txi&dev ;RDRF == Bit 7 - in0 a,(asext0) + ; 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,(cntla0) ; - res EFR,d ; - out0 (cntla0),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,s0.inbuf ; + ld hl,s&dev&.inbuf ; add hl,bc - in0 a,(rdr0) ; - 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,rxtxi0_2 + ;todo: parity, framing, overrun error + ld (hl),b +; bit IXON,d +; jr z,rxi_2 ;todo: test XON/XOFF - -rxtxi0_2: - +rxi_2: ld a,c ;increment buffer in pointer inc a ; @@ -648,125 +710,91 @@ rxtxi0_2: and b ; ld c,a - sub (ix+o.out_idx) ; - jr z,rxtxi0_lp1 ;skip if buffer is full - - ld (ix+o.in_idx),c ; - - jr nc,$+3 ; - adc b ; - - cp s0.tx_len*3/4 - jr c,rxi0_noflow - - bit CRTS_IFLOW,e - jr z,rxtxi0_4 + 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 - set EFR,d - set RTS0,d ;RTS inactive - out0 (cntla0),d ; + cp s&dev&.tx_len*3/4 ;buffer now 75% full? + jr nz,rxtxi&dev&_lp1 -rxtxi0_4: - bit IXOFF,e - jr z,rxtxi0_lp1 - ;todo: send XOFF + if dev=0 ; only channel 0 has rts line + bit CRTS_IFLOW,d + jr z,rxi0_nocrts -rxi0_noflow: - jr rxtxi0_lp1 + in0 a,(cntla&dev) ;reset all error flags + or M_RTS0+M_EFR ;RTS inactive + out0 (cntla0),a ; +rxi0_nocrts: + endif + bit IXOFF,d + jr z,rxtxi&dev&_lp1 + ;send XOFF + set TDC3,(ix+oint.stat) + set TIE,e ; + out0 (stat&dev),e ; + jr rxtxi&dev&_lp1 -rxtxi0_1: - ld e,a +txi&dev: bit TDRE,e ;TX int? - jr z,rxtxi0_e ; - - - ld ix,s0.outbuf ; - - ld a,(ix+o.out_idx) ; - cp (ix+o.in_idx) ;if index.in == index.out - jr z,?0ti_2 ; buffer empty - - ld hl,s0.outbuf ; - ld c,a - ld b,0 - add hl,bc - ld b,(hl) - out0 (tdr0),b ; 7 + jr z,rxtxi&dev&_exit + + ; 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] + ld c,(hl) ; + cp c ; + jr z,txi&dev&_empty ; + inc hl ;fifo base + ld b,0 ; + add hl,bc ; + ld a,(hl) ; + out0 (tdr&dev),a ; + inc c ; + ld a,(s&dev&.outbuf+o.mask) ; + and c ; + ld (s&dev&.outbuf+o.out_idx),a ; - inc a - and (ix+o.mask) - ld (ix+o.out_idx),a - jr rxtxi0_lp0 + jp rxtxi&dev&_lp1 -?0ti_2: +txi&dev&_empty: res TIE,e ;disable tx-int - out0 (stat0),e ; 5 + out0 (stat&dev),e ; 5 -rxtxi0_e: +rxtxi&dev&_exit: pop ix ret - - -;-------------------------------------------------------------- -; ASCI 1 Transmit/Receive interupt routines + endm dseg -rxtxi1: - in0 e,(stat1) ;receive flag set? 5 - jp p,txi1_0 ; - - in0 d,(rdr1) ;todo: break detection 9 - bit FE,e ;framing error? - jr nz,??ri_1 - - push ix - ld ix,s1.inbuf ; - ld hl,s1.inbuf ; - ld c,(ix+o.in_idx) ; - ld b,0 - add hl,bc - ld (hl),d - - ld a,c ; - inc a - and (ix+o.mask) - cp (ix+o.out_idx) ; - jr z,$+5 ;skip if buffer is full - ld (ix+o.in_idx),a - pop ix -??ri_1: - in0 a,(cntla1) ; 1 - res EFR,a ; - out0 (cntla1),a ; 1 - ret - -txi1_0: - push ix - ld ix,s1.outbuf ; - - ld a,(ix+o.out_idx) ; - cp (ix+o.in_idx) ;if index.in == index.out - jr z,??ti_2 ; buffer empty +;-------------------------------------------------------------- +; ASCI 0 Transmit/Receive interupt routines - ld hl,s1.outbuf ; - ld c,a - ld b,0 - add hl,bc - ld l,(hl) - out0 (tdr1),l ; 7 - - inc a - and (ix+o.mask) - ld (ix+o.out_idx),a - jr ??ti_3 -??ti_2: - res TIE,e ;disable tx-int - out0 (stat1),e ; 5 -??ti_3: - pop ix - ret +asci0_int: + asci_int 0 +;-------------------------------------------------------------- +; ASCI 1 Transmit/Receive interupt routines +asci1_int: + asci_int 1 end