I have included the source code for the CRC calculation and the building of
the packet itself.  Some users may find it useful to include this routine 
in their black box for testing purposes.  (i.e.  The black box will send 
the CRC packet to Terminal Plus.  Terminal Plus will then display CRC 
errors coming from the black box.)

Here is the code for generating the CRC packet that is sent from Terminal Plus.  

The packet is built in TPlus::SendCRCPacket(void).

The CRC calculation is done in get_crc(char *, char *).

The CRC receive checking is done in TTermView::crcTestPacket(char)


void TPlus::SendCrcPacket(void)
  {
    char buffer[100];
    char *end=&buffer[0];
    unsigned int crc=0;
    unsigned char rand_index=0;
    char random_value=0;
    int len, iCount;
    buffer[0]=STX;
    buffer[1]=0x00;
    for(iCount=46;iCount<123;iCount++) // fill with 46-122 ascii chars
      buffer[(iCount-46)+1]=iCount;
    buffer[(iCount-46)+1]=0x00;         // terminate string
    strcat(buffer,"\r\n");
    len=strlen(buffer);
    len+=(1+1+1);                //  crc_high byte + crc_low byte +etx --- stx was included in above strlen
    end+=((strlen(buffer))-1);   // don't include stx in length
    crc=get_crc(&buffer[1],end+1); // crc calc compare is < so need to add 1 to include last byte
    *(end+1)=(char)(crc>>8);       // high byte
    *(end+2)=(char)(crc&0x00FF);   // lowbyte
    *(end+3)=ETX;
    *(end+4)=0x00;
    if(CommRoutines->TXCharsQued()<len)
      CommRoutines->TX_String_Raw(&buffer[0], len,10);
  }


unsigned int get_crc(char *start, char *end)
  {
    unsigned int crc_val=0;
    while(start<end)
      {
        crc_val^=*start++;
        if(crc_val&0x80)
          crc_val=(crc_val<<1)|0x01;  /* shift and set LSB - equiv. to roll */
        else 
          crc_val<<=1;
      }
    return(crc_val);  
  }


void TTermView::crcTestPacket(char c)
  {
    static char packet_buffer[256];
    static char *packet_ptr=&packet_buffer[0];
    static int packet_start=0;
    unsigned int calc_crc=0;
    unsigned int Rx_crc=0;
    switch (c)
      {
        case STX:
          packet_start=1;
          packet_ptr=&packet_buffer[0];
          break;
        case ETX:
          if(packet_start)
            {
              calc_crc=get_crc(&packet_buffer[0],packet_ptr-2);  // don't include crc - 2 bytes
              Rx_crc=(unsigned int) *(packet_ptr-2);    // high byte
              Rx_crc<<=8;
              Rx_crc|=(unsigned char)*(packet_ptr-1);   // low byte
              if(calc_crc!=Rx_crc)
                totalCRCErrors++;
            }
          else
            totalCRCErrors++;  // did not get a startup packet - sync error
          packet_start=0;  // reset
          packet_ptr=&packet_buffer[0]; // reset
          break;
        default:
          *packet_ptr++=c;
          if(packet_ptr>=&packet_buffer[255])
            {
              packet_ptr=&packet_buffer[0];  // reset to avoid memory overwrite
              packet_start=0;
            }
          *packet_ptr=0x00;  
          break;
      }
  }
