home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 13 / CDA13.ISO / cdactual / demobin / share / program / Pascal / ANSIDRVR.ZIP / CONCOMIO.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1992-05-03  |  8.3 KB  |  428 lines

  1. {
  2. Turbo Pascal ANSI Drivers
  3. Version 1.12
  4. Copyright (c) 1990 by Not So Serious Software
  5.  
  6. Original concept by Ian Silver
  7. Design and implementation by Kevin Dean
  8.  
  9. Kevin Dean
  10. Fairview Mall P.O. Box 55074
  11. 1800 Sheppard Avenue East
  12. Willowdale, Ontario
  13. CANADA    M2J 5B9
  14. CompuServe ID: 76336,3114
  15. }
  16.  
  17.  
  18. {$I-,F-,S-,R-}
  19. unit CONCOMIO;
  20.  
  21.  
  22. interface
  23.  
  24.  
  25. uses
  26.   DOS,
  27.   ANSI, ANSICON, ANSICOM;
  28.  
  29.  
  30. type
  31.   ErrorProc =            { Communications error handling procedure }
  32.     ANSICOM.ErrorProc;
  33.  
  34.  
  35. const
  36.   Init =            { Initialize modem when setting parameters }
  37.     ANSICOM.Init;
  38.   NoInit =            { Assume modem already initialized }
  39.     ANSICOM.NoInit;
  40.  
  41.   SyncTransmit =        { Synchronize transmission with output function }
  42.     ANSICOM.SyncTransmit;
  43.   AsyncTransmit =        { Return from output function immediately }
  44.     ANSICOM.AsyncTransmit;
  45.  
  46.   NoCommError =            { No communications error }
  47.     ANSICOM.NoCommError;
  48.   ReceiveOverrun =        { Received data overrun }
  49.     ANSICOM.ReceiveOverrun;
  50.   TransmitOverrun =        { Output buffer overrun }
  51.     ANSICOM.TransmitOverrun;
  52.   ParityError =            { Data parity error }
  53.     ANSICOM.ParityError;
  54.   FramingError =        { Data framing error }
  55.     ANSICOM.FramingError;
  56.   BreakDetect =            { Break signal detected }
  57.     ANSICOM.BreakDetect;
  58.   CommTimeOut =            { Communications time-out (off-line) }
  59.     ANSICOM.CommTimeOut;
  60.   NoCarrier =            { No carrier }
  61.     ANSICOM.NoCarrier;
  62.   CtrlBreak =            { Ctrl-Break key pressed }
  63.     ANSICOM.CtrlBreak;
  64.   NotOnline =            { Communications routines not online }
  65.     ANSICOM.NotOnline;
  66.  
  67.   NoneActive =            { No I/O driver active }
  68.     $0000;
  69.   ConsoleActive =        { Console I/O driver active }
  70.     $0001;
  71.   CommActive =            { Communications I/O driver active }
  72.     $0002;
  73.   BothActive =            { Both I/O drivers active }
  74.     ConsoleActive or CommActive;
  75.  
  76.   ActiveInput : word =        { Active input drivers }
  77.     BothActive;
  78.   ActiveOutput : word =        { Active output drivers }
  79.     BothActive;
  80.  
  81.  
  82. function InitCOM(COMPort : byte; Baud : integer; Bits : byte; Parity : char;
  83.  Stop : byte; Init : boolean; Sync : boolean; Error : pointer) : integer;
  84. function SetBaud(Baud : integer; Bits : byte; Parity : char; Stop : byte) : integer;
  85. procedure Disconnect;
  86. procedure ReleaseCOM;
  87. procedure AssignCONCOM(var F : Text);
  88. function KeyPressed : boolean;
  89. function ReadKey : char;
  90.  
  91.  
  92. implementation
  93.  
  94.  
  95. {***}
  96. { Initialize communications port and install interrupt }
  97. function InitCOM(COMPort : byte; Baud : integer; Bits : byte; Parity : char;
  98.  Stop : byte; Init : boolean; Sync : boolean; Error : pointer) : integer;
  99.  
  100. begin
  101. InitCOM := ANSICOM.InitCOM(COMPort, Baud, Bits, Parity, Stop, Init, Sync, Error)
  102. end;
  103.  
  104.  
  105. {***}
  106. { Change baud rate and data format dynamically }
  107. function SetBaud(Baud : integer; Bits : byte; Parity : char; Stop : byte) : integer;
  108.  
  109. begin
  110. SetBaud := ANSICOM.SetBaud(Baud, Bits, Parity, Stop)
  111. end;
  112.  
  113.  
  114. {***}
  115. { Disconnect modem }
  116. procedure Disconnect;
  117.  
  118. begin
  119. ANSICOM.Disconnect
  120. end;
  121.  
  122.  
  123. {***}
  124. { Release communications port }
  125. procedure ReleaseCOM;
  126.  
  127. begin
  128. ANSICOM.ReleaseCOM
  129. end;
  130.  
  131.  
  132. {$F+}
  133.  
  134. {***}
  135. { Handle line-oriented console or modem input }
  136. function CONCOMIn(var F : Text) : integer;
  137.  
  138. var
  139.   NumRead : integer;    { Number of characters read }
  140.   Done : boolean;    { True if end of line }
  141.   PendingKey : char;    { Key waiting on input stream }
  142.  
  143. begin
  144. case ActiveInput of
  145.   ConsoleActive:
  146.     CONCOMIn := ConsoleIn(F);
  147.  
  148.   CommActive:
  149.     CONCOMIn := ModemIn(F);
  150.  
  151.   BothActive:
  152.     begin
  153.     NumRead := 0;
  154.  
  155.     Done := false;
  156.     while not Done do
  157.       begin
  158.       { Wait for input from console or modem }
  159.       while not KeyPressed do
  160.     inline
  161.     (
  162.     $CD/$28        { INT    28h }
  163.     );
  164.  
  165.       { Give priority to console }
  166.       if ANSICON.KeyPressed then
  167.     PendingKey := ANSICON.ReadKey
  168.       else
  169.     PendingKey := ANSICOM.ReadKey;
  170.  
  171.       case PendingKey of
  172.     NUL:
  173.       { Ignore extended keys }
  174.       begin
  175.       { Wait for input from console or modem }
  176.       while not KeyPressed do
  177.         inline
  178.         (
  179.         $CD/$28        { INT    28h }
  180.         );
  181.  
  182.       { Give priority to console }
  183.       if ANSICON.KeyPressed then
  184.         PendingKey := ANSICON.ReadKey
  185.       else
  186.         PendingKey := ANSICOM.ReadKey
  187.       end;
  188.  
  189.     BS:
  190.       { Erase last character if possible }
  191.       if (NumRead <> 0) and (WhereX <> 1) then
  192.         begin
  193.         Write(BS, ' ', BS);
  194.         Dec(NumRead)
  195.         end;
  196.  
  197.         CR, LF:
  198.       { End of line }
  199.       begin
  200.       Done := true;
  201.       TextRec(F).BufPtr^[NumRead] := CR;
  202.       Inc(NumRead);
  203.       TextRec(F).BufPtr^[NumRead] := LF;
  204.       Inc(NumRead);
  205.       WriteLn
  206.       end;
  207.  
  208.     EOF_:
  209.       { End of file }
  210.       if CheckEOF then
  211.         begin
  212.         Done := true;
  213.         TextRec(F).BufPtr^[NumRead] := EOF_;
  214.         Inc(NumRead)
  215.         end;
  216.  
  217.     ESC:
  218.       { Clear current input }
  219.       begin
  220.       Write('\', LF);
  221.       if MaxX = 0 then
  222.         GotoXY(WhereX - NumRead - 1 + MaxX, WhereY)
  223.       else
  224.         GotoXY((WhereX - NumRead + MaxX - 2) mod MaxX + 1, WhereY);
  225.       NumRead := 0
  226.       end;
  227.  
  228.     else
  229.       { Display the character }
  230.       with TextRec(F) do
  231.         if NumRead < BufSize - 2 then
  232.           begin
  233.           BufPtr^[NumRead] := PendingKey;
  234.           Write(PendingKey);
  235.           Inc(NumRead)
  236.           end
  237.     end
  238.       end;
  239.  
  240.     { Save buffer pointers }
  241.     with TextRec(F) do
  242.       begin
  243.       BufPos := 0;
  244.       BufEnd := NumRead
  245.       end;
  246.  
  247.     CONCOMIn := 0
  248.     end;
  249.  
  250.   else
  251.     { Device read fault }
  252.     CONCOMIn := 161
  253.   end
  254. end;
  255.  
  256.  
  257. {***}
  258. { Display text on console and modem }
  259. function CONCOMOut(var F : Text) : integer;
  260.  
  261. var
  262.   BufPos : word;    { Output buffer position }
  263.   CONResult : integer;    { Result of console output }
  264.   COMResult : integer;    { Result of modem output }
  265.  
  266. begin
  267. BufPos := TextRec(F).BufPos;
  268. case ActiveOutput of
  269.   ConsoleActive:
  270.     CONCOMOut := ConsoleOut(F);
  271.  
  272.   CommActive:
  273.     CONCOMOut := ModemOut(F);
  274.  
  275.   BothActive:
  276.     begin
  277.     BufPos := TextRec(F).BufPos;
  278.     CONResult := ConsoleOut(F);
  279.     TextRec(F).BufPos := BufPos;
  280.     COMResult := ModemOut(F);
  281.     if CONResult = 0 then
  282.       CONCOMOut := COMResult
  283.     else
  284.       CONCOMOut := CONResult
  285.     end;
  286.  
  287.   else
  288.     { Device write fault }
  289.     CONCOMOut := 160
  290.   end
  291. end;
  292.  
  293.  
  294. {***}
  295. { Flush console and modem buffers }
  296. function CONCOMFlush(var F : Text) : integer;
  297.  
  298. begin
  299. with TextRec(F) do
  300.   if Mode = fmInput then
  301.     { Ignore flush request }
  302.     CONCOMFlush := 0
  303.   else
  304.     { Chain to F's default output routine }
  305.     CONCOMFlush := IOFunc(InOutFunc)(F)
  306. end;
  307.  
  308.  
  309. {***}
  310. { Open console and modem for input or output }
  311. function CONCOMOpen(var F : Text) : integer;
  312.  
  313. begin
  314. with TextRec(F) do
  315.   if Mode = fmInput then
  316.     IOFunctions(UserData).NextInOut := @CONCOMIn
  317.   else
  318.     IOFunctions(UserData).NextInOut := @CONCOMOut;
  319.  
  320. CONCOMOpen := 0
  321. end;
  322.  
  323.  
  324. {***}
  325. { Close console and modem (do nothing) }
  326. function CONCOMClose(var F : Text) : integer;
  327.  
  328. begin
  329. CONCOMClose := 0
  330. end;
  331.  
  332. {$F-}
  333.  
  334.  
  335. {***}
  336. { Assign a file to the console and the communications port }
  337. procedure AssignCONCOM(var F : Text);
  338.  
  339. var
  340.   IOChain : IOFunctions;    { Console I/O function chain }
  341.  
  342. begin
  343. with IOChain do
  344.   begin
  345.   NextOpen := @CONCOMOpen;
  346.   NextInOut := nil;
  347.   NextFlush := @CONCOMFlush;
  348.   NextClose := @CONCOMClose
  349.   end;
  350.  
  351. AssignANSI(F, IOChain)
  352. end;
  353.  
  354.  
  355. {***}
  356. { Return true if character in either input buffer }
  357. function KeyPressed : boolean;
  358.  
  359. begin
  360. case ActiveInput of
  361.   ConsoleActive:
  362.     KeyPressed := ANSICON.KeyPressed;
  363.  
  364.   CommActive:
  365.     KeyPressed := ANSICOM.KeyPressed;
  366.  
  367.   BothActive:
  368.     KeyPressed := ANSICON.KeyPressed or ANSICOM.KeyPressed;
  369.  
  370.   else
  371.     KeyPressed := false
  372.   end
  373. end;
  374.  
  375.  
  376. {***}
  377. { Read character from input buffer }
  378. function ReadKey : char;
  379.  
  380. var
  381.   Regs : Registers;    { MS-DOS registers }
  382.  
  383. begin
  384. case ActiveInput of
  385.   ConsoleActive:
  386.     ReadKey := ANSICON.ReadKey;
  387.  
  388.   CommActive:
  389.     ReadKey := ANSICOM.ReadKey;
  390.  
  391.   BothActive:
  392.     begin
  393.     { Wait for input from console or modem }
  394.     while not KeyPressed do
  395.       inline
  396.       (
  397.       $CD/$28        { INT    28h }
  398.       );
  399.  
  400.     { Give priority to console }
  401.     if ANSICON.KeyPressed then
  402.       ReadKey := ANSICON.ReadKey
  403.     else
  404.       ReadKey := ANSICOM.ReadKey
  405.     end;
  406.  
  407.   else
  408.     ReadKey := #0
  409.   end
  410. end;
  411.  
  412.  
  413. {***}
  414. begin
  415. CheckBreak := false;
  416.  
  417. Close(Input);
  418. Close(Output);
  419.  
  420. AssignCONCOM(ANSIFile);
  421. Rewrite(ANSIFile);
  422.  
  423. AssignCONCOM(Input);
  424. Reset(Input);
  425.  
  426. AssignCONCOM(Output);
  427. Rewrite(Output)
  428. end.