Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung Nächste ÜberarbeitungBeide Seiten der Revision | ||
cpm:crc [2011/08/30 09:41] – volkerp | cpm:crc [2013/10/20 06:28] – volkerp | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
====== CRC-Berechnung ====== | ====== CRC-Berechnung ====== | ||
- | In diversen U880-Programmen, | + | In diversen U880-Programmen, |
CRC-CCITT (CRC-16) x^16 + x^12 + x^5 + 1 | CRC-CCITT (CRC-16) x^16 + x^12 + x^5 + 1 | ||
Zeile 12: | Zeile 12: | ||
< | < | ||
- | sub crc16 { | + | $buf = ....; #Arrays von 2KiByte FFh |
- | #Arrays von 2KiByte FFh | + | $len = 2048; #Anzahl der Bytes |
- | $len = 2048; | + | |
- | + | ||
- | #CRC-CCITT (CRC-16) x16 + x12 + x5 + 1 | + | |
- | $POLY = 0b_0001_0000_0010_0001; | + | |
- | + | ||
- | # | + | |
- | $crc16 = 0xFFFF; | + | |
- | + | ||
- | for ($i=0; | + | |
- | my $byte = ord(substr($buf, | + | |
- | $byte = $byte * 0x100; | + | #CRC-CCITT (CRC-16) x16 + x12 + x5 + 1 |
- | for (0..7) # 8 Bits pro Byte | + | $POLY = 0b_0001_0000_0010_0001; |
- | { | + | # da nur mit 16 Bit gearbeitet wird |
- | if (($byte & 0x8000) ^ ($crc16 & 0x8000)) { | + | |
- | $crc16 <<= 1; | + | # |
- | $crc16 ^= $POLY; | + | $crc16 = 0xFFFF; |
- | $crc16 &= 0xFFFF; | + | |
- | } else { | + | for ($i=0; |
- | $crc16 <<= 1; | + | my $byte = ord(substr($buf, |
- | $crc16 &= 0xFFFF; | + | |
- | } | + | $byte = $byte * 0x100; |
- | $byte <<= 1; | + | for (0..7) # 8 Bits pro Byte |
- | $byte &= 0xFFFF; | + | { |
+ | if (($byte & 0x8000) ^ ($crc16 & 0x8000)) { | ||
+ | # wenn die Hi-Bits unterschiedlich sind, dann | ||
+ | $crc16 <<= 1; # shift left | ||
+ | $crc16 ^= $POLY; # XOR-Verknüpfung mit CRC-Poly | ||
+ | $crc16 &= 0xFFFF; # beschränken auf 16 Bit | ||
+ | } else { | ||
+ | # ansonsten nächstes Bit ohne Verküpfung | ||
+ | $crc16 <<= 1; # shift left | ||
+ | $crc16 &= 0xFFFF; # beschränken auf 16 Bit | ||
} | } | ||
+ | $byte <<= 1; # shift left, nächstes Bit | ||
+ | $byte &= 0xFFFF; | ||
} | } | ||
- | |||
- | # ausgabe | ||
- | printf "CRC = %.4X\n", | ||
} | } | ||
+ | |||
+ | # Ausgabe | ||
+ | printf "CRC = %.4X\n", | ||
</ | </ | ||
Normalerweise werden CRC-Polynome mit reverser Bit-Reihenfolge berechnet; auch die einzelnen Bytes werden in umgekehrter Reihenfolge abgearbeitet. Und richtig optimal wird es erst mit vorbrechneten Tabellen... | Normalerweise werden CRC-Polynome mit reverser Bit-Reihenfolge berechnet; auch die einzelnen Bytes werden in umgekehrter Reihenfolge abgearbeitet. Und richtig optimal wird es erst mit vorbrechneten Tabellen... | ||
- | In Assembler sieht die CRC-Routine wie folgt aus. Die Berechnung ist optimiert und erfolgt tetradenweise. | + | In Assembler sieht die CRC-Routine wie folgt aus. Die Berechnung ist optimiert und erfolgt tetradenweise. |
in: DE = Startadr., BC = Länge\\ | in: DE = Startadr., BC = Länge\\ | ||
Zeile 91: | Zeile 92: | ||
</ | </ | ||
- | s.a. http:// | + | s.a. |
+ | |||
+ | * http:// | ||
+ | * http:// |