[comp.sys.ibm.pc] using com1: from assembler

hjg@bunker.UUCP (04/15/87)

HELP!!

	Ok, here is my problem:

	From within a dBase II/86 program, call an assembler routine that can
dial the modem.

	Easy you say.  Just create an assembly routine, org'ed at de00:0000,
and poke it into memory (or LOAD the file into memory if you can transform the
executable into Intel HEX86 format - but I can't find a utility to do that from
a Microsoft MASM output file).  Then use the dBase CALL instruction, passing
the number to dial as a memory variable.

	In principle, this should work fine. BUT!!! (isn't there always a but?)

	I can't seem to get the assembler routine to talk to the modem.  So
here's my question.  Given the following assembler routine (designed to be
called from a C mainline - for testing), why doesn't the thing work?  What it
_does_ do is dive into a black hole, the third time INT 14h gets executed.
(I marked the spot in the loop).

	title	dial

	.287
_text	segment	byte public 'code'
_text	ends
	assume	cs: _text

_text	segment
	public	_dial

_dial	proc	near

	push	bp		;c routine linkage
	mov	bp,sp
	push	ax		;save all regs used, just in case
	push	bx
	push	cx
	push	dx
	push	ds

	mov	ah, 0		;set com1: port to 300 baud, 8 data bits
	mov	al, 43h		;no parity, 1 stop bit
	mov	dx, 0
	int	14h

	mov	bx, offset preamble	;pointer to "ATDT"
	mov	cx, 4			;guess what kind of modem I'm using!

top1:	mov	dx, seg preamble	;segment of "ATDT"
	mov	ds, dx			;this is to get ds:bx to really point
	mov	dx, 0			;to the character string
	mov	al, [bx]		;for this move
	pop	ds			;restore ds to what it 'should be'
	push	ds			;query - is this necessary?
	mov	ah, 1
	int	14h			;output the character in al - here is
					;where it blows up - second time through
					;the loop
	inc	bx
	loop	top1			;next character

	mov	bx, [bp+4]		;now, output the phone number
	push	bx
	call	buflen			;get its length
	add	sp, 2

	mov	bx, [bp+4]		;and do the same thing as above
	mov	cx, ax			;only no need to mess with ds,
top2:	mov	al, [bx]		;because ds is already correctly
	mov	ah, 1			;set to the dBase data segment, where
	int	14h			;the phone number is located
	inc	bx
	loop	top2

	mov	al, dh			;ok - now output a '\r' to tell the
	mov	ah, 1			;modem that input is done
	int	14h

	pop	ds			;restore all regs
	pop	dx
	pop	cx
	pop	bx
	pop	ax
	mov	sp, bp
	pop	bp
	ret				;and return

_dial	endp

preamble	db	"ATDT"

buflen	proc	near			;routine to calculate length of
					;null terminated string pointed to
					;by stack argument
					;note - originally a C routine, hence
					;the [bp op #] notation

	push	bp
	mov	bp, sp
	sub	sp, 2
	mov	word ptr [bp-2], 0
$wc11:
	mov	bx, [bp+4]
	cmp	byte ptr [bx], 0
	je	$wb12
	inc	word ptr [bp+4]
	inc	word ptr [bp-2]
	jmp	short $wc11
$wb12:
	mov	ax, [bp-2]
	mov	sp, bp
	pop	bp
	ret				;answer left in ax register on return

buflen	endp

_text	ends
	end


	Ok - sorry for the length, but I had to show what I've got here.  I
realize that for real communications, you can't use the BIOS reliably, but all
I want to do is dial the phone, so that _shouldn't_ be a real problem.

	I'd appreciate any suggestions, corrections, assistance, etc. that
you can provide.

					Harry Gross
					..!bunker!hjg

P.S. If anyone wants to use that lousy chunk of code above, feel free.
Especially if you can tell me why it isn't working, and can show me a fix!

					hjg