-- Title: math_mw -- ---------------------------------------------------------------------- -- Title: math.jal - Collection of mathematical functions. -- Authors: Rob Hamerling, Michael Watterson -- Copyright (c) 2009, all rights reserved. -- Adapted-by: -- Compiler: 2.4l -- -- This file is part of jallib (http://jallib.googlecode.com) -- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html) -- -- Description: -- Collection of mathematical routines. -- -- Sources: Several authors. -- -- Notes: -- -- -------------------------------------------------------- -- Calculate the square root of an unsigned 16-bits integer -- Returns an 8-bits integer -- Original author: Kyle York -- -- function sqrt16(word in x) return byte is var word m, y m = 0x4000 y = 0 while (m != 0) loop var word b b = y | m y = y >> 1 if (x >= b) then x = x - b y = y | m end if m = m >> 2 end loop return byte(y) end function -- -------------------------------------------------------- -- Calculate the square root of an unsigned 32-bits integer -- Returns a 16-bits integer -- Original author: Kyle York -- -- function sqrt32(dword in x) return word is var dword m, y m = 0x40000000 y = 0 while (m != 0) loop var dword b b = y | m y = y >> 1 if (x >= b) then x = x - b y = y | m end if m = m >> 2 end loop return word(y) end function -- Author: Michael Watterson function digitsWord(word in valu)return byte is var byte temp = 1 var dword index = 9 while (dword(valu) > index) loop index = index * 10 +9 temp = temp +1 end loop return temp end function -- fixed point math is 8 bits for decimal in this library. -- approx two decimal paces, the part after "point" is 0 to 255 -- sword fixed point numbers are thus -127.00 to +127.00 approx -- if you want bigger numbers replace all swords by sdwords and -- sdwords by sbyte*8 if the compiler can do the math still. function byteToFixed (byte in anInt) return sword is return ((sword(anInt)) << 8) end function function truncFixed (sword in fixedPoint) return sbyte is return ( sbyte(fixedPoint >> 8)) end function function roundFixed (sword in fixedPoint) return sbyte is if ((fixedPoint & 0x10) >0) then -- 128 and more = 0.5 return ( sbyte(fixedPoint >> 8) +1) else return ( sbyte(fixedPoint >> 8)) end if end function -- unlike integer max is 128 * 128 *256 approx function multFixed (sword in a, sword in b) return sdword is return ((sdword(a) * sdword(b)) >> 8) -- fix point end function function divFixed (sword in a, sword in b) return sdword is return ( sword((sdword(a) * sdword (256*256)) / sdword(b)) >> 16) end function -- probably a better way to do this! function modFixed (sword in a, sword in b) return sword is return ( a - sword(sdword(b)*((sdword(a) * sdword (256*256)) / sdword(b)) >> 16)) end function -- sin values scaled to (256 * 1.0) -1 for values above Zero -- (i.e. add one to lookup if using table directly for other than Zeroth Element) -- apart from zero, all values are 1 less than actual -- to allow storage in 1 byte each const byte SINLOOKUP[] = {0, 3, 8, 12, 17, 21, 26, 30, 35, 39, 43, 48, 52, 57, 61, 65, 70, 74, 78, 82, 87, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131, 135, 138, 142, 146, 149, 153, 157, 160, 164, 167, 170, 174, 177, 180, 183, 186, 189, 192, 195, 198, 201, 203, 206, 209, 211, 214, 216, 218, 221, 223, 225, 227, 229, 231, 233, 235, 236, 238, 240, 241, 242, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 253, 254, 254, 254, 255, 255, 255, 255 } -- 0 to 90 degrees in 1 degree steps -- 8bit resolution sin function R x Sin (angle) in degrees -32767 to +32767 -- result can be same magnitude and opposite sign -- use to generate audio waves by changing angle at a fixed speed. -- if using all 360 degrees in one degree steps, then frequency is step rate / 360 -- at nyquist frequency you only need 0 and 180 degrees, i.e. 1/2 sample rate. -- if sample rate is 48kHz then for 12kHz you have only 4 samples, i.e. 90 degree steps -- at 1.2kHz thus you use 9 degree steps. -- 1 degree steps is thus 133.33 Hz if step speed is 48KHz -- PWM can be loaded via this lookup -- use 128 and add 127 to answer for 8 bit PWM -- use 512 and add 511 to answer for 10bit PWM -- if summing two frequencies, peak value is twice, so add as swords < 16383 and -- divide sum by 2! -- Author: Michael Watterson -- works with fixed point numbers 256 = 1.0 function rSin8( sword in radius, sword in angle ) return sword is var sword yPos --make sure works for ANY angle ... While (angle < 0) loop angle = angle + 360 end Loop While (angle >= 360) loop angle = angle - 360 end Loop Case angle of 0: yPos = 0 90: yPos = radius 180: yPos =0 270: yPos = -radius otherwise block -- add or subtract one as lookups above zero have -1 so 256x 1.0 -- fits in one byte If (angle > 0) & (angle < 90) Then yPos = sword(SINLOOKUP[angle]) + 1 elsif (angle > 90) & (angle < 180) Then angle = angle - 90 yPos = sword(SINLOOKUP[(90 - angle)]) + 1 elsif (angle > 180) & (angle < 270) Then angle = angle - 180 yPos = -sword(SINLOOKUP[angle]) - 1 elsif (angle > 270) & (angle < 360) Then angle = angle - 270 yPos = -sword(SINLOOKUP[(90 - angle)]) - 1 End If yPos = yPos * radius / 256 end block End case return (yPos) end function -- Author: Michael Watterson function rCos8( sword in radius, sword in angle ) return sword is var sword xPos --make sure works for ANY angle ... While (angle < 0) loop angle = angle + 360 end Loop While (angle >= 360) loop angle = angle - 360 end Loop Case angle of 0: xPos = radius 90: xPos = 0 180: xPos = -radius 270: xPos = 0 otherwise block -- add or subtract one as lookups above zero have -1 so 256x 1.0 -- fits in one byte If (angle > 0) & (angle < 90) Then xPos = sword(SINLOOKUP[(90 - angle)]) + 1 elsif (angle > 90) & (angle < 180) Then angle = angle - 90 xPos = -sword(SINLOOKUP[angle]) - 1 elsif (angle > 180) & (angle < 270) Then angle = angle - 180 xPos = -sword(SINLOOKUP[(90 - angle)]) - 1 elsif (angle > 270) & (angle < 360) Then angle = angle - 270 xPos = sword(SINLOOKUP[angle]) + 1 End If xPos = xPos * radius / 256 end block End case return (xPos) end function -- use to rotate angle of a line by calculating endpoints -- use to generate quadrature waves by changing angle at a fixed speed. -- if using all 360 degrees in one degree steps, then frequency is step rate / 360 -- Author: Michael Watterson procedure PolarToCartesian(sword in radius, sword in angle, sword out xPos, sword out yPos) is --make sure works for ANY angle ... While (angle < 0) loop angle = angle + 360 end Loop While (angle >= 360) loop angle = angle - 360 end Loop Case angle of 0: block xPos = radius yPos = 0 end block 90: Block xPos = 0 yPos = radius end block 180: block xPos = -radius yPos = 0 end block 270: block xPos = 0 yPos = -radius end block otherwise block -- add or subtract one as lookups above zero have -1 so 256 x 1.0 -- fits in one byte If (angle > 0) & (angle < 90) Then yPos = sword(SINLOOKUP[angle]) + 1 xPos = sword(SINLOOKUP[(90 - angle)]) + 1 elsif (angle > 90) & (angle < 180) Then angle = angle - 90 xPos = -sword(SINLOOKUP[angle]) - 1 yPos = sword(SINLOOKUP[(90 - angle)]) + 1 elsif (angle > 180) & (angle < 270) Then angle = angle - 180 xPos = -sword(SINLOOKUP[(90 - angle)]) - 1 yPos = -sword(SINLOOKUP[angle]) - 1 elsif (angle > 270) & (angle < 360) Then angle = angle - 270 xPos = sword(SINLOOKUP[angle]) + 1 yPos = -sword(SINLOOKUP[(90 - angle)]) - 1 End If xPos = xPos * radius / 256 yPos = yPos * radius / 256 end block End case End procedure -- Random number psuedo random number generators -- http://www.coyotegulch.com/products/libcoyotl/twisted_road/index.html -- wikipedia on both these: -- BlumBlumShub : good for crypographic stuff, not so good for MonteCarlo etc. -- Mersenne Twister: not good for crypo. But good for MonteCarlo and other stuff -- it needs a 624 doubleword array though, 4 x 624 bytes! -- A simple version of the pretty poor rand generator of C and C++ -- is a linear congruential generator -- a bit better than RANDU (wikipedia) var volatile dword _lgr_next = 1 -- private! -- rand is our pseudo variable function rand() return word is _lgr_next = _lgr_next * 1103515245 + 12345 return (word((_lgr_next / 65536) % 32767)) end function procedure rand_Seed(word in seed) is _lgr_next = seed end procedure --/* A C-program for TT800 : July 8th 1996 Version */ --/* by M. Matsumoto, email: matumoto@math.keio.ac.jp */ --/* genrand() generate one pseudorandom number with double precision */ --/* which is uniformly distributed on [0,1]-interval */ --/* for each call. One may choose any initial 25 seeds */ -- /* except all zeros. */ -- /* See: ACM Transactions on Modelling and Computer Simulation, */ -- /* Vol. 4, No. 3, 1994, pages 254-266. */ -- #include -- #define N 25 --- #define M 7 -- block const N = 25 const M = 7 var sword k = 0 var dword x[N]={ --/* initial 25 seeds, change as you wish */ 0x95f24dab, 0x0b685215, 0xe76ccae7, 0xaf3ec239, 0x715fad23, 0x24a590ad, 0x69e4b5ef, 0xbf456141, 0x96bc1b7b, 0xa7bdf825, 0xc1de75b7, 0x8858a9c9, 0x2da87693, 0xb657f9dd, 0xffdc8a9f, 0x8121da71, 0x8b823ecb, 0x885d05f5, 0x4e20cd47, 0x5a9ad5d9, 0x512c0c03, 0xea857ccd, 0x4cc1d30f, 0x8891a8a1, 0xa6b7aadb } var dword mag01[2]={ 0x0, 0x8ebfd028 --/* this is magic vector `a', don't change */ } function genrand() return dword is -- uses more RAM than rand() var dword y if (k == N) then -- { /* generate N words at one time */ var sword kk = 0 while kk < (N - M) loop --(kk=0;kk> 1) ^ mag01[x[kk] % 2] kk = kk + 1 end loop while kk < N loop -- (; kk> 1) ^ mag01[x[kk] % 2] kk = kk + 1 end loop k=0 end if y = x[k]; y = y ^ (y << 7) & 0x2b5b2500; /* s and b, magic vectors */ y = y ^ (y << 15) & 0xdb8b0000; /* t and c, magic vectors */ y = y & 0xffffffff --; /* you may delete this line if word size = 32 */ --/* -- the following line was added by Makoto Matsumoto in the 1996 version -- to improve lower bit's corellation. -- Delete this line to o use the code published in 1994. --*/ -- y = y^(y >> 16) -- /* added to the 1994 version */ k = k+ 1 return( y) end function --end block -- http://en.wikipedia.org/wiki/Cyclic_redundancy_check -- http://www.ross.net/crc/download/crc_v3.txt -- lookup table for IEEE 802.3 32bit CRC -- x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 -- or generate a new one -- From http://www.ross.net/crc/download/crc_v3.txt --Here is the specification for the CRC-32 algorithm which is reportedly --used in PKZip, AUTODIN II, Ethernet, FDDI and PNG images -- -- Name : "CRC-32" -- Width : 32 -- Poly : 04C11DB7 msbit first -- Init : FFFFFFFF -- RefIn : True -- RefOut : True -- XorOut : FFFFFFFF -- Check : CBF43926 -- Its polynomial can be written -- msbit-first as 0x04C11DB7, or lsbit-first as 0xEDB88320. -- There are really only two forms: normal and reflected. Normal -- shifts to the left and covers the case of algorithms with Refin=FALSE -- and Refot=FALSE. Reflected shifts to the right and covers algorithms -- with both those parameters true. (If you want one parameter true and -- the other false, you'll have to figure it out for yourself!) The -- polynomial is embedded in the lookup table (to be discussed). The -- other parameters, Init and XorOt can be coded as macros. Here is the -- 32-bit normal form (the 16-bit form is similar). -- -- unsigned long crc_normal (); -- unsigned long crc_normal (blk_adr,blk_len) -- unsigned char *blk_adr; -- unsigned long blk_len; -- { -- unsigned long crc = INIT; -- while (blk_len--) -- crc = crctable[((crc>>24) ^ *blk_adr++) & 0xFFL] ^ (crc << 8); -- return crc ^ XOROT; -- } -- -- Here is the reflected form: -- -- unsigned long crc_reflected (); -- unsigned long crc_reflected (blk_adr,blk_len) -- unsigned char *blk_adr; -- unsigned long blk_len; -- { -- unsigned long crc = INIT_REFLECTED; -- while (blk_len--) -- crc = crctable[(crc ^ *blk_adr++) & 0xFFL] ^ (crc >> 8)); -- return crc ^ XOROT; -- // Msbit-first -- rem = (rem leftShift 8) xor big_endian_table[(leftmost 8 bits of rem) rightShift (n-8)] -- -- // Lsbit-first -- rem = (rem rightShift 8) xor little_endian_table[rightmost 8 bits of rem] -- not tested -- translated from "c" on http://www.eccpage.com/crc-32b.c -- CRC_POLY_32 is for pkzip Xmodem etc, other 32bit CRCs may use a different -- polynomial var byte crcTable_32[256] const dword CRC_POLY_32 = 0xEDB88320 -- lsbit-first -- HD maxBits poly -- see Koopman on crc -- 4 2048 0xBAAD -- 5 241 0xAC9A -- 6 135 0xC86C -- 7 19 0x968B -- 8 15 0x8FDB procedure crcgen(dword in poly ) is var dword crc var sword i, j -- should be poly = 0xEDB88320 allegedly for 256 using i loop crc = dword(i) j = 8 for 8 loop if ((crc & 1) > 0) then crc = (crc >> 1) ^ poly else crc = crc >> 1 end if j = j -1 end loop crcTable_32[i] = byte(crc & 0xFF) end loop end procedure -- not tested -- pass array of data and see what CRC should be, to compare on receive -- or append on transmitt function getcrc32(byte in datas[] )return dword is const byte CRC32_803_3[] = { 0x00,0x00,0x00,0x00, 0x96,0x30,0x07,0x77, 0x2C,0x61,0x0E,0xEE, 0xBA,0x51,0x09,0x99, 0x19,0xC4,0x6D,0x07, 0x8F,0xF4,0x6A,0x70, 0x35,0xA5,0x63,0xE9, 0xA3,0x95,0x64,0x9E, 0x32,0x88,0xDB,0x0E, 0xA4,0xB8,0xDC,0x79, 0x1E,0xE9,0xD5,0xE0, 0x88,0xD9,0xD2,0x97, 0x2B,0x4C,0xB6,0x09, 0xBD,0x7C,0xB1,0x7E, 0x07,0x2D,0xB8,0xE7, 0x91,0x1D,0xBF,0x90, 0x64,0x10,0xB7,0x1D, 0xF2,0x20,0xB0,0x6A, 0x48,0x71,0xB9,0xF3, 0xDE,0x41,0xBE,0x84, 0x7D,0xD4,0xDA,0x1A, 0xEB,0xE4,0xDD,0x6D, 0x51,0xB5,0xD4,0xF4, 0xC7,0x85,0xD3,0x83, 0x56,0x98,0x6C,0x13, 0xC0,0xA8,0x6B,0x64, 0x7A,0xF9,0x62,0xFD, 0xEC,0xC9,0x65,0x8A, 0x4F,0x5C,0x01,0x14, 0xD9,0x6C,0x06,0x63, 0x63,0x3D,0x0F,0xFA, 0xF5,0x0D,0x08,0x8D, 0xC8,0x20,0x6E,0x3B, 0x5E,0x10,0x69,0x4C, 0xE4,0x41,0x60,0xD5, 0x72,0x71,0x67,0xA2, 0xD1,0xE4,0x03,0x3C, 0x47,0xD4,0x04,0x4B, 0xFD,0x85,0x0D,0xD2, 0x6B,0xB5,0x0A,0xA5, 0xFA,0xA8,0xB5,0x35, 0x6C,0x98,0xB2,0x42, 0xD6,0xC9,0xBB,0xDB, 0x40,0xF9,0xBC,0xAC, 0xE3,0x6C,0xD8,0x32, 0x75,0x5C,0xDF,0x45, 0xCF,0x0D,0xD6,0xDC, 0x59,0x3D,0xD1,0xAB, 0xAC,0x30,0xD9,0x26, 0x3A,0x00,0xDE,0x51, 0x80,0x51,0xD7,0xC8, 0x16,0x61,0xD0,0xBF, 0xB5,0xF4,0xB4,0x21, 0x23,0xC4,0xB3,0x56, 0x99,0x95,0xBA,0xCF, 0x0F,0xA5,0xBD,0xB8, 0x9E,0xB8,0x02,0x28, 0x08,0x88,0x05,0x5F, 0xB2,0xD9,0x0C,0xC6, 0x24,0xE9,0x0B,0xB1, 0x87,0x7C,0x6F,0x2F, 0x11,0x4C,0x68,0x58, 0xAB,0x1D,0x61,0xC1, 0x3D,0x2D,0x66,0xB6, 0x90,0x41,0xDC,0x76, 0x06,0x71,0xDB,0x01, 0xBC,0x20,0xD2,0x98, 0x2A,0x10,0xD5,0xEF, 0x89,0x85,0xB1,0x71, 0x1F,0xB5,0xB6,0x06, 0xA5,0xE4,0xBF,0x9F, 0x33,0xD4,0xB8,0xE8, 0xA2,0xC9,0x07,0x78, 0x34,0xF9,0x00,0x0F, 0x8E,0xA8,0x09,0x96, 0x18,0x98,0x0E,0xE1, 0xBB,0x0D,0x6A,0x7F, 0x2D,0x3D,0x6D,0x08, 0x97,0x6C,0x64,0x91, 0x01,0x5C,0x63,0xE6, 0xF4,0x51,0x6B,0x6B, 0x62,0x61,0x6C,0x1C, 0xD8,0x30,0x65,0x85, 0x4E,0x00,0x62,0xF2, 0xED,0x95,0x06,0x6C, 0x7B,0xA5,0x01,0x1B, 0xC1,0xF4,0x08,0x82, 0x57,0xC4,0x0F,0xF5, 0xC6,0xD9,0xB0,0x65, 0x50,0xE9,0xB7,0x12, 0xEA,0xB8,0xBE,0x8B, 0x7C,0x88,0xB9,0xFC, 0xDF,0x1D,0xDD,0x62, 0x49,0x2D,0xDA,0x15, 0xF3,0x7C,0xD3,0x8C, 0x65,0x4C,0xD4,0xFB, 0x58,0x61,0xB2,0x4D, 0xCE,0x51,0xB5,0x3A, 0x74,0x00,0xBC,0xA3, 0xE2,0x30,0xBB,0xD4, 0x41,0xA5,0xDF,0x4A, 0xD7,0x95,0xD8,0x3D, 0x6D,0xC4,0xD1,0xA4, 0xFB,0xF4,0xD6,0xD3, 0x6A,0xE9,0x69,0x43, 0xFC,0xD9,0x6E,0x34, 0x46,0x88,0x67,0xAD, 0xD0,0xB8,0x60,0xDA, 0x73,0x2D,0x04,0x44, 0xE5,0x1D,0x03,0x33, 0x5F,0x4C,0x0A,0xAA, 0xC9,0x7C,0x0D,0xDD, 0x3C,0x71,0x05,0x50, 0xAA,0x41,0x02,0x27, 0x10,0x10,0x0B,0xBE, 0x86,0x20,0x0C,0xC9, 0x25,0xB5,0x68,0x57, 0xB3,0x85,0x6F,0x20, 0x09,0xD4,0x66,0xB9, 0x9F,0xE4,0x61,0xCE, 0x0E,0xF9,0xDE,0x5E, 0x98,0xC9,0xD9,0x29, 0x22,0x98,0xD0,0xB0, 0xB4,0xA8,0xD7,0xC7, 0x17,0x3D,0xB3,0x59, 0x81,0x0D,0xB4,0x2E, 0x3B,0x5C,0xBD,0xB7, 0xAD,0x6C,0xBA,0xC0, 0x20,0x83,0xB8,0xED, 0xB6,0xB3,0xBF,0x9A, 0x0C,0xE2,0xB6,0x03, 0x9A,0xD2,0xB1,0x74, 0x39,0x47,0xD5,0xEA, 0xAF,0x77,0xD2,0x9D, 0x15,0x26,0xDB,0x04, 0x83,0x16,0xDC,0x73, 0x12,0x0B,0x63,0xE3, 0x84,0x3B,0x64,0x94, 0x3E,0x6A,0x6D,0x0D, 0xA8,0x5A,0x6A,0x7A, 0x0B,0xCF,0x0E,0xE4, 0x9D,0xFF,0x09,0x93, 0x27,0xAE,0x00,0x0A, 0xB1,0x9E,0x07,0x7D, 0x44,0x93,0x0F,0xF0, 0xD2,0xA3,0x08,0x87, 0x68,0xF2,0x01,0x1E, 0xFE,0xC2,0x06,0x69, 0x5D,0x57,0x62,0xF7, 0xCB,0x67,0x65,0x80, 0x71,0x36,0x6C,0x19, 0xE7,0x06,0x6B,0x6E, 0x76,0x1B,0xD4,0xFE, 0xE0,0x2B,0xD3,0x89, 0x5A,0x7A,0xDA,0x10, 0xCC,0x4A,0xDD,0x67, 0x6F,0xDF,0xB9,0xF9, 0xF9,0xEF,0xBE,0x8E, 0x43,0xBE,0xB7,0x17, 0xD5,0x8E,0xB0,0x60, 0xE8,0xA3,0xD6,0xD6, 0x7E,0x93,0xD1,0xA1, 0xC4,0xC2,0xD8,0x38, 0x52,0xF2,0xDF,0x4F, 0xF1,0x67,0xBB,0xD1, 0x67,0x57,0xBC,0xA6, 0xDD,0x06,0xB5,0x3F, 0x4B,0x36,0xB2,0x48, 0xDA,0x2B,0x0D,0xD8, 0x4C,0x1B,0x0A,0xAF, 0xF6,0x4A,0x03,0x36, 0x60,0x7A,0x04,0x41, 0xC3,0xEF,0x60,0xDF, 0x55,0xDF,0x67,0xA8, 0xEF,0x8E,0x6E,0x31, 0x79,0xBE,0x69,0x46, 0x8C,0xB3,0x61,0xCB, 0x1A,0x83,0x66,0xBC, 0xA0,0xD2,0x6F,0x25, 0x36,0xE2,0x68,0x52, 0x95,0x77,0x0C,0xCC, 0x03,0x47,0x0B,0xBB, 0xB9,0x16,0x02,0x22, 0x2F,0x26,0x05,0x55, 0xBE,0x3B,0xBA,0xC5, 0x28,0x0B,0xBD,0xB2, 0x92,0x5A,0xB4,0x2B, 0x04,0x6A,0xB3,0x5C, 0xA7,0xFF,0xD7,0xC2, 0x31,0xCF,0xD0,0xB5, 0x8B,0x9E,0xD9,0x2C, 0x1D,0xAE,0xDE,0x5B, 0xB0,0xC2,0x64,0x9B, 0x26,0xF2,0x63,0xEC, 0x9C,0xA3,0x6A,0x75, 0x0A,0x93,0x6D,0x02, 0xA9,0x06,0x09,0x9C, 0x3F,0x36,0x0E,0xEB, 0x85,0x67,0x07,0x72, 0x13,0x57,0x00,0x05, 0x82,0x4A,0xBF,0x95, 0x14,0x7A,0xB8,0xE2, 0xAE,0x2B,0xB1,0x7B, 0x38,0x1B,0xB6,0x0C, 0x9B,0x8E,0xD2,0x92, 0x0D,0xBE,0xD5,0xE5, 0xB7,0xEF,0xDC,0x7C, 0x21,0xDF,0xDB,0x0B, 0xD4,0xD2,0xD3,0x86, 0x42,0xE2,0xD4,0xF1, 0xF8,0xB3,0xDD,0x68, 0x6E,0x83,0xDA,0x1F, 0xCD,0x16,0xBE,0x81, 0x5B,0x26,0xB9,0xF6, 0xE1,0x77,0xB0,0x6F, 0x77,0x47,0xB7,0x18, 0xE6,0x5A,0x08,0x88, 0x70,0x6A,0x0F,0xFF, 0xCA,0x3B,0x06,0x66, 0x5C,0x0B,0x01,0x11, 0xFF,0x9E,0x65,0x8F, 0x69,0xAE,0x62,0xF8, 0xD3,0xFF,0x6B,0x61, 0x45,0xCF,0x6C,0x16, 0x78,0xE2,0x0A,0xA0, 0xEE,0xD2,0x0D,0xD7, 0x54,0x83,0x04,0x4E, 0xC2,0xB3,0x03,0x39, 0x61,0x26,0x67,0xA7, 0xF7,0x16,0x60,0xD0, 0x4D,0x47,0x69,0x49, 0xDB,0x77,0x6E,0x3E, 0x4A,0x6A,0xD1,0xAE, 0xDC,0x5A,0xD6,0xD9, 0x66,0x0B,0xDF,0x40, 0xF0,0x3B,0xD8,0x37, 0x53,0xAE,0xBC,0xA9, 0xC5,0x9E,0xBB,0xDE, 0x7F,0xCF,0xB2,0x47, 0xE9,0xFF,0xB5,0x30, 0x1C,0xF2,0xBD,0xBD, 0x8A,0xC2,0xBA,0xCA, 0x30,0x93,0xB3,0x53, 0xA6,0xA3,0xB4,0x24, 0x05,0x36,0xD0,0xBA, 0x93,0x06,0xD7,0xCD, 0x29,0x57,0xDE,0x54, 0xBF,0x67,0xD9,0x23, 0x2E,0x7A,0x66,0xB3, 0xB8,0x4A,0x61,0xC4, 0x02,0x1B,0x68,0x5D, 0x94,0x2B,0x6F,0x2A, 0x37,0xBE,0x0B,0xB4, 0xA1,0x8E,0x0C,0xC3, 0x1B,0xDF,0x05,0x5A, 0x8D,0xEF,0x02,0x2D } var dword crc var word indec crc = 0xFFFFFFFF for count(datas) using indec loop crc = ((crc>>8) & 0x00FFFFFF) ^ dword(CRC32_803_3[ byte((crc^dword(datas[indec])) & 0xFF )]) end loop return( crc^0xFFFFFFFF ) end function -- CRC-8 not so good above 85 bits message length (10 bytes) HD =4 -- performs poorer than possible 85 to 119 bits. HD =2 -- HD maxBits poly -- 2 2048+ 0xA6 -- 3 247 0xA6 -- 4 119 0x97 -- 5 9 0x9C function getCRC8(byte in Buffer[])return byte is -- CRC-8 for Dallas iButton products -- as per Maxim data sheet const byte CRC8[] = { 0x00, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83, 0xc2, 0x9c, 0x7e, 0x20, 0xa3, 0xfd, 0x1f, 0x41, 0x9d, 0xc3, 0x21, 0x7f, 0xfc, 0xa2, 0x40, 0x1e, 0x5f, 0x01, 0xe3, 0xbd, 0x3e, 0x60, 0x82, 0xdc, 0x23, 0x7d, 0x9f, 0xc1, 0x42, 0x1c, 0xfe, 0xa0, 0xe1, 0xbf, 0x5d, 0x03, 0x80, 0xde, 0x3c, 0x62, 0xbe, 0xe0, 0x02, 0x5c, 0xdf, 0x81, 0x63, 0x3d, 0x7c, 0x22, 0xc0, 0x9e, 0x1d, 0x43, 0xa1, 0xff, 0x46, 0x18, 0xfa, 0xa4, 0x27, 0x79, 0x9b, 0xc5, 0x84, 0xda, 0x38, 0x66, 0xe5, 0xbb, 0x59, 0x07, 0xdb, 0x85, 0x67, 0x39, 0xba, 0xe4, 0x06, 0x58, 0x19, 0x47, 0xa5, 0xfb, 0x78, 0x26, 0xc4, 0x9a, 0x65, 0x3b, 0xd9, 0x87, 0x04, 0x5a, 0xb8, 0xe6, 0xa7, 0xf9, 0x1b, 0x45, 0xc6, 0x98, 0x7a, 0x24, 0xf8, 0xa6, 0x44, 0x1a, 0x99, 0xc7, 0x25, 0x7b, 0x3a, 0x64, 0x86, 0xd8, 0x5b, 0x05, 0xe7, 0xb9, 0x8c, 0xd2, 0x30, 0x6e, 0xed, 0xb3, 0x51, 0x0f, 0x4e, 0x10, 0xf2, 0xac, 0x2f, 0x71, 0x93, 0xcd, 0x11, 0x4f, 0xad, 0xf3, 0x70, 0x2e, 0xcc, 0x92, 0xd3, 0x8d, 0x6f, 0x31, 0xb2, 0xec, 0x0e, 0x50, 0xaf, 0xf1, 0x13, 0x4d, 0xce, 0x90, 0x72, 0x2c, 0x6d, 0x33, 0xd1, 0x8f, 0x0c, 0x52, 0xb0, 0xee, 0x32, 0x6c, 0x8e, 0xd0, 0x53, 0x0d, 0xef, 0xb1, 0xf0, 0xae, 0x4c, 0x12, 0x91, 0xcf, 0x2d, 0x73, 0xca, 0x94, 0x76, 0x28, 0xab, 0xf5, 0x17, 0x49, 0x08, 0x56, 0xb4, 0xea, 0x69, 0x37, 0xd5, 0x8b, 0x57, 0x09, 0xeb, 0xb5, 0x36, 0x68, 0x8a, 0xd4, 0x95, 0xcb, 0x29, 0x77, 0xf4, 0xaa, 0x48, 0x16, 0xe9, 0xb7, 0x55, 0x0b, 0x88, 0xd6, 0x34, 0x6a, 0x2b, 0x75, 0x97, 0xc9, 0x4a, 0x14, 0xf6, 0xa8, 0x74, 0x2a, 0xc8, 0x96, 0x15, 0x4b, 0xa9, 0xf7, 0xb6, 0xe8, 0x0a, 0x54, 0xd7, 0x89, 0x6b, 0x35 } var dword ind var word crc =0xFFFF for count(Buffer)using ind loop crc =(crc >> 8) ^ CRC8[byte(word(Buffer[ind]) ^ (crc & 0xff))] end loop return (byte(crc & 0xff)) end function procedure BCD4add (byte in out bcda[4], byte in incb[]) is var byte carry, hia, hib, index, loopCount carry = 0 loopCount = byte(count(incb)) if loopCount > count(bcda) then loopCount = count(bcda) end if index = 1 for loopCount loop hia = bcda[index] >> 4 hib = incb[index] >> 4 bcda[index] = bcda[index] & 0xF incb[index] = incb[index] & 0xF carry = bcda[index] + incb[index] + carry if (carry < 10) then bcda[index] = carry elsif carry > 19 then -- up to 9 + 9 + 9 = 27 bcda[index] = carry -20 elsif carry > 9 then bcda[index] = carry -10 end if carry = carry - bcda[index] -- now do high nibble carry = hib + hia + carry if carry < 10 then hia = carry elsif carry > 19 then -- up to 9 + 9 + 9 = 27 hia = carry -20 elsif carry > 9 then hia = carry -10 end if carry = carry - hia -- now add in high nibble bcda[index] = bcda[index] + (hia << 4) index = index+1 end loop While (carry > 0 ) & (index < count(bcda)) loop hia = bcda[index] >> 4 bcda[index] = bcda[index] & 0xF carry = bcda[index] + carry if carry < 10 then bcda[index] = carry elsif carry > 19 then -- up to 9 + 9 + 9 = 27 bcda[index] = carry -20 elsif carry > 9 then bcda[index] = carry -10 end if carry = carry - bcda[index] -- now do high nibble carry = hia + carry if carry < 10 then hia = carry elsif carry > 19 then -- up to 9 + 9 + 9 = 27 hia = carry -20 elsif carry > 9 then hia = carry -10 end if carry = carry - hia -- now add in high nibble bcda[index] = bcda[index] + (hia << 4) index = index+1 end loop end procedure