[Back to COMM SWAG index] [Back to Main SWAG index] [Original]
{
I've read some questions latelly with questions about how to use a com-port in
pascal. I've written a couple of procedures for doing this. The following
routines can be improved, for example they can be satt to run on interrupts
and a few other thing, but... I'm not supposed to do all the job for you, am
I??
}
USES CRT,DOS;
CONST
Com1 : WORD = 1;
Com2 : WORD = 2;
type
port = object
port: byte;
base: word;
baud: longint;
inter: byte;
function init(comport: word; baudrate: longint): boolean;
function sendchar(c: char): boolean;
function getchar(var c: char): boolean;
end;
function port.init(comport: word; baudrate: longint): boolean;
var
tmp: word;
bas: word;
test: byte;
begin
if odd(comport) then inter:=$C else inter:=$B;
{This is for later use with interrupts...}
init:=false;
if comport<5 then
begin
asm {get port base address}
mov bx,40h
mov es,bx
mov bx,comport
dec bx
shl bx,1
mov ax,es:[bx]
mov bas,ax
end;
if bas=0 then
begin
writeln('Could''n find selected com-port!');
exit;
end;
end
else
begin
case comport of {don't know where to find ps/2 etd
bios, standard base is supposed}
5: bas:=$4220;
6: bas:=$4228;
7: bas:=$5220;
8: bas:=$5228;
end;
end;
base:=bas;
tmp:=115200 div baudrate; {baudrate divisor}
asm {lower DTS and DSR}
mov dx,bas
add dx,4
xor al,al
out dx,al
end;
delay(50);
asm {raise DTS and DSR}
mov dx,bas
add dx,4
mov al,11b
out dx,al
end;
asm {set baudrate and N,8,1}
mov dx,bas
add dx,3
mov al,10000011b {N,8,1, set baudrate divisor}
out dx,al
mov ax,tmp {baudrate divisor}
mov dx,bas
out dx,al
inc dx
mov al,ah
out dx,al
mov dx,bas
add dx,3
mov al,00000011b {N,8,1}
out dx,al
end;
asm {interrupt enable, no interrupts enabled --> gain time}
mov dx,bas
inc dx
xor al,al
out dx,al
end;
asm {raise DTS and DSR}
mov dx,bas
add dx,4
mov al,11b
out dx,al
in al,dx
and al,11b
mov test,al
end;
if test<>3 then
begin
writeln('Some error....');
exit;
end;
init:=true;
end;
function port.sendchar(c: char): boolean;
var
bas: word;
cts: byte;
label
no_send;
begin
cts:=0;
bas:=base;
asm
mov dx,bas
add dx,5
in al,dx
and al,00100000b {test CTS (Clear To Send status)}
jz no_send
mov cts,1
mov dx,bas
mov al,c
out dx,al
no_send:
end;
if cts=0 then sendchar:=false else sendchar:=true;
end;
function port.getchar(var c: char): boolean;
var
bas: word;
rts: byte;
c2: char;
label
no_data;
begin
rts:=0;
bas:=base;
asm
mov dx,bas
add dx,5
in al,dx
and al,00000001b {test for data ready}
jz no_data
mov rts,1
mov dx,bas
in al,dx
no_data:
mov c2,al
end;
c:=c2;
if rts=0 then getchar:=false else getchar:=true;
end;
var
modem: port;
s: string;
a: byte;
c : Char;
begin
if not modem.init(com2,38400) then
begin
writeln('Couldn''t initialize modem...');
halt;
end;
s:='atz'+#13;
for a:=1 to length(s) do modem.sendchar(s[a]);
end.
If you think these routines are just great and you decide to use them as they
are I wouldn't mind if you gave me a credit.
[Back to COMM SWAG index] [Back to Main SWAG index] [Original]