envbvs@epb7.lbl.gov (Brian V. Smith) (01/25/91)
I have some in-line assembly code that I have used with Turbo Pascal
3.0, 4.0 and 5.0 to initialize the communication ports and do I/O with
them. This has worked fine on an 8086 and an 80286 (AT). However, I can't
get it to work at all with an 80386. I have tried it on two different
machines (a laptop by by DATAworld and a generic 386 desktop model).
Here is the code I have been using for several years now. The put() proc
seems to timeout as does the get() procedure.
Can anyone help me? Are there differences in the communications ports
from the 286 to the 386?
Thanks for any help.
{----------------------------------------------------------------------------}
{ get : Get one character from 'port' into 'chr' }
procedure get(port :integer; var chr : char);
begin
inline (
$C4/$BE/chr/ { les di,chr[bp] ; get ptr to the char }
$B4/$02/ { mov ah,2 ; get char }
$8B/$96/port/ { mov dx,port[bp] ; port }
$CD/$14/ { int 14h ; call int }
$26/$88/$05 { mov es:[di],al ; store char }
)
end; { get }
{----------------------------------------------------------------------------}
{ put : Print 'chr' to 'port' }
procedure put(port :integer; chr : char);
begin
inline (
$8A/$96/chr/ { mov dl,chr ; get char to print }
$8A/$C2/ { mov al,dl ; put char in al }
$B4/$01/ { mov ah,1 ; print char }
$8B/$96/port/ { mov dx,port[bp] ; port }
$CD/$14 { int 14h ; call int }
)
end; { put }
{----------------------------------------------------------------------------}
procedure clearaux(port : integer);
begin
inline (
$B4/$03/ {loop: mov ah,3 ; status check }
$8B/$96/port/{ mov dx,port[bp] ; port }
$CD/$14/ { int 14h ; call aux status }
$80/$e4/$01/{ and ah,1 ; check for data ready }
$74/$0A/ { jz exit ; no chars, return }
$B4/$02/ { mov ah,2 ; get char }
$8B/$96/port/{ mov dx,port[bp] ; port }
$CD/$14/ { int 14h ; get the char }
$EB/$E9/ { jmp loop ; check if another }
$90 {exit: nop ; that's all }
)
end; { clearaux }
{----------------------------------------------------------------------------}
procedure init9600(port :integer);
begin
inline (
$B4/$00/ { mov ah,0 ; function 0 }
$B0/$E2/ { mov al,0E2h ; 9600 baud, no parity, 1 stop bit, 7 data}
$8B/$96/port/{ mov dx,port[bp] ; port }
$CD/$14 { int 14h ; call int }
);
clearaux(port);
end; { init9600 }
--
Brian V. Smith (bvsmith@lbl.gov)
Lawrence Berkeley Laboratory
I don't speak for LBL; they don't pay me enough for that.