home *** CD-ROM | disk | FTP | other *** search
/ Jason Aller Floppy Collection / 189.img / TCS120S.ZIP / PIBASYNC.PAS < prev    next >
Pascal/Delphi Source File  |  1980-01-01  |  24KB  |  657 lines

  1. type      regpack=record
  2.        case integer of
  3.          0:(ax,bx,cx,dx,bp,si,di,ds,es,flags:integer);
  4.          1:(al,ah,bl,bh,cl,ch,dl,dh:byte)
  5.      end;
  6.  
  7. Const
  8.  
  9.    UART_THR = $00;       (* offset from base of UART Registers for IBM PC *)
  10.    UART_RBR = $00;
  11.    UART_IER = $01;
  12.    UART_IIR = $02;
  13.    UART_LCR = $03;
  14.    UART_MCR = $04;
  15.    UART_LSR = $05;
  16.    UART_MSR = $06;
  17.  
  18.    I8088_IMR = $21;      (* port address of the Interrupt Mask Register *)
  19.  
  20.    COM1_Base = $03F8;    (* port addresses for the UART *)
  21.    COM2_Base = $02F8;
  22.  
  23.    COM1_Irq = 4;         (* Interrupt line for the UART *)
  24.    COM2_Irq = 3;
  25.  
  26. Const
  27.  
  28.    Async_DSeg_Save : Integer = 0;  (* Save DS reg in Code Segment for *)
  29.                                    (* interrupt routine               *)
  30.  
  31.  
  32. Const
  33.  
  34.    Async_Buffer_Max    = 8191;       (* Size of Communications Buffer   *)
  35.    Async_Loops_Per_Sec = 6500;       (* Loops per second -- 4.77 clock  *)
  36.    TimeOut             = 256;        (* TimeOut value                   *)
  37.  
  38. Var
  39.                                      (* Communications Buffer Itself *)
  40.  
  41.    Async_Buffer          : Array[0..Async_Buffer_Max] of Char;
  42.  
  43.    Async_Open_Flag       : Boolean;  (* true if Open but no Close         *)
  44.    Async_Port            : Integer;  (* current Open port number (1 or 2) *)
  45.    Async_Base            : Integer;  (* base for current open port        *)
  46.    Async_Irq             : Integer;  (* irq for current open port         *)
  47.  
  48.    Async_Buffer_Overflow : Boolean;  (* True if buffer overflow has happened *)
  49.    Async_Buffer_Used     : Integer;
  50.    Async_MaxBufferUsed   : Integer;
  51.  
  52.                                      (* Async_Buffer empty if Head = Tail    *)
  53.    Async_Buffer_Head    : Integer;   (* Loc in Async_Buffer to put next char *)
  54.    Async_Buffer_Tail    : Integer;   (* Loc in Async_Buffer to get next char *)
  55.    Async_Buffer_NewTail : Integer;
  56.  
  57.  
  58. Procedure BIOS_RS232_Init( ComPort, ComParm : Integer );
  59.  
  60.  
  61. Var
  62.    Regs: RegPack;
  63.  
  64. Begin   (* BIOS_RS232_Init *)
  65.  
  66.    With Regs Do
  67.       Begin
  68.          Ax := ComParm AND $00FF;  (* AH=0; AL=ComParm   *)
  69.          Dx := ComPort;            (* Port number to use *)
  70.          INTR($14, Regs);
  71.       End;
  72.  
  73. End    (* BIOS_RS232_Init *);
  74.  
  75.  
  76.  
  77. Procedure DOS_Set_Intrpt( v, s, o : Integer );
  78.  
  79.  
  80. Var
  81.    Regs : Regpack;
  82.  
  83. Begin   (* DOS_Set_Intrpt *)
  84.  
  85.    With Regs Do
  86.       Begin
  87.          Ax := $2500 + ( v AND $00FF );
  88.          Ds := s;
  89.          Dx := o;
  90.          MsDos( Regs );
  91.       End;
  92.  
  93. End    (* DOS_Set_Intrpt *);
  94.  
  95.  
  96. Procedure Async_Isr;
  97.  
  98.  
  99. Begin   (* Async_Isr *)
  100.  
  101.  
  102.   Inline(
  103.       (* save all registers used *)
  104.     $50/                           (* PUSH AX *)
  105.     $53/                           (* PUSH BX *)
  106.     $52/                           (* PUSH DX *)
  107.     $1E/                           (* PUSH DS *)
  108.     $FB/                           (* STI *)
  109.       (* set up the DS register to point to Turbo Pascal's data segment *)
  110.     $2E/$FF/$36/Async_Dseg_Save/   (* PUSH CS:Async_Dseg_Save *)
  111.     $1F/                           (* POP DS *)
  112.       (* get the incomming character *)
  113.       (* Async_Buffer[Async_Buffer_Head] := Chr(Port[UART_RBR + Async_Base]); *)
  114.     $8B/$16/Async_Base/            (* MOV DX,Async_Base *)
  115.     $EC/                           (* IN AL,DX *)
  116.     $8B/$1E/Async_Buffer_Head/     (* MOV BX,Async_Buffer_Head *)
  117.     $88/$87/Async_Buffer/          (* MOV Async_Buffer[BX],AL *)
  118.       (* Async_Buffer_NewHead := Async_Buffer_Head + 1; *)
  119.     $43/                           (* INC BX *)
  120.       (* if Async_Buffer_NewHead > Async_Buffer_Max then
  121.           Async_Buffer_NewHead := 0; *)
  122.     $81/$FB/Async_Buffer_Max/      (* CMP BX,Async_Buffer_Max *)
  123.     $7E/$02/                       (* JLE L001 *)
  124.     $33/$DB/                       (* XOR BX,BX *)
  125.       (* if Async_Buffer_NewHead = Async_Buffer_Tail then
  126.           Async_Buffer_Overflow := TRUE
  127.         else *)
  128. (*L001:*)
  129.     $3B/$1E/Async_Buffer_Tail/     (* CMP BX,Async_Buffer_Tail *)
  130.     $75/$08/                       (* JNE L002 *)
  131.     $C6/$06/Async_Buffer_Overflow/$01/ (* MOV Async_Buffer_Overflow,1 *)
  132.     $90/                           (* NOP generated by assembler for some reason *)
  133.     $EB/$16/                       (* JMP SHORT L003 *)
  134.       (* begin
  135.           Async_Buffer_Head := Async_Buffer_NewHead;
  136.           Async_Buffer_Used := Async_Buffer_Used + 1;
  137.           if Async_Buffer_Used > Async_MaxBufferUsed then
  138.             Async_MaxBufferUsed := Async_Buffer_Used
  139.         end; *)
  140. (*L002:*)
  141.     $89/$1E/Async_Buffer_Head/     (* MOV Async_Buffer_Head,BX *)
  142.     $FF/$06/Async_Buffer_Used/     (* INC Async_Buffer_Used *)
  143.     $8B/$1E/Async_Buffer_Used/     (* MOV BX,Async_Buffer_Used *)
  144.     $3B/$1E/Async_MaxBufferUsed/   (* CMP BX,Async_MaxBufferUsed *)
  145.     $7E/$04/                       (* JLE L003 *)
  146.     $89/$1E/Async_MaxBufferUsed/   (* MOV Async_MaxBufferUsed,BX *)
  147. (*L003:*)
  148.       (* disable interrupts *)
  149.     $FA/                           (* CLI *)
  150.       (* Port[$20] := $20; *)  (* use non-specific EOI *)
  151.     $B0/$20/                       (* MOV AL,20h *)
  152.     $E6/$20/                       (* OUT 20h,AL *)
  153.       (* restore the registers then use IRET to return *)
  154.       (* the last two POPs are required because Turbo Pascal PUSHes these regs
  155.         before we get control.  The manual doesn't say so, but that is what
  156.         really happens *)
  157.     $1F/                           (* POP DS *)
  158.     $5A/                           (* POP DX *)
  159.     $5B/                           (* POP BX *)
  160.     $58/                           (* POP AX *)
  161.     $5C/                           (* POP SP *)
  162.     $5D/                           (* POP BP *)
  163.     $CF)                           (* IRET *)
  164.  
  165. End    (* Async_Isr *);
  166.  
  167. (*----------------------------------------------------------------------*)
  168. (*               Async_Init --- Initialize Asynchronous Variables       *)
  169. (*----------------------------------------------------------------------*)
  170.  
  171. Procedure Async_Init;
  172.  
  173. (*                                                                      *)
  174. (*     Procedure:  Async_Init                                           *)
  175. (*                                                                      *)
  176. (*     Purpose:    Initializes variables                                *)
  177. (*                                                                      *)
  178. (*     Calling Sequence:                                                *)
  179. (*                                                                      *)
  180. (*        Async_Init;                                                   *)
  181. (*                                                                      *)
  182. (*     Calls:  None                                                     *)
  183. (*                                                                      *)
  184.  
  185. Begin   (* Async_Init *)
  186.  
  187.   Async_DSeg_Save       := DSeg;
  188.   Async_Open_Flag       := FALSE;
  189.   Async_Buffer_Overflow := FALSE;
  190.   Async_Buffer_Used     := 0;
  191.   Async_MaxBufferUsed   := 0;
  192.  
  193. End     (* Async_Init *);
  194.  
  195. (*----------------------------------------------------------------------*)
  196. (*               Async_Close --- Close down communications interrupts   *)
  197. (*----------------------------------------------------------------------*)
  198.  
  199. Procedure Async_Close;
  200.  
  201. (*                                                                      *)
  202. (*     Procedure:  Async_Close                                          *)
  203. (*                                                                      *)
  204. (*     Purpose:    Resets interrupt system when UART interrupts         *)
  205. (*                 are no longer needed.                                *)
  206. (*                                                                      *)
  207. (*     Calling Sequence:                                                *)
  208. (*                                                                      *)
  209. (*        Async_Close;                                                  *)
  210. (*                                                                      *)
  211. (*     Calls:  None                                                     *)
  212. (*                                                                      *)
  213.  
  214. Var
  215.    i : Integer;
  216.    m : Integer;
  217.  
  218. Begin  (* Async_Close *)
  219.  
  220.    If Async_Open_Flag Then
  221.       Begin
  222.  
  223.                      (* disable the IRQ on the 8259 *)
  224.  
  225.          Inline($FA);                 (* disable interrupts *)
  226.  
  227.          i := Port[I8088_IMR];        (* get the interrupt mask register *)
  228.          m := 1 shl Async_Irq;        (* set mask to turn off interrupt  *)
  229.          Port[I8088_IMR] := i or m;
  230.  
  231.                      (* disable the 8250 data ready interrupt *)
  232.  
  233.          Port[UART_IER + Async_Base] := 0;
  234.  
  235.                      (* disable OUT2 on the 8250 *)
  236.  
  237.          Port[UART_MCR + Async_Base] := 0;
  238.  
  239.          Inline($FB);                 (* enable interrupts *)
  240.  
  241.                      (* re-initialize our data areas so we know *)
  242.                      (* the port is closed                      *)
  243.  
  244.          Async_Open_Flag := FALSE;
  245.  
  246.       End;
  247.  
  248. End    (* Async_Close *);
  249.  
  250. (*----------------------------------------------------------------------*)
  251. (*               Async_Open --- Open communications port                *)
  252. (*----------------------------------------------------------------------*)
  253.  
  254. Function Async_Open( ComPort       : Integer;
  255.                      BaudRate      : Integer;
  256.                      Parity        : Char;
  257.                      WordSize      : Integer;
  258.                      StopBits      : Integer  ) : Boolean;
  259.  
  260. (*                                                                      *)
  261. (*     Function:   Async_Open                                           *)
  262. (*                                                                      *)
  263. (*     Purpose:    Opens communications port                            *)
  264. (*                                                                      *)
  265. (*     Calling Sequence:                                                *)
  266. (*                                                                      *)
  267. (*        Flag := Async_Open( ComPort       : Integer;                  *)
  268. (*                            BaudRate      : Integer;                  *)
  269. (*                            Parity        : Char;                     *)
  270. (*                            WordSize      : Integer;                  *)
  271. (*                            StopBits      : Integer) : Boolean;       *)
  272. (*                                                                      *)
  273. (*           ComPort  --- which port (1 or 2)                           *)
  274. (*           BaudRate --- Baud rate (110 to 9600)                       *)
  275. (*           Parity   --- "E" for even, "O" for odd, "N" for none       *)
  276. (*           WordSize --- Bits per character  (5 through 8)             *)
  277. (*           StopBits --- How many stop bits  (1 or 2)                  *)
  278. (*                                                                      *)
  279. (*                                                                      *)
  280. (*     Calls:                                                           *)
  281. (*                                                                      *)
  282. (*        BIOS_RS232_Init --- initialize RS232 port                     *)
  283. (*        DOS_Set_Intrpt  --- set address of RS232 interrupt routine    *)
  284. (*                                                                      *)
  285.  
  286. Const   (* Baud Rate Constants *)
  287.  
  288.    Async_Num_Bauds = 8;
  289.  
  290.    Async_Baud_Table : Array [1..Async_Num_Bauds] Of Record
  291.                                                        Baud, Bits : Integer;
  292.                                                     End
  293.  
  294.                     = ( ( Baud: 110;  Bits: $00 ),
  295.                         ( Baud: 150;  Bits: $20 ),
  296.                         ( Baud: 300;  Bits: $40 ),
  297.                         ( Baud: 600;  Bits: $60 ),
  298.                         ( Baud: 1200; Bits: $80 ),
  299.                         ( Baud: 2400; Bits: $A0 ),
  300.                         ( Baud: 4800; Bits: $C0 ),
  301.                         ( Baud: 9600; Bits: $E0 ) );
  302.  
  303. Var
  304.    ComParm : Integer;
  305.    i       : Integer;
  306.    m       : Integer;
  307.  
  308. Begin  (* Async_Open *)
  309.  
  310.                              (* If port open, close it down first. *)
  311.  
  312.    If Async_Open_Flag Then Async_Close;
  313.  
  314.                              (* Choose communications port *)
  315.    If ComPort = 2 Then
  316.       Begin
  317.          Async_Port := 2;
  318.          Async_Base := COM2_Base;
  319.          Async_Irq  := COM2_Irq;
  320.       End
  321.    Else
  322.       Begin
  323.          Async_Port := 1;  (* default to COM1 *)
  324.          Async_Base := COM1_Base;
  325.          Async_Irq  := COM1_Irq;
  326.       End;
  327.  
  328.    If (Port[UART_IIR + Async_Base] and $00F8) <> 0 Then
  329.       Async_Open := FALSE    (* Serial port not installed *)
  330.    Else
  331.       Begin   (* Open the port *)
  332.  
  333.                    (* Set buffer pointers *)
  334.  
  335.          Async_Buffer_Head     := 0;
  336.          Async_Buffer_Tail     := 0;
  337.          Async_Buffer_Overflow := FALSE;
  338.  
  339.             (*---------------------------------------------------*)
  340.             (*    Build the ComParm for RS232_Init               *)
  341.             (*    See Technical Reference Manual for description *)
  342.             (*---------------------------------------------------*)
  343.  
  344.                    (* Set up the bits for the baud rate *)
  345.  
  346.          If BaudRate > 9600 Then
  347.             BaudRate := 9600
  348.          Else If BaudRate <= 0 Then
  349.             BaudRate := 300;
  350.  
  351.          i := 0;
  352.  
  353.          Repeat
  354.             i := i + 1
  355.          Until ( ( i >= Async_Num_Bauds ) OR
  356.                  ( BaudRate = Async_Baud_Table[i].Baud ) );
  357.  
  358.          ComParm := Async_Baud_Table[i].Bits;
  359.  
  360.                    (* Choose Parity *)
  361.  
  362.          If Parity In ['E', 'e'] Then
  363.             ComParm := ComParm or $0018
  364.          Else If Parity In ['O', 'o'] Then
  365.             ComParm := ComParm or $0008;
  366.  
  367.                    (* Choose number of data bits *)
  368.  
  369.          WordSize := WordSize - 5;
  370.  
  371.          If ( WordSize < 0 ) OR ( WordSize > 3 ) Then
  372.             WordSize := 3;
  373.  
  374.          ComParm := ComParm OR WordSize;
  375.  
  376.                    (* Choose stop bits *)
  377.  
  378.          If StopBits = 2 Then
  379.             ComParm := ComParm OR $0004;  (* default is 1 stop bit *)
  380.  
  381.                    (* use the BIOS COM port initialization routine *)
  382.  
  383.          BIOS_RS232_Init( Async_Port - 1 , ComParm );
  384.  
  385.          DOS_Set_Intrpt( Async_Irq + 8 , CSeg , Ofs( Async_Isr ) );
  386.  
  387.                    (* Read the RBR and reset any pending error conditions. *)
  388.                    (* First turn off the Divisor Access Latch Bit to allow *)
  389.                    (* access to RBR, etc.                                  *)
  390.  
  391.          Inline($FA);  (* disable interrupts *)
  392.  
  393.          Port[UART_LCR + Async_Base] := Port[UART_LCR + Async_Base] and $7F;
  394.  
  395.                    (* Read the Line Status Register to reset any errors *)
  396.                    (* it indicates                                      *)
  397.  
  398.          i := Port[UART_LSR + Async_Base];
  399.  
  400.                    (* Read the Receiver Buffer Register in case it *)
  401.                    (* contains a character                         *)
  402.  
  403.          i := Port[UART_RBR + Async_Base];
  404.  
  405.                    (* enable the irq on the 8259 controller *)
  406.  
  407.          i := Port[I8088_IMR];  (* get the interrupt mask register *)
  408.          m := (1 shl Async_Irq) xor $00FF;
  409.  
  410.          Port[I8088_IMR] := i and m;
  411.  
  412.                    (* enable the data ready interrupt on the 8250 *)
  413.  
  414.          Port[UART_IER + Async_Base] := $01;
  415.  
  416.                    (* enable OUT2 on 8250 *)
  417.  
  418.          i := Port[UART_MCR + Async_Base];
  419.          Port[UART_MCR + Async_Base] := i or $08;
  420.  
  421.  
  422.          Inline($FB); (* enable interrupts *)
  423.  
  424.          Async_Open := TRUE
  425.  
  426.     End;
  427.  
  428. End   (* Async_Open *);
  429.  
  430. (*----------------------------------------------------------------------*)
  431. (*      Async_Carrier_Detect --- Check for modem carrier detect         *)
  432. (*----------------------------------------------------------------------*)
  433.  
  434. Function Carrier : Boolean;
  435.  
  436. (*                                                                      *)
  437. (*     Function:   Async_Carrier_Detect                                 *)
  438. (*                                                                      *)
  439. (*     Purpose:    Looks for modem carrier detect                       *)
  440. (*                                                                      *)
  441. (*     Calling Sequence:                                                *)
  442. (*                                                                      *)
  443. (*        Flag := Async_Carrier_Detect : Boolean;                       *)
  444. (*                                                                      *)
  445. (*           Flag is set TRUE if carrier detected, else FALSE.          *)
  446. (*                                                                      *)
  447. (*     Calls:  None                                                     *)
  448. (*                                                                      *)
  449.  
  450. Begin (* Async_Carrier_Detect *)
  451.  
  452.    Carrier := ODD( Port[ UART_MSR + Async_Base ] SHR 7 );
  453.  
  454. End   (* Async_Carrier_Detect *);
  455.  
  456. (*----------------------------------------------------------------------*)
  457. (*      Async_Term_Ready --- Set terminal ready status                  *)
  458. (*----------------------------------------------------------------------*)
  459.  
  460. Procedure Setterminalready ( Ready_Status : Boolean );
  461.  
  462.  
  463. Var
  464.    Mcr_Value: Byte;
  465.  
  466. Begin (* Async_Term_Ready *)
  467.  
  468.    Mcr_Value := Port[ UART_MCR + Async_Base ];
  469.  
  470.    If ODD( Mcr_Value ) Then Mcr_Value := Mcr_Value - 1;
  471.  
  472.    If Ready_Status Then Mcr_Value := Mcr_Value + 1;
  473.  
  474.    Port[ UART_MCR + Async_Base ] := Mcr_Value;
  475.  
  476. End   (* Async_Term_Ready *);
  477.  
  478. (*----------------------------------------------------------------------*)
  479. (*          Async_Buffer_Check --- Check if character in buffer         *)
  480. (*----------------------------------------------------------------------*)
  481.  
  482. Function numchars: integer;
  483.  
  484. (*                                                                      *)
  485. (*     Function:   Async_Buffer_Check                                   *)
  486. (*                                                                      *)
  487. (*     Purpose:    Check if character in buffer                         *)
  488. (*                                                                      *)
  489. (*     Calling Sequence:                                                *)
  490. (*                                                                      *)
  491. (*        Flag := Async_Buffer_Check : Boolean;                         *)
  492. (*                                                                      *)
  493. (*           Flag returned TRUE if character received in buffer,        *)
  494. (*           Flag returned FALSE if no character received.              *)
  495. (*                                                                      *)
  496. (*     Calls:  None                                                     *)
  497. (*                                                                      *)
  498. (*     Remarks:                                                         *)
  499. (*                                                                      *)
  500. (*       This routine only checks if a character has been received      *)
  501. (*       and thus can be read; it does NOT return the character.        *)
  502. (*       Use Async_Receive to read the character.                       *)
  503. (*                                                                      *)
  504.  
  505. Begin   (* Async_Buffer_Check *)
  506.  
  507. if Async_Buffer_Head<>Async_Buffer_Tail then
  508.    numchars :=2 else numchars:=0;
  509.  
  510. End     (* Async_Buffer_Check *);
  511.  
  512. (*----------------------------------------------------------------------*)
  513. (*          Async_Receive --- Return character from buffer              *)
  514. (*----------------------------------------------------------------------*)
  515.  
  516. Function getchar: char;
  517. var c:char;
  518. (*                                                                      *)
  519. (*     Function:   Async_Receive                                        *)
  520. (*                                                                      *)
  521. (*     Purpose:    Retrieve character (if any) from buffer              *)
  522. (*                                                                      *)
  523. (*     Calling Sequence:                                                *)
  524. (*                                                                      *)
  525. (*        Flag := Async_Receive( Var C: Char ) : Boolean;               *)
  526. (*                                                                      *)
  527. (*           C --- character (if any) retrieved from buffer;            *)
  528. (*                 set to CHR(0) if no character available.             *)
  529. (*                                                                      *)
  530. (*           Flag returned TRUE if character retrieved from buffer,     *)
  531. (*           Flag returned FALSE if no character retrieved.             *)
  532. (*                                                                      *)
  533. (*     Calls:  None                                                     *)
  534. (*                                                                      *)
  535.  
  536. Begin   (* Async_Receive *)
  537.  
  538.  
  539.  
  540.          INLINE( $FA );       (* CLI --- Turn off interrupts *)
  541.  
  542.          c := Async_Buffer[ Async_Buffer_Tail ];
  543.              Async_Buffer_Tail := Async_Buffer_Tail + 1;
  544.          If Async_Buffer_Tail > Async_Buffer_Max Then
  545.             Async_Buffer_Tail := 0;
  546.          INLINE( $FB );       (* STI --- Turn on interrupts *)
  547.      Async_Buffer_Used  := Async_Buffer_Used - 1;
  548.  
  549.          getchar:=c;
  550.  
  551. End   (* Async_Receive *);
  552.  
  553.  
  554. (*----------------------------------------------------------------------*)
  555. (*          Async_Send --- Send character over communications port      *)
  556. (*----------------------------------------------------------------------*)
  557.  
  558. Procedure sendchar( C : Char );
  559.  
  560.  
  561. Var
  562.    i       : Integer;
  563.    m       : Integer;
  564.    Counter : Integer;
  565.  
  566. Begin   (* Async_Send *)
  567.  
  568.                    (* Turn on OUT2, DTR, and RTS *)
  569.  
  570.    Port[UART_MCR + Async_Base] := $0B;
  571.  
  572.                    (* Wait for CTS using Busy Wait *)
  573.  
  574.    Counter := MaxInt;
  575.  
  576.    While ( Counter <> 0 ) AND
  577.          ( ( Port[UART_MSR + Async_Base] AND $10 ) = 0 ) Do
  578.       Counter := Counter - 1;
  579.  
  580.    If Counter <> 0 Then Counter := MaxInt;
  581.  
  582.    While ( Counter <> 0 ) AND
  583.          ( ( Port[UART_LSR + Async_Base] AND $20 ) = 0 ) Do
  584.       Counter := Counter - 1;
  585.   If Counter <> 0 Then
  586.      Begin  (* Send the Character *)
  587.  
  588.         Inline($FA); (* CLI --- disable interrupts *)
  589.  
  590.         Port[UART_THR + Async_Base] := Ord(C);
  591.  
  592.         Inline($FB); (* STI --- enable interrupts *)
  593.  
  594.      End;    (* Send the Character *)
  595.  
  596.  
  597. End    (* Async_Send *);
  598.  
  599.  
  600.  
  601.  
  602. var icomoffset:integer;
  603. FUNCTION HUNGUPON:BOOLEAN;FORWARD;
  604.  
  605.  
  606.  
  607.  
  608.  
  609. procedure hangup;
  610. var r:regpack;
  611. begin
  612. setterminalready(false);
  613.  delay (200);
  614. end;
  615.  
  616.  
  617. procedure UNINIT;
  618. var r:regpack;
  619. begin
  620. Async_close;
  621. end;
  622.  
  623.  
  624. procedure setparam (comnum:byte; baud:integer; parity:boolean);
  625. var r:regpack;
  626.     p:byte;
  627.     yomama:boolean;
  628. begin
  629.  
  630.   case comnum of
  631.     1:icomoffset:=0;
  632.     2:icomoffset:=-256
  633.   end;
  634.   async_init;
  635. repeat until Async_Open (comnum,baud,'N',8,1);
  636.  setterminalready(true);
  637. end;
  638.  
  639.  
  640.  
  641. procedure dontanswer;
  642. begin
  643.   setterminalready (false)
  644. end;
  645.  
  646. procedure doanswer;
  647. begin
  648.   setterminalready (true)
  649. end;
  650.  
  651. function waitchar:char;
  652. begin
  653. while (not hungupon) and (numchars<1) do;
  654. IF NOT HUNGUPON THEN WAITCHAR:=GETCHAR;
  655. end;
  656.  
  657.