home *** CD-ROM | disk | FTP | other *** search
- ///////////////////////////////////////////////////////////////////////////
- // //
- // File: serial.cpp //
- // started on: 5/2/92 //
- // //
- ///////////////////////////////////////////////////////////////////////////
- // //
- // This class sends and receives data via interrupt driven Serial //
- // engine. very comfortable interface (I think). Might not work on //
- // slow machines in high baud rates (after all it's written in a high //
- // level language). //
- // //
- ///////////////////////////////////////////////////////////////////////////
- // //
- // by Ofer Laor (AKA LeucroTTA) //
- // //
- ///////////////////////////////////////////////////////////////////////////
-
- #include "serial.h"; // SERIAL_PORT.
-
- #include <dos.h> // inportb, outportb, enable, disable.
-
- // sends top byte out.
- //
- void SERIAL_PORT::do_send(void)
- {
- BYTE out_byte;
- BUFF_OP buff_op;
-
- if (out_buff.len()==0) {
- return;
- }
-
- do_send_recursive_count++;
-
- if (do_send_recursive_flag)
- return;
-
- do_send_recursive_flag= TRUE;
- // add one more to the recursive_count, just in case
- // a misplaced interrupt does not occur (spare...).
- //
-
- for (do_send_recursive_count++ ;do_send_recursive_count!= 0;do_send_recursive_count--) {
-
- if (out_buff.len()==0) {
- do_send_recursive_count= 0;
- break;
- }
-
- // check for flow control.
- //
- flow_check();
-
- // if flow is not enabled, exit outtahere.
- //
- if (!flow_enabled) {
- do_send_recursive_flag= FALSE;
- return;
- }
-
- // TX_REGS EMPTY!
- buff_op= (out_buff>> out_byte);
-
- if (buff_op> BUFF_OK_START_POINT) {
- // sending a byte, so turn send_sema on.
-
- while (!(inportb(com_port+ LSR) & 0x20))
- ;//TX REGS not both empty!
-
- outportb (com_port+ DATA, out_byte);
- }
- }
- do_send_recursive_flag= FALSE;
- }
-
- // serial_port - interrupt service routine.
- //
- void SERIAL_PORT::isr ()
- {
- INT_ID cause;
- BYTE temp;
-
- do {
-
- cause= INT_ID(inportb(com_port+ IID));
- switch (cause) {
-
- case RX_INT:
-
- temp= inportb(com_port+ DATA);
- if (!flow_set(temp))
- in_buff<< temp;
-
- break;
-
- case TX_INT:
- do_send();
-
- break;
-
- case MODEM_STATUS_INT:
-
- // call msr_int with the new msr.
- //
- msr_int(inportb (com_port+ MSR));
-
- do_send();
-
- break;
-
- case LINE_STATUS_INT:
-
- temp= inportb(com_port+ LSR);
- // break has been received.
- //
- if (temp& 0x10)
- com_break();
-
- // error has been received.
- //
- if (temp& 0xe)
- com_error();
-
- break;
-
- case NO_INT_ACTIVE:
- default:
- // support other com handlers...
- // (*old_vect)();
- break;
- }
-
- } while (cause!= NO_INT_ACTIVE);
-
-
- eoi(); // 8259A EOI.
- set_imr(); // fix td's Bpt BUG!!!!
- }
-
- // outputting a char (to the serial_port).
- //
- OPERATION SERIAL_PORT::operator << (const BYTE out_byte)
- {
- BUFF_OP buff_op;
-
- buff_op= out_buff<< out_byte;
-
- if ((inportb(com_port+ LSR)& 0x20))
- do_send();
-
- return ((buff_op== BUFF_OVERFLOW)? OP_FAILURE: OP_SUCCESSFUL);
- }
-
- // inputting a char (from the serial_port).
- //
- OPERATION SERIAL_PORT::operator >> (BYTE& in_byte)
- {
- if ((in_buff>> in_byte)< BUFF_OK_START_POINT)
- return OP_FAILURE;
-
- return OP_SUCCESSFUL;
- }
-
- // peeking on the input char...
- //
- OPERATION SERIAL_PORT::operator > (BYTE& peek_byte)
- {
- if ((in_buff> peek_byte)< BUFF_OK_START_POINT)
- return OP_FAILURE;
-
- return OP_SUCCESSFUL;
- }
-
- unsigned SERIAL_PORT::output_buff_len(void)
- {
- return out_buff.len();
- }
-
- unsigned SERIAL_PORT::input_buff_len(void)
- {
- return in_buff.len();
- }
-
- // empty both in and out buffers.
- //
- void SERIAL_PORT::empty_io_buffers(void)
- {
- out_buff.empty_buff();
- in_buff.empty_buff();
- }
-
- // set controls...
- //
- void SERIAL_PORT::set_controls(BYTE mcr)
- {
- mcr|= 0x8; // out2= on.
-
- outportb(com_port+ MCR, mcr);
- }