Hi everyone,
This is kind of a doublepost as I originally put this question as a response in this thread without noticing the thread was in the wishlist section of the forum. Hopefully it gets a bit more attention here.

Allright, I'm working a MODBUS stack for PBP. I found a CRC routine (I think it was in another thread here) which I've modified slightly and it works nicely. The problem is that it is, or seems, quite slow. Here's the current code:
Code:
MB_CRC = 65535
MB_k = MB_Buffer_Ptr - 3                   ' Find out where in the array to stop.
FOR MB_i = 0 to MB_k                       ' Iterate thru the frame, stop before the last two bytes which are the actual CRC.
    MB_CRC = MB_CRC ^ MB_Buffer[MB_i]      ' Bitwise EXOR the current low byte of the CRC "value" with the byte in the buffer
 
    For MB_j = 0 to 7                      ' Cycle thru the low byte of the CRC value                      
        If MB_CRC.Bit0 THEN                ' If the LSB is set
            MB_CRC = MB_CRC >> 1           ' We shift CRC on bit to the right....
            MB_CRC = $A001 ^ MB_CRC        ' and EXOR it with out polynomial for MODBUS CRC-16 ($A001)
        ELSE
            MB_CRC = MB_CRC >> 1           ' If the LSB is not set we simply shift CRC one bit to the right.
        ENDIF
    Next                                   ' Next bit in the byte
NEXT                                       ' Next byte in the frame
RETURN
This thing takes 1730 cycles, including a GOSUB and RETURN, to calculate the CRC value for 9 bytes (123456789). In the tread I linked to above Darrel has a, what looks to me, very similar routined which is said to do it in 825 cycles. For reference, here's Darrels code:
Code:
CRC       VAR WORD
CRC_IN    VAR BYTE
Idx       VAR BYTE
CRC_Len   CON 16
CRC_Poly  CON $1021  ; x16 + x12 + x5 + 1
;-----CRC-16 -----------------------------------------------------
CRC16:
  CRC.HighByte = CRC.HighByte ^ CRC_IN
  FOR Idx = 0 to 7
    IF CRC.0(CRC_Len-1) THEN
      CRC = (CRC << 1) ^ CRC_Poly
    ELSE
      CRC = CRC << 1
    ENDIF
  NEXT Idx
RETURN
As you can see it's very simmilar, it uses another polynominal (which I don't think should make any difference (?)) and it shifts to the left instead of the right so it's another kind of CRC than what I need or I'd use it directly.

Does anyone have any idea why mine is so much slower than Darrels and/or what I might do to speed it up? MODBUS frames can get quite large and currently it takes more than 12000 cycles to go thru a frame of 67 bytes.

Thanks!
/Henrik.