home *** CD-ROM | disk | FTP | other *** search
- (*********************************************)
- (* *)
- (* --- 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 : String20; (* 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 : String20; (* 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 : String20; (* 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 : String20; (* 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.