Add support for 18 MHz Clock
[pub/USBasp.git] / firmware / usbdrv / usbdrvasm.S
index 2e8097d..80f4970 100644 (file)
@@ -5,7 +5,6 @@
  * Tabsize: 4
  * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
  * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
- * Revision: $Id: usbdrvasm.S 785 2010-05-30 17:57:07Z cs $
  */
 
 /*
@@ -146,7 +145,8 @@ RTMODEL "__rt_version", "3"
 #if USB_USE_FAST_CRC
 
 ; This implementation is faster, but has bigger code size
-; Thanks to Slawomir Fras (BoskiDialer) for this code!
+; Thanks to Slawomir Fras (BoskiDialer) for this code and to Shay Green for
+; even further optimizations!
 ; It implements the following C pseudo-code:
 ; unsigned table(unsigned char x)
 ; {
@@ -176,35 +176,29 @@ RTMODEL "__rt_version", "3"
 ;   resCrc  r24+r25 / r16+r17
 ;   ptr     X / Z
 usbCrc16:
-    mov     ptrL, argPtrL
-    mov     ptrH, argPtrH
+    movw    ptrL, argPtrL
     ldi     resCrcL, 0xFF
     ldi     resCrcH, 0xFF
+    clr     bitCnt          ; zero reg
     rjmp    usbCrc16LoopTest
 usbCrc16ByteLoop:
     ld      byte, ptr+
-    eor     resCrcL, byte   ; resCrcL is now 'x' in table()
-    mov     byte, resCrcL   ; compute parity of 'x'
+    eor     byte, resCrcL   ; scratch is now 'x' in table()
+    mov     scratch, byte   ; compute parity of 'x'
     swap    byte
-    eor     byte, resCrcL
-    mov     scratch, byte
+    eor     byte, scratch
+    mov     resCrcL, byte
     lsr     byte
     lsr     byte
-    eor     byte, scratch
+    eor     byte, resCrcL
     inc     byte
-    lsr     byte
-    andi    byte, 1         ; byte is now parity(x)
-    mov     scratch, resCrcL
-    mov     resCrcL, resCrcH
-    eor     resCrcL, byte   ; low byte of if(parity(x)) value ^= 0xc001;
-    neg     byte
-    andi    byte, 0xc0
-    mov     resCrcH, byte   ; high byte of if(parity(x)) value ^= 0xc001;
-    clr     byte
-    lsr     scratch
-    ror     byte
-    eor     resCrcH, scratch
-    eor     resCrcL, byte
+    andi    byte, 2        ; byte is now parity(x) << 1
+    cp      bitCnt, byte   ; c = (byte != 0), then put in high bit
+    ror     scratch        ; so that after xoring, shifting, and xoring, it gives
+    ror     byte           ; the desired 0xC0 with resCrcH
+    mov     resCrcL, byte
+    eor     resCrcL, resCrcH
+    mov     resCrcH, scratch
     lsr     scratch
     ror     byte
     eor     resCrcH, scratch
@@ -372,7 +366,7 @@ usbMFTimeout:
 #   if USB_CFG_CLOCK_KHZ == 18000
 #       include "usbdrvasm18-crc.inc"
 #   else
-#       error "USB_CFG_CLOCK_KHZ is not one of the supported crc-rates!"
+#       error "USB_CFG_CLOCK_KHZ is not one of the supported rates for USB_CFG_CHECK_CRC!"
 #   endif
 #else   /* USB_CFG_CHECK_CRC */
 #   if USB_CFG_CLOCK_KHZ == 12000
@@ -385,9 +379,11 @@ usbMFTimeout:
 #       include "usbdrvasm16.inc"
 #   elif USB_CFG_CLOCK_KHZ == 16500
 #       include "usbdrvasm165.inc"
+#   elif USB_CFG_CLOCK_KHZ == 18000
+#       include "usbdrvasm18.inc"
 #   elif USB_CFG_CLOCK_KHZ == 20000
 #       include "usbdrvasm20.inc"
 #   else
-#       error "USB_CFG_CLOCK_KHZ is not one of the supported non-crc-rates!"
+#       error "USB_CFG_CLOCK_KHZ is not one of the supported rates!"
 #   endif
 #endif /* USB_CFG_CHECK_CRC */