/* -*- linux-c -*- */ /****************************************************************************** * FILE: crc32.c * * Copyright: Telford Tools, Inc. * 1996 * * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ****************************************************************************** */ /****************************************************************************** * REVISION HISTORY: (Most Recent First) * ------------------------------------- * 2-Apr-91 ALEX Introduced "fn_calc_novram_crc32()". ****************************************************************************** */ /****************************************************/ /* header files */ /****************************************************/ #include "crc32dcl.h" #include "endian.h" /****************************************************/ /* constants */ /****************************************************/ #define k_poly ((unsigned int)(0xedb88320)) #define k_crc_table_size (256) #if defined (AMD29K) pragma Code ("rkernel"); pragma Off(cross_jump); #endif /****************************************************/ /* static data */ /****************************************************/ #if defined(AMD29K) pragma Data (Export,"fastbss"); #endif // defined(AMD29K) unsigned int gg_a_crc_table[k_crc_table_size]; #if defined(AMD29K) pragma Data; #endif // defined(AMD29K) /****************************************************/ /* global procedures */ /****************************************************/ void fn_init_crc_table() { short i_table; for (i_table = 0; i_table < k_crc_table_size; i_table++) { unsigned int result = 0; short i_bit; for (i_bit = 0; i_bit < 8; i_bit++) { unsigned int bit = ((i_table & (1 << i_bit)) != 0); if ((bit ^ (result & 1)) != 0) result = (result >> 1) ^ k_poly; else result >>= 1; } gg_a_crc_table[i_table] = result; } } /* end of fn_init_crc_table */ /****************************************************/ static unsigned int fn_calc_memory_chunk_crc32(void *p, unsigned int n_bytes, unsigned int crc) { unsigned char *p_uc = (unsigned char*)p; unsigned int result = ~crc; while (n_bytes-- > 0) { result = (result >> 8) ^ gg_a_crc_table[(result ^ *p_uc++) & 0xff]; } return(~result); } /* end of fn_calc_memory_chunk_crc32 */ /****************************************************/ unsigned int fn_calc_memory_crc32(void *p, unsigned int n_bytes) { fnm_assert_stmt(n_bytes > 4); return(fn_calc_memory_chunk_crc32(p, n_bytes, k_initial_crc_value)); } /* end of fn_calc_memory_crc32 */ /****************************************************/ unsigned int fn_check_memory_crc32(void *p, unsigned int n_bytes, unsigned int crc) { return(fn_calc_memory_crc32(p, n_bytes) == crc); } /* end of fn_check_memory_crc32 */ /****************************************************/ /* Adds current longword to the crc value and */ /* returns that value. */ unsigned int fn_update_crc(char *val, unsigned int crcval) { long i; /* ----< break long into bytes >---- */ /* ----< put bytes into crc >---- */ for (i = 0; i < 4; i++) { crcval = gg_a_crc_table[(crcval ^ val[i]) & 0xff] ^ ((crcval >> 8) & 0x00ffffff); } return(crcval); } /* endfunc--fn_update_crc */ /****************************************************/ /****************************************************/ /* End source file "crc32.c" */ /****************************************************/ /****************************************************/