home *** CD-ROM | disk | FTP | other *** search
- // --------- serial.cpp
-
- #include "serial.h"
-
- static void interrupt (*oldtimer)(...);
- static void interrupt (*oldcomint)(...);
-
- Timer CommPort::serialtimer;
- CommPort *CommPort::mp_CommPort;
-
- // ------ ISRs to count timer ticks
- void interrupt newtimer(...)
- {
- (*oldtimer)();
- if (CommPort::serialtimer.running())
- CommPort::serialtimer.countdown();
- }
-
- // ---- serial input interrupt service routine
- void interrupt newcomint(...)
- {
- CommPort::mp_CommPort->CommInterrupt();
- }
-
- void CommPort::CommInterrupt()
- {
- int c;
- outp(PIC00,EOI);
- if (mp_nextin == mp_recvbuff+BufSize)
- mp_nextin = mp_recvbuff; // circular buffer
- c = inp(RxData()); // read the input
- if (xonxoff_enabled)
- if (c == xoff) /* test XON */
- waiting_for_xon = true;
- else if (c == xon) /* test XOFF */
- waiting_for_xon = false;
- if (!xonxoff_enabled || (c != xon && c != xoff)) {
- *mp_nextin++ = (char) c; /* put char in buff*/
- buffer_count++;
- }
- if (xonxoff_enabled && !waiting_to_send_xon &&
- buffer_count > Threshold) {
- while ((inp(LineStatus()) & XmitDataReady) == 0)
- ;
- outp(TxData(), xoff); /* send XOFF */
- waiting_to_send_xon = true;
- }
- }
-
- CommPort::CommPort(const CommParameters& cp) : commparms(cp)
- {
- mp_CommPort = this;
- mp_recvbuff = new char[BufSize];
- mp_nextin = mp_nextout = mp_recvbuff;
- xonxoff_enabled = true;
- buffer_count = 0;
- waiting_for_xon = false;
- waiting_to_send_xon = false;
- oldtimer = 0;
- oldcomint = 0;
- timeout = 10;
- Initialize();
- }
-
- CommPort::~CommPort()
- {
- delete mp_recvbuff;
- if (oldcomint) {
- setvect(vector(), oldcomint);
- oldcomint = 0;
- }
- if (oldtimer) {
- setvect(systimer, oldtimer);
- oldtimer = 0;
- }
- }
- /* -------- initialize the com port ----------- */
- void CommPort::Initialize()
- {
- initcom.initbits.parity = commparms.parity == 2 ? 3 : commparms.parity;
- initcom.initbits.stopbits = commparms.stopbits-1;
- initcom.initbits.wordlen = commparms.databits-5;
- initcom.initbits.brk = 0;
- initcom.initbits.divlatch = 1;
- outp(LineCtl(), initcom.initchar);
- outp(DivLSB(), (char) ((115200L/commparms.baud) & 255));
- outp(DivMSB(), (char) ((115200L/commparms.baud) >> 8));
- initcom.initbits.divlatch = 0;
- outp(LineCtl(), initcom.initchar);
- /* ---- intercept the timer interrupt vector ----- */
- if (oldtimer == 0) {
- oldtimer = getvect(systimer);
- setvect(systimer, newtimer);
- }
- /* ------ hook serial interrupt vector --------- */
- if (oldcomint == 0) {
- oldcomint = getvect(vector());
- setvect(vector(), newcomint);
- }
- outp(ModemCtl(), (inp(ModemCtl()) | DTR | RTS | OUT2));
- outp(PIC01, (inp(PIC01) & ComIRQ()));
- outp(IntEnable(), DataReady);
- outp(PIC00, EOI);
- /* ----- flush any old interrupts ------ */
- inp(RxData());
- inp(IntIdent());
- inp(LineStatus());
- inp(ModemStatus());
- }
-
- int CommPort::readcomm()
- {
- CommPort::serialtimer.set(timeout);
- while (!input_char_ready())
- if (CommPort::serialtimer.timed_out())
- return 0;
- if (mp_nextout == mp_recvbuff+BufSize)
- mp_nextout = mp_recvbuff;
- --buffer_count;
- if (waiting_to_send_xon && buffer_count < SafetyLevel) {
- waiting_to_send_xon = false;
- writecomm(xon);
- }
- return *mp_nextout++;
- }
- bool CommPort::writecomm(int ch)
- {
- while (waiting_for_xon)
- ;
- CommPort::serialtimer.set(timeout);
- while ((inp(LineStatus()) & XmitDataReady) == 0)
- if (CommPort::serialtimer.timed_out())
- return false;
- outp(TxData(), ch);
- return true;
- }
- void CommPort::clear_serial_queue()
- {
- mp_nextin = mp_nextout = mp_recvbuff;
- buffer_count = 0;
- }
-
-