home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / PAS_ALL.ZIP / TI407.ASC < prev    next >
Encoding:
Text File  |  1991-09-11  |  26.2 KB  |  925 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.   PRODUCT  :  TURBO PASCAL                           NUMBER  :  407
  9.   VERSION  :  4.0xx
  10.        OS  :  PC-DOS
  11.      DATE  :  January 28, 1988                        PAGE  :  1/13
  12.  
  13.     TITLE  :  ASYNCHRONOUS COMMUNICATIONS
  14.  
  15.  
  16.  
  17.  
  18.   This  version  of Michael Quinlan's ASYNC.INC is compatible  with
  19.   IBM  PC  and  Compatibles.  It  gives  interrupt-driven  buffered
  20.   communication capabilities  to Turbo Pascal  programs written for
  21.   the IBM PC. It is heavily dependent on that hardware.
  22.  
  23.   The Async_ITR routine was taken  from  N.  Arley  Dealey's Async4
  24.   procedures, to make this set of routines work with version 4.0 of
  25.   Turbo Pascal.
  26.  
  27.   The  following example routines are public domain  programs  that
  28.   have  been uploaded to our Forum on CompuServe.  As a courtesy to
  29.   our  users  that  do not have  immediate  access  to  CompuServe,
  30.   Technical Support distributes these routines free of charge.
  31.  
  32.   However,  because these routines are public domain programs,  not
  33.   developed by Borland International,  we are unable to provide any
  34.   technical support or assistance using these routines. If you need
  35.   assistance   using   these   routines,    or   are   experiencing
  36.   difficulties,  we  recommend  that you log  onto  CompuServe  and
  37.   request  assistance  from the Forum members that developed  these
  38.   routines.
  39.   }
  40.  
  41.   Unit Async;
  42.  
  43.   Interface
  44.  
  45.   Uses DOS;
  46.   {--------------------------------------------------------------}
  47.   {                        ASYNC.INC                             }
  48.   {                                                              }
  49.   {  Async Communication Routines                                }
  50.   {  by Michael Quinlan                                          }
  51.   {  with a bug fixed by Scott Herr                              }
  52.   {  with Async_ISR update to 4.0 by N. Arley Dealey substituted }
  53.   {                               by Keith Hawes                 }
  54.   {  made PCjr-compatible by W. M. Miller                        }
  55.   {  Highly dependent on the IBM PC and PC DOS 2.0 or later      }
  56.   {                                                              }
  57.   {  based on the DUMBTERM program by CJ Dunford                 }
  58.   {  in the January 1984                                         }
  59.   {  issue of PC Tech Journal.                                   }
  60.   {                                                              }
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.   PRODUCT  :  TURBO PASCAL                           NUMBER  :  407
  75.   VERSION  :  4.0xx
  76.        OS  :  PC-DOS
  77.      DATE  :  January 28, 1988                        PAGE  :  2/13
  78.  
  79.     TITLE  :  ASYNCHRONOUS COMMUNICATIONS
  80.  
  81.  
  82.  
  83.  
  84.   {  Entry points:                                               }
  85.   {--------------------------------------------------------------}
  86.  
  87.   Procedure Async_Init;
  88.   {--------------------------------------------------------------}
  89.   {      Performs initialization.                                }
  90.   {                                                              }
  91.   {--------------------------------------------------------------}
  92.  
  93.   function Async_Open(ComPort       : Word;
  94.                       BaudRate      : Word;
  95.                       Parity        : Char;
  96.                       WordSize      : Word;
  97.                       StopBits      : Word) : Boolean;
  98.   {--------------------------------------------------------------}
  99.   {   Sets up interrupt vector, initialize the COM port for      }
  100.   {   processing, sets pointers to the buffer.  Returns FALSE    }
  101.   {   if COM port not installed.                                 }
  102.   {--------------------------------------------------------------}
  103.  
  104.   Function Async_Buffer_Check(var C : Char) : Boolean;
  105.   {--------------------------------------------------------------}
  106.   {      If a character is available, returns TRUE and moves the }
  107.   {        character from the buffer to the parameter            }
  108.   {      Otherwise, returns FALSE                                }
  109.   {--------------------------------------------------------------}
  110.  
  111.   Procedure Async_Send(C : Char);
  112.   {--------------------------------------------------------------}
  113.   {      Transmits the character.                                }
  114.   {--------------------------------------------------------------}
  115.  
  116.   Procedure Async_Send_String(S : string);
  117.   {--------------------------------------------------------------}
  118.   {      Calls Async_Send to send each character of S.           }
  119.   {--------------------------------------------------------------}
  120.  
  121.   Procedure Async_Close;
  122.   {--------------------------------------------------------------}
  123.   {    Turns off the COM port interrupts.                        }
  124.   {    ** MUST ** BE CALLED BEFORE EXITING YOUR PROGRAM;         }
  125.   {    otherwise you will see some really strange errors and     }
  126.   {    to re-boot.                                               }
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.   PRODUCT  :  TURBO PASCAL                           NUMBER  :  407
  141.   VERSION  :  4.0xx
  142.        OS  :  PC-DOS
  143.      DATE  :  January 28, 1988                        PAGE  :  3/13
  144.  
  145.     TITLE  :  ASYNCHRONOUS COMMUNICATIONS
  146.  
  147.  
  148.  
  149.  
  150.   {--------------------------------------------------------------}
  151.  
  152.   procedure Async_Change(BaudRate      : Word;
  153.                          Parity        : Char;
  154.                          WordSize      : Word;
  155.                          StopBits      : Word);
  156.   {--------------------------------------------------------------}
  157.   { Changes communication parameters "on the fly".               }
  158.   { You cannot use the BIOS routines because they drop DTR.      }
  159.   {--------------------------------------------------------------}
  160.  
  161.   var
  162.     Async_Buffer_Overflow : Boolean;
  163.                           { True if buffer overflow has happened }
  164.     Async_Buffer_Used     : Word;
  165.     Async_MaxBufferUsed   : Word;
  166.  
  167.   Implementation
  168.                                            { global declarations }
  169.  
  170.   const
  171.     UART_THR = $00;
  172.                  { offset from base of UART Registers for IBM PC }
  173.     UART_RBR = $00;
  174.     UART_IER = $01;
  175.     UART_IIR = $02;
  176.     UART_LCR = $03;
  177.     UART_MCR = $04;
  178.     UART_LSR = $05;
  179.     UART_MSR = $06;
  180.  
  181.     I8088_IMR = $21;
  182.                    { port address of the Interrupt Mask Register }
  183.  
  184.   const
  185.     Async_Buffer_Max     = 4095;
  186.   var
  187.     Async_Interrupt_Save : pointer;
  188.     Async_ExitProc_Save  : pointer;
  189.     Async_Buffer         : Array[0..Async_Buffer_Max] of char;
  190.     Async_Open_Flag      : Boolean;
  191.     Async_Port           : Word; { current Open port number     }
  192.                                  { (1 or 2)                     }
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.   PRODUCT  :  TURBO PASCAL                           NUMBER  :  407
  207.   VERSION  :  4.0xx
  208.        OS  :  PC-DOS
  209.      DATE  :  January 28, 1988                        PAGE  :  4/13
  210.  
  211.     TITLE  :  ASYNCHRONOUS COMMUNICATIONS
  212.  
  213.  
  214.  
  215.  
  216.     Async_Base           : Word; { base for current open port   }
  217.     Async_Irq            : Word; { irq for current open port    }
  218.  
  219.                          { Async_Buffer is empty if Head = Tail }
  220.  
  221.     Async_Buffer_Head    : Word;   { Locn in Async_Buffer to put }
  222.                                     { next char                  }
  223.     Async_Buffer_Tail    : Word;    { Locn in Async_Buffer to get}
  224.                                     { next char                  }
  225.     Async_Buffer_NewTail  : Word;
  226.  
  227.     Async_BIOS_Port_Table : Array[1..2] of Word absolute $40:0;
  228.       { This table is initialized by BIOS equipment determination}
  229.       { code at boot time to contain the base addresses for the  }
  230.       { installed async adapters.  A value of 0 means "not in-   }
  231.       { stalled."                                                }
  232.  
  233.   const
  234.     Async_Num_Bauds = 8;
  235.     Async_Baud_Table : array [1..Async_Num_Bauds] of record
  236.                                            Baud, Bits : Word
  237.                                         end
  238.                      = ((Baud:110;  Bits:$00),
  239.                         (Baud:150;  Bits:$20),
  240.                         (Baud:300;  Bits:$40),
  241.                         (Baud:600;  Bits:$60),
  242.                         (Baud:1200; Bits:$80),
  243.                         (Baud:2400; Bits:$A0),
  244.                         (Baud:4800; Bits:$C0),
  245.                         (Baud:9600; Bits:$E0));
  246.  
  247.   procedure BIOS_RS232_Init(ComPort, ComParm : Word);
  248.  
  249.   { Issue Interrupt $14 to initialize the UART   }
  250.   { Format of ComParm:  (From IBM Tech. Ref.)    }
  251.   {                                              }
  252.   { 7     6     5     4     3     2      1     0 }
  253.   { --Baud Rate--     -Parity   StopBit  Word Len}
  254.   {  000 =  110       x0 = None   0 = 1  10 = 7  }
  255.   {  001 =  150       01 = Odd    1 = 2  11 = 8  }
  256.   {  010 =  300       11 = Even                  }
  257.   {  011 =  600                                  }
  258.   {  100 = 1200                                  }
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.   PRODUCT  :  TURBO PASCAL                           NUMBER  :  407
  273.   VERSION  :  4.0xx
  274.        OS  :  PC-DOS
  275.      DATE  :  January 28, 1988                        PAGE  :  5/13
  276.  
  277.     TITLE  :  ASYNCHRONOUS COMMUNICATIONS
  278.  
  279.  
  280.  
  281.  
  282.   {  101 = 2400                                  }
  283.   {  110 = 4800                                  }
  284.   {  111 = 9600                                  }
  285.   {                                              }
  286.  
  287.   var
  288.     Regs : registers;
  289.   begin
  290.     with Regs do
  291.       begin
  292.         ax := ComParm and $00FF;  { AH=0; AL=ComParm }
  293.         dx := ComPort;
  294.         Intr($14, Regs)
  295.       end;
  296.   end; { BIOS_RS232_Init }
  297.  
  298.   {--------------------------------------------------------------}
  299.   {         ISR - Interrupt Service Routine                      }
  300.   {--------------------------------------------------------------}
  301.  
  302.   PROCEDURE Async_ISR ; INTERRUPT ;
  303.   { Interrupt Service Routine }
  304.   { Invoked when the USART has received a byte of data from the  }
  305.   { comm line re-written 9/10/84 in machine language ; original  }
  306.   { source left as comments re-written 1987 to work under Turbo  }
  307.   { Pascal Version 4.0                                           }
  308.  
  309.   BEGIN { ISR }
  310.     inline($FB/                                { STI }
  311.  
  312.       { get the incoming character }
  313.       { Async_Buffer[Async_Buffer_Head] :=
  314.                       CHR( port[Async_Base + UART_RBR] ) ;       }
  315.       $8B/$16/Async_Base/                    { MOV DX,Base       }
  316.       $EC/                                   { IN AL,DX          }
  317.       $8B/$1E/Async_Buffer_Head/             { MOV BX,BufferHead }
  318.       $88/$87/Async_Buffer/                  { MOV Buffer[BX],AL }
  319.  
  320.       { Async_Buffer_NewHead := SUCC( Async_Buffer_Head ) ;      }
  321.       $43/                                   { INC BX            }
  322.  
  323.       { IF Async_Buffer_NewHead > Async_Buffer_Max
  324.                                 THEN Async_Buffer_NewHead := 0 ; }
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337.  
  338.   PRODUCT  :  TURBO PASCAL                           NUMBER  :  407
  339.   VERSION  :  4.0xx
  340.        OS  :  PC-DOS
  341.      DATE  :  January 28, 1988                        PAGE  :  6/13
  342.  
  343.     TITLE  :  ASYNCHRONOUS COMMUNICATIONS
  344.  
  345.  
  346.  
  347.  
  348.       $81/$FB/Async_Buffer_Max/              { CMP BX,BufferMax  }
  349.       $7E/$02/                               { JLE L001          }
  350.       $33/$DB/                               { XOR BX,BX         }
  351.  
  352.       { IF Async_Buffer_NewHead = Async_Buffer_Tail THEN Overflow}
  353.       { := TRUE                                                  }
  354.       {L001:}
  355.       $3B/$1E/Async_Buffer_Tail/      { CMP BX,Async_Buffer_Tail }
  356.       $75/$08/                               { JNE L002          }
  357.       $C6/$06/Async_Buffer_Overflow/$01/     { MOV Overflow,1    }
  358.       $90/                                   { NOP generated by  }
  359.                                              { assembler         }
  360.       $EB/$16/                               { JMP SHORT L003    }
  361.       { ELSE BEGIN                                               }
  362.       { Async_Buffer_Head := Async_Buffer_NewHead ;              }
  363.       { Async_Buffer_Used  := SUCC( Async_Buffer_Used ) ;        }
  364.       { IF Async_Buffer_Used > Async_MaxBufferUsed THEN          }
  365.       {  Async_MaxBufferUsed := Async_BufferUsed                 }
  366.       {   END ;                                                  }
  367.       {L002:}
  368.       $89/$1E/Async_Buffer_Head/             { MOV BufferHead,BX }
  369.       $FF/$06/Async_Buffer_Used/          { INC Async_BufferUsed }
  370.       $8B/$1E/Async_Buffer_Used/       { MOV BX,Async_BufferUsed }
  371.       $3B/$1E/Async_MaxBufferUsed/  { CMP BX,Async_MaxBufferUsed }
  372.       $7E/$04/                               { JLE L003          }
  373.       $89/$1E/Async_MaxBufferUsed/  { MOV Async_MaxBufferUsed,BX }
  374.       {L003:}
  375.  
  376.       $FA/                                   { CLI               }
  377.  
  378.                                         { issue non-specific EOI }
  379.       { port[$20] := $20 ;                                       }
  380.       $B0/$20/                               { MOV AL,20h        }
  381.       $E6/$20                                { OUT 20h,AL        }
  382.       )
  383.     END { Async_ISR } ;
  384.  
  385.  
  386.   procedure Async_Init;
  387.   { initialize variables }
  388.   begin
  389.     Async_Open_Flag := FALSE;
  390.     Async_Buffer_Overflow := FALSE;
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402.  
  403.  
  404.   PRODUCT  :  TURBO PASCAL                           NUMBER  :  407
  405.   VERSION  :  4.0xx
  406.        OS  :  PC-DOS
  407.      DATE  :  January 28, 1988                        PAGE  :  7/13
  408.  
  409.     TITLE  :  ASYNCHRONOUS COMMUNICATIONS
  410.  
  411.  
  412.  
  413.  
  414.     Async_Buffer_Used := 0;
  415.     Async_MaxBufferUsed := 0;
  416.   end; { Async_Init }
  417.  
  418.   procedure Async_Close;
  419.   { reset the interrupt system when UART interrupts              }
  420.   { no longer needed                                             }
  421.   var
  422.     i, m : Word;
  423.   begin
  424.     if Async_Open_Flag then
  425.       begin
  426.  
  427.         { disable the IRQ on the 8259 }
  428.         Inline($FA);                         { disable interrupts }
  429.         i := Port[I8088_IMR];   { get the interrupt mask register }
  430.         m := 1 shl Async_Irq;    { set mask to turn off interrupt }
  431.         Port[I8088_IMR] := i or m;
  432.  
  433.         { disable the 8250 data ready interrupt }
  434.         Port[UART_IER + Async_Base] := 0;
  435.  
  436.         { disable OUT2 on the 8250 }
  437.         Port[UART_MCR + Async_Base] := 0;
  438.         Inline($FB);                         { enable interrupts  }
  439.  
  440.         { re-initialize our data areas so we know the port is     }
  441.         { closed                                                  }
  442.         Async_Open_Flag := FALSE;
  443.  
  444.         { Version 4 support by Keith Hawes next 2 lines           }
  445.         SetIntVec( Async_IRQ + 8, @Async_Interrupt_Save );
  446.                                           { Restore old interrupt }
  447.         ExitProc := Async_ExitProc_Save; { Restore ExitProc chain}
  448.       end
  449.   end; { Async_Close }
  450.  
  451.   function Async_Open(ComPort       : Word;
  452.                       BaudRate      : Word;
  453.                       Parity        : Char;
  454.                       WordSize      : Word;
  455.                       StopBits      : Word) : Boolean;
  456.   { open a communications port }
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.   PRODUCT  :  TURBO PASCAL                           NUMBER  :  407
  471.   VERSION  :  4.0xx
  472.        OS  :  PC-DOS
  473.      DATE  :  January 28, 1988                        PAGE  :  8/13
  474.  
  475.     TITLE  :  ASYNCHRONOUS COMMUNICATIONS
  476.  
  477.  
  478.  
  479.  
  480.   var
  481.     ComParm : Word;
  482.     i, m : Word;
  483.   begin
  484.     if Async_Open_Flag then Async_Close;
  485.  
  486.     if (ComPort = 2) and (Async_BIOS_Port_Table[2] <> 0) then
  487.       Async_Port := 2
  488.     else
  489.       Async_Port := 1;  { default to COM1 }
  490.     Async_Base := Async_BIOS_Port_Table[Async_Port];
  491.     Async_Irq := Hi(Async_Base) + 1;
  492.  
  493.     if (Port[UART_IIR + Async_Base] and $00F8) <> 0 then
  494.       Async_Open := FALSE
  495.     else
  496.       begin
  497.         Async_Buffer_Head := 0;
  498.         Async_Buffer_Tail := 0;
  499.         Async_Buffer_Overflow := FALSE;
  500.  
  501.     { Build the ComParm for RS232_Init }
  502.     { See Technical Reference Manual for description }
  503.  
  504.         ComParm := $0000;
  505.  
  506.     { Set up the bits for the baud rate }
  507.         i := 0;
  508.         repeat
  509.           i := i + 1
  510.         until (Async_Baud_Table[i].Baud = BaudRate)
  511.                 or (i = Async_Num_Bauds);
  512.         ComParm := ComParm or Async_Baud_Table[i].Bits;
  513.  
  514.         if Parity in ['E', 'e'] then ComParm := ComParm or $0018
  515.         else if Parity in ['O', 'o'] then
  516.              ComParm := ComParm or $0008
  517.         else ComParm := ComParm or $0000;  { default to No parity }
  518.         if WordSize = 7 then ComParm := ComParm or $0002
  519.         else ComParm := ComParm or $0003;
  520.                                          { default to 8 data bits }
  521.  
  522.         if StopBits = 2 then ComParm := ComParm or $0004
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.  
  535.  
  536.   PRODUCT  :  TURBO PASCAL                           NUMBER  :  407
  537.   VERSION  :  4.0xx
  538.        OS  :  PC-DOS
  539.      DATE  :  January 28, 1988                        PAGE  :  9/13
  540.  
  541.     TITLE  :  ASYNCHRONOUS COMMUNICATIONS
  542.  
  543.  
  544.  
  545.  
  546.         else ComParm := ComParm or $0000;
  547.                                           { default to 1 stop bit }
  548.  
  549.         { use the BIOS COM port initialization routine            }
  550.         { to save typing the code                                 }
  551.  
  552.         BIOS_RS232_Init(Async_Port - 1, ComParm);
  553.         GetIntVec( Async_Irq + 8, Async_Interrupt_Save );
  554.                                            { Version 4 support KH }
  555.         Async_ExitProc_Save := ExitProc; { Version 4 support KH }
  556.         ExitProc := @Async_Close;         { Version 4 support KH }
  557.         SetIntVec( Async_Irq + 8, @Async_Isr );
  558.                                            { Version 4 support KH }
  559.  
  560.   { Read the RBR and reset any possible pending error conditions. }
  561.   { First turn off the Divisor Access Latch Bit to allow access to}
  562.   { RBR, etc.                                                     }
  563.  
  564.         Inline($FA);                         { disable interrupts }
  565.  
  566.         Port[UART_LCR + Async_Base] :=
  567.                 Port[UART_LCR + Async_Base] and $7F;
  568.         { read the Line Status Register to reset any errors it    }
  569.         { indicates                                               }
  570.         i := Port[UART_LSR + Async_Base];
  571.         { read the Receiver Buffer Register in case it contains a }
  572.         { character                                               }
  573.         i := Port[UART_RBR + Async_Base];
  574.  
  575.         { enable the irq on the 8259 controller                   }
  576.         i := Port[I8088_IMR];   { get the interrupt mask register }
  577.         m := (1 shl Async_Irq) xor $00FF;
  578.         Port[I8088_IMR] := i and m;
  579.  
  580.         { enable the data ready interrupt on the 8250             }
  581.         Port[UART_IER + Async_Base] := $01;
  582.         { enable data ready interrupt                             }
  583.  
  584.         { enable OUT2 on 8250                                     }
  585.         i := Port[UART_MCR + Async_Base];
  586.         Port[UART_MCR + Async_Base] := i or $08;
  587.         Inline($FB);                         { enable interrupts  }
  588.         Async_Open_Flag := TRUE;          { bug fix by Scott Herr }
  589.  
  590.  
  591.  
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600.  
  601.  
  602.   PRODUCT  :  TURBO PASCAL                           NUMBER  :  407
  603.   VERSION  :  4.0xx
  604.        OS  :  PC-DOS
  605.      DATE  :  January 28, 1988                       PAGE  :  10/13
  606.  
  607.     TITLE  :  ASYNCHRONOUS COMMUNICATIONS
  608.  
  609.  
  610.  
  611.  
  612.         Async_Open := TRUE
  613.       end;
  614.   end; { Async_Open }
  615.  
  616.   function Async_Buffer_Check(var C : Char) : Boolean;
  617.         { see if a character has been received; return it if yes  }
  618.   begin
  619.     if Async_Buffer_Head = Async_Buffer_Tail then
  620.       Async_Buffer_Check := FALSE
  621.     else
  622.       begin
  623.         C := Async_Buffer[Async_Buffer_Tail];
  624.         Async_Buffer_Tail := Async_Buffer_Tail + 1;
  625.         if Async_Buffer_Tail > Async_Buffer_Max then
  626.           Async_Buffer_Tail := 0;
  627.         Async_Buffer_Used := Async_Buffer_Used - 1;
  628.         Async_Buffer_Check := TRUE
  629.       end
  630.   end; { Async_Buffer_Check }
  631.  
  632.   procedure Async_Send(C : Char);
  633.                                            { transmit a character }
  634.   var
  635.     i, m, counter : Word;
  636.   begin
  637.     Port[UART_MCR + Async_Base] := $0B;
  638.                                      { turn on OUT2, DTR, and RTS }
  639.  
  640.                                              { wait for CTS       }
  641.     counter := MaxInt;
  642.     while (counter <> 0) and
  643.           ((Port[UART_MSR + Async_Base] and $10) = 0) do
  644.       counter := counter - 1;
  645.  
  646.                    { wait for Transmit Hold Register Empty (THRE) }
  647.     if counter <> 0 then counter := MaxInt;
  648.     while (counter <> 0) and
  649.           ((Port[UART_LSR + Async_Base] and $20) = 0) do
  650.       counter := counter - 1;
  651.     if counter <> 0 then
  652.       begin
  653.                                              { send the character }
  654.         Inline($FA);                         { disable interrupts }
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662.  
  663.  
  664.  
  665.  
  666.  
  667.  
  668.   PRODUCT  :  TURBO PASCAL                           NUMBER  :  407
  669.   VERSION  :  4.0xx
  670.        OS  :  PC-DOS
  671.      DATE  :  January 28, 1988                       PAGE  :  11/13
  672.  
  673.     TITLE  :  ASYNCHRONOUS COMMUNICATIONS
  674.  
  675.  
  676.  
  677.  
  678.         Port[UART_THR + Async_Base] := Ord(C);
  679.         Inline($FB)                          { enable interrupts  }
  680.       end
  681.     else
  682.       writeln('<<<TIMEOUT>>>');
  683.   end; { Async_Send }
  684.  
  685.   procedure Async_Send_String(S : String);
  686.   { transmit a string }
  687.   var
  688.     i : Word;
  689.   begin
  690.     for i := 1 to length(S) do
  691.       Async_Send(S[i])
  692.   end; { Async_Send_String }
  693.  
  694.   procedure Async_Change(BaudRate      : Word;
  695.                          Parity        : Char;
  696.                          WordSize      : Word;
  697.                          StopBits      : Word);
  698.   { change communication parameters "on the fly"                 }
  699.   { you cannot use the BIOS routines because they drop DTR       }
  700.  
  701.   const num_bauds = 15;
  702.       divisor_table : array [1..num_bauds] of record
  703.                                               baud, divisor : Word
  704.                                             end
  705.          = ((baud:50;  divisor:2304),
  706.             (baud:75;  divisor:1536),
  707.             (baud:110; divisor:1047),
  708.             (baud:134; divisor:857),
  709.             (baud:150; divisor:768),
  710.             (baud:300; divisor:384),
  711.             (baud:600; divisor:192),
  712.             (baud:1200; divisor:96),
  713.             (baud:1800; divisor:64),
  714.             (baud:2000; divisor:58),
  715.             (baud:2400; divisor:48),
  716.             (baud:3600; divisor:32),
  717.             (baud:4800; divisor:24),
  718.             (baud:7200; divisor:16),
  719.             (baud:9600; divisor:12));
  720.  
  721.  
  722.  
  723.  
  724.  
  725.  
  726.  
  727.  
  728.  
  729.  
  730.  
  731.  
  732.  
  733.  
  734.   PRODUCT  :  TURBO PASCAL                           NUMBER  :  407
  735.   VERSION  :  4.0xx
  736.        OS  :  PC-DOS
  737.      DATE  :  January 28, 1988                       PAGE  :  12/13
  738.  
  739.     TITLE  :  ASYNCHRONOUS COMMUNICATIONS
  740.  
  741.  
  742.  
  743.  
  744.   var i : Word;
  745.       dv  : Word;
  746.       lcr : Word;
  747.   begin
  748.  
  749.     { Build the Line Control Register and find                   }
  750.     { the divisor (for the baud rate)                            }
  751.  
  752.     { Set up the divisor for the baud rate                       }
  753.     i := 0;
  754.     repeat
  755.       i := i + 1
  756.     until (Divisor_Table[i].Baud = BaudRate) or (i = Num_Bauds);
  757.     dv  := Divisor_Table[i].divisor;
  758.  
  759.     lcr := 0;
  760.     case Parity of
  761.       'E' : lcr := lcr or $18;  { even parity }
  762.       'O' : lcr := lcr or $08;  { odd parity }
  763.       'N' : lcr := lcr or $00;  { no parity }
  764.       'M' : lcr := lcr or $28;  { Mark parity }
  765.       'S' : lcr := lcr or $38;  { Space parity }
  766.     else
  767.       lcr := lcr or $00;  { default to no parity }
  768.     end;
  769.  
  770.     case WordSize of
  771.       5 : lcr := lcr or $00;
  772.       6 : lcr := lcr or $01;
  773.       7 : lcr := lcr or $02;
  774.       8 : lcr := lcr or $03;
  775.     else
  776.       lcr := lcr or $03;  { default to 8 data bits }
  777.     end;
  778.  
  779.     if StopBits = 2 then lcr := lcr or $04
  780.     else lcr := lcr or $00;  { default to 1 stop bit }
  781.  
  782.     lcr := lcr and $7F;   { make certain the DLAB is off }
  783.  
  784.     Inline($FA);  { disable interrupts }
  785.  
  786.     { turn on DLAB to access the divisor                         }
  787.  
  788.  
  789.  
  790.  
  791.  
  792.  
  793.  
  794.  
  795.  
  796.  
  797.  
  798.  
  799.  
  800.   PRODUCT  :  TURBO PASCAL                           NUMBER  :  407
  801.   VERSION  :  4.0xx
  802.        OS  :  PC-DOS
  803.      DATE  :  January 28, 1988                       PAGE  :  13/13
  804.  
  805.     TITLE  :  ASYNCHRONOUS COMMUNICATIONS
  806.  
  807.  
  808.  
  809.  
  810.     Port[UART_LCR + Async_Base] := Port[UART_LCR +
  811.                                        Async_Base] or $80;
  812.  
  813.     { set the divisor                                            }
  814.     Port[Async_Base] := Lo(dv);
  815.     Port[Async_Base + 1] := Hi(dv);
  816.  
  817.     { turn off the DLAB and set the new comm. parameters         }
  818.     Port[UART_LCR + Async_Base] := lcr;
  819.  
  820.     Inline($FB);  { enable interrupts }
  821.  
  822.   end; { Async_Change }
  823.   end.
  824.  
  825.   *****************************************************************
  826.     Test Program.... place in a  separate file and compile with the
  827.   Make option.
  828.  
  829.   program tty;
  830.   uses crt,async;
  831.   var
  832.     c : char;
  833.  
  834.   begin
  835.     Async_Init;  { initialize variables }
  836.     if not Async_Open(2, 1200, 'E', 7, 1) then
  837.                                        { open communications port }
  838.       begin
  839.         writeln('**ERROR: Async_Open failed');
  840.         halt
  841.       end;
  842.  
  843.     writeln('TTY Emulation begins now...');
  844.     writeln('Press ESC key to terminate...');
  845.  
  846.     repeat
  847.       if Async_Buffer_Check(c) then
  848.         case c of
  849.           #000 : ;  { strip incoming nulls }
  850.           #010 : ;  { strip incoming line feeds }
  851.           #012 : ClrScr;  { clear screen on a form feed }
  852.           #013 : Writeln  { handle carriage return as CR/LF }
  853.  
  854.  
  855.  
  856.  
  857.  
  858.  
  859.  
  860.  
  861.  
  862.  
  863.  
  864.  
  865.  
  866.   PRODUCT  :  TURBO PASCAL                           NUMBER  :  407
  867.   VERSION  :  4.0xx
  868.        OS  :  PC-DOS
  869.      DATE  :  January 28, 1988                       PAGE  :  14/13
  870.  
  871.     TITLE  :  ASYNCHRONOUS COMMUNICATIONS
  872.  
  873.  
  874.  
  875.  
  876.         else
  877.           write(c)  { else write incoming char to the screen }
  878.         end; { case }
  879.       if KeyPressed then
  880.         begin
  881.           c := readkey;
  882.           if c = #027 then  { Trap Esc Key }
  883.             begin
  884.               Async_Close;   { reset the interrupt system, etc. }
  885.               Writeln('End of TTY Emulation...');
  886.               halt;          { terminate the program }
  887.             end
  888.           else
  889.             Async_Send(c)
  890.         end;
  891.     until FALSE;
  892.   end.
  893.  
  894.   ****************************************************************
  895.  
  896.  
  897.  
  898.  
  899.  
  900.  
  901.  
  902.  
  903.  
  904.  
  905.  
  906.  
  907.  
  908.  
  909.  
  910.  
  911.  
  912.  
  913.  
  914.  
  915.  
  916.  
  917.  
  918.  
  919.  
  920.  
  921.  
  922.  
  923.  
  924.  
  925.