home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 2 / ctrom_ii_b.zip / ctrom_ii_b / PROGRAM / C / ISC365 / SERIALSE.CPP < prev    next >
C/C++ Source or Header  |  1993-07-06  |  7KB  |  255 lines

  1. // This module was written by LeucroTTa inc. (AKA OLAOR).
  2.  
  3. #include "serial.h" // SERIAL_PORT
  4. #include <dos.h>    // outportb, inportb
  5.  
  6.  
  7. const unsigned long SERIAL_PORT::BAUD_CONST = 115200L;
  8.  
  9. const unsigned BUFF_SIZE= 256; // communication buffer size.
  10.  
  11. // sets the imr to enable the hardware interrupt request line.
  12. //
  13. void SERIAL_PORT::set_imr(void)
  14. {
  15.     outportb (com_pic_port+ PIC_IMR, (inportb (com_pic_port+ PIC_IMR) & com_imr_mask));
  16. }
  17.  
  18. // sends an eoi to the pic.
  19. //
  20. void SERIAL_PORT::eoi(void)
  21. {
  22.     outportb (com_pic_port+ PIC_DATA, 0x20); // send pic eoi message.
  23. }
  24.  
  25. // update flow_enabled.
  26. //
  27. void SERIAL_PORT::flow_check(void)
  28. {
  29.     flow_enabled= TRUE;
  30. }
  31.  
  32. // error has been received.
  33. //
  34. void SERIAL_PORT::com_error(void)
  35. {
  36.     // read twice to try and free the error.
  37.     inportb(com_port+ DATA);
  38.     inportb(com_port+ DATA);
  39. }
  40.  
  41. // set up the serial port.
  42. //
  43. void SERIAL_PORT::set_up_port( const long baud_rate, const BYTE word_len,
  44.                                const BYTE parity, const BYTE stop_bits)
  45. {
  46.     // if already initialized, exit.
  47.     //
  48.     if (InitFlag)
  49.        return;
  50.  
  51.     outportb (com_port+ LCR, 0x80); // set DLAB
  52.  
  53.     outport (com_port+ BAUDLOW, (unsigned)(BAUD_CONST / baud_rate));
  54.  
  55.     // LCR is eventual going to be set to temp.
  56.     //
  57.     BYTE temp= 0; // DLAB= 0;
  58.  
  59.     temp&=0xc7; // clear parity.
  60.     switch (parity) {
  61.            case 'N': // no parity
  62.                      temp|= 0x0;
  63.                      break;
  64.            case 'O': // ODD parity.
  65.                      temp|= 0x8;
  66.                      break;
  67.            case 'E': // EVEN parity.
  68.                      temp|= 0x18;
  69.                      break;
  70.            case 'M': // MARK.
  71.                      temp|= 0x28;
  72.                      break;
  73.            case 'S': // SPACE.
  74.                      temp|= 0x38;
  75.                      break;
  76.     }
  77.  
  78.     temp&=0xfb; // clear stop bits.
  79.     switch (stop_bits) {
  80.            case 1: // one stop bit.
  81.                    break;
  82.            case 2: // two stop bits.
  83.                    temp|= 0x4;
  84.     }
  85.  
  86.     temp&=0xfc; // clear word len.
  87.     switch (word_len) {
  88.            case 5: // word len= 5.
  89.                    break;
  90.            case 6: // word len= 6.
  91.                    temp|= 0x1;
  92.                    break;
  93.            case 7: // word len= 7.
  94.                    temp|= 0x2;
  95.                    break;
  96.            case 8: // word len= 8.
  97.                    temp|= 0x3;
  98.                    break;
  99.     }
  100.  
  101.     outportb (com_port+ LCR, temp); // set LCR to options.
  102.  
  103. }
  104.  
  105. // the constructor gets as parameters- the port number associated with the
  106. // serial port, as well as the HARDWARE interrupt number it is attached to,
  107. // the software interrupt it generates and the PIC port that holds it.
  108. //
  109.  
  110. SERIAL_PORT::SERIAL_PORT (const unsigned port_num,
  111.                          const unsigned irq_line_num,
  112.                          const unsigned int_num,
  113.                          const unsigned pic_port_num= 0x20) : ISC()
  114. {
  115.     InitFlag= FALSE;
  116.  
  117.     // setup serial_port parameters.
  118.     activate(port_num, irq_line_num, int_num, pic_port_num);
  119. }
  120.  
  121. void SERIAL_PORT::activate (const unsigned port_num,
  122.                            const unsigned irq_line_num,
  123.                            const unsigned int_num,
  124.                            const unsigned pic_port_num= 0x20)
  125. {
  126.     // if already initialized, exit.
  127.     //
  128.     if (InitFlag)
  129.        return;
  130.  
  131.     // initializing do_send vars.
  132.     do_send_recursive_count= 0;
  133.     do_send_recursive_flag= FALSE;
  134.  
  135.     // resize I/O buffers.
  136.  
  137.     in_buff.reset_size(BUFF_SIZE, TRUE);
  138.     out_buff.reset_size(BUFF_SIZE, TRUE);
  139.  
  140.     // the serial's port.
  141.     com_port= port_num;
  142.  
  143.     // hardware interrupt request line num.
  144.  
  145.     com_imr_mask= ~(0x1 << irq_line_num); // all "1" except a "0" on the line request...
  146.  
  147.     // hardware interrupt num.
  148.     com_int= int_num;
  149.  
  150.     // default imr_port is 0x20.
  151.     //
  152.     com_pic_port= pic_port_num;
  153.  
  154.     // now hook interrupts via ISC.
  155.     //
  156.     ISC::activate(com_int);
  157.  
  158.     outportb (com_port+ IER, 0xF); //  enable UART interrupts on all calls!!!
  159.  
  160.     // clear RCV buffers
  161.     inportb (com_port+ LSR);  // clear LSR.
  162.     inportb (com_port+ DATA); // clear RX register.
  163.     inportb (com_port+ MSR);  // clear MSR register.
  164.  
  165.     inportb (com_port+ IID);  // read IID register (to clear it's Flip-Flop flag).
  166.  
  167.     // repeat all readings to be sure they are clear.
  168.     if (inportb (com_port+ IID) & 1) {
  169.        // repeat the clearing...
  170.        inportb (com_port+ LSR);  // clear LSR
  171.        inportb (com_port+ DATA); // clear RX register
  172.        inportb (com_port+ MSR);  // clear MSR register
  173.     }
  174.  
  175.     // and now enable the modem's interrupt enable.
  176.  
  177.     outportb (com_port+ MCR, (inportb(com_port+ MCR)| 8));  // write it into MCR. (turn on OUT2).
  178.  
  179.     // 8259A programming...
  180.     set_imr(); // setup imr.
  181.  
  182.     eoi();     // send pic an EOI just to be sure.
  183.  
  184.     // allow derived classes to extend the initialization of the port.
  185.     //
  186.     extended_init();
  187.  
  188.     // default port settings.
  189.     set_up_port (9600,8,'N',1);
  190. }
  191.  
  192. // this constructor gets a single number from 1 to 4 (must be a legal serial
  193. // port- it does not test it's validity), and hooks to it.
  194. //
  195. SERIAL_PORT::SERIAL_PORT (const unsigned com_num) : ISC()
  196. {
  197.     InitFlag= FALSE;
  198.  
  199.     // setup serial port parameters.
  200.     activate(com_num);
  201. }
  202.  
  203. // setup parameters.
  204. //
  205. void SERIAL_PORT::activate(const unsigned com)
  206. {
  207.     unsigned com_num= com;
  208.  
  209.     // exit if already initialized.
  210.     if (InitFlag)
  211.        return;
  212.  
  213.     com_num--;
  214.     com_num%= 4;  // now com_num is between 0-3 (and can be used for offsets!).
  215.  
  216.     unsigned huge *port_num= (unsigned huge *)0x00000400L; // bios data area.
  217.  
  218.     com_port= *(port_num+ com_num); // access bios data area and retrieve the com port...
  219.  
  220.     unsigned com_irq_line;
  221.     switch (com_num) {
  222.  
  223.            // com1 & com3.
  224.  
  225.            case 0:
  226.            case 2:
  227.                 com_irq_line= 4;
  228.                 com_int= 0xc;
  229.                 break;
  230.  
  231.            // com2 & com4.
  232.  
  233.            case 1:
  234.            case 3:
  235.                 com_irq_line= 3;
  236.                 com_int= 0xb;
  237.                 break;
  238.     }
  239.  
  240.  
  241.     // now reuse activate.
  242.     //
  243.     activate(com_port, com_irq_line, com_int);
  244. }
  245.  
  246. SERIAL_PORT::SERIAL_PORT() : ISC()
  247. {
  248.     InitFlag= FALSE;
  249. }
  250.  
  251. SERIAL_PORT::~SERIAL_PORT()
  252. {
  253.     outportb (com_port+ IER, 0); //  disable UART interrupts on all calls!!!
  254. }
  255.