db 0 ;absolute device #\r
db 0 ;relative device\r
db 0 ;iflags\r
- db 0 ;fflags\r
+ db M_CREAD+M_CRTS_IFLOW+M_CCTS_OFLOW ;fflags\r
db M_CS8 ;cflags\r
o.absdev equ 0\r
o.reldev equ 1\r
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 0 ;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
ld a,(hl) ;get baudrate index\r
call as_br_div\r
ld c,astc0l\r
- ld a,l\r
- call out_asci_reg\r
- inc c\r
- ld a,h\r
- call out_asci_reg\r
-\r
+ call out_asci_reg_hl\r
\r
ld c,cntlb0\r
ld a,M_MPBT ;No MP Mode, X16\r
or a,M_RE+M_TE+M_RTS0+M_EFR ;Rx/Tx enable\r
call out_asci_reg\r
\r
- push ix\r
bit 0,(ix+o.reldev)\r
+ push ix\r
jr nz,init_1\r
ld hl,rtxisvjmp0 ;rx/tx int vector\r
ld (ivtab + IV$ASCI0),hl ;\r
; Get the current serial port settings.\r
\r
func_tcgeta:\r
- ld a,d\r
- or e\r
- ld a,0ffh\r
- jr z,fgeta_e\r
+ call chk_ptr\r
\r
ld a,(ix+o.iflags)\r
call b_st_a\r
dec de\r
dec de\r
xor a\r
-fgeta_e:\r
ret\r
\r
-\r
;--------------------------------------------------------------\r
; Set the current serial port settings.\r
\r
func_tcseta:\r
- ld a,d\r
- or e\r
- ld a,0ffh\r
- jr z,fseta_e\r
+ call chk_ptr\r
\r
call asci_stop\r
\r
call init_st\r
pop de\r
xor a\r
-fseta_e:\r
ret\r
\r
-\r
;--------------------------------------------------------------\r
; Allow the output buffer to drain\r
\r
\r
;--------------------------------------------------------------\r
\r
+chk_ptr:\r
+ ld a,e\r
+ or d\r
+ ret nz\r
+ cpl\r
+ pop hl\r
+ ret\r
+\r
+;--------------------------------------------------------------\r
+\r
asci_stop:\r
ld c,stat0 ;Disable rx/tx interrupts\r
xor a ;\r
;--------------------------------------------------------------\r
\r
asci_start:\r
+ bit 0,(ix+o.reldev)\r
+ jr nz,asci_st1\r
+ in0 a,cntla0 ;asci0\r
+ and ~M_RTS0 ;Activate RTS\r
+ or M_EFR\r
+ out0 (cntla0),a\r
+asci_st1:\r
ld c,stat0 ;\r
ld a,M_RIE\r
jr out_asci_reg\r
\r
out_asci_reg:\r
push bc\r
- ld b,a\r
- ld a,c\r
- cp astc0l ;astc0/1 are 16 bit\r
- jr c,$+5\r
- add a,(ix+o.reldev)\r
- add a,(ix+o.reldev)\r
- ld c,a\r
- ld a,b\r
+ bit 0,(ix+o.reldev)\r
+ jr z,$+3\r
+ inc c\r
ld b,0\r
out (c),a\r
pop bc\r
ret\r
\r
+;--------------------------------------------------------------\r
+; output 16 bit value to asci0/1 register\r
+;\r
+; c: register address\r
+; hl: value\r
+; a destroyed\r
+\r
+out_asci_reg_hl:\r
+ ld a,b ;save b\r
+ bit 0,(ix+o.reldev)\r
+ jr z,$+4\r
+ inc c\r
+ inc c\r
+ ld b,0\r
+ out (c),l\r
+ inc c\r
+ out (c),h\r
+ ld b,a\r
+ ret\r
+\r
;--------------------------------------------------------------\r
; baud rate divider\r
;\r
;--------------------------------------------------------------\r
; Get an input character\r
\r
+if 0\r
asci0_inp:\r
push ix\r
ld ix,s0.inbuf ;\r
- call ff_gech\r
- ld a,b\r
- cp s0.rx_len/4\r
+ call ff_cnt\r
+ cp 32\r
jr nc,a0i_1\r
di\r
in0 a,(cntla0)\r
+ res RTS0,a\r
+ set EFR,a\r
+ out0 (cntla0),a\r
+ ei\r
+a0i_1:\r
+ call ff_get\r
+ pop ix\r
+ ret\r
+endif\r
+\r
+\r
+asci0_inp:\r
+ push ix\r
+ ld ix,s0.inbuf ;\r
+ call ff_gech\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
cseg\r
rtxisvjmp0:\r
call isv_sw\r
- dw rxtxi0\r
+ dw asci0_int\r
+\r
rtxisvjmp1:\r
call isv_sw\r
- dw rxtxi1\r
+ dw asci1_int\r
\r
;--------------------------------------------------------------\r
-; ASCI 0 Transmit/Receive interupt routines\r
+; ASCI 0/1 Transmit/Receive interupt routines\r
+\r
+ .lall\r
+asci_int macro dev\r
+ local rxi_2,rxi_3\r
\r
- dseg\r
-rxtxi0:\r
push ix\r
-rxtxi0_lp0:\r
- ld ix,s0.inbuf ;\r
-rxtxi0_lp1:\r
- in0 a,(stat0) ;receive flag set?\r
- jp p,rxtxi0_1 ;RDRF == Bit 7\r
- and M_OVRN+M_PERR+M_FE\r
- ld e,a\r
+ ld ix,s&dev&.inbuf ;\r
+ ld d,(ix+oint.fflags)\r
+rxtxi&dev&_lp1:\r
+ in0 e,(stat&dev) ;get asci status\r
+ jp p,txi&dev ;RDRF == Bit 7\r
\r
- in0 a,(asext0)\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,(cntla0) ;\r
- res EFR,d ;\r
- out0 (cntla0),d\r
-\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,s0.inbuf ;\r
+ ld hl,s&dev&.inbuf ;\r
add hl,bc\r
\r
- in0 a,(rdr0) ;\r
- ld (hl),a\r
+ in0 b,(rdr&dev) ;get char\r
;todo: break detection\r
- ;todo: parity, framing overrun error\r
-\r
-\r
- ld e,(ix+oint.fflags)\r
- bit IXON,e\r
- jr z,rxtxi0_2\r
+ ;todo: parity, framing, overrun error\r
+ ld (hl),b\r
\r
+; bit IXON,d\r
+; jr z,rxi_2\r
;todo: test XON/XOFF\r
-\r
-rxtxi0_2:\r
-\r
+rxi_2:\r
\r
ld a,c ;increment buffer in pointer\r
inc a ;\r
and b ;\r
ld c,a\r
\r
- sub (ix+o.out_idx) ;\r
- jr z,rxtxi0_lp1 ;skip if buffer is full\r
-\r
- ld (ix+o.in_idx),c ;\r
-\r
- jr nc,$+3 ;\r
- adc b ;\r
-\r
- cp s0.tx_len*3/4\r
- jr c,rxi0_noflow\r
-\r
- bit CRTS_IFLOW,e\r
- jr z,rxtxi0_4\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
- set EFR,d\r
- set RTS0,d ;RTS inactive\r
- out0 (cntla0),d ;\r
+ cp s&dev&.tx_len*3/4 ;buffer now 75% full?\r
+ jr nz,rxtxi&dev&_lp1\r
\r
-rxtxi0_4:\r
- bit IXOFF,e\r
- jr z,rxtxi0_lp1\r
- ;todo: send XOFF\r
+ if dev=0 ; only channel 0 has rts line\r
+ bit CRTS_IFLOW,d\r
+ jr z,rxi0_nocrts\r
\r
-rxi0_noflow:\r
- jr rxtxi0_lp1\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
+ bit IXOFF,d\r
+ jr z,rxtxi&dev&_lp1\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
-rxtxi0_1:\r
- ld e,a\r
+txi&dev:\r
bit TDRE,e ;TX int?\r
- jr z,rxtxi0_e ;\r
-\r
-\r
- ld ix,s0.outbuf ;\r
-\r
- ld a,(ix+o.out_idx) ;\r
- cp (ix+o.in_idx) ;if index.in == index.out\r
- jr z,?0ti_2 ; buffer empty\r
-\r
- ld hl,s0.outbuf ;\r
- ld c,a\r
- ld b,0\r
- add hl,bc\r
- ld b,(hl)\r
- out0 (tdr0),b ; 7\r
+ jr z,rxtxi&dev&_exit\r
+\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
+ ld c,(hl) ;\r
+ cp c ;\r
+ jr z,txi&dev&_empty ;\r
+ inc hl ;fifo base\r
+ ld b,0 ;\r
+ add hl,bc ;\r
+ ld a,(hl) ;\r
+ out0 (tdr&dev),a ;\r
+ inc c ;\r
+ ld a,(s&dev&.outbuf+o.mask) ;\r
+ and c ;\r
+ ld (s&dev&.outbuf+o.out_idx),a ;\r
\r
- inc a\r
- and (ix+o.mask)\r
- ld (ix+o.out_idx),a\r
- jr rxtxi0_lp0\r
+ jp rxtxi&dev&_lp1\r
\r
-?0ti_2:\r
+txi&dev&_empty:\r
res TIE,e ;disable tx-int\r
- out0 (stat0),e ; 5\r
+ out0 (stat&dev),e ; 5\r
\r
-rxtxi0_e:\r
+rxtxi&dev&_exit:\r
pop ix\r
ret\r
-\r
-\r
-;--------------------------------------------------------------\r
-; ASCI 1 Transmit/Receive interupt routines\r
+ endm\r
\r
dseg\r
-rxtxi1:\r
- in0 e,(stat1) ;receive flag set? 5\r
- jp p,txi1_0 ;\r
-\r
- in0 d,(rdr1) ;todo: break detection 9\r
- bit FE,e ;framing error?\r
- jr nz,??ri_1\r
-\r
- push ix\r
- ld ix,s1.inbuf ;\r
- ld hl,s1.inbuf ;\r
- ld c,(ix+o.in_idx) ;\r
- ld b,0\r
- add hl,bc\r
- ld (hl),d\r
-\r
- ld a,c ;\r
- inc a\r
- and (ix+o.mask)\r
- cp (ix+o.out_idx) ;\r
- jr z,$+5 ;skip if buffer is full\r
- ld (ix+o.in_idx),a\r
- pop ix\r
-??ri_1:\r
- in0 a,(cntla1) ; 1\r
- res EFR,a ;\r
- out0 (cntla1),a ; 1\r
- ret\r
-\r
-txi1_0:\r
- push ix\r
- ld ix,s1.outbuf ;\r
-\r
- ld a,(ix+o.out_idx) ;\r
- cp (ix+o.in_idx) ;if index.in == index.out\r
- jr z,??ti_2 ; buffer empty\r
+;--------------------------------------------------------------\r
+; ASCI 0 Transmit/Receive interupt routines\r
\r
- ld hl,s1.outbuf ;\r
- ld c,a\r
- ld b,0\r
- add hl,bc\r
- ld l,(hl)\r
- out0 (tdr1),l ; 7\r
-\r
- inc a\r
- and (ix+o.mask)\r
- ld (ix+o.out_idx),a\r
- jr ??ti_3\r
-??ti_2:\r
- res TIE,e ;disable tx-int\r
- out0 (stat1),e ; 5\r
-??ti_3:\r
- pop ix\r
- ret\r
+asci0_int:\r
+ asci_int 0\r
\r
+;--------------------------------------------------------------\r
+; ASCI 1 Transmit/Receive interupt routines\r
\r
+asci1_int:\r
+ asci_int 1\r
\r
end\r