home *** CD-ROM | disk | FTP | other *** search
/ CD/PC Actual 13 / CDA13.ISO / cdactual / demobin / share / program / Pascal / ANSIDRVR.ZIP / ANSIDRVR.DOC < prev    next >
Encoding:
Text File  |  1992-05-03  |  41.2 KB  |  993 lines

  1. Turbo Pascal ANSI Drivers
  2. Version 1.12
  3. Copyright (c) 1990 by Not So Serious Software
  4.  
  5. Original concept by Ian Silver
  6. Design and implementation by Kevin Dean
  7.  
  8. Turbo Pascal is a registered trademark of Borland International Inc.
  9. Coke is a registered trademark of Coca-Cola Ltd.
  10.  
  11.  
  12.  
  13.  
  14.                                  Introduction
  15.                             "What you're getting."
  16.  
  17. ------------------------------------------------------------------------------
  18. December 1989 (exam time)
  19.  
  20. Ian  : "Kev, is there any way to get the Turbo Pascal CRT unit to go to the 
  21. modem?"
  22.  
  23. Kevin: "No.  The CRT unit goes straight to the video hardware.  What 
  24. are you trying to do?"
  25.  
  26. Ian  : "I'm writing a game as a door for a BBS and I need video control. What 
  27. I really need is a good driver that will talk nicely to a COM port - unlike 
  28. DOS."
  29.  
  30. Kevin: "I wish you wouldn't keep doing this to me, Silver.  You always come up 
  31. with interesting ideas for me to implement when I don't have the time."
  32.  
  33. Ian  : "Anyhow, we do need this, here ... have a Coke." (Gratuitous bribery)
  34.  
  35. Kevin:  "Silver, you don't _need_ it; you want it for writing a game ... ok, 
  36. maybe you _do_ need it."
  37.  
  38.         - And thus a project was born.
  39. ------------------------------------------------------------------------------
  40.  
  41.         The routines in this package are intended to replace the Turbo Pascal 
  42. CRT unit (Turbo Pascal Version 5.0 or greater).  The procedures and functions 
  43. provided in the ANSI unit mirror many of the CRT unit functions but, instead 
  44. of going directly to the screen or through the BIOS, these functions go 
  45. through a user-defined text file device driver.  For more information on text 
  46. file device drivers, please read Chapter 15, "Inside Turbo Pascal", of the 
  47. Turbo Pascal reference manual.  No knowledge of text file device drivers is 
  48. needed to use the three ANSI interface units (ANSICON, ANSICOM, and CONCOMIO) 
  49. provided.
  50.  
  51.         The ANSICON unit provides an ANSI interface to the MS-DOS console and 
  52. the MS-DOS device driver ANSI.SYS.  One application of this unit is in Turbo 
  53. Pascal programs that would be portable to generic MS-DOS environments, (e.g. 
  54. environments that would be incompatible with the CRT unit) while still 
  55. maintaining full control of the cursor and the video attributes.
  56.  
  57.         The ANSICOM unit provides an ANSI interface to a modem or serial 
  58. device.  One application (already in use as a door on a bulletin board system) 
  59. is in text video games that would be played by remote over a phone line.
  60.  
  61.         The CONCOMIO unit incorporates both the ANSICON and ANSICOM units and 
  62. gets input from the console, serial port, or both and sends output to the 
  63. console, serial port, or both.  It does this by chaining to the required input 
  64. and output functions in the other units.
  65.  
  66.         Keep in mind that these drivers are mutually exclusive; you cannot use 
  67. more than one in any one program since each takes over the standard input and 
  68. output files and only one unit can have control of those files.  Only the last 
  69. of these units in your "uses" clause will actually have control.
  70.  
  71.  
  72.  
  73.  
  74.                                    Warranty
  75.                      "Legalese - better safe than sorry."
  76.  
  77.         Kevin Dean (hereafter referred to as "the author") makes no warranty 
  78. of any kind, expressed or implied, including, without limitation, any 
  79. warranties of merchantability and/or fitness for a particular purpose.  The 
  80. author shall not be liable for any damages, whether direct, indirect, special, 
  81. or consequential arising from a failure of this program to operate in the 
  82. manner desired by the user.  The author shall not be liable for any damage to 
  83. data or property which may be caused directly or indirectly by use of the 
  84. program.
  85.  
  86.         In no event will the author be liable to the user for any damages,
  87. including any lost profits, lost savings, or other incidental or consequential
  88. damages arising out of the use or inability to use the program, or for any
  89. claim by any other party.
  90.  
  91.  
  92.  
  93.  
  94.                                  Registration
  95.                           "Capitalism at its finest."
  96.  
  97.         A lot of late nights and Cokes went into the creation of these 
  98. routines.  If you're going to use them regularly and would like to show your 
  99. appreciation (or at least help me in the upkeep of my caffeine and sugar 
  100. habit), please send a donation ($20 suggested) to:
  101.  
  102.                                   Kevin Dean
  103.                          Fairview Mall P.O. Box 55074
  104.                            1800 Sheppard Avenue East
  105.                               Willowdale, Ontario
  106.                                CANADA    M2J 5B9
  107.                            CompuServe ID: 76336,3114
  108.  
  109. These drivers may come to you as part of the DoorLib package; if you register 
  110. DoorLib with its author, you will automatically be registered for these 
  111. drivers as well and no further payment will be required.
  112.  
  113.  
  114.  
  115.  
  116.                               Program Development
  117.                   "How to write your very own ANSI programs."
  118.  
  119.         Development of programs using these units may be done with the units 
  120. themselves or with the CRT unit.  You may use any of the standard CRT 
  121. constants, procedures, functions, or variables with the following exceptions:
  122.  
  123.           Constants       Procedures      Functions        Variables
  124.           ---------       ----------      ---------       -----------
  125.             BW40           DelLine         all CRT         CheckSnow
  126.             BW80           InsLine        functions       DirectVideo
  127.             Mono            Sound            are           LastMode
  128.             CO40           NoSound        available         WindMin
  129.             CO80           TextMode                         WindMax
  130.            Font8x8          Window
  131.              C40
  132.              C80
  133.  
  134.         If you develop your program using the CRT unit, just replace the "uses 
  135. CRT;" clause at the top of all your source files with either "uses ANSI, 
  136. ANSICON;", "uses ANSI, ANSICOM;", or "uses ANSI, CONCOMIO;" depending on 
  137. whether you want your output to go through the standard DOS ANSI device 
  138. driver, through a serial port to a remote terminal, or both.
  139.  
  140.  
  141.  
  142.  
  143.                               The ANSI I/O Driver
  144.                           "The heart of the system."
  145.  
  146. ------------------------------------------------------------------------------
  147. December 1989 (Christmas time, time for rest and relaxation)
  148.  
  149. Ian  : "Ok, I've got the game finished, well... at least I think it's 
  150. finished.  How's that ANSI driver coming along?" 
  151. ------------------------------------------------------------------------------
  152.  
  153.         The ANSI I/O driver is a generic ANSI driver designed to interface to 
  154. any text file device driver.  For more information on text file device 
  155. drivers, please read Chapter 15, "Inside Turbo Pascal", of the Turbo Pascal 
  156. reference manual.
  157.  
  158.         The best tutorial you can get in writing your own ANSI unit interface 
  159. is by looking at the code for the three drivers included with this package.  
  160. The structure of the code is the same in all cases, but for simplicity the 
  161. best one to look at is ANSICON.PAS.
  162.  
  163.  
  164.         The ANSI unit defines the following types:
  165.  
  166.                 type 
  167.                   IOFunc = function(var F : Text) : integer;
  168.  
  169.                         This is a function declaration of the text file device 
  170.                 driver interface to the Open, InOut, Flush, and Close 
  171.                 functions in Turbo Pascal.
  172.  
  173.  
  174.                 type 
  175.                   IOFunctions =
  176.                     record
  177.                     NextOpen, NextInOut, NextFlush, NextClose : pointer
  178.                     end;
  179.  
  180.                         This is a record of the linked I/O functions that are 
  181.                 called by the ANSI text file device drivers.  These functions 
  182.                 actually handle the input from and output to the system.  The 
  183.                 I/O functions in ANSI.PAS simply do the necessary character 
  184.                 interpretation necessary, e.g. update the cursor position 
  185.                 variables or change the screen color.
  186.  
  187.                         When a call is made to the AssignANSI procedure 
  188.                 (below), this record is passed as a parameter.  This record is 
  189.                 stored in the UserData field of the file variable, and you 
  190.                 should not modify that field unless the modification merely 
  191.                 changes one of the pointers.
  192.  
  193.                         The field NextOpen should point to the Open function 
  194.                 written for your text file device.  It is not necessary to 
  195.                 have an Open function defined for your device driver; if none 
  196.                 exists (NextOpen = nil) it will be ignored and the open 
  197.                 request (through a Reset or Rewrite) will proceed normally.
  198.  
  199.                         The field NextInOut should point to the InOut function 
  200.                 written for your text file device.  If you do not assign a 
  201.                 value to the InOut function when you call AssignANSI, 
  202.                 (NextInOut = nil), you must be sure to assign a value to it 
  203.                 when the file is opened, i.e. when your Open function is 
  204.                 called.  The Open function for ANSICON.PAS looks like this:
  205.  
  206.                         function ConsoleOpen(var F : Text) : integer;
  207.  
  208.                         begin
  209.                         with TextRec(F) do
  210.                           if Mode = fmInput then
  211.                             IOFunctions(UserData).NextInOut := @ConsoleIn
  212.                           else
  213.                             IOFunctions(UserData).NextInOut := @ConsoleOut;
  214.  
  215.                         ConsoleOpen := 0
  216.                         end;
  217.  
  218.                 Here the NextInOut pointer is assigned to a procedure to 
  219.                 handle either input or output depending on the mode in which 
  220.                 the file is opened.  If no InOut function is defined, then any 
  221.                 calls to Read or ReadLn will return an I/O result of 161 
  222.                 (device read fault) and any calls to Write or WriteLn will 
  223.                 return an I/O result of 160 (device write fault).
  224.  
  225.                         The NextFlush function flushes the input or output 
  226.                 buffer if necessary.  It is called at the end of every read or 
  227.                 write and so you are strongly advised to define it; if you do 
  228.                 not, you will have to wait until the output buffer (128 
  229.                 characters) is full before it is written to the screen.  At 
  230.                 the very least it should chain to the output function defined 
  231.                 for the current file.  The following is the Flush function 
  232.                 from ANSICON.PAS:
  233.  
  234.                         function ConsoleFlush(var F : Text) : integer;
  235.  
  236.                         begin
  237.                         with TextRec(F) do
  238.                           if Mode = fmInput then
  239.                             { Ignore flush request }
  240.                             ConsoleFlush := 0
  241.                           else
  242.                             { Chain to F's default output routine }
  243.                             ConsoleFlush := IOFunc(InOutFunc)(F)
  244.                         end;
  245.  
  246.                 I advise against calling your own output function directly 
  247.                 from the flush function because by doing so you may bypass the 
  248.                 ANSI output function.  This will prevent the internal cursor 
  249.                 position from being updated and may affect your colors as 
  250.                 well.
  251.  
  252.                         The NextClose function is called when a text file is 
  253.                 closed.  It is not necessary to define this function unless 
  254.                 you have to do some cleanup before closing the file.
  255.  
  256.                         Please remember that these functions in the I/O chain 
  257.                 are treated just like any other text file device driver; if 
  258.                 the return code is non-zero, then Turbo Pascal will signal an 
  259.                 I/O error which you must check to ensure success.
  260.  
  261.  
  262.         The ANSI unit defines the following character constants:
  263.  
  264.                 const
  265.                   NUL = #0;     { The NUL character }
  266.                   BRK = #3;     { Ctrl-C }
  267.                   BEL = #7;     { Bell }
  268.                   BS = #8;      { BackSpace }
  269.                   TAB = #9;     { Tab }
  270.                   LF = #10;     { Line feed }
  271.                   FF = #12;     { Form feed }
  272.                   CR = #13;     { Carriage return }
  273.                   EOF_ = #26;   { End-of-file marker }
  274.                   ESC = #27;    { Escape }
  275.  
  276.  
  277. ------------------------------------------------------------------------------
  278. January 1990
  279.  
  280. Ian  : "Kev, the colors are all messed up.  I do wish you'd get a color 
  281. monitor." 
  282. Kevin: "Ok, I'll look into it."
  283. Ian  : "I looked at your code, the bug is right in this routine."
  284. Kevin: "No, there's no problem there.  I'm checking something else here ..."
  285. Ian  : "I tell you, the bug is right here!"
  286. Kevin: "No, that's not it.  Give me a few minutes ..."
  287. Ian  : "If you say so."
  288.  
  289. (half an hour later)
  290.  
  291. Kevin: "You're right.  That code you were looking at _was_ the problem."
  292. Ian  : <grin>
  293. ------------------------------------------------------------------------------
  294.  
  295.         The ANSI unit defines the following video constants:
  296.  
  297.                 const
  298.                   Black = 0;
  299.                   Blue = 1;
  300.                   Green = 2;
  301.                   Cyan = 3;
  302.                   Red = 4;
  303.                   Magenta = 5;
  304.                   Brown = 6;
  305.                   LightGray = 7;
  306.                   DarkGray = 8;
  307.                   LightBlue = 9;
  308.                   LightGreen = 10;
  309.                   LightCyan = 11;
  310.                   LightRed = 12;
  311.                   LightMagenta = 13;
  312.                   Yellow = 14;
  313.                   White = 15;
  314.                   Blink = 128;
  315.  
  316.  
  317.         The ANSI unit defines the following constants:
  318.  
  319.                 const
  320.                   On = true;
  321.                   Off = false;
  322.  
  323.                         These are passed to the ANSIStatus procedure to turn 
  324.                 the ANSI control sequences on or off (default is On).
  325.  
  326.  
  327.         The ANSI unit defines the following variables:
  328.  
  329.                 var
  330.                   WrapAround : boolean;
  331.  
  332.                         True if the cursor wraps around from one line to the 
  333.                 next when it reaches the end of a line.  Default value is 
  334.                 true.
  335.  
  336.  
  337.                 var 
  338.                   MaxX, MaxY : byte;
  339.  
  340.                         These hold the screen dimensions.  MaxX is the maximum 
  341.                 number of columns (default 80) and MaxY is the maximum number 
  342.                 of rows (default 25).  Values of 0 mean no maximum.  These 
  343.                 variables are used in part to determine the current cursor 
  344.                 position.
  345.  
  346.  
  347.                 var
  348.                   TabLength : byte;
  349.  
  350.                         This is the distance between tab stops.  Default value 
  351.                 is 8.
  352.  
  353.  
  354.                 var
  355.                   TextAttr : byte;
  356.  
  357.                         This defines the current screen color.  It is 
  358.                 compatible with the TextAttr variable in the CRT unit.  
  359.                 Default value is LightGray.
  360.  
  361.  
  362.                 var
  363.                   ANSIFile : Text;
  364.  
  365.                         This is the file to which all ANSI control sequences 
  366.                 are written.  It must be explicitly assigned to a device or 
  367.                 file and opened before your program is run.  Once you have 
  368.                 assigned and opened this file it is advised that you make an 
  369.                 explicit call to either GotoXY or ClrScr to fix the cursor in 
  370.                 a known position.  The internal mechanisms have no way of 
  371.                 knowing what the initial position is.
  372.  
  373.  
  374.                 var
  375.                   CheckEOF : boolean;
  376.  
  377.                         This variable is used by text file device drivers 
  378.                 linked to the ANSI output routines.  If true, the driver 
  379.                 should check for the end-of-file marker (Ctrl-Z) when reading 
  380.                 from its device and signal end of file if found.  Default 
  381.                 value is false.
  382.  
  383.  
  384.                 var
  385.                   CheckBreak : boolean;
  386.  
  387.                         This variable is used by text file device drivers 
  388.                 linked to the ANSI output routines.  If true, the driver 
  389.                 should check for Ctrl-Break or Ctrl-C when reading from its 
  390.                 device and signal a break if found.  Default value is true.
  391.  
  392.  
  393.         The ANSI unit defines the following procedures and functions:
  394.  
  395.                 function Redirected : boolean;
  396.  
  397.                         This function returns true if either the standard 
  398.                 input or standard output has been redirected.  This may be 
  399.                 useful in conjunction with the ANSICON or CONCOMIO units if 
  400.                 you want to guarantee that input will come from the keyboard 
  401.                 and output will go to the screen.
  402.  
  403.  
  404.                 procedure ANSIStatus(Status : boolean);
  405.  
  406.                         Status is either On or Off (defined above).  If On, 
  407.                 ANSI control sequences are used as normal.  If Off, all ANSI 
  408.                 control sequences are ignored; the output is in teletype mode.  
  409.                 Default mode is On.
  410.  
  411.  
  412.                 procedure AssignANSI(var F : Text; IOChain : IOFunctions);
  413.  
  414.                         This assigns the file F to the ANSI text file device.  
  415.                 The parameter IOChain must contain a record of valid I/O chain 
  416.                 functions as described above.
  417.  
  418.  
  419.                 procedure ClrEol;
  420.  
  421.                         Sends the ANSI control sequence to clear to the end of 
  422.                 the current line.
  423.  
  424.  
  425.                 procedure ClrScr;
  426.  
  427.                         Sends the ANSI control sequence to clear the screen.
  428.  
  429.  
  430.                 procedure Delay(MS : word);
  431.  
  432.                         Delays program execution for MS milliseconds.
  433.  
  434.  
  435.                 procedure GotoXY(X, Y : byte);
  436.  
  437.                         Sends the ANSI control sequence to position the cursor 
  438.                 at (X, Y).  If X is not in the range 1 .. MaxX or Y is not in 
  439.                 the range 1 .. MaxY then this request is ignored.  If MaxX and 
  440.                 MaxY are both 0, no check is made and the procedure positions 
  441.                 the cursor blindly.
  442.  
  443.  
  444.                 function WhereX : byte;
  445.  
  446.                         Returns the current X position of the cursor.  Since 
  447.                 the internal mechanisms have no way of knowing what the 
  448.                 initial cursor position is, this function is unreliable unless 
  449.                 you make an explicit call to either GotoXY or ClrScr to fix the 
  450.                 cursor in a known position.
  451.  
  452.  
  453.                 function WhereY : byte;
  454.  
  455.                         Returns the current Y position of the cursor.  Since 
  456.                 the internal mechanisms have no way of knowing what the 
  457.                 initial cursor position is, this function is unreliable unless 
  458.                 you make an explicit call to either GotoXY or ClrScr to fix the 
  459.                 cursor in a known position.
  460.  
  461.  
  462.                 procedure HighVideo;
  463.  
  464.                         Turns on high video by setting the high video bit of 
  465.                 TextAttr.
  466.  
  467.  
  468.                 procedure LowVideo;
  469.  
  470.                         Turns on low video by resetting the high video bit of 
  471.                 TextAttr.
  472.  
  473.  
  474.                 procedure NormVideo;
  475.  
  476.                         Resets TextAttr to the original color at startup 
  477.                 (LightGray).
  478.  
  479.  
  480.                 procedure TextBackground(Color : byte);
  481.  
  482.                         Changes the text background to Color.
  483.  
  484.  
  485.                 procedure TextColor(Color : byte);
  486.  
  487.                         Changes the text foreground to Color; the text 
  488.                 background is not affected.
  489.  
  490.  
  491.         Where any of the above constants, variables, procedures, or functions 
  492. have the same name as in the CRT unit, the functionality is the same.
  493.  
  494.         This is a bare minimum replacement for the CRT unit.  Certain 
  495. variables, procedures, and functions cannot be handled by the ANSI unit 
  496. because they are too tightly bound to the particular device.  Two such 
  497. functions, for example, are KeyPressed and ReadKey; these cannot be unbound 
  498. from the device and so the ANSI unit does not implement them.  It is up to you 
  499. to create these missing variables, procedures, and functions if you need them.  
  500. The ANSICON, ANSICOM, and CONCOMIO units provided implement some of these 
  501. missing functions.  They are described in the following sections.
  502.  
  503.  
  504.  
  505.  
  506.                           The ANSICON Console Driver
  507.      "How to make your keyboard and screen look like any other terminal."
  508.  
  509.         The ANSICON console driver takes all input from the standard input 
  510. device (the console) and sends all output to the standard output device (the 
  511. console) via the ANSI.SYS device driver.  To uses this unit, make sure you 
  512. have the statement "DEVICE=ANSI.SYS" in your CONFIG.SYS file; for more 
  513. information on the CONFIG.SYS file, please see your DOS manual.
  514.  
  515.         This unit can be used with the ANSI unit as a replacement for the 
  516. Turbo Pascal CRT unit.  Programs developed using these units may be ported to 
  517. generic MS-DOS environments where the CRT unit may not be compatible.
  518.  
  519.         When you include the ANSICON unit in your program, it automatically 
  520. assigns the standard input and output files and the ANSI file to the ANSICON 
  521. I/O functions.
  522.  
  523.  
  524.         The ANSICON unit defines the following procedures and functions:
  525.  
  526.                 procedure AssignCON(var F : Text);
  527.  
  528.                         This assigns the file F to the console by defining its 
  529.                 I/O chain functions and then assigning the file to the ANSI 
  530.                 device above.
  531.  
  532.  
  533.                 function KeyPressed : boolean;
  534.  
  535.                         Returns true if a key is waiting in the keyboard 
  536.                 buffer.
  537.  
  538.  
  539.                 function ReadKey : char;
  540.  
  541.                         Reads the next key from the keyboard buffer.
  542.  
  543.  
  544.         Where any of the above constants, variables, procedures, or functions 
  545. have the same name as in the CRT unit, the functionality is the same.
  546.  
  547.  
  548.  
  549.  
  550.                        The ANSICOM Communications Driver
  551.      "How to make any other terminal look like your keyboard and screen."
  552.  
  553. ------------------------------------------------------------------------------
  554. January 1990 (back to university, second term)
  555.  
  556. Ian  : "Four assignments eh?  That's a tough break ... so how's that code 
  557. coming along?"
  558. Kevin: "SILVER!!!"
  559. ------------------------------------------------------------------------------
  560.  
  561.         The ANSICOM communications driver takes all input from and sends all 
  562. output to a single modem or serial device.  The driver is interrupt-driven, 
  563. which means that data can be received and transmitted while the computer is 
  564. engaged doing something else.  The advantage of this unit is that it treats 
  565. your modem almost exactly the same way as the Turbo Pascal CRT unit treats 
  566. your keyboard and screen.
  567.  
  568.         When developing programs that will use the ANSICOM unit, it is best to 
  569. design them using either the Turbo Pascal CRT unit or the ANSICON unit 
  570. provided with this package.  In this way, you can fully design, test, and 
  571. debug your program on your own machine before committing it to the serial 
  572. port.
  573.  
  574.         When you include the ANSICOM unit in your program, it automatically 
  575. assigns the standard input and output files and the ANSI file to the ANSICOM 
  576. I/O functions.
  577.  
  578.  
  579. ------------------------------------------------------------------------------
  580. Kevin: "I finally figured out why the error handler was not working properly.  
  581. Not only had I failed to declare it as a far procedure, but it was going 
  582. through infinite recursion: the halt procedure in the error handler called the 
  583. flush procedure to flush the output file, which in turn called the error 
  584. handler (because the error had not been cleared), which in turn called halt 
  585. ... system go whiirrrrrrrrrrrrr ..." 
  586. Ian  : "Oh lovely.  We should work for the government ... perpetual job 
  587. creation." 
  588. ------------------------------------------------------------------------------
  589.  
  590.         The ANSICOM unit defines the following types:
  591.  
  592.                 type
  593.                   ErrorProc = procedure(var Error : word);
  594.  
  595.                         This is the communications error handling procedure.  
  596.                 Your error handling procedure must be of the above type and 
  597.                 must be declared as a far procedure (use the {$F+} compiler 
  598.                 directive).  The parameter error will have one or more of the 
  599.                 following flags set: ReceiveOverrun, TransmitOverrun, 
  600.                 ParityError, FramingError, BreakDetect, CommTimeOut, 
  601.                 NoCarrier, or CtrlBreak.  These are described below.  If your 
  602.                 error procedure is to return control to the communications 
  603.                 routines, you may want to clear some or all of the error 
  604.                 flags so that you don't have to handle that error the next 
  605.                 time the procedure is called.  To clear all error flags set 
  606.                 Error equal to NoCommError (0).
  607.  
  608.                         To test for a communications error, mask the Error 
  609.                 parameter with one or more of the above flags.  For example,
  610.  
  611.                         { Halt if lost carrier }
  612.                         if Error and NoCarrier <> 0 then
  613.                           begin
  614.                           ReleaseCOM;
  615.                           halt(1)
  616.                           end;
  617.  
  618.                         { Ignore parity and framing errors }
  619.                         if Error and (ParityError or FramingError) <> 0 then
  620.                           Error := Error and not (ParityError or FramingError);
  621.  
  622.                         If you want to send an error message to the console 
  623.                 (not the serial port), you will have to open the console as a 
  624.                 file since the ANSICOM driver redirects the standard output 
  625.                 file to the modem.  Thus:
  626.  
  627.                         Assign(ConF, 'CON');
  628.                         Rewrite(ConF);
  629.  
  630.                         if Error and NoCarrier <> 0 then
  631.                           begin
  632.                           WriteLn(ConF, 'Error : No carrier');
  633.                           ReleaseCOM;
  634.                           halt(1)
  635.                           end;
  636.  
  637.  
  638.         The ANSICOM unit defines the following constants:
  639.  
  640.                 const
  641.                   Init = true;
  642.                   NoInit = false;
  643.  
  644.                         These constants are used when installing the 
  645.                 communications routines.  If the modem is to be initialized, 
  646.                 i.e. its baud rate and data format has yet to be set up, then 
  647.                 use Init in the call to InitCOM.  If the modem is already 
  648.                 initialized or on-line, use NoInit in the call to InitCOM to 
  649.                 prevent the modem from losing the connection.
  650.  
  651.  
  652.                 const
  653.                   SyncTransmit = true;
  654.                   AsyncTransmit = false;
  655.  
  656.                         These constants are used when installing the 
  657.                 communications routines.  Synchronous transmission means that 
  658.                 the program output (through Write or WriteLn) waits until all 
  659.                 characters have been transmitted before returning control to 
  660.                 the program.  This approach is advised when writing 
  661.                 interactive programs such as video games; use the SyncTransmit 
  662.                 constant when initializing the modem.  If you don't want to 
  663.                 wait for the output to be transmitted, use AsyncTransmit and 
  664.                 control will be returned to your program while the ANSICOM 
  665.                 unit takes care of the transmission in the background.
  666.  
  667.  
  668.                 const
  669.                   NoCommError = $0000;
  670.  
  671.                         No communications error.
  672.  
  673.  
  674.                 const
  675.                   ReceiveOverrun = $0001;
  676.  
  677.                         Either a character arrived over the modem before the 
  678.                 ANSICOM unit had a chance to remove the previous character or 
  679.                 the receive buffer is full (your program is not reading the 
  680.                 data as it comes across the line).
  681.  
  682.  
  683.                 const
  684.                   TransmitOverrun = $0002;
  685.  
  686.                         The transmission buffer is full.  This error occurs 
  687.                 only in asynchronous transmission when you write more to the 
  688.                 modem than it can handle in that length of time.
  689.  
  690.  
  691.                 const
  692.                   ParityError = $0004;
  693.                   FramingError = $0008;
  694.  
  695.                         Data arriving over the modem has somehow been 
  696.                 corrupted.  The character or characters affected were lost in 
  697.                 transmission.
  698.  
  699.  
  700.                 const
  701.                   BreakDetect = $0010;
  702.  
  703.                         The remote modem is requesting that you break the 
  704.                 connection.  Suggested action is to disconnect the modem with 
  705.                 a call to the Disconnect procedure.
  706.  
  707.  
  708.                 const
  709.                   CommTimeOut = $0020;
  710.  
  711.                         The modem timed-out (the remote modem has probably 
  712.                 gone off-line).
  713.  
  714.  
  715.                 const
  716.                   NoCarrier = $0040;
  717.  
  718.                         The modem has lost the carrier signal.
  719.  
  720.  
  721.                 const
  722.                   CtrlBreak = $0080;
  723.  
  724.                         A Ctrl-C character has been received and CheckBreak 
  725.                 (above) is true.
  726.  
  727.  
  728.                 const
  729.                   NotOnline = $0100;
  730.  
  731.                         You are trying to read from the communications port 
  732.                 without having initialized the communications routines.
  733.  
  734.  
  735.         The ANSICOM unit defines the following functions and procedures:
  736.  
  737.                 function InitCOM(COMPort : byte; Baud : integer; Bits : byte; 
  738.                  Parity : char; Stop : byte; Init : boolean; Sync : boolean; 
  739.                  Error : pointer) : integer;
  740.  
  741.                         This initializes the modem, installs the 
  742.                 communications interrupt, sets the desired transmission 
  743.                 synchronization, and installs a user-defined error handler.
  744.  
  745.                         The parameters are:
  746.  
  747.                                 COMPort - Port number from 1 to 4
  748.                                 Baud    - Desired baud rate
  749.                                 Bits    - Number of data bits (5 to 8)
  750.                                 Parity  - Parity type ('E'ven, 'O'dd, 'M'ark, 
  751.                                           'S'pace, or 'N'one)
  752.                                 Stop    - Number of stop bits (1 or 2; to get 
  753.                                           1.5 stop bits for 5 data bits, use 
  754.                                           2 stop bits)
  755.                                 Init    - Use the constants Init to initialize 
  756.                                           the modem with the given data format 
  757.                                           or NoInit if the modem has already 
  758.                                           been initialized.
  759.                                 Sync    - Use the constants SyncTransmit for 
  760.                                           synchronous transmission or 
  761.                                           AsyncTransmit for asynchronous 
  762.                                           transmission (described above)
  763.                                 Error   - Pointer to a user-defined error 
  764.                                           handler of the type ErrorProc 
  765.                                           (defined above) or nil if no error 
  766.                                           handler is desired
  767.  
  768.                         This function returns 0 if successful or 1 if not 
  769.                 (invalid COM port number or data format).
  770.  
  771.  
  772.                 function SetBaud(Baud : integer; Bits : byte; Parity : char; 
  773.                  Stop : byte) : integer;
  774.  
  775.                         This function is useful if you want to change the data 
  776.                 format on the fly, for example if the modem, previously 
  777.                 initialized at 2400 baud, connects at 1200.  To use this 
  778.                 function, you must first have initialized it using the InitCOM 
  779.                 function.
  780.  
  781.                         The parameters are:
  782.  
  783.                                 Baud    - Desired baud rate
  784.                                 Bits    - Number of data bits (5 to 8)
  785.                                 Parity  - Parity type ('E'ven, 'O'dd, 'M'ark, 
  786.                                           'S'pace, or 'N'one)
  787.                                 Stop    - Number of stop bits (1 or 2; to get 
  788.                                           1.5 stop bits for 5 data bits, use 
  789.                                           2 stop bits)
  790.  
  791.                         This function returns 0 if successful or 1 if not 
  792.                 (modem not previously initialized or invalid data format).
  793.  
  794.  
  795.                 procedure Disconnect;
  796.  
  797.                         Disconnects the modem by turning off the carrier.
  798.  
  799.  
  800.                 procedure ReleaseCOM;
  801.  
  802.                         Releases the modem by resetting the modem state to its 
  803.                 initial configuration.  If the modem was initialized (by 
  804.                 specifying Init in InitCOM) then it is disconnected.
  805.  
  806.  
  807.                 procedure AssignCOM(var F : Text);
  808.  
  809.                         This assigns the file F to the modem by defining its 
  810.                 I/O chain functions and then assigning the file to the ANSI 
  811.                 device above.
  812.  
  813.  
  814.                 function KeyPressed : boolean;
  815.  
  816.                         Returns true if a key is waiting in the modem input 
  817.                 buffer.
  818.  
  819.  
  820.                 function ReadKey : char;
  821.  
  822.                         Reads the next key from the modem input buffer.
  823.  
  824.  
  825.         Where any of the above constants, variables, procedures, or functions 
  826. have the same name as in the CRT unit, the functionality is the same.
  827.  
  828.  
  829.  
  830.  
  831.                 The CONCOMIO Console and Communications Driver
  832.               "How to make your keyboard and screen look like any 
  833.                         other terminal and vice versa."
  834.  
  835. ------------------------------------------------------------------------------
  836. February 1990
  837.  
  838. Kevin: "There.  Done.  Documented.  It's all yours."
  839. Ian  : "Great!  Now, is there any way to get the output to go to both the 
  840. console and the modem and to get input from both as well?"
  841. Kevin: "(sigh) Alright ... give me another hour ... (grumble, grumble)"
  842. ------------------------------------------------------------------------------
  843.  
  844.         The CONCOMIO driver takes its input from the console, the 
  845. communications port, or both, depending on how CONCOMIO has been configured.  
  846. To use this unit, you must have ANSI.SYS installed in your CONFIG.SYS file 
  847. (see ANSICON documentation above).
  848.  
  849.         When you include the CONCOMIO unit in your program, it automatically 
  850. assigns the standard input and output files and the ANSI file to the CONCOMIO 
  851. I/O functions.
  852.  
  853.         All types, constants, variables, procedures, and functions defined in 
  854. ANSICOM are also defined in CONCOMIO (with the exception of AssignCOM).  As 
  855. before, you must initialize the modem, install an error handler, etc.  In 
  856. addition to the stuff declared in ANSICOM, CONCOMIO has its own declarations 
  857. described below.
  858.  
  859.         The CONCOMIO uses both the ANSICON and ANSICOM units to handle the 
  860. input and output.  The sole purpose of this unit is to direct the input and 
  861. output calls to the correct handlers.
  862.  
  863.         Communications error handlers for the CONCOMIO unit function exactly 
  864. the same way as they do for the ANSICOM unit.  However, since the console is 
  865. part of the CONCOMIO routines, you do not need to open the console as a 
  866. separate file; instead, set the variable ActiveOutput := ConsoleActive.  The 
  867. variable ActiveOutput and constant ConsoleActive are described below.
  868.  
  869.  
  870.         The CONCOMIO unit defines the following constants:
  871.  
  872.                 const
  873.                   NoneActive = $0000;
  874.  
  875.                         No text file device driver is active for this 
  876.                 operation (input or output, see below).
  877.  
  878.  
  879.                 const
  880.                   ConsoleActive = $0001;
  881.  
  882.                         The console device driver is active for this operation 
  883.                 (input or output, see below).
  884.  
  885.  
  886.                 const
  887.                   CommActive = $0002;
  888.  
  889.                         The communications device driver is active for this 
  890.                 operation (input or output, see below).
  891.  
  892.  
  893.                 const
  894.                   BothActive = ConsoleActive or CommActive;
  895.  
  896.                         Both the console and communications device drivers are 
  897.                 active for this operation (input or output, see below).
  898.  
  899.  
  900.         The CONCOMIO unit defines the following variables:
  901.  
  902.                 var
  903.                   ActiveInput : word;
  904.  
  905.                         This is the active input device.  Valid values are 
  906.                 NoneActive (no input allowed), ConsoleActive (input from 
  907.                 console only allowed), CommActive (input from modem only 
  908.                 allowed), and BothActive (input from both console and modem 
  909.                 allowed).
  910.  
  911.                         If the value is NoneActive, any Read or ReadLn 
  912.                 operation will return an I/O result of 161 (device read 
  913.                 fault).
  914.  
  915.  
  916.                 var
  917.                   ActiveOutput : word;
  918.  
  919.                         This is the active output device.  Valid values are 
  920.                 NoneActive (no output allowed), ConsoleActive (output to 
  921.                 console only allowed), CommActive (output to modem only 
  922.                 allowed), and BothActive (output to both console and modem 
  923.                 allowed).
  924.  
  925.                         If the value is NoneActive, any Write or WriteLn 
  926.                 operation will return an I/O result of 160 (device write 
  927.                 fault).
  928.  
  929.  
  930.         The CONCOMIO unit defines the following procedures and functions:
  931.  
  932.                 procedure AssignCONCOM(var F : Text);
  933.  
  934.                         This assigns the file F to the console and the modem 
  935.                 by defining its I/O chain functions and then assigning the 
  936.                 file to the ANSI device above.
  937.  
  938.  
  939.                 function KeyPressed : boolean;
  940.  
  941.                         Returns true if a key is waiting in the keyboard or 
  942.                 modem buffer, depending on the value of ActiveInput.
  943.  
  944.  
  945.                 function ReadKey : char;
  946.  
  947.                         Reads the next key from the keyboard or modem buffer, 
  948.                 depending on the value of ActiveInput.
  949.  
  950.  
  951.         Where any of the above constants, variables, procedures, or functions 
  952. have the same name as in the CRT unit, the functionality is the same.
  953.  
  954.         When using the CONCOMIO unit, you must be sure to initialize the modem 
  955. using the InitCOM() call since CONCOMIO does in fact use the modem.
  956.  
  957.         WARNING: By default, the CONCOMIO startup routine sets CheckBreak to 
  958. false.  This is because a Ctrl-Break in the ANSICON driver generates INT 23h, 
  959. the Ctrl-Break interrupt, and does not allow the communications routines to do 
  960. any cleanup.  When this happens, the communications interrupt in the ANSICOM 
  961. driver may not be properly released and your computer may be left in an 
  962. unknown state.
  963.  
  964.  
  965.  
  966.  
  967.                              Demonstration Programs
  968.                              "Cut-and-paste code."
  969.  
  970.         The files DEMOCON.EXE (source DEMOCON.PAS), DEMOCOM.EXE (source 
  971. DEMOCOM.PAS), and DEMOBOTH.EXE (source DEMOBOTH.PAS) demonstrate simple 
  972. applications of the ANSICON or ANSICOM units or both respectively.  These 
  973. programs handle line-oriented input and output and some simple color and 
  974. screen control.
  975.  
  976.         To run DEMOCON, just type DEMOCON at the DOS prompt.  After you enter 
  977. your name, a box showing your name, current colors, and the cursor position 
  978. will be displayed.  The colors will change randomly.
  979.  
  980.         To run DEMOCOM, your modem must be on-line to a remote terminal.  The 
  981. baud rate at which it is connected is really immaterial since your modem will 
  982. not be initialized by the DEMOCOM program itself.  However, you must be 
  983. connected at 8 data bits.  The remote terminal will see exactly the same thing 
  984. that you saw in the DEMOCON program.
  985.  
  986.         To run DEMOBOTH, your modem must be on-line to a remote terminal.  The 
  987. baud rate at which it is connected is really immaterial since your modem will 
  988. not be initialized by the DEMOBOTH program itself.  However, you must be 
  989. connected at 8 data bits.  In this case, both the remote terminal and your 
  990. screen will display the same thing and each will have the ability to enter 
  991. data.
  992.  
  993.