home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / TPIO.ZIP / IO.PAS next >
Encoding:
Pascal/Delphi Source File  |  1989-01-02  |  12.0 KB  |  475 lines

  1. Unit IO;
  2.  
  3.               { FOSSIL communications I/O routines }
  4.               { Turbo Pascal Version by Tony Hsieh }
  5.  
  6.   {}{}{}{ Copyright (c) 1989 by Tony Hsieh, All Rights Reserved. }{}{}{}
  7.  
  8.  
  9. { The following routines are basic input/output routines, using a }
  10. { fossil driver.  These are NOT all the routines that a fossil    }
  11. { driver can do!  These are just a portion of the functions that  }
  12. { fossil drivers can do.  However, these are the only ones most   }
  13. { people will need.  I highly recommend for those that use this   }
  14. { to download an arced copy of the X00.SYS driver.  In the arc    }
  15. { is a file called "FOSSIL.DOC", which is where I derived my      }
  16. { routines from.  If there are any routines that you see are not  }
  17. { implemented here, use FOSSIL.DOC to add/make your own!  I've    }
  18. { listed enough examples here for you to figure out how to do it  }
  19. { yourself.                                                       }
  20. { This file was written as a unit for Turbo Pascal v4.0.  You     }
  21. { should compile it to DISK, and then in your own program type    }
  22. { this right after your program heading (before Vars and Types)   }
  23. { this: "uses IO;"                                                }
  24. { EXAMPLE: }
  25. {
  26.  
  27. Program Communications;
  28.  
  29. uses IO;
  30.  
  31. begin
  32.   InitializeDriver;
  33.   Writeln ('Driver is initalized!');
  34.   ModemSettings (1200,8,'N',1); Baud := 1200;
  35.   DTR (0); Delay (1000); DTR (1);
  36.   Writeln ('DTR is now true!');
  37.   CloseDriver;
  38.   Writeln ('Driver is closed!');
  39. end.
  40.  
  41. }
  42.  
  43. { Feel free to use these routines in your programs; copy this  }
  44. { file freely, but PLEASE DO NOT MODIFY IT.  If you do use     }
  45. { these routines in your program, please give proper credit to }
  46. { the author.                                                  }
  47. {                                                              }
  48. { Thanks, and enjoy!                                           }
  49. {                                                              }
  50. { Tony Hsieh                                                   }
  51.  
  52.  
  53.  
  54.  
  55. INTERFACE
  56.  
  57. uses DOS;
  58.                                        { These are communications routines }
  59.                                        { that utilize a FOSSIL driver.  A  }
  60.                                        { FOSSIL driver MUST be installed,  }
  61.                                        { such as X00.SYS and OPUS!COM...   }
  62.  
  63. type
  64.   String255 = String [255];
  65.  
  66. var
  67.   Port: Integer;                 { I decided to make 'Port' a global    }
  68.                                  { variable to make life easier.        }
  69.  
  70.   Baud: Word;                    { Same with Baud                       }
  71.  
  72.   RegistersRecord: Registers;    { DOS registers AX, BX, CX, DX, and Flags }
  73.  
  74.  
  75. procedure BlankRegisters;
  76. procedure ModemSettings (Baud, DataBits: Integer; Parity: Char;
  77.                          Stopbits: Integer);
  78. procedure InitializeDriver;
  79. procedure CloseDriver;
  80. procedure ReadKeyAhead (var First, Second: Char);
  81. function ReceiveAhead (var Character: CHAR): Boolean;
  82. function Online: boolean;
  83. procedure DTR (DTRState: Integer);
  84. procedure Reboot;
  85. procedure BiosScreenWrite (Character: CHAR);
  86. procedure WatchDog (INPUT: Boolean);
  87. procedure WhereCursor (var Row: Integer; var Column: Integer);
  88. procedure MoveCursor (Row: Integer; Column: Integer);
  89. procedure KillInputBuffer;
  90. procedure KillOutputBuffer;
  91. procedure FlushOutput;
  92. function InputAvailable: Boolean;
  93. function OutputOkay: Boolean;
  94. procedure ReceiveCharacter (var Character: CHAR);
  95. procedure TransmitCharacter (Character: CHAR; var Status: Integer);
  96. procedure FlowControl (Control: Boolean);
  97. procedure CharacterOut (Character: CHAR);
  98. procedure StringOut (Message: String255);
  99. procedure LineOut (Message: String255);
  100. procedure CrOut;
  101.  
  102.  
  103. IMPLEMENTATION
  104.  
  105. procedure BlankRegisters;
  106. begin
  107.   Fillchar (RegistersRecord, SizeOf (RegistersRecord), 0);
  108. end;
  109.  
  110. procedure ModemSettings (Baud, DataBits: Integer; Parity: Char;
  111.                          StopBits: Integer);
  112.                                                { Do this after initializing }
  113.                                                { the FOSSIL driver and also }
  114.                                                { when somebody logs on      }
  115. var
  116.   GoingOut: Integer;
  117. begin
  118.   GoingOut := 0;
  119.   Case Baud of
  120.       0 : Exit;
  121.     100 : GoingOut := GoingOut + 000 + 00 + 00;
  122.     150 : GoingOut := GoingOut + 000 + 00 + 32;
  123.     300 : GoingOut := GoingOut + 000 + 64 + 00;
  124.     600 : GoingOut := GoingOut + 000 + 64 + 32;
  125.     1200: GoingOut := GoingOut + 128 + 00 + 00;
  126.     2400: GoingOut := GoingOut + 128 + 00 + 32;
  127.     4800: GoingOut := GoingOut + 128 + 64 + 00;
  128.     9600: GoingOut := GoingOut + 128 + 64 + 32;
  129.   end;
  130.   Case DataBits of
  131.     5: GoingOut := GoingOut + 0 + 0;
  132.     6: GoingOut := GoingOut + 0 + 1;
  133.     7: GoingOut := GoingOut + 2 + 0;
  134.     8: GoingOut := GoingOut + 2 + 1;
  135.   end;
  136.   Case Parity of
  137.     'N'    : GoingOut := GoingOut + 00 + 0;
  138.     'O','o': GoingOut := GoingOut + 00 + 8;
  139.     'n'    : GoingOut := GoingOut + 16 + 0;
  140.     'E','e': GoingOut := GoingOut + 16 + 8;
  141.   end;
  142.   Case StopBits of
  143.     1: GoingOut := GoingOut + 0;
  144.     2: GoingOut := GoingOut + 4;
  145.   end;
  146.   BlankRegisters;
  147.   With RegistersRecord do
  148.   begin
  149.     AH := 0; AL := GoingOut;
  150.     DX := (Port);
  151.     Intr ($14, RegistersRecord);
  152.   end;
  153. end;
  154.  
  155. procedure InitializeDriver;                         { Do this before doing }
  156. begin                                               { any IO routines!!!   }
  157.   BlankRegisters;
  158.   With RegistersRecord do
  159.   begin
  160.     AH := 4;
  161.     DX := (Port);
  162.     Intr ($14, RegistersRecord);
  163.     If AX <> $1954 then
  164.     begin
  165.       Writeln ('* FOSSIL DRIVER NOT RESPONDING!  OPERATION HALTED!');
  166.       halt (1);
  167.     end;
  168.   end;
  169. end;
  170.  
  171. procedure CloseDriver;  { Run this after all I/O routines are done with }
  172. begin
  173.   BlankRegisters;
  174.   With RegistersRecord do
  175.   begin
  176.     AH := 5;
  177.     DX := (Port);
  178.     Intr ($14, RegistersRecord);
  179.   end;
  180.   BlankRegisters;
  181. end;
  182.  
  183. procedure ReadKeyAhead (var First, Second: Char); { This procedure is via  }
  184.                                                   { the FOSSIL driver, not }
  185.                                                   { DOS!                   }
  186. begin
  187.   BlankRegisters;
  188.   With RegistersRecord do
  189.   begin
  190.     AH := $0D;
  191.     Intr ($14,RegistersRecord);
  192.     First := chr(lo(AX));
  193.     Second := chr(hi(AX));
  194.   end;
  195. end;
  196.  
  197. function ReceiveAhead (var Character: CHAR): Boolean;  { Non-destructive }
  198. begin
  199.   If Baud=0 then exit;
  200.   BlankRegisters;
  201.   With RegistersRecord do
  202.   begin
  203.     AH := $0C;
  204.     DX := Port;
  205.     Intr ($14,RegistersRecord);
  206.     Character := CHR (AL);
  207.     ReceiveAhead := AX <> $FFFF;
  208.   end;
  209. end;
  210.  
  211. function OnLine: Boolean;
  212. begin
  213.   BlankRegisters;
  214.   With RegistersRecord do
  215.   begin
  216.     AH := 3;
  217.     DX := (Port);
  218.     Intr ($14, RegistersRecord);
  219.     OnLine := ((AL AND 128) = 128);
  220.   end;
  221. end;
  222.  
  223. procedure DTR (DTRState: Integer);    { 1=ON, 0=OFF }
  224.                                       { Be sure that the modem dip switches }
  225.                                       { are set properly... when DTR is off }
  226.                                       { it usually drops carrier if online  }
  227. begin
  228.   BlankRegisters;
  229.   With RegistersRecord do
  230.   begin
  231.     AH := 6;
  232.     DX := (Port);
  233.     AL := DTRState;
  234.     Intr ($14, RegistersRecord);
  235.   end;
  236. end;
  237.  
  238. procedure Reboot;                  { For EXTREME emergencies... Hmmm... }
  239. begin
  240.   BlankRegisters;
  241.   With RegistersRecord do
  242.   begin
  243.     AH := 23;
  244.     AL := 1;
  245.     Intr ($14, RegistersRecord);
  246.   end;
  247. end;
  248.  
  249. {       This is ANSI Screen Write via Fossil Driver }
  250. {
  251. procedure ANSIScreenWrite (Character: CHAR);
  252. begin
  253.   BlankRegisters;
  254.   With RegistersRecord do
  255.   begin
  256.     AH := 19;
  257.     AL := ORD (Character);
  258.     Intr ($14, RegistersRecord);
  259.   end;
  260. end;
  261. }
  262.  
  263. { This is ANSI Screen Write via DOS! }
  264.  
  265. procedure ANSIScreenWrite (Character: CHAR);
  266. begin
  267.   BlankRegisters;
  268.   With RegistersRecord do
  269.   begin
  270.     AH := 2;
  271.     DL := ORD (Character);
  272.     Intr ($21, RegistersRecord);
  273.   end;
  274. end;
  275.  
  276.  
  277. procedure BIOSScreenWrite (Character: CHAR); { Through the FOSSIL driver }
  278. begin
  279.   BlankRegisters;
  280.   With RegistersRecord do
  281.   begin
  282.     AH := 21;
  283.     AL := ORD (Character);
  284.     Intr ($14, RegistersRecord);
  285.   end;
  286. end;
  287.  
  288. procedure WatchDog (INPUT: Boolean);
  289. begin
  290.   BlankRegisters;
  291.   With RegistersRecord do
  292.   begin
  293.     AH := 20;
  294.     DX := Port;
  295.     Case INPUT of
  296.       TRUE:  AL := 1;
  297.       FALSE: AL := 0;
  298.     end;
  299.     Intr ($14, RegistersRecord);
  300.   end;
  301. end;
  302.  
  303. procedure WhereCursor (var Row: Integer; var Column: Integer);
  304. begin
  305.   BlankRegisters;
  306.   With RegistersRecord do
  307.   begin
  308.     AH := 18;
  309.     Intr ($14, RegistersRecord);
  310.     Row := DH;
  311.     Column := DL;
  312.   end;
  313. end;
  314.  
  315. procedure MoveCursor (Row: Integer; Column: Integer);
  316. begin
  317.   BlankRegisters;
  318.   With RegistersRecord do
  319.   begin
  320.     AH := 17;
  321.     DH := Row;
  322.     DL := Column;
  323.     Intr ($14, RegistersRecord);
  324.   end;
  325. end;
  326.  
  327. procedure KillInputBuffer;   { Kills all remaining input that has not been }
  328.                              { read in yet }
  329. begin
  330.   If Baud=0 then exit;
  331.   BlankRegisters;
  332.   With RegistersRecord do
  333.   begin
  334.     AH := 10;
  335.     DX := Port;
  336.     Intr ($14, RegistersRecord);
  337.   end;
  338. end;
  339.  
  340. procedure KillOutputBuffer;  { Kills all pending output that has not been }
  341.                              { send yet }
  342. begin
  343.   If Baud=0 then exit;
  344.   BlankRegisters;
  345.   With RegistersRecord do
  346.   begin
  347.     AH := 9;
  348.     DX := Port;
  349.     Intr ($14, RegistersRecord);
  350.   end;
  351. end;
  352.  
  353. procedure FlushOutput;       { Flushes the output buffer }
  354. begin
  355.   If Baud=0 then exit;
  356.   BlankRegisters;
  357.   With RegistersRecord do
  358.   begin
  359.     AH := 8;
  360.     DX := Port;
  361.     Intr ($14, RegistersRecord);
  362.   end;
  363. end;
  364.  
  365. function InputAvailable: Boolean;   { Returns true if there's input }
  366.                                     { from the modem.               }
  367. begin
  368.   InputAvailable := False;
  369.   If Baud=0 then exit;
  370.   BlankRegisters;
  371.   With RegistersRecord do
  372.   begin
  373.     AH := 3;
  374.     DX := Port;
  375.     Intr ($14, RegistersRecord);
  376.     InputAvailable := ((AH AND 1) = 1);
  377.   end;
  378. end;
  379.  
  380. function OutputOkay: Boolean;     { Returns true if output buffer isn't full }
  381. begin
  382.   OutputOkay := True;
  383.   If Baud=0 then exit;
  384.   BlankRegisters;
  385.   With RegistersRecord do
  386.   begin
  387.     AH := 3;
  388.     DX := Port;
  389.     Intr ($14, RegistersRecord);
  390.     OutputOkay := ((AH AND 32) = 32);
  391.   end;
  392. end;
  393.  
  394. procedure ReceiveCharacter (var Character: CHAR);   { Takes a character }
  395.                                                     { out of the input  }
  396.                                                     { buffer }
  397. begin
  398.   Character := #0;
  399.   BlankRegisters;
  400.   With RegistersRecord do
  401.   begin
  402.     AH := 2;
  403.     DX := Port;
  404.     Intr ($14, RegistersRecord);
  405.     Character := CHR (AL);
  406.   end;
  407. end;
  408.  
  409. procedure TransmitCharacter (Character: CHAR; var Status: Integer);
  410. begin
  411.   BlankRegisters;
  412.   With RegistersRecord do
  413.   begin
  414.     AH := 1;
  415.     DX := Port;
  416.     AL := ORD (Character);
  417.     Intr ($14, RegistersRecord);
  418.     Status := AX;        { Refer to FOSSIL.DOC about the STATUS var }
  419.   end;
  420. end;
  421.  
  422. procedure FlowControl (Control: Boolean);
  423. begin
  424.   BlankRegisters;
  425.   With RegistersRecord do
  426.   begin
  427.     AH := 15;
  428.     DX := Port;
  429.     Case Control of
  430.      TRUE:  AL := 255;
  431.      FALSE: AL := 0;
  432.     end;
  433.     Intr ($14, RegistersRecord);
  434.   end;
  435. end;
  436.  
  437. procedure CharacterOut (Character: CHAR);
  438. var
  439.   Status: INTEGER;
  440. begin
  441.   { If SNOOP is on then }
  442.     ANSIScreenWrite (Character);
  443.   TransmitCharacter (Character, Status);
  444. end;
  445.  
  446. procedure StringOut (Message: String255);
  447. var
  448.   CharPos: Byte;
  449. begin
  450.   CharPos := 0;
  451.   If Length(Message) <> 0 then
  452.   begin
  453.     Repeat
  454.       If NOT Online then exit;
  455.       CharPos := CharPos + 1;
  456.       CharacterOut (Message [CharPos]);
  457.     Until CharPos = Length (Message);
  458.   end;
  459. end;
  460.  
  461. procedure LineOut (Message: String255);
  462. begin
  463.   StringOut (Message);
  464.   CharacterOut (#13);
  465.   CharacterOut (#10);
  466. end;
  467.  
  468. procedure CrOut; { Outputs a carriage return and a line feed }
  469. begin
  470.   CharacterOut (#13);
  471.   CharacterOut (#10);
  472. end;
  473.  
  474. end.
  475.