]> cloudbase.mooo.com Git - z180-stamp-cpm3.git/blobdiff - cbios/ascii.180
simplify buffer level calculation
[z180-stamp-cpm3.git] / cbios / ascii.180
index fbe193d768f6f0b6a9ea99006419045a9fd69c60..d3f6b20fa5a73d1561c2678336e86ee5b7c37c32 100644 (file)
@@ -42,9 +42,14 @@ o.fflags     equ     3
 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
@@ -58,7 +63,7 @@ as1_dev:
        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
@@ -108,9 +113,8 @@ asci_ioctl:
        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
@@ -546,18 +550,28 @@ asci0_inp:
        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
@@ -569,6 +583,19 @@ asci1_inp:
        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
@@ -595,7 +622,6 @@ asci1_osta:
 ;--------------------------------------------------------------\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
@@ -603,16 +629,15 @@ asci0_out:
        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
@@ -620,9 +645,9 @@ asci1_out:
        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
@@ -643,41 +668,40 @@ rtxisvjmp1:
 \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
@@ -686,42 +710,53 @@ rxi_2:
        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
@@ -738,7 +773,7 @@ txi&dev:
        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