
	page	66, 120
	title 	DBASE III+ Com Port Handler V1.0
	subttl	By Carl R. Weber

IF1
	%out	Pass 1
ENDIF
IF2
	%out	Pass 2
ENDIF

;
;====================================
;
;	Get a string of characters from the com port
;	terminated by a Carriage Return or the end of string
;	The number of characters received is the length of the
;	Dbase III+ string passed.
;	A single character may be obtained if this routine is called
;	with a string whose length is one.
;
;	return ffh if no carrier 
;	return feh if activity timeout
;	else characters received with parity stripped
;
;	By C.R. Weber
;	6256 Golden Coin Court
;	Columbia, MD 21045
;
;	8/8/86
;
;======================================

;	default comm port to use

comline		equ	0000h		;com 1


;	time out defaults

carr_time	equ	30		;time to wait for carrier
					;20 seconds now
no_act_time	equ	600		;no activity timeout
					;7 min

rs232_port	equ	0000h		;offset to port addresses at segment 40h



cseg	segment
	assume cs:cseg


inport 	proc	far			;call this with dbase

	push	si			;save registers
	push	dx
	push	cx
	push 	bx
	push	ax

	mov	dx,	comline		;set up for com line

	cmp	bx,	0		;check for valid string passed
	jz	eloop			;no data if zero

	mov	cs:beg_buf,	bx	;save begining of buffer
					;in cs relative storage

start	label	near

	cmp	byte ptr [bx],0		;end of original dbase string?
	jz	short	eloop		;yes then return


nextch	label	near

	call	short	chin		;get character from modem
	or	al, 	al		;was it a timeout or loss of carrier
	js	opps			;yes

	cmp	al,	13		;CR?
	jnz	short	nocr


strend	label	near

	mov	byte ptr [bx],	0	;Yes then terminate the string
	jmp	short	eloop		;and return to dbase


nocr	label	near

	cmp	al, 	8		;back space?
	jnz	short	nobs
	call	short	erase		;erase the character
	jmp	short	nextch		;get next character


nobs	label	near

	cmp	al, 	7fh		;DELETE?
	jnz	short	svchr
	call	short	erase		;erase the character
	jmp	short	nextch		;get next char


svchr	label	near

	mov	byte ptr [bx],	al	;save character
	inc	bx			;point to next location
	call	short	chout		;echo it back
	jmp	short	start


opps	label	near

	mov	bx,	cs:beg_buf	;get begining of str
	mov	byte ptr [bx], al	;save error code as first character
	inc	bx			;so dbase can find it
	jmp	short	strend		;and ret to dbase


eloop	label	near

	pop	ax			;restore registers
	pop	bx
	pop	cx
	pop	dx
	pop	si
	ret				;far return to dbase


inport	endp

;	temp storage for local vars

beg_buf	dw	0			;beg of dbase string buffer
t_cnt	dw	0			;inactivity timeout count
car_cnt	dw	0			;no carrier timeount count


;======================================
;	get character from com port
;
;	return ffh if no carrier 
;	return feh if activity timeout
;	else character received with parity stripped
;======================================


chin	proc	near

	push	ds
	mov	ax,	40h		;set up data segment for RS232 port
	mov	ds,	ax		;address

	mov	ax,	no_act_time	;sec to wait for no activity
	mov	cs:t_cnt,	ax
	mov	ax,	carr_time	;sec to wait for carrier detect
	mov	cs:car_cnt,	ax

	mov	si,	comline		;get comline index
	shl	si,	1		;make word offset
	mov	dx,	rs232_port[si]	;get address of port

	add	dx,	4		;control reg
	mov	al,	1
	out	dx,	al		;set DTR

	add	dx,	2		;modem status reg


carr_loop	label	near

	mov	ah,	80h		;Data carrier detect
	call	wait_st			;wait for DCD
	jz	car_ok			;timed out no carrier

	mov	ax,	cs:car_cnt
	dec	ax
	mov	cs:car_cnt,	ax
	jnz	carr_loop
	pop	ds
	mov	al,	0ffh		;no carrier
	ret


car_ok	label	near

	dec	dx			;line status register


ch_loop	label	near

	mov	ah,	1		;recv char?
	call	wait_st			;wait for character
	jz	ch_rdy			;got one ?

	mov	ax,	cs:t_cnt	;no - then check count
	dec	ax
	mov	cs:t_cnt,	ax
	jnz	ch_loop			;more time
	pop	ds			;else return error as
	mov	al,	0feh		;just timeout
	ret


ch_rdy	label	near

	mov	dx,	rs232_port[si]	;get address of port
	in	al,	dx		;get char
	and	al,	07fh		;strip parity anyway
	pop	ds
	ret


chin	endp


;======================================
;	send out character in al
;======================================


chout	proc	near

	push	dx
	mov	ah,	1
	mov	dx,	comline
	int	14h
	pop	dx
	ret

chout	endp


;======================================
;	erase prev character typed
;======================================


erase	proc	near

	push	ax
	cmp	bx,	cs:beg_buf	;make sure that there are characters
	jle	short	era1		;first character
	dec	bx			;move pointer back
	mov	al,	8		;delete char on user's
	call	short	chout		;screen
	mov	al,	' '		;with space
	call	short	chout
	mov	al,	8		;
	call	short	chout


era1	label	near

	pop	ax
	ret
erase	endp


;======================================
;	wait for a status in port [dx] and bit pattern in ah
;
;======================================


wait_st	proc	near

	push	cx
	xor	cx,	cx		;set up loop count


w1	label	near

	in	al,	dx		;get stat
	and	al,	ah		;strip unwanted bits
	cmp	al,	ah		;check for all set
	je	w_end			;yes?
	loop	w1			;loop again

	or	ah,	ah		;zero flag off - error


w_end	label	near

	pop	cx
	ret

wait_st	endp


cseg	ends
	end
