home *** CD-ROM | disk | FTP | other *** search
/ C++ Games Programming / CPPGAMES.ISO / thx / source / theatrix / serial.cpp < prev    next >
C/C++ Source or Header  |  1995-04-09  |  4KB  |  143 lines

  1. // --------- serial.cpp
  2.  
  3. #include "serial.h"
  4.  
  5. static void interrupt (*oldtimer)(...);
  6. static void interrupt (*oldcomint)(...);
  7.  
  8. Timer CommPort::serialtimer;
  9. CommPort *CommPort::mp_CommPort;
  10.  
  11. // ------ ISRs to count timer ticks
  12. void interrupt newtimer(...)
  13. {
  14.     (*oldtimer)();
  15.     if (CommPort::serialtimer.running())
  16.            CommPort::serialtimer.countdown();
  17. }
  18.  
  19. // ---- serial input interrupt service routine
  20. void interrupt newcomint(...)
  21. {
  22.     CommPort::mp_CommPort->CommInterrupt();
  23. }
  24.  
  25. void CommPort::CommInterrupt()
  26. {
  27.     int c;
  28.     outp(PIC00,EOI);
  29.     if (mp_nextin == mp_recvbuff+BufSize)
  30.         mp_nextin = mp_recvbuff;           // circular buffer
  31.     c = inp(RxData());              // read the input
  32.     if (xonxoff_enabled)
  33.         if (c == xoff)               /* test XON        */
  34.             waiting_for_xon = true;
  35.         else if (c == xon)           /* test XOFF       */
  36.             waiting_for_xon = false;
  37.     if (!xonxoff_enabled || (c != xon && c != xoff))    {
  38.         *mp_nextin++ = (char) c;        /* put char in buff*/
  39.         buffer_count++;
  40.     }
  41.     if (xonxoff_enabled && !waiting_to_send_xon &&
  42.             buffer_count > Threshold)    {
  43.         while ((inp(LineStatus()) & XmitDataReady) == 0)
  44.             ;
  45.         outp(TxData(), xoff);          /* send XOFF        */
  46.         waiting_to_send_xon = true;
  47.     }
  48. }
  49.  
  50. CommPort::CommPort(const CommParameters& cp) : commparms(cp)
  51. {
  52.     mp_CommPort = this;
  53.     mp_recvbuff = new char[BufSize];
  54.     mp_nextin = mp_nextout = mp_recvbuff;
  55.     xonxoff_enabled = true;
  56.     buffer_count = 0;
  57.     waiting_for_xon = false;
  58.     waiting_to_send_xon = false;
  59.     oldtimer = 0;
  60.     oldcomint = 0;
  61.     timeout = 10;
  62.     Initialize();
  63. }
  64.  
  65. CommPort::~CommPort()
  66. {
  67.     delete mp_recvbuff;
  68.     if (oldcomint)    {
  69.         setvect(vector(), oldcomint);
  70.         oldcomint = 0;
  71.     }
  72.     if (oldtimer)    {
  73.         setvect(systimer, oldtimer);
  74.         oldtimer = 0;
  75.     }
  76. }
  77. /* -------- initialize the com port ----------- */
  78. void CommPort::Initialize()
  79. {
  80.     initcom.initbits.parity   = commparms.parity == 2 ? 3 : commparms.parity;
  81.     initcom.initbits.stopbits = commparms.stopbits-1;
  82.     initcom.initbits.wordlen  = commparms.databits-5;
  83.     initcom.initbits.brk      = 0;
  84.     initcom.initbits.divlatch = 1;
  85.     outp(LineCtl(), initcom.initchar);
  86.     outp(DivLSB(), (char) ((115200L/commparms.baud) & 255));
  87.     outp(DivMSB(), (char) ((115200L/commparms.baud) >> 8));
  88.     initcom.initbits.divlatch = 0;
  89.     outp(LineCtl(), initcom.initchar);
  90.     /* ---- intercept the timer interrupt vector ----- */
  91.     if (oldtimer == 0)    {
  92.         oldtimer = getvect(systimer);
  93.         setvect(systimer, newtimer);
  94.     }
  95.     /* ------ hook serial interrupt vector --------- */
  96.     if (oldcomint == 0)    {
  97.         oldcomint = getvect(vector());
  98.         setvect(vector(), newcomint);
  99.     }
  100.     outp(ModemCtl(), (inp(ModemCtl()) | DTR | RTS | OUT2));
  101.     outp(PIC01, (inp(PIC01) & ComIRQ()));
  102.     outp(IntEnable(), DataReady);
  103.     outp(PIC00, EOI);
  104.     /* ----- flush any old interrupts ------ */
  105.     inp(RxData());
  106.     inp(IntIdent());
  107.     inp(LineStatus());
  108.     inp(ModemStatus());
  109. }
  110.  
  111. int CommPort::readcomm()
  112. {
  113.     CommPort::serialtimer.set(timeout);
  114.     while (!input_char_ready())
  115.         if (CommPort::serialtimer.timed_out())
  116.             return 0;
  117.     if (mp_nextout == mp_recvbuff+BufSize)
  118.         mp_nextout = mp_recvbuff;
  119.     --buffer_count;
  120.     if (waiting_to_send_xon && buffer_count < SafetyLevel)    {
  121.         waiting_to_send_xon = false;
  122.         writecomm(xon);
  123.     }
  124.     return *mp_nextout++;
  125. }
  126. bool CommPort::writecomm(int ch)
  127. {
  128.     while (waiting_for_xon)
  129.         ;
  130.     CommPort::serialtimer.set(timeout);
  131.     while ((inp(LineStatus()) & XmitDataReady) == 0)
  132.         if (CommPort::serialtimer.timed_out())
  133.             return false;
  134.     outp(TxData(), ch);
  135.     return true;
  136. }
  137. void CommPort::clear_serial_queue()
  138. {
  139.     mp_nextin = mp_nextout = mp_recvbuff;
  140.     buffer_count = 0;
  141. }
  142.  
  143.