From: <m97...@us...> - 2012-03-24 16:36:31
|
Revision: 12447 http://openmsx.svn.sourceforge.net/openmsx/?rev=12447&view=rev Author: m9710797 Date: 2012-03-24 16:36:19 +0000 (Sat, 24 Mar 2012) Log Message: ----------- compute CRC16 of short sequences at compile time Modified Paths: -------------- openmsx/trunk/src/fdc/RawTrack.cc openmsx/trunk/src/fdc/TC8566AF.cc openmsx/trunk/src/fdc/WD2793.cc openmsx/trunk/src/utils/CRC16.hh Modified: openmsx/trunk/src/fdc/RawTrack.cc =================================================================== --- openmsx/trunk/src/fdc/RawTrack.cc 2012-03-24 16:35:59 UTC (rev 12446) +++ openmsx/trunk/src/fdc/RawTrack.cc 2012-03-24 16:36:19 UTC (rev 12447) @@ -35,12 +35,11 @@ bool RawTrack::decodeSector(int idx, Sector& sector) const { // read (and check) address mark - CRC16 addrCrc; // assume addr mark starts with three A1 bytes (should be // located right before the current 'idx' position) - for (int i = 0; i < 3; ++i) { - addrCrc.update(0xA1); - } + CRC16 addrCrc; + addrCrc.init<0xA1, 0xA1, 0xA1>(); + if (read(idx++) != 0xFE) return false; addrCrc.update(0xFE); int addrIdx = idx; Modified: openmsx/trunk/src/fdc/TC8566AF.cc =================================================================== --- openmsx/trunk/src/fdc/TC8566AF.cc 2012-03-24 16:35:59 UTC (rev 12446) +++ openmsx/trunk/src/fdc/TC8566AF.cc 2012-03-24 16:36:19 UTC (rev 12447) @@ -502,7 +502,7 @@ } // Initialize crc // TODO 0xFB vs 0xF8 depends on deleted vs normal data - crc.init(0xE295); // A1 A1 A1 FB + crc.init<0xA1, 0xA1, 0xA1, 0xFB>(); // first byte is available when it's rotated below the // drive-head Modified: openmsx/trunk/src/fdc/WD2793.cc =================================================================== --- openmsx/trunk/src/fdc/WD2793.cc 2012-03-24 16:35:59 UTC (rev 12446) +++ openmsx/trunk/src/fdc/WD2793.cc 2012-03-24 16:36:19 UTC (rev 12447) @@ -253,7 +253,7 @@ // 3rd A1 byte. Though what we do instead is on // each A1 byte initialize the value as if // there were already 2 A1 bytes written. - crc.init(0x968B); + crc.init<0xA1, 0xA1>(); } else if (value == 0xF6) { // write C2 with missing clock transitions write = 0xC2; @@ -606,7 +606,7 @@ // - write A1 A1 A1 FB (or F8) // But ATM we reuse the previous location of the data block } - crc.init(0xE295); // A1 A1 A1 FB + crc.init<0xA1, 0xA1, 0xA1, 0xFB>(); // wait till sector is actually rotated under head schedule(FSM_TYPE2_ROTATED, next); Modified: openmsx/trunk/src/utils/CRC16.hh =================================================================== --- openmsx/trunk/src/utils/CRC16.hh 2012-03-24 16:35:59 UTC (rev 12446) +++ openmsx/trunk/src/utils/CRC16.hh 2012-03-24 16:36:19 UTC (rev 12447) @@ -28,6 +28,40 @@ crc = initialCRC; } + /** (Re)initialize with a short initial sequence. + * The initial value is guaranteed to be computed at compile time. + */ + template<byte V1> void init() + { + static const word T0 = 0xffff; + static const word T1 = CT_CRC16<T0, V1>::value; + init(T1); + } + template<byte V1, byte V2> void init() + { + static const word T0 = 0xffff; + static const word T1 = CT_CRC16<T0, V1>::value; + static const word T2 = CT_CRC16<T1, V2>::value; + init(T2); + } + template<byte V1, byte V2, byte V3> void init() + { + static const word T0 = 0xffff; + static const word T1 = CT_CRC16<T0, V1>::value; + static const word T2 = CT_CRC16<T1, V2>::value; + static const word T3 = CT_CRC16<T2, V3>::value; + init(T3); + } + template<byte V1, byte V2, byte V3, byte V4> void init() + { + static const word T0 = 0xffff; + static const word T1 = CT_CRC16<T0, V1>::value; + static const word T2 = CT_CRC16<T1, V2>::value; + static const word T3 = CT_CRC16<T2, V3>::value; + static const word T4 = CT_CRC16<T3, V4>::value; + init(T4); + } + /** Update CRC with one byte */ void update(byte value) @@ -45,6 +79,20 @@ private: word crc; static const word CRC16Table[256]; + + // The Stuff below is template magic to perform the following + // computation at compile-time: + // for (int i = 8; i < 16; ++i) { + // crc = (crc << 1) ^ ((((crc ^ (data << i)) & 0x8000) ? 0x1021 : 0)); + // } + template<word C, word V, int B> struct CT_H { + static const word D = word(C << 1) ^ (((C ^ V) & 0x8000) ? 0x1021 : 0); + static const word value = CT_H<D, word(V << 1), B - 1>::value; + }; + template<word C, word V> struct CT_H<C, V, 0> { + static const word value = C; + }; + template<word IN, byte VAL> struct CT_CRC16 : CT_H<IN, VAL << 8, 8> {}; }; } // namespace openmsx This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |