home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / modem / cvt100.zip / COMIO.C next >
Text File  |  1988-07-31  |  14KB  |  337 lines

  1. #include <stdio.h>
  2. #include <dos.h>
  3.  
  4. #define MDMDAT1 0x03F8            /* Address of modem port 1 data */
  5. #define MDMSTS1 0x03FD            /* Address of modem port 1 status  */
  6. #define MDMCOM1 0x03FB            /* Address of modem port 1 command */
  7. #define MDMDAT2 0x02F8            /* Address of modem port 2 data */
  8. #define MDMSTS2 0x02FD            /* Address of modem port 2 status */
  9. #define MDMCOM2 0x02FB            /* Address of modem port 2 command */
  10. #define MDMINTV 0x000C            /* Com 1 interrupt vector */
  11. #define MDINTV2 0x000B            /* Com 2 interrupt vector */
  12. #define MDMINTO 0x0EF             /* Mask to enable IRQ3 for port 1 */
  13. #define MDINTO2 0x0F7             /* Mask to enable IRQ4 for port 2 */
  14. #define MDMINTC 0x010             /* Mask to Disable IRQ4 for port 1 */
  15. #define MDINTC2 0x008             /* Mask to Disable IRQ3 for port 2 */
  16. #define INTCONT 0x0021            /* 8259 interrupt controller ICW2-3 */
  17. #define INTCON1 0x0020            /* Address of 8259 ICW1 */
  18.  
  19. #define COM_BUFF_SIZE 1024        /* Communications port buffer size */
  20. #define XOFFPT  COM_BUFF_SIZE*3/4 /* chars in buff before sending XOFF */
  21. #define XONPT   COM_BUFF_SIZE*1/4 /* chars in buff to send XON after XOFF */
  22. #define XOFF    0x13              /* XOFF value */
  23. #define XON     0x11              /* XON value */
  24.  
  25. /*****************************************************************************/
  26. /* function prototypes                                                       */
  27.  
  28. void TTinit();                    /* Initialize the communications system */
  29. int ttopen();                     /* Open a port for communications */
  30. int ttclose( void );              /* Close the communications port */
  31. int ttchk( void );                /* Return count of received characters */
  32. void ttoc( unsigned char );       /* Output a character to the com port */
  33. int ttinc( void );                /* Input a character from circular buffer */
  34. void ttflui( void );              /* Flush circular buffer of characters */
  35. int dobaud( unsigned int );       /* Set the baud rate for the port */
  36. void coms( int );                 /* Establish modem data */
  37. void serini( void );              /* Initialize the com port for interrupts */
  38. void serrst( void );              /* Reset the com port to original settings */
  39. void interrupt serint( void );    /* Com port receiver ISR */
  40.  
  41.  
  42. /*****************************************************************************/
  43. /* Global Data                                                               */
  44.  
  45. unsigned int port;                /* COM port */
  46. unsigned int speed;               /* BAUD rate */
  47. char parity[5];                   /* Parity setting */
  48. unsigned int databits;            /* Number of Data bits */
  49. unsigned int stopbits;            /* Number of Stop bits */
  50.  
  51. /*****************************************************************************/
  52. /* External variables                                                        */
  53.  
  54.  
  55.  
  56. /*****************************************************************************/
  57. /* Local Static Data                                                         */
  58.  
  59. static char buffer[COM_BUFF_SIZE];/* Circular buffer */
  60. static char *inptr;               /* Pointer to input point of circular buff*/
  61. static char *outptr;              /* Pointer to output point of circular buff*/
  62. static int  count = 0;            /* Number of characters in buffer */
  63.  
  64. struct mdminfo {                  /* struct to hold current com port info */
  65.     unsigned int mddat;             /* 8250 data register */
  66.     unsigned int mdstat;            /* 8250 line-status register */
  67.     unsigned int mdcom;             /* 8250 line-control register */
  68.     unsigned char mden;             /* 8259 IRQ enable mask */
  69.     unsigned char mddis;            /* 8259 IRQ disable mask */
  70.     unsigned char mdintv;           /* Interrupt for selected com port */
  71. } modem ;
  72.  
  73. void interrupt (*oldvec)();       /* Vector of previous com interrupt */
  74. int portin = 0;                   /* Flag to indicate com port is open */
  75. int xofsnt = 0;                   /* Flag to indicate an XOFF transmitted */
  76. int xofrcv = 0;                   /* Flag to indicate an XOFF received */
  77.  
  78. /*****************************************************************************/
  79.  
  80. /*  T T I N I T  -- Initialize the communications system */
  81.  
  82. void TTinit() {
  83.  
  84.     if (GetTTSetup() == 0) {        /* If no saved values are available */
  85.         port = 1;                     /* Then set default values */
  86.         speed = 2400;
  87.         strcpy(parity,"NONE");
  88.         databits = 8;
  89.         stopbits = 1;
  90.     }
  91. }
  92.  
  93.  
  94. /*  T T O P E N  -- Open the communications port */
  95.  
  96. ttopen() {
  97.     if (portin == 0) {            /* Ignore call if already open */
  98.         switch (port) {
  99.             case 1:
  100.                 coms(1);             /* COM 1 */
  101.                 break;
  102.             case 2:
  103.                 coms(2);             /* COM 2 */
  104.                 break;
  105.             default:                 /* others not supported, return error */
  106.                 return(-1);
  107.         }
  108.         dobaud(speed);               /* Set baud rate */
  109.         serini();                    /* enable interrupt handler */
  110.     }
  111.     return(0);                    /* return success */
  112. }
  113.  
  114.  
  115. /*  T T C L O S E --  Close the communications port  */
  116.  
  117. ttclose() {
  118.     if (portin != 0)              /* Ignore if port is already closed */
  119.         serrst();                    /* otherwise disable interrupts */
  120.     return(0);                    /* return success */
  121. }
  122.  
  123.  
  124.  
  125.  
  126. /* T T C H K  --  Return a count of characters at the serial port */
  127.  
  128. ttchk() {
  129.     return( count );              /* return maintained count */
  130. }
  131.  
  132.  
  133. /* T T O C -- Output a character to the current serial port */
  134.  
  135. void ttoc( unsigned char c ) {
  136.  
  137.     while( (inportb(modem.mdstat) & 0x20) == 0 )
  138.        ;                          /* Wait til transmitter is ready */
  139.     outportb(modem.mddat,c);      /* then output the character */
  140. }
  141.  
  142.  
  143. /* T T F L U I  --  Clear the input buffer of characters */
  144.  
  145.  
  146. void ttflui() {
  147.  
  148.     if (xofsnt){                  /* Check if XON should be sent after XOFF */
  149.        xofsnt = 0;                  /* if so then reset XOFF sent status */
  150.        ttoc(XON);                   /* and send the XON */
  151.        }
  152.     disable();                    /* NO interrupts allowed now */
  153.     inptr = outptr = buffer;      /* Reset input out output pointers */
  154.     count = 0;                    /* Set received characters count to 0 */
  155.     enable();                     /* Now interrupts are ok */
  156. }
  157.  
  158.  
  159. /* T T I N C  -- Read a character from serial ports circular buffer */
  160.  
  161. ttinc() {
  162.     int c;
  163.     register char * ptr;
  164.  
  165.     if (count < XONPT && xofsnt){ /* Check if XON should be sent after XOFF */
  166.        xofsnt = 0;                  /* if so then reset XOFF sent status */
  167.        ttoc(XON);                   /* and send the XON */
  168.        }
  169.  
  170.     while (count == 0)            /* If no characters have arrived then */
  171.         ;                            /* wait til one arrives */
  172.  
  173.     ptr = outptr;                 /* Save address of buffer output point */
  174.  
  175.     c = *ptr++;                   /* Get this character and increment ptr */
  176.  
  177.                                   /* See if circular buff should be wrapped */
  178.     if (ptr == &buffer[COM_BUFF_SIZE])
  179.         ptr = buffer;                /* if so then save new output point */
  180.  
  181.     disable();                    /* NO interrupts allowed now */
  182.     outptr = ptr;                 /* Save the address of output point */
  183.     count--;                      /* Decrement count of received characters */
  184.     enable();                     /* Interrupts can continue now */
  185.  
  186.     return(c);                    /* Return the received character */
  187. }
  188.  
  189.  
  190. /* D O B A U D  --  Set the baud rate for the current port */
  191.  
  192. dobaud( unsigned int baudrate ) {
  193.    unsigned char portval;
  194.    unsigned char blo, bhi;
  195.    switch (baudrate) {            /* Get 8250 baud rate divisor values */
  196.        case 50:     bhi = 0x9;  blo = 0x00;  break;
  197.        case 75:     bhi = 0x6;  blo = 0x00;  break;
  198.        case 110:    bhi = 0x4;  blo = 0x17;  break;
  199.        case 150:    bhi = 0x3;  blo = 0x00;  break;
  200.        case 300:    bhi = 0x1;  blo = 0x80;  break;
  201.        case 600:    bhi = 0x0;  blo = 0xC0;  break;
  202.        case 1200:   bhi = 0x0;  blo = 0x60;  break;
  203.        case 1800:   bhi = 0x0;  blo = 0x40;  break;
  204.        case 2000:   bhi = 0x0;  blo = 0x3A;  break;
  205.        case 2400:   bhi = 0x0;  blo = 0x30;  break;
  206.        case 4800:   bhi = 0x0;  blo = 0x18;  break;
  207.        case 9600:   bhi = 0x0;  blo = 0x0C;  break;
  208.        case 19200:  bhi = 0x0;  blo = 0x06;  break;
  209.        case 38400:  bhi = 0x0;  blo = 0x03;  break;
  210.  
  211.        default:                   /* Return failure if baud unsupported */
  212.            return(-1);
  213.    }
  214.  
  215.    portval = inportb(modem.mdcom);/* Save current value of command register */
  216.  
  217.                                   /* In order to set the baud rate the */
  218.                                   /* high bit of command data register is */
  219.    outportb(modem.mdcom,portval | 0x80 ); /* set before sending baud data */
  220.  
  221.    outportb(modem.mddat,blo);     /* Set LSB Baud-Rate divisor for baud */
  222.    outportb(modem.mddat + 1,bhi); /* Set MSB Baud-Rate divisor for baud */
  223.  
  224.    outportb(modem.mdcom,portval); /* Reset original command register value */
  225.  
  226.    return(0);                     /* Return success */
  227. }
  228.  
  229.  
  230. /*  C O M S  --  Set up the modem structure for the specified com port */
  231.  
  232. void coms( int portid ) {
  233.  
  234.     if (portid == 1) {            /* Port data for COM 1 */
  235.         modem.mddat = MDMDAT1;       /* Port 1 Data register */
  236.         modem.mdstat = MDMSTS1;      /* Port 1 Status register */
  237.         modem.mdcom = MDMCOM1;       /* Port 1 Command register */
  238.         modem.mddis = MDMINTC;       /* Port 1 8259 IRQ4 disable mask */
  239.         modem.mden = MDMINTO;        /* Port 1 8259 IRQ4 enable mask */
  240.         modem.mdintv = MDMINTV;      /* Port 1 interrupt number */
  241.     }
  242.     else if (portid == 2) {       /* Port data for COM 2 */
  243.         modem.mddat = MDMDAT2;       /* Port 2 Data register */
  244.         modem.mdstat = MDMSTS2;      /* Port 2 Status register */
  245.         modem.mdcom = MDMCOM2;       /* Port 2 Command register */
  246.         modem.mddis = MDINTC2;       /* Port 2 8259 IRQ4 disable mask */
  247.         modem.mden = MDINTO2;        /* Port 2 8259 IRQ4 enable mask */
  248.         modem.mdintv = MDINTV2;      /* Port 2 interrupt number */
  249.     }
  250. }
  251.  
  252. /* S E R I N I  -- initialize the serial port for interrupts */
  253.  
  254. void serini() {
  255.     unsigned char portval;
  256.  
  257.     if (portin == 0) {            /* Ignore if already open */
  258.         portin = 1;                  /* save port open status */
  259.         inptr = outptr = buffer;     /* set circular buffer pointers */
  260.         count = 0;                   /* indicate no characters received */
  261.         oldvec=getvect(modem.mdintv);/* save old com interrupt */
  262.         setvect(modem.mdintv,serint);/* set SERINT as communications ISR */
  263.  
  264.         portval = 0;              /* Byte value to output to the Line */
  265.                                   /* Control Register (LCR) to set the */
  266.                                   /* Parity, Stopbits, Databits */
  267.                                   /* Start out with all bits zero */
  268.  
  269.         if (strcmp(parity,"EVEN") == 0)
  270.            portval |= 0x8;        /* Set bit 3 on for odd parity */
  271.         else if (strcmp(parity,"ODD") == 0)
  272.            portval |= 0x18;       /* Set bits 3 and 4 on for even parity */
  273.                                   /* Leave bits 3 and 4 off for no parity */
  274.  
  275.  
  276.         if (stopbits == 2)        /* Set bit 2 on if 2 Stopbits are used */
  277.            portval |= 0x4;
  278.                                   /* Leave bit 2 off for 1 Stopbit */
  279.  
  280.         if (databits == 6)        /* Set bit 0 on for 6 data bits */
  281.            portval |= 0x1;
  282.         else if (databits == 7)   /* Set bit 1 on for 7 data bits */
  283.            portval |= 0x2;
  284.         else if (databits == 8)   /* Set bits 0 and 1 on for 8 data bits */
  285.            portval |= 0x3;
  286.                                   /* Leave bits 0 and 1 off for 5 data bits */
  287.  
  288.         outportb(modem.mdcom,portval);  /* Output the settings to the LCR */
  289.  
  290.  
  291.         outportb(modem.mdcom + 1,0xb); /* Assert OUT2, RTS, DTR */
  292.  
  293.         inportb(modem.mddat);        /* Clear any left over characters */
  294.         outportb(modem.mddat+1,0x1); /* Enable receiver interrupts */
  295.  
  296.         portval = inportb(INTCONT);  /* Read 8259 interrupt enable mask */
  297.         outportb(INTCONT,modem.mden & portval); /*Set bit on for com IRQ */
  298.     }
  299. }
  300.  
  301.  
  302. /* S E R R S T -- Reset serial port interrupts */
  303.  
  304. void serrst() {
  305.     unsigned char portval;
  306.  
  307.     if (portin != 0) {            /* Ignore if interrupts already disabled */
  308.         portin = 0;                    /* save port closed status */
  309.         portval = inportb(INTCONT);    /* Read 8259 interrupt enable mask */
  310.         outportb(INTCONT,modem.mddis | portval);/*Set bit off for com IRQ */
  311.         setvect(modem.mdintv,oldvec);  /* return original interrupt vector */
  312.     }
  313. }
  314.  
  315.  
  316. /*  S E R I N T  -- Serial interrupt handler, recieves incoming characters */
  317.  
  318. void interrupt serint() {
  319.  
  320.     *inptr++=inportb(modem.mddat);/* Quickly read arriving character */
  321.     count++;                      /* Increment received count */
  322.  
  323.     if (count > XOFFPT && xofsnt != 1){ /* If buffer almost full then */
  324.        ttoc(XOFF);                /* send an XOFF */
  325.        xofsnt = 1;                /* and save XOFF sent status */
  326.        }
  327.     disable();                    /* NO interrupts are allowed while */
  328.                                   /* new input pointer is stored */
  329.     if (inptr == &buffer[COM_BUFF_SIZE]) /* At end of circular buff? */
  330.        inptr = buffer;                /* if so then save new output point */
  331.  
  332.     enable();                     /* Interrupts ok now */
  333.  
  334.     outportb(0x20,0x20);          /* send End Of Interrupt to 8259 */
  335. }
  336.  
  337.