home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / progc / c_all592.arj / TI445.ASC < prev    next >
Text File  |  1992-02-25  |  20KB  |  793 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.   PRODUCT  :  TURBO C                                NUMBER  :  445
  9.   VERSION  :  1.0 & 1.5
  10.        OS  :  DOS 2.X & 3.X
  11.      DATE  :  OCTOBER 5, 1988                         PAGE  :  1/13
  12.  
  13.     TITLE  :  INTERRUPT DRIVEN SERIAL COMMUNICATIONS
  14.  
  15.  
  16.  
  17.  
  18.   /*-------------------------------------------------------------*
  19.                               SERIAL.C
  20.  
  21.      The following code shows how to take advantage of some of
  22.      the Turbo C extensions to the C language to do asynchronous
  23.      communications without having to write supporting assembly-
  24.      language routines.
  25.  
  26.      This program bypasses the less-than-adequate PC BIOS com-
  27.      munications routines and installs a serial interrupt handler.
  28.      Direct access to PC hardware allows the program to run at
  29.      faster baud rates and eliminates the need for the main
  30.      program to continuously poll the serial port for data; thus,
  31.      implementing background communications.  Data that enters
  32.      the serial port is stored in a circular buffer.
  33.  
  34.      * Compile this program with Test Stack Overflow OFF.
  35.    *-------------------------------------------------------------*/
  36.   #include "serial.h"
  37.   #include <dos.h>
  38.   #include <conio.h>
  39.   #include <stdio.h>
  40.   #include <string.h>
  41.  
  42.   #define VERSION 0x0101
  43.  
  44.   #define FALSE           0
  45.   #define TRUE            (!FALSE)
  46.  
  47.   #define NOERROR         0       /* No error               */
  48.   #define BUFOVFL         1       /* Buffer overflowed      */
  49.  
  50.   #define ESC             0x1B    /* ASCII Escape character */
  51.   #define ASCII           0x007F  /* Mask ASCII characters  */
  52.   #define SBUFSIZ         0x4000  /* Serial buffer size     */
  53.  
  54.   int            SError          = NOERROR;
  55.   int            portbase        = 0;
  56.   void           interrupt(*oldvects[2])();
  57.  
  58.   static   char  ccbuf[SBUFSIZ];
  59.   unsigned int   startbuf        = 0;
  60.   unsigned int   endbuf          = 0;
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.   PRODUCT  :  TURBO C                                NUMBER  :  445
  75.   VERSION  :  1.0 & 1.5
  76.        OS  :  DOS 2.X & 3.X
  77.      DATE  :  OCTOBER 5, 1988                         PAGE  :  2/13
  78.  
  79.     TITLE  :  INTERRUPT DRIVEN SERIAL COMMUNICATIONS
  80.  
  81.  
  82.  
  83.  
  84.   /* Handle communications interrupts and put them in ccbuf */
  85.   void   interrupt com_int(void)
  86.   {
  87.       disable();
  88.       if ((inportb(portbase + IIR) & RX_MASK) == RX_ID)
  89.       {
  90.           if (((endbuf + 1) & SBUFSIZ - 1) == startbuf)
  91.               SError = BUFOVFL;
  92.  
  93.          ccbuf[endbuf++] = inportb(portbase + RXR);
  94.           endbuf &= SBUFSIZ - 1;
  95.       }
  96.  
  97.       /* Signal end of hardware interrupt */
  98.       outportb(ICR, EOI);
  99.       enable();
  100.   }
  101.  
  102.   /* Output a character to the serial port */
  103.   int    SerialOut(char x)
  104.   {
  105.       long int   timeout = 0x0000FFFFL;
  106.  
  107.       outportb(portbase + MCR,  MC_INT | DTR | RTS);
  108.  
  109.       /* Wait for Clear To Send from modem */
  110.       while ((inportb(portbase + MSR) & CTS) == 0)
  111.           if (!(--timeout))
  112.               return (-1);
  113.  
  114.       timeout = 0x0000FFFFL;
  115.  
  116.       /* Wait for transmitter to clear */
  117.       while ((inportb(portbase + LSR) & XMTRDY) == 0)
  118.           if (!(--timeout))
  119.               return (-1);
  120.  
  121.       disable();
  122.       outportb(portbase + TXR, x);
  123.       enable();
  124.  
  125.       return (0);
  126.   }
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.   PRODUCT  :  TURBO C                                NUMBER  :  445
  141.   VERSION  :  1.0 & 1.5
  142.        OS  :  DOS 2.X & 3.X
  143.      DATE  :  OCTOBER 5, 1988                         PAGE  :  3/13
  144.  
  145.     TITLE  :  INTERRUPT DRIVEN SERIAL COMMUNICATIONS
  146.  
  147.  
  148.  
  149.  
  150.   /* Output a string to the serial port */
  151.   void   SerialString(char *string)
  152.   {
  153.       while (*string)
  154.          SerialOut(*string++);
  155.   }
  156.  
  157.   /* This routine returns the current value in the buffer */
  158.   int    getccb(void)
  159.   {
  160.       int                res;
  161.  
  162.       if (endbuf == startbuf)
  163.           return (-1);
  164.  
  165.       res = (int) ccbuf[startbuf++];
  166.       startbuf %= SBUFSIZ;
  167.       return (res);
  168.   }
  169.  
  170.   /* Install our functions to handle communications */
  171.   void   setvects(void)
  172.   {
  173.       oldvects[0] = getvect(0x0B);
  174.       oldvects[1] = getvect(0x0C);
  175.       setvect(0x0B, com_int);
  176.       setvect(0x0C, com_int);
  177.   }
  178.  
  179.   /* Uninstall our vectors before exiting the program */
  180.   void   resvects(void)
  181.   {
  182.       setvect(0x0B, oldvects[0]);
  183.       setvect(0x0C, oldvects[1]);
  184.   }
  185.  
  186.   /* Turn on communications interrupts */
  187.   void   i_enable(int pnum)
  188.   {
  189.       int                c;
  190.  
  191.       disable();
  192.       c = inportb(portbase + MCR) | MC_INT;
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.   PRODUCT  :  TURBO C                                NUMBER  :  445
  207.   VERSION  :  1.0 & 1.5
  208.        OS  :  DOS 2.X & 3.X
  209.      DATE  :  OCTOBER 5, 1988                         PAGE  :  4/13
  210.  
  211.     TITLE  :  INTERRUPT DRIVEN SERIAL COMMUNICATIONS
  212.  
  213.  
  214.  
  215.  
  216.       outportb(portbase + MCR, c);
  217.       outportb(portbase + IER, RX_INT);
  218.       c = inportb(IMR) & (pnum == COM1 ? IRQ4 : IRQ3);
  219.       outportb(IMR, c);
  220.       enable();
  221.   }
  222.  
  223.   /* Turn off communications interrupts */
  224.   void   i_disable(void)
  225.   {
  226.       int                c;
  227.  
  228.       disable();
  229.       c = inportb(IMR) | ~IRQ3 | ~IRQ4;
  230.       outportb(IMR, c);
  231.       outportb(portbase + IER, 0);
  232.       c = inportb(portbase + MCR) & ~MC_INT;
  233.       outportb(portbase + MCR, c);
  234.       enable();
  235.   }
  236.  
  237.   /* Tell modem that we're ready to go */
  238.   void   comm_on(void)
  239.   {
  240.       int                c, pnum;
  241.  
  242.       pnum = (portbase == COM1BASE ? COM1 : COM2);
  243.       i_enable(pnum);
  244.       c = inportb(portbase + MCR) | DTR | RTS;
  245.       outportb(portbase + MCR, c);
  246.   }
  247.  
  248.   /* Go off-line */
  249.   void   comm_off(void)
  250.   {
  251.       i_disable();
  252.       outportb(portbase + MCR, 0);
  253.   }
  254.  
  255.   void   initserial(void)
  256.   {
  257.       endbuf = startbuf = 0;
  258.       setvects();
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.   PRODUCT  :  TURBO C                                NUMBER  :  445
  273.   VERSION  :  1.0 & 1.5
  274.        OS  :  DOS 2.X & 3.X
  275.      DATE  :  OCTOBER 5, 1988                         PAGE  :  5/13
  276.  
  277.     TITLE  :  INTERRUPT DRIVEN SERIAL COMMUNICATIONS
  278.  
  279.  
  280.  
  281.  
  282.       comm_on();
  283.   }
  284.  
  285.   void   closeserial(void)
  286.   {
  287.       comm_off();
  288.       resvects();
  289.   }
  290.  
  291.   /* Set the port number to use */
  292.   int    SetPort(int Port)
  293.   {
  294.       int                Offset, far *RS232_Addr;
  295.  
  296.       switch (Port)
  297.       { /* Sort out the base address */
  298.         case COM1 : Offset = 0x0000;
  299.                     break;
  300.         case COM2 : Offset = 0x0002;
  301.                     break;
  302.         default   : return (-1);
  303.       }
  304.  
  305.       RS232_Addr = MK_FP(0x0040, Offset);  /* Find out where the
  306.                                               port is.  */
  307.       if (*RS232_Addr == NULL) return (-1);/* If NULL, then port
  308.                                               not used. */
  309.       portbase = *RS232_Addr;              /* Otherwise, set
  310.                                               portbase. */
  311.  
  312.       return (0);
  313.   }
  314.  
  315.   /* This routine sets the speed; will accept funny baud rates. */
  316.   /* Setting the speed requires that the DLAB be set on.        */
  317.   int    SetSpeed(int Speed)
  318.   {
  319.       char                c;
  320.       int         divisor;
  321.  
  322.       if (Speed == 0)            /* Avoid divide by zero */
  323.           return (-1);
  324.       else
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337.  
  338.   PRODUCT  :  TURBO C                                NUMBER  :  445
  339.   VERSION  :  1.0 & 1.5
  340.        OS  :  DOS 2.X & 3.X
  341.      DATE  :  OCTOBER 5, 1988                         PAGE  :  6/13
  342.  
  343.     TITLE  :  INTERRUPT DRIVEN SERIAL COMMUNICATIONS
  344.  
  345.  
  346.  
  347.  
  348.           divisor = (int) (115200L/Speed);
  349.  
  350.       if (portbase == 0)
  351.           return (-1);
  352.  
  353.       disable();
  354.       c = inportb(portbase + LCR);
  355.       outportb(portbase + LCR, (c | 0x80)); /* Set DLAB   */
  356.       outportb(portbase + DLL, (divisor & 0x00FF));
  357.       outportb(portbase + DLH, ((divisor >> 8) & 0x00FF));
  358.       outportb(portbase + LCR, c);          /* Reset DLAB */
  359.       enable();
  360.  
  361.       return (0);
  362.   }
  363.  
  364.   /* Set other communications parameters */
  365.   int    SetOthers(int Parity, int Bits, int StopBit)
  366.   {
  367.       int                setting;
  368.  
  369.       if (portbase == 0)                                  r e t urn
  370.   (-1);
  371.       if (Bits < 5 || Bits > 8)                           r e t urn
  372.   (-1);
  373.       if (StopBit != 1 && StopBit != 2)           return (-1);
  374.       if (Parity != NO_PARITY && Parity != ODD_PARITY && Parity !=
  375.           EVEN_PARITY)                         return (-1);
  376.  
  377.       setting  = Bits-5;
  378.       setting |= ((StopBit == 1) ? 0x00 : 0x04);
  379.       setting |= Parity;
  380.  
  381.       disable();
  382.       outportb(portbase + LCR, setting);
  383.       enable();
  384.  
  385.       return (0);
  386.   }
  387.  
  388.   /* Set up the port */
  389.   int    SetSerial(int Port, int Speed, int Parity, int Bits, int
  390.                    StopBit)
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402.  
  403.  
  404.   PRODUCT  :  TURBO C                                NUMBER  :  445
  405.   VERSION  :  1.0 & 1.5
  406.        OS  :  DOS 2.X & 3.X
  407.      DATE  :  OCTOBER 5, 1988                         PAGE  :  7/13
  408.  
  409.     TITLE  :  INTERRUPT DRIVEN SERIAL COMMUNICATIONS
  410.  
  411.  
  412.  
  413.  
  414.   {
  415.       if (SetPort(Port))                    return (-1);
  416.       if (SetSpeed(Speed))                  return (-1);
  417.       if (SetOthers(Parity, Bits, StopBit)) return (-1);
  418.  
  419.       return (0);
  420.   }
  421.  
  422.   /* Control-Break interrupt handler */
  423.   int    c_break(void)
  424.   {
  425.       i_disable();
  426.       fprintf(stderr, "\nStill online.\n");
  427.  
  428.       return(0);
  429.   }
  430.  
  431.   main()
  432.   {
  433.       /* Communications parameters */
  434.       int        port     = COM2;
  435.       int        speed    = 1200;
  436.       int        parity   = NO_PARITY;
  437.       int        bits     = 8;
  438.       int        stopbits = 1;
  439.  
  440.       int        c, done  = FALSE;
  441.  
  442.       if (SetSerial(port, speed, parity, bits, stopbits) != 0)
  443.       {
  444.           fprintf(stderr, "Serial Port setup error.\n");
  445.           return (99);
  446.       }
  447.  
  448.       initserial();
  449.  
  450.       ctrlbrk(c_break);
  451.  
  452.       fprintf(stdout, "TURBO C TERMINAL\n...You're now in terminal
  453.               mode, press [ESC] to quit...\n\n");
  454.  
  455.       /* The main loop acts as a dumb terminal. We repeatedly check
  456.          the keyboard buffer, and communications buffer. */
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.   PRODUCT  :  TURBO C                                NUMBER  :  445
  471.   VERSION  :  1.0 & 1.5
  472.        OS  :  DOS 2.X & 3.X
  473.      DATE  :  OCTOBER 5, 1988                         PAGE  :  8/13
  474.  
  475.     TITLE  :  INTERRUPT DRIVEN SERIAL COMMUNICATIONS
  476.  
  477.  
  478.  
  479.  
  480.       do {
  481.           if (kbhit())
  482.           {
  483.               /* Look for an Escape key */
  484.               switch (c=getch())
  485.               {
  486.                   case ESC: done = TRUE;  /* Exit program */
  487.                             break;
  488.  
  489.                   /* You may want to handle other keys here... */
  490.               }
  491.               SerialOut(c);
  492.           }
  493.           if ((c=getccb()) != -1)
  494.               fputc(c & ASCII, stdout);
  495.  
  496.       } while (!done && !SError);
  497.  
  498.       /* Check for errors */
  499.       switch (SError)
  500.       {
  501.           case NOERROR: fprintf(stderr, "\nbye.\n");
  502.                         closeserial();
  503.                         return (0);
  504.  
  505.           case BUFOVFL: fprintf(stderr, "\nBuffer Overflow.\n");
  506.                         closeserial();
  507.                         return (99);
  508.  
  509.           default:      fprintf(stderr, "\nUnknown Error, SError =
  510.                                 %d\n", SError);
  511.                         closeserial();
  512.                         return (99);
  513.       }
  514.   }
  515.  
  516.   /*-------------------------------------------------------------*
  517.                               SERIAL.H
  518.  
  519.                   Some definitions used by SERIAL.C
  520.    *-------------------------------------------------------------*/
  521.  
  522.   #define COM1            1
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.  
  535.  
  536.   PRODUCT  :  TURBO C                                NUMBER  :  445
  537.   VERSION  :  1.0 & 1.5
  538.        OS  :  DOS 2.X & 3.X
  539.      DATE  :  OCTOBER 5, 1988                         PAGE  :  9/13
  540.  
  541.     TITLE  :  INTERRUPT DRIVEN SERIAL COMMUNICATIONS
  542.  
  543.  
  544.  
  545.  
  546.   #define COM2            2
  547.   #define COM1BASE        0x3F8   /* Base port address for COM1 */
  548.   #define COM2BASE        0x2F8   /* Base port address for COM2 */
  549.  
  550.   /*
  551.       The 8250 UART has 10 registers accessible through 7 port
  552.       addresses.  Here are their addresses relative to COM1BASE and
  553.       COM2BASE.  Note that the baud rate registers, (DLL) and (DLH)
  554.       are active only when the Divisor-Latch Access-Bit (DLAB) is
  555.       on.  The (DLAB) is bit 7 of the (LCR).
  556.  
  557.           o TXR Output data to the serial port.
  558.           o RXR Input data from the serial port.
  559.           o LCR Initialize the serial port.
  560.           o IER Controls interrupt generation.
  561.           o IIR Identifies interrupts.
  562.           o MCR Send contorl signals to the modem.
  563.           o LSR Monitor the status of the serial port.
  564.           o MSR Receive status of the modem.
  565.           o DLL Low byte of baud rate divisor.
  566.           o DHH High byte of baud rate divisor.
  567.   */
  568.   #define TXR             0       /* Transmit register (WRITE) */
  569.   #define RXR             0       /* Receive register  (READ)  */
  570.   #define IER             1       /* Interrupt Enable          */
  571.   #define IIR             2       /* Interrupt ID              */
  572.   #define LCR             3       /* Line control              */
  573.   #define MCR             4       /* Modem control             */
  574.   #define LSR             5       /* Line Status               */
  575.   #define MSR             6       /* Modem Status              */
  576.   #define DLL             0       /* Divisor Latch Low         */
  577.   #define DLH             1       /* Divisor latch High        */
  578.  
  579.   /*-------------------------------------------------------------*
  580.     Bit values held in the Line Control Register (LCR).
  581.           bit             meaning
  582.           ---             -------
  583.           0-1             00=5 bits,  01=6  bits,  10=7  bits, 11=8
  584.   bits.
  585.           2               Stop bits.
  586.           3               0=parity off, 1=parity on.
  587.           4               0=parity odd, 1=parity even.
  588.           5               Sticky parity.
  589.  
  590.  
  591.  
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600.  
  601.  
  602.   PRODUCT  :  TURBO C                                NUMBER  :  445
  603.   VERSION  :  1.0 & 1.5
  604.        OS  :  DOS 2.X & 3.X
  605.      DATE  :  OCTOBER 5, 1988                        PAGE  :  10/13
  606.  
  607.     TITLE  :  INTERRUPT DRIVEN SERIAL COMMUNICATIONS
  608.  
  609.  
  610.  
  611.  
  612.           6               Set break.
  613.           7               Toggle port addresses.
  614.    *-------------------------------------------------------------*/
  615.   #define NO_PARITY       0x00
  616.   #define EVEN_PARITY     0x18
  617.   #define ODD_PARITY      0x08
  618.  
  619.  
  620.   /*-------------------------------------------------------------*
  621.     Bit values held in the Line Status Register (LSR).
  622.           bit             meaning
  623.           ---             -------
  624.           0               Data ready.
  625.           1               Overrun    error    -    Data    register
  626.   overwritten.
  627.           2               Parity error - bad transmission.
  628.           3               Framing error - No stop bit was found.
  629.           4               Break  detect  -   End   to  transmission
  630.   requested.
  631.           5               Transmitter holding register is empty.
  632.           6               Transmitter shift register is empty.
  633.           7         Time out - off line.
  634.    *-------------------------------------------------------------*/
  635.   #define RCVRDY          0x01
  636.   #define OVRERR          0x02
  637.   #define PRTYERR         0x04
  638.   #define FRMERR          0x08
  639.   #define BRKERR          0x10
  640.   #define XMTRDY          0x20
  641.   #define XMTRSR          0x40
  642.   #define TIMEOUT     0x80
  643.  
  644.   /*-------------------------------------------------------------*
  645.     Bit values held in the Modem Output Control Register (MCR).
  646.           bit             meaning
  647.           ---             -------
  648.           0               Data  Terminal Ready.  Computer ready  to
  649.   go.
  650.           1               Request To Send.   Computer wants to send
  651.   data.
  652.           2               Auxillary output #1.
  653.           3               Auxillary output  #2.    (Note:  This bit
  654.   must be
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662.  
  663.  
  664.  
  665.  
  666.  
  667.  
  668.   PRODUCT  :  TURBO C                                NUMBER  :  445
  669.   VERSION  :  1.0 & 1.5
  670.        OS  :  DOS 2.X & 3.X
  671.      DATE  :  OCTOBER 5, 1988                        PAGE  :  11/13
  672.  
  673.     TITLE  :  INTERRUPT DRIVEN SERIAL COMMUNICATIONS
  674.  
  675.  
  676.  
  677.  
  678.                           set  to allow the communications card  to
  679.   send
  680.                           interrupts to the system.)
  681.           4               UART ouput looped back as input.
  682.           5-7             Not used.
  683.    *-------------------------------------------------------------*/
  684.   #define DTR             0x01
  685.   #define RTS             0x02
  686.   #define MC_INT              0x08
  687.  
  688.  
  689.   /*-------------------------------------------------------------*
  690.     Bit values held in the Modem Input Status Register (MSR).
  691.           bit             meaning
  692.           ---             -------
  693.           0               Delta Clear To Send.
  694.           1               Delta Data Set Ready.
  695.           2               Delta Ring Indicator.
  696.           3               Delta Data Carrier Detect.
  697.           4               Clear To Send.
  698.           5               Data Set Ready.
  699.           6               Ring Indicator.
  700.           7               Data Carrier Detect.
  701.    *-------------------------------------------------------------*/
  702.   #define CTS             0x10
  703.   #define DSR             0x20
  704.  
  705.   /*-------------------------------------------------------------*
  706.     Bit values held in the Interrupt Enable Register (IER).
  707.           bit             meaning
  708.           ---             -------
  709.           0               Interrupt when data received.
  710.           1               Interrupt when  transmitter  holding reg.
  711.   empty.
  712.           2               Interrupt when data reception error.
  713.           3               Interrupt  when  change in  modem  status
  714.   register.
  715.           4-7             Not used.
  716.    *-------------------------------------------------------------*/
  717.   #define RX_INT          0x01
  718.  
  719.   /*-------------------------------------------------------------*
  720.     Bit values held in the Interrupt Identification Register (IIR).
  721.  
  722.  
  723.  
  724.  
  725.  
  726.  
  727.  
  728.  
  729.  
  730.  
  731.  
  732.  
  733.  
  734.   PRODUCT  :  TURBO C                                NUMBER  :  445
  735.   VERSION  :  1.0 & 1.5
  736.        OS  :  DOS 2.X & 3.X
  737.      DATE  :  OCTOBER 5, 1988                        PAGE  :  12/13
  738.  
  739.     TITLE  :  INTERRUPT DRIVEN SERIAL COMMUNICATIONS
  740.  
  741.  
  742.  
  743.  
  744.           bit             meaning
  745.           ---             -------
  746.           0               Interrupt pending.
  747.           1-2       Interrupt ID code.
  748.                           00=Change in modem status register,
  749.                           01=Transmitter holding register empty,
  750.                           10=Data received,
  751.                           11=reception error, or break encountered.
  752.           3-7             Not used.
  753.    *-------------------------------------------------------------*/
  754.   #define RX_ID           0x04
  755.   #define RX_MASK         0x07
  756.  
  757.  
  758.   /* These are the port addresses of the 8259 Programmable
  759.      Interrupt Controller (PIC). */
  760.   #define IMR             0x21   /* Interrupt Mask Register port */
  761.   #define ICR             0x20   /* Interrupt Control Port       */
  762.  
  763.  
  764.   /* An end of interrupt needs to be sent to the Control Port of
  765.      the 8259 when a hardware interrupt ends. */
  766.   #define EOI             0x20   /* End Of Interrupt */
  767.  
  768.  
  769.   /* The (IMR) tells the (PIC) to service an interrupt only if it
  770.      is not masked (FALSE). */
  771.   #define IRQ3            0xF7  /* COM2 */
  772.   #define IRQ4            0xEF  /* COM1 */
  773.  
  774.  
  775.  
  776.  
  777.  
  778.  
  779.  
  780.  
  781.  
  782.  
  783.  
  784.  
  785.  
  786.  
  787.  
  788.  
  789.  
  790.  
  791.  
  792.  
  793.