Пример #1
0
static void getChars(void *user)
{
    Uns8 c;

    while(1) {
        double d = DEFAULT_RX_DELAY;

        //
        // keep getting chars till we fill the fifo
        //
        bhmWaitDelay(d);
        while (!Rx.full) {
            Int32 bytes = readInput(&c, 1);
            if (bytes > 0) {
                //
                // We have got a char, so insert to buffer
                //
                fifoPush(&Rx, c);
                eval_interrupts();
            }
            bhmWaitDelay(d);
        }
        if (!Rx.empty) {
            eval_interrupts();
        }
    }
}
Пример #2
0
void CSerial::receive(const char* data, int dsize)
{
  while(dsize)
  {
    state.rcvBuffer[state.rcvW++] = *data;
    if(state.rcvW == FIFO_SIZE)
      state.rcvW = 0;
    data++;
    dsize--;
    eval_interrupts();
  }
}
Пример #3
0
static void putChars()
{
    Bool ok;
    Uns8 c;

    //
    // keep sending characters whilst the TX fifo is not empty
    //
    if (!Tx.empty) {
        ok = fifoPop(&Tx, &c);
        if (ok) {
            writeOutput(&c, 1);
        }
    }

    if (Tx.empty) {
        //
        // Generate an interrupt if enabled
        //
        eval_interrupts();
    } else {
        if (BHM_DIAG_HIGH) bhmMessage("F", PREFIX, "Tx.empty is false !!!");
    }
}
Пример #4
0
void CSerial::execute()
{
  fd_set          readset;
  unsigned char   buffer[FIFO_SIZE + 1];
  unsigned char   cbuffer[FIFO_SIZE + 1]; // cooked buffer
  unsigned char*  b;

  // cooked buffer
  unsigned char *c;
  ssize_t         size;
  struct timeval  tv;

  state.serial_cycles++;
  if(state.serial_cycles >= RECV_TICKS)
  {
    FD_ZERO(&readset);
    FD_SET(connectSocket, &readset);
    tv.tv_sec = 0;
    tv.tv_usec = 0;
    if(select(connectSocket + 1, &readset, NULL, NULL, &tv) > 0)
    {
#if defined(_WIN32) || defined(__VMS)

      // Windows Sockets has no direct equivalent of BSD's read
      size = recv(connectSocket, (char*) buffer, FIFO_SIZE, 0);
#else
      size = read(connectSocket, &buffer, FIFO_SIZE);
#endif

      extern int  got_sigint;
      if(size == 0 && !got_sigint)
      {
        printf("%%SRL-W-DISCONNECT: Write socket closed on other end for serial port %d.\n",
             state.iNumber);
        printf("-SRL-I-WAITFOR: Waiting for a new connection on port %d.\n",
               listenPort);
        WaitForConnection();
        return;
      }

      b = buffer;
      c = cbuffer;
      while((ssize_t) (b - buffer) < size)
      {
        if(*b == 0x0a)
        {
          b++;      // skip LF
          continue;
        }

        if(*b == IAC)
        {
          if(*(b + 1) == IAC)
          {         // escaped IAC.
            b++;
          }
          else if(*(b + 1) >= WILL)
          {         // will/won't/do/don't
            b += 3; // skip this byte, and following two. (telnet escape)
            continue;
          }
          else if(*(b + 1) == SB)
          {         // skip until IAC SE
            b += 2; // now we're at start of subnegotiation.
            while(*b != IAC && *(b + 1) != SE)
              b++;
            b += 2;
            continue;
          }
          else if(*(b + 1) == BREAK)
          {         // break (== halt button?)
            b += 2;
            breakHit = true;
          }
          else if(*(b + 1) == AYT)
          {         // are you there?
          }
          else
          {         // misc single byte command.
            b += 2;
            continue;
          }
        }

        *c = *b;
        c++;
        b++;
      }

      this->receive((const char*) &cbuffer, (c - cbuffer));
    }

    state.serial_cycles = 0;
  }

  eval_interrupts();
}
Пример #5
0
void CSerial::WriteMem(int index, u64 address, int dsize, u64 data)
{
  u8    d;
  d = (u8) data;

  switch(address)
  {
  case 0:
    if(state.bLCR & 0x80)   // divisor latch access bit set
    {

      // LSB of divisor latch
      state.bBRB_LSB = d;
    }
    else
    {

      // Transmit Hold Register
      write((const char*) &d, 1);
      TRC_DEV4("Write character %02x (%c) on serial port %d\n", d, printable(d),
               state.iNumber);
#if defined(DEBUG_SERIAL)
      printf("Write character %02x (%c) on serial port %d\n", d, printable(d),
             state.iNumber);
#endif
      eval_interrupts();
    }
    break;

  case 1:
    if(state.bLCR & 0x80)   // divisor latch access bit set
    {

      // MSB of divisor latch
      state.bBRB_MSB = d;
    }
    else
    {

      // Interrupt Enable Register
      state.bIER = d;
      eval_interrupts();
    }
    break;

  case 2:
    state.bFCR = d;
    break;

  case 3:
    state.bLCR = d;
    break;

  case 4:
    state.bMCR = d;
    break;

  default:
    state.bSPR = d;
  }
}