home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 18
/
CD_ASCQ_18_111294_W.iso
/
dos
/
prg
/
pas
/
pcl4p42
/
amodem.pas
next >
Wrap
Pascal/Delphi Source File
|
1994-08-23
|
10KB
|
332 lines
(*********************************************)
(* *)
(* --- ASCII Protocol --- *)
(* *)
(* This program is donated to the Public *)
(* Domain by MarshallSoft Computing, Inc. *)
(* It is provided as an example of the use *)
(* of the Personal Communications Library. *)
(* *)
(*********************************************)
{ $DEFINE DEBUG}
{$I DEFINES.PAS}
unit amodem;
interface
uses term_io,PCL4P,crt,xypacket;
(* reference 'xypacket' to get BufferType definition *)
function TxAscii(
Port : Integer; (* COM port [0..3] *)
Var Filename : String12; (* filename buffer *)
Var Buffer : BufferType; (* 1024 buffer *)
CharPace : Integer; (* millisecond delay between characters *)
TermChar : Byte; (* termination character ($00 => none) *)
TimeOut : Integer; (* delay after which assume sender is dome *)
EchoFlag : Boolean) (* local echo flag *)
: Boolean;
function RxAscii(
Port : Integer; (* COM port [0..3] *)
Var Filename : String12; (* filename buffer *)
Var Buffer : BufferType; (* 1024 buffer *)
RxBufSize: Integer; (* size of RX receive buffer *)
TermChar : Byte; (* termination character ($00 => none) *)
TimeOut : Integer; (* delay after which assume sender is dome *)
EchoFlag : Boolean) (* local echo flag *)
: Boolean;
implementation
Const
XON = $11;
XOFF = $13;
CAN = $18;
ONE_SECOND = 18;
Var (* globals *)
LastXchar : Byte; (* last XON or XOFF *)
LastTime : LongInt; (* last time character was received *)
DataCount : Integer; (* # bytes in Buffer *)
procedure ReportBytes(Bytes : LongInt);
var
Message : String[50];
begin
Str(Bytes,Message);
Message := 'Ascii: ' + Message + ' bytes.';
WriteMsg(Message,1);
end;
function UserQuits(Port : Integer) : Boolean;
var
UserChar : Char;
Code : Integer;
begin
(* does user want to quit ? *)
UserQuits := FALSE;
if KeyPressed then
begin
UserChar := ReadKey;
if Ord(UserChar) = CAN then
begin
TxCAN(Port);
Code := SioPutc(Port,chr($03));
WriteMsg('Ascii: Aborted by USER...',1);
UserQuits := TRUE
end
else Code := SioPutc(Port,UserChar);
end
end;
function CheckForXOFF(Port:Integer) : Boolean;
Var
Code : Integer;
begin
(* check for incoming XOFF *)
Code := GetChar(Port,0);
if Code = XOFF then
begin
(* received a XOFF *)
WriteMsg('Ascii: XOFF received',1);
LastXchar := XOFF;
CheckForXOFF := TRUE;
end
else CheckForXOFF := FALSE
end;
function WaitForXON(Port:Integer;TimeOut:Integer) : Boolean;
Var
Code : Integer;
ExitFlag : Boolean;
begin
LastTime := SioTimer;
ExitFlag := FALSE;
repeat
Code := GetChar(Port,ONE_SECOND);
if Code = -1 then
begin
(* nothing there *)
if SioTimer-LastTime > 60*ONE_SECOND then
begin
(* we have timed out *)
WriteMsg('Ascii: Timed out waiting for XON',1);
WaitForXON := FALSE;
ExitFlag := TRUE;
end
end
else
(* character received *)
begin
if Code = XON then
begin
(* received character was XON *)
WriteMsg('Ascii: XON received',1);
LastXchar := XON;
WaitForXON := TRUE;
ExitFlag := TRUE;
end
else
begin
(* received character wasn't a XON *)
WriteMsg('Ascii: Received character not XON',1);
end
end
until ExitFlag;
end;
procedure CheckQueue(Port,LoMark,HiMark:Integer);
var
QueueSize : Integer;
begin
QueueSize := SioRxQue(Port);
if (QueueSize>HiMark) and (LastXchar=XON) then
begin
PutChar(Port,XOFF);
LastXchar := XOFF;
WriteMsg('Ascii: Sending XOFF',1)
end;
if (QueueSize<LoMark) and (LastXchar=XOFF) then
begin
PutChar(Port,XON);
LastXchar := XON;
WriteMsg('Ascii: Sending XON',1)
end
end;
function TxAscii(
Port : Integer; (* COM port [0..3] *)
Var Filename : String12; (* filename buffer *)
Var Buffer : BufferType; (* 1024 buffer *)
CharPace : Integer; (* millisecond delay between characters *)
TermChar : Byte; (* termination character ($00 => none) *)
TimeOut : Integer; (* delay after which assume sender is done *)
EchoFlag : Boolean) (* local echo flag *)
: Boolean;
Label 999;
Var
i : Integer;
Code : Integer;
Handle : File;
c : Char;
TheByte : Byte;
BytesRead : Integer;
ExitFlag : Boolean;
TxChars : LongInt;
Message : String[50];
begin
{$I-}
(* open the file *)
Assign(Handle,Filename);
Reset(Handle,1);
{$I+}
if IOResult <> 0 then
begin
Message := 'Ascii: Cannot open ' + Filename;
WriteMsg(Message,1);
TxAscii := FALSE;
goto 999;
end;
(* start ascii send *)
WriteMsg('Ascii: Starting SEND',1);
LastXchar := XON;
ExitFlag := FALSE;
TxChars := 0;
(* flush keyboard & serial port *)
while KeyPressed do c := ReadKey;
Code := SioRxFlush(Port);
(* send ascii file *)
repeat
(* does user want to quit ? *)
if UserQuits(Port) then goto 999;
(* read next buffer from disk *)
BlockRead(Handle,Buffer,1024,BytesRead);
(* send 1 character at a time *)
for i := 0 to BytesRead-1 do
begin
(* send character & delay *)
TheByte := Buffer[i];
PutChar(Port,TheByte);
if EchoFlag then write(chr(TheByte));
if CharPace > 0 then Delay(CharPace);
if TheByte = $0d then Delay(250);
TxChars := TxChars + 1;
if (TxChars mod 100) = 0 then ReportBytes(TxChars);
(* check for incoming XOFF *)
if CheckForXOFF(Port) then
begin
(* received XOFF, so wait for XON *)
if not WaitForXON(Port,TimeOut) then ExitFlag := TRUE;
end
end;
until ExitFlag or (BytesRead = 0);
(* send termination character, if any *)
if TermChar <> $00 then
begin
PutChar(Port,TermChar);
WriteMsg('Ascii: Termination character sent',1);
end;
close(Handle);
999:end; (* TxAscii *)
function RxAscii(
Port : Integer; (* COM port [0..3] *)
Var Filename : String12; (* filename buffer *)
Var Buffer : BufferType; (* 1024 buffer *)
RxBufSize: Integer; (* receive buffer size *)
TermChar : Byte; (* termination character ($00 => none) *)
TimeOut : Integer; (* delay after which assume sender is done *)
EchoFlag : Boolean) (* local echo flag *)
: Boolean;
Label 999;
Var
c : Char;
i, k : Integer;
Handle : File; (* file Handle *)
Code : Integer; (* return code *)
Flag : Boolean;
Message : String40;
Temp : String40;
Result : Integer;
LoMark : Integer; (* receive buffer low water mark *)
HiMark : Integer; (* receive buffer high water mark *)
ExitFlag : Boolean;
RxChars : LongInt;
(* begin *)
begin
{$I-}
(* open the file for write *)
Assign(Handle,Filename);
Rewrite(Handle,1);
{$I+}
if IOResult <> 0 then
begin
Message := 'Ascii: Cannot open ' + Filename;
WriteMsg(Message,1);
RxAscii := FALSE;
goto 999;
end;
(* flush keyboard & serial port *)
while KeyPressed do c := ReadKey;
Code := SioRxFlush(Port);
(* receive text *)
WriteMsg('Ascii: Starting RECEIVE',1);
LoMark := RxBufSize div 8;
HiMark := 5 * LoMark;
LastXchar := XON;
DataCount := 0;
RxChars := 0;
ExitFlag := FALSE;
repeat
(* does user want to quit ? *)
if UserQuits(Port) then goto 999;
(* check receive queue size *)
CheckQueue(Port,LoMark,HiMark);
(* get next character *)
if RxChars = 0 then
begin
(* wait 1 minute for 1st character *)
Code := GetChar(Port,60*ONE_SECOND);
LastTime := SioTimer
end
else Code := GetChar(Port,TimeOut*ONE_SECOND);
(* did we timeout ? *)
if Code = -1 then
begin
(* we have timed out ! *)
ExitFlag := TRUE;
WriteMsg('Ascii: Timeout.',1);
end;
(* termination character ? *)
if (Code <> -1) and (TermChar<>$00) and (Code=TermChar) then
begin
(* received termination character *)
ExitFlag := TRUE;
WriteMsg('Ascii: Termination character received',1);
end
else
begin
RxChars := RxChars + 1;
if EchoFlag then write(chr(Code));
if (RxChars mod 100) = 0 then ReportBytes(RxChars);
(* put character in buffer *)
Buffer[DataCount] := Code;
DataCount := DataCount + 1;
if DataCount = 1024 then
begin
BlockWrite(Handle,Buffer,DataCount);
DataCount := 0;
end
end
until ExitFlag;
(* flush the data buffer *)
if DataCount > 0 then BlockWrite(Handle,Buffer,DataCount);
(* close the output file *)
close(Handle);
999:end; (* end - RxAscii *)
end.