Category : C++ Source Code
Archive   : ISC36.ZIP
Filename : SERIAL.CPP

 
Output of file : SERIAL.CPP contained in archive : ISC36.ZIP

///////////////////////////////////////////////////////////////////////////
// //
// File: serial.cpp //
// (project version). //
// started on: 5/2/92 //
// //
///////////////////////////////////////////////////////////////////////////
// //
// // //
///////////////////////////////////////////////////////////////////////////

#include "serial.h"

#include // inportb, outportb, enable, disable.

// sends top byte out.
//
void SERIAL_PORT::do_send(void)
{
static BYTE out_byte;
static unsigned recursive_count= 0;
static BOOLEAN recursive_flag= FALSE;
static BUFF_OP buff_op;

if (out_buff.length()==0) {
return;
}

recursive_count++;

if (recursive_flag)
return;

recursive_flag= TRUE;
// add one more to the recursive_count, just in case
// a misplaced interrupt does not occur (spare...).
//

for (recursive_count++ ;recursive_count!= 0;recursive_count--) {

if (out_buff.length()==0) {
break;
}

// check for flow control.
//
flow_check();

// if flow is not enabled, exit outtahere.
//
if (!flow_enabled) {
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);
}
}
recursive_flag= FALSE;
}

// serial_port - interrupt service routine.
//
void SERIAL_PORT::isr (void)
{
static BYTE temp;

temp= inportb(com_port+ IID);

// hardware interrupt, send 8259A its eoi.
eoi();

switch (temp) {

case RX_INT:

temp= inportb(com_port+ DATA);
in_buff<< temp;

break;

case TX_INT:

if (out_buff.length()== 0) {
break; // get out of switch.
}

// if not empty, send.
//
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;
}

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.length();
}

unsigned SERIAL_PORT::input_buff_len(void)
{
return in_buff.length();
}

// 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);
}