[Back to COMM SWAG index]  [Back to Main SWAG index]  [Original]

{
From: ELAD NACHMAN
Subj: High Speed COM I/O
---------------------------------------------------------------------------
 RL> Dose anyone know how a humble young TP programmer can access
 RL> modems at speeds of say 57,600 baud rates? I would love even
 RL> 14,400 routines. I had a set of simple I/O routines, but speeds
 RL> over 2400 term programs would lose characters. I would like to
 RL> write some doors for a BBS but can't break the 2400 limit.

You probably use a very simple way, which doesn't envolves capturing the
modem's Com port IRQ. That's why you use chars over faster transmitions.
To make sure the program will be fast, optimize it to assembler, or at least
use I/O Ports manipulations (If you odn't use it already).
A cut from a source I have here (Design for com1, if you need support for other
ports use a guide such as Helppc. If you want To write Doors for BBSes you
better use Fossil functions, For that either use Fsildoc.??? (It's in several
FTP sites) or Ralf Brown's Interrupt list):
}

const

{ 8250 IRQ Registers }

Data=$03f8; { Contains 8 bits for send/receive }

IER=$03f9; { Enables Serial Port when set to 1 }

LCR=$03fb; { Sets communication Parameters }

MCR=$03FC; { bits 1,2,4 are turned on to ready modems }

LSR=$3FD; { when bit 6 is on, it is safe to send a byte }

MDMMSR=$03FE; { initialized to $80 when starting }

ENBLRDY=$01; { initial value for port[IER] }

MDMMOD=$0b; { initial value for port[MCR] }

MDMCD=$80; { initial value for port[MDMMSR] }

INTCTLR=$21; { port for 8259 interrupt controller }

var

mybyte:byte;
vector:pointer;


procedure asyncint; interrupt;
begin
inline($FB); {STI}
mybyte:=port[dataport];
inline($FA); {CLI}

Port[$20]:=$20;

end;

procedure setmodem;
var
regs: registers;
parm : byte;

begin

parm:=3+4+0+$d0;
{8 databits,1 stopbit,no parity,9600 baud}
{databits: values 0,1,2,3 represent 5,6,7,8 databits
stopbits: value 4 is for 1 stopbits, 0 for none
parity: value 0 or $10 for none, $8 for odd, $18 for even
baud: $d0 for 9600, $b0 for 4800, $a0 for 2400, $80 for 1200, $60 for 600, $40
for 300 add all this values and get the correct byte parameter}

with regs do
begin
dx:=0; { comport -1 }
ah:=0;
al:=parm;
flags:=0;
intr($14,regs);
end;
end;

procedure EnablePorts;
var
b: byte;
begin
getintvec($0c,Vector); { $0c is for com1/com3 - IRQ 4 }
setintvec($0c,@AsyncInt);
b:=port[INTCTLR];
b:=b and $0ef;
port[INTCTLR]:=b;
b:=port[LCR];
b:=b and $7f;

port[lcr]:=b;
port[ier]:=enblrdy;
port[mcr]:=$08 or MDMMOD;
port[mdmmsr]:=mdmcd;
port[$20]:=$20;

{ when: port[MDMMSR] and $80 = $80 then there's carrier }

procedure sendchartoport(b: byte);
begin
while ( (port[lsr] and $20) <> $20 ) do
begin
end;
port[dataport]:=b;
end;

procedure sendstringtoport(s: string);
var
i:integer;
begin
for i:=1 to length(s) do
sendchartoport(ord(S[i]));
snedchartoport(13);
end;

procedure disableports;
var
b: byte;
begin
sendstringtoport('ATC0');
b:=port[intctlr];
b:=b or $10;
port[intctlr]:=b;
b:=port[lcr];
b:=b and $7f;
port[lcr]:=b;
port[ier]:=$0;

port[mcr]:=$0;
port[$20]:=$20;
setintvec($0c,vector);
end;

{ How the program itself should generally be }

begin

setmodem;
enableports;
send strings or chars
disableports;

end.

[Back to COMM SWAG index]  [Back to Main SWAG index]  [Original]