Раз уж пошла такая жара с полиномами, поделюсь и я своими процедурами по расчёту CRC. Давно столкнулся с тем что постоянно нужны разные полиномы, с разными параметрами. Каждый раз раздувать процедурами жуть как не хотелось, поэтому сделал одну универсальную библиотечку с генератором таблиц и набором готовых процедур. Краткое описание, CRC_GEN это процедура которая в зависимости от входных параметров сгенерирует таблицу под нужный полином с нужными параметрами, сама проинвертирует и перевернёт, в зависимости от ваших нужд. В конце кода есть адрес на таблицу CRC_TBL, размер которой сейчас 1024 байта, с учётом, что CRC32, если нужно меньше, догадайтесь, что нужно сделать со строчкой "DS 256*4". Выкладываю пример с примером CRC16_CITT, если правильно помню название одного из распространённых полиномов.
- Code: Select all
ORG 32768
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;EXAMPLE FOR CRC 16
LD A,00000100B ;CONFIG (CRC16)+(NON INVERT)+(NON REVERSE)
LD IX,0000H ;POLYNOM DWORD HI
LD BC,1021H ;POLYNOM DWORD LOW
LD HL,CRC_TBL
CALL CRC_GEN
LD HL,TEXT
CALL CALC_CRC16_STR
LD C,E ;this for basic PRINT USR 32768
LD B,D
RET
TEXT: DB "Hello Z80 TRUE CODERS ..."
DB 0
; IN:HL=TEXT with zerro end
;OUT:DE=CRC
CALC_CRC16_STR:
LD DE,0FFFFH
CACSx1 LD A,(HL)
OR A
RET Z
CALL CRC16DE
INC HL
JR CACSx1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;MCRC = CRCTBL
;CRC_D = DATA
;CRC_C = CRCVALUE
; A=DATA
; E=CRC8
CRC8E: PUSH HL
XOR E
LD H,HIGH(CRC_TBL)
LD L,A
LD E,(HL)
POP HL
RET
; A=DATA
;DE=CRC16
CRC16DE:PUSH HL
XOR D
LD H,HIGH(CRC_TBL)+1
LD L,A
LD A,(HL)
XOR E
LD D,A
DEC H
LD E,(HL)
POP HL
RET
; A=DATA
;BCDE=CRC16
CRC32BCDE:
PUSH HL
XOR E
LD H,HIGH(CRC_TBL)
LD L,A
LD A,D
XOR (HL)
LD E,A
INC H
LD A,C
XOR (HL)
LD D,A
INC H
LD A,B
XOR (HL)
LD C,A
INC H
LD B,(HL)
POP HL
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;IXBC CRC_START
;DEHL TEMP_EAX
;A-MODE
CRC_GEN:
PUSH HL
LD HL,CRGE08B
BIT 1,A;(IX+8) ;TEST 8-BIT
JR NZ,CRGEx7
LD HL,CRGE16B
BIT 2,A;(IX+8) ;TEST 16-BIT
JR NZ,CRGEx7
LD HL,CRGE32B
CRGEx7 LD (CRGEx6+1),HL
LD HL,CRGEx0A
BIT 0,A;(IX+8) ;TEST REVERT
JR NZ,CRGEx9
LD HL,CRGEx0B
BIT 1,A;(IX+8) ;TEST 8-BIT
JR NZ,CRGEx9
LD HL,CRGEx0C
BIT 2,A;(IX+8) ;TEST 16-BIT
JR NZ,CRGEx9
LD HL,CRGEx0D
CRGEx9 PUSH BC
LD DE,CRGEx01
LD BC,8
LDIR
LD DE,CRGEx4
LD C,6
LDIR
POP BC
LD L,C
LD H,B
PUSH IX
POP DE
BIT 0,A;(IX+8) ;TEST REVERT
JR Z,CRGEx1
CALL MIR_EAX_CRCS32
BIT 3,A;(IX+8) ;TEST 32-BIT
JR NZ,CRGEx1
EX DE,HL
LD DE,0
BIT 2,A;(IX+8) ;TEST 16-BIT
JR NZ,CRGEx1
LD L,H
LD H,D
CRGEx1 LD A,L
LD (CRGExo0+1),A
LD A,H
LD (CRGExo1+1),A
LD A,E
LD (CRGExo2+1),A
LD A,D
LD (CRGExo3+1),A
CRGEx4 DS 6
CALL CRGEx08
;STORE DATA IN TABLE
LD C,H
LD A,L
POP HL
LD (HL),A
PUSH HL
INC H
CRGEx6 CALL CRGE08B
POP HL
INC L
PUSH HL
LD HL,CRGEx4+1
INC (HL)
JR NZ,CRGEx4
POP HL
RET
CRGE16B:LD (HL),C
CRGE08B:RET
CRGE32B:LD (HL),C
INC H
LD (HL),E
INC H
LD (HL),D
RET
CRGEx08:CALL CRGEx04
CRGEx04:CALL CRGEx02
CRGEx02:CALL CRGEx01
CRGEx01:DS 8
CRGEx0E RET NC
EXA
LD A,L
CRGExo0 XOR 0
LD L,A
LD A,H
CRGExo1 XOR 0
LD H,A
LD A,E
CRGExo2 XOR 0
LD E,A
LD A,D
CRGExo3 XOR 0
LD D,A
EXA
RET
;REVERT
CRGEx0A SRL D
RR E
RR H
RR L
LD HL,0
LD DE,0
;8-BIT
CRGEx0B SLA L
DS 2
DS 2
DS 2
LD HL,0
LD DE,0
;16-BIT
CRGEx0C SLA L
RL H
DS 2
DS 2
LD H,0
LD L,0
LD D,L
LD E,L
;32-BIT
CRGEx0D SLA L
RL H
RL E
RL D
LD D,0
LD E,0
LD L,E
LD H,E
MIR_EAX_CRCS32:CALL MIR_EAX_CRCS16
MIR_EAX_CRCS16:CALL MIR_EAX_CRCS08
MIR_EAX_CRCS08:CALL MIR_EAX_CRCS04
MIR_EAX_CRCS04:CALL MIR_EAX_CRCS02
MIR_EAX_CRCS02:CALL MIR_EAX_CRCS01
MIR_EAX_CRCS01:
PUSH IX
EX (SP),HL
SRL H
RR L
EX (SP),HL
POP IX
RR B
RR C
RL L
RL H
RL E
RL D
RET
ALIGN 256
CRC_TBL DS 256*4