Всё, сделал, ну как же всё, блин через жопу (в общем описании теории расчёта CRC не ни слова об особенностях реализации CCITT-варианта) ещё немного пооптимизировал :)
;CRC16 - CCITT (XMODEM)
;27/X.13
;(C) Vladimir Kovalev
;St.Petersburg, Russia
;------------------------
;Время исполнения менее 67 тактов (включая call/ret)
;время обсчёта тестовой ASCII строки "123456789" с побайтовой загрузкой данных в TMP-регистр - 623 такта
;
;подсчёт CRC16_CCITT отличается от теории по расчёту CRC.
; Исходные данные предварительно XORятся со старшим байтом CRC-регистра, а затем уже производятся
; операции сдвига и XOR с полиномом (деление на полином по правилам CRC-арифметики).
; В теории же (в обще описании CRC-алгоритма), данные должны просто побитно вдвигаться в CRC-регистр справа.
;Стартовое значение CRC-регистра д.б. 0xFFFF
;Операции финализации, требуемые по теории (дополнение исходного вектора данных нулями в размере полинома,
;и XOR на финальной стадии с финализирующей константой (0xFFFF) - не производятся
;
;Правила использования:
; CRC16_INIT 0xFFFF,0x1021 ;начальная инициализация CRC-регистра (запись в него 0xFFFF)
; ;и значение полинома (0x1021).
; ldi TMP,DATAbyte1
; call CRC16_CCITT_update
; ldi TMP,DATAbyte2
; call CRC16_CCITT_update
; .
; .
; .
; ldi TMP,DATAbyteN
; call CRC16_CCITT_update
;
;Результат забирать в регистре "Y"
;---------------------------
;Test vector: '123456789' (0x031,0x032,0x033,0x034,0x035,0x036,0x037,0x038,0x039)
;Result: 0x29b1
;
;'1' - c782
;'2' - 3dba
;'3' - 5bce
;'4' - 5349
;'5' - 4560
;'6' - 2ef4
;'7' - 7718
;'8' - a12b
;'9' - 29b1
;
;Если сообщение (например Test Vector) дополнить его CRC контрольной суммой, то посчитав CRC для всего вектора данных вместе
;со значением CRC должны получить ноль.
; т.е. CRC16_CCITT (0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39)=0x29B1
; соответственно: CRC16_CCITT (0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x29,0xB1)=0x0000
;
;Используемые регистры:
;TMP, TMP2, Y, X
;
;!! ВНИМАНИЕ !!
;во время всей процедурв подсчёта CRC16_CCITT регистр "Y" (регистр контрольной суммы)
;и регистр "X" (значение полинома) - не портить!!
;
;TMP - исходные данные (подсчитываемый байт данных)
;X- значение полинома
;Y - CRC-регистр - текущее и финальное значения контрольной суммы CRC16_CCITT
;-----------------
.macro LDX
ldi XL,low(@0)
ldi XH,high(@0)
.endmacro
;-----------------
.macro LDY
ldi YL,low(@0)
ldi YH,high(@0)
.endmacro
;-----------------
.macro CRC16_INIT
LDY @0 ;начальная инициализация CRC-регистра
LDX @1 ;значение полинома
.endmacro
;----------------------------------------
CRC16_CCITT_update:
eor YH,TMP ;помещаем байт данных в CRC регистр (XOR байта данных со старшим байтом CRC-регистра)
ldi TMP2,7 ;В TMP2 организуем счётчик бит для операций сдвига байта исходных данных
;В TMP на данный момент лежат исходные данные (подсчитываемый байт данных)
CRC_Count:
lsl YL ;Сдвигаем побитно данные влево в CRC-регистре (Y).
rol YH
brcc CRC_CheckByteEnd ;Если "выдвинутый" из CRC-регистра бит - нулевой, то проверяем, не закончился ли байт входных данных
eor YL,XL ; иначе считаем, что выдвинулась "1", сл-но нужно поXORить CRC регистр с полиномом
eor YH,XH ; (!! важный момент, - так как выдвинутая "1" "потерялась", но у полинома старший (17-й) бит = "1"
; то это совершенно неважно. т.к. XOR выдвинутой "1" и старшего бита полинома даст "0")
CRC_CheckByteEnd:
subi TMP2,1 ;Проверяем счётчик бит (сдвигов) для исходного байта данных
brcc CRC_Count ; продолжаем цикл подсчёта CRC, если не все разряды исходного байта просмотрены.
;
ret ;Если просмотрели все разряды исходного байта, то выходим (результат в регистре Y)
;----------------------------------------------------------------------------