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

  1. // This module was written by LeucroTTa inc. (AKA OLAOR).
  2.  
  3. #include "serial.h"
  4.  
  5. #include <dos.h> // inportb, outportb, enable, disable.
  6.  
  7. // sends top byte out.
  8. //
  9. void SERIAL_PORT::do_send(void)
  10. {
  11.     BYTE out_byte;
  12.     BUFF_OP buff_op;
  13.  
  14.     if (out_buff.len()==0) {
  15.        return;
  16.     }
  17.  
  18.     do_send_recursive_count++;
  19.  
  20.     if (do_send_recursive_flag)
  21.        return;
  22.  
  23.     do_send_recursive_flag= TRUE;
  24.     // add one more to the recursive_count, just in case
  25.     // a misplaced interrupt does not occur (spare...).
  26.     //
  27.  
  28.     for (do_send_recursive_count++ ;do_send_recursive_count!= 0;do_send_recursive_count--) {
  29.  
  30.         if (out_buff.len()==0) {
  31.            do_send_recursive_count= 0;
  32.            break;
  33.         }
  34.  
  35.         // check for flow control.
  36.         //
  37.         flow_check();
  38.  
  39.         // if flow is not enabled, exit outtahere.
  40.         //
  41.         if (!flow_enabled) {
  42.            do_send_recursive_flag= FALSE;
  43.            return;
  44.         }
  45.  
  46.         //  TX_REGS EMPTY!
  47.         buff_op= (out_buff>> out_byte);
  48.  
  49.         if (buff_op> BUFF_OK_START_POINT) {
  50.            // sending a byte, so turn send_sema on.
  51.  
  52.            while (!(inportb(com_port+ LSR) & 0x20))
  53.                  ;//TX REGS not both empty!
  54.  
  55.            outportb (com_port+ DATA, out_byte);
  56.         }
  57.     }
  58.     do_send_recursive_flag= FALSE;
  59. }
  60.  
  61. // serial_port - interrupt service routine.
  62. //
  63. void SERIAL_PORT::isr ()
  64. {
  65.    INT_ID cause;
  66.    BYTE temp;
  67.  
  68.    do {
  69.  
  70.       cause= INT_ID(inportb(com_port+ IID));
  71.       switch (cause) {
  72.  
  73.             case RX_INT:
  74.  
  75.                  temp= inportb(com_port+ DATA);
  76.                  if (!flow_set(temp))
  77.                     in_buff<< temp;
  78.  
  79.                  break;
  80.  
  81.             case TX_INT:
  82.                  do_send();
  83.  
  84.                  break;
  85.  
  86.             case MODEM_STATUS_INT:
  87.  
  88.                  // call msr_int with the new msr.
  89.                  //
  90.                  msr_int(inportb (com_port+ MSR));
  91.  
  92.                  do_send();
  93.  
  94.                  break;
  95.  
  96.             case LINE_STATUS_INT:
  97.  
  98.                  temp= inportb(com_port+ LSR);
  99.                  // break has been received.
  100.                  //
  101.                  if (temp& 0x10)
  102.                     com_break();
  103.  
  104.                  // error has been received.
  105.                  //
  106.                  if (temp& 0xe)
  107.                     com_error();
  108.  
  109.                  break;
  110.  
  111.             case NO_INT_ACTIVE:
  112.             default:
  113.                     // support other com handlers...
  114. //                    (*old_vect)();
  115.                  break;
  116.       }
  117.  
  118.    } while (cause!= NO_INT_ACTIVE);
  119.  
  120.  
  121.    eoi(); // 8259A EOI.
  122.    set_imr(); // fix td's Bpt BUG!!!!
  123. }
  124.  
  125. // outputting a char (to the serial_port).
  126. //
  127. OPERATION SERIAL_PORT::operator << (const BYTE out_byte)
  128. {
  129.     BUFF_OP buff_op;
  130.  
  131.     buff_op= out_buff<< out_byte;
  132.  
  133.     if ((inportb(com_port+ LSR)& 0x20))
  134.        do_send();
  135.  
  136.     return ((buff_op== BUFF_OVERFLOW)? OP_FAILURE: OP_SUCCESSFUL);
  137. }
  138.  
  139. // inputting a char (from the serial_port).
  140. //
  141. OPERATION SERIAL_PORT::operator >> (BYTE& in_byte)
  142. {
  143.     if ((in_buff>> in_byte)< BUFF_OK_START_POINT)
  144.        return OP_FAILURE;
  145.  
  146.     return OP_SUCCESSFUL;
  147. }
  148.  
  149. // peeking on the input char...
  150. //
  151. OPERATION SERIAL_PORT::operator >  (BYTE& peek_byte)
  152. {
  153.     if ((in_buff> peek_byte)< BUFF_OK_START_POINT)
  154.        return OP_FAILURE;
  155.  
  156.     return OP_SUCCESSFUL;
  157. }
  158.  
  159. unsigned SERIAL_PORT::output_buff_len(void)
  160. {
  161.     return out_buff.len();
  162. }
  163.  
  164. unsigned SERIAL_PORT::input_buff_len(void)
  165. {
  166.     return in_buff.len();
  167. }
  168.  
  169. // empty both in and out buffers.
  170. //
  171. void SERIAL_PORT::empty_io_buffers(void)
  172. {
  173.     out_buff.empty_buff();
  174.     in_buff.empty_buff();
  175. }
  176.  
  177. // set controls...
  178. //
  179. void SERIAL_PORT::set_controls(BYTE mcr)
  180. {
  181.     mcr|= 0x8; // out2= on.
  182.  
  183.     outportb(com_port+ MCR, mcr);
  184. }
  185.