home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / ISC366.ZIP / SERIAL / SERIAL.CPP < prev    next >
Text File  |  1993-09-01  |  5KB  |  201 lines

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