/* * This module was translated from the C language to PL/M-86 * * The original C language source was extracted from * http://stigge.org/martin/pub/SAR-PR-2006-05.pdf */ $include (..\lib\compStch.ext) /* *============================================================================ * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE * * Permission to use for any purpose, modify, copy, and make enhancements * and derivative works of the software is granted if attribution is given to * R.M. Gillmore, dba the ACME Software Deli, as the author * * While the ACME Software Deli does not work for money, there is nonetheless * a significant amount of work involved. The ACME Software Deli maintains the * rights to all code written, though it may be used and distributed as long as * the following conditions are maintained. * * 1. The copyright statement at the top of each code block is maintained in * your distribution. * 2. You do not identify yourself as the ACME Software Deli * 3. Any changes made to the software are sent to the ACME Software Deli *============================================================================ */ CRC32Module: do; $include (..\lib\comnDefs.ext) $set (CRC32Implementation) $include (..\lib\crc32.ext) $if not noID declare IDString (*) byte data ( '@(#)crc32.p86 $Author: rmgillmore $ $Date:: 2025-05-04 19:35:39#$:', 0 ); $endif declare CRCPOLY literally '0edb88320h', CRCINV literally '05b358fd3h', /* inverse poly of (x^N) mod CRCPOLY */ FINALXOR literally 'INITXOR'; declare VALUES_PER_BYTE literally '256'; declare CRC_Table ( VALUES_PER_BYTE ) UInt32_t, /* the logic assumes that tableExists is false when app started */ tableExists boolean; /** * Creates the CRC table with 256 32-bit entries. CAUTION: Assumes that * enough space for the resulting table has already been allocated. */ makeCRC_Table: procedure ( tablePtr ); declare tablePtr pointer, table based tablePtr (*) UInt32_t; declare tableValue UInt32_t, /* c */ tableIndex integer, /* n */ numberBitsPerByte integer; /* k */ do tableIndex = 0 to ( VALUES_PER_BYTE - 1 ); tableValue = UInt32_t( tableIndex ); do numberBitsPerByte = 0 to ( 8 - 1 ); if ( ( tableValue and 1 ) <> 0 ) then do; tableValue = CRCPOLY xor ( shr( tableValue, 1 ) ); end; else do; tableValue = shr( tableValue, 1 ); end; end; table( tableIndex ) = tableValue; end; end makeCRC_Table; $if 0 void writeTable() { /* * This function write (in Hexadecimal/ASCII) the contents of the table */ int tableIndex = 0; printf( "\tconst UInt32_t\t\tCRCTable[] =\n\t{\n\t\t" ); for ( ; tableIndex < VALUES_PER_BYTE; tableIndex++ ) { printf( "0x%08x,\t", CRC_Table[ tableIndex ] ); if ( ( tableIndex & 7 ) == 7 ) printf( "\n\t\t" ); } printf( "\n\t};\n" ); } $endif $if 0 /** * Computes the CRC32 of the buffer of the given length * using the supplied crc_table */ crc32: procedure( bufferPtr, bufferLength, bufferSeed ) UInt32_t public; declare bufferPtr pointer, buffer based bufferPtr (*) byte, bufferLength word, bufferSeed UInt32_t; declare bufferIndex word, /* i */ crcreg UInt32_t, tableIndex integer, bufferValue UInt32_t; crcreg = bufferSeed; if ( not tableExists ) then do; call makeCRC_Table( @CRC_Table ); tableExists = true; /* * writeTable(); */ end; do bufferIndex = 0 to ( bufferLength - 1 ); /* * shift a 32-bit to the right by 8 bits */ declare crcregShifted UInt32_t, crcregInBytes ( 4 ) byte at ( @crcRegShifted ); crcRegShifted = crcreg; crcreg = UInt32_t( shr( crcreg, 8 ) ) xor CRC_Table( ( ( crcreg xor UInt32_t( buffer( bufferIndex ) ) ) and UInt32_t( VALUES_PER_BYTE - 1 ) ) ); $if 0 crcreg = shr( crcreg, 8 ); bufferValue = UInt32_t( buffer( bufferIndex ) ); tableIndex = integer( ( crcreg xor bufferValue ) and UInt32_t( VALUES_PER_BYTE - 1 ) ); crcreg = crcreg xor CRC_Table( tableIndex ); $endif end; return ( crcreg xor FINALXOR ); end crc32; $else /* * Computes the CRC32 of the buffer of the given length using the * ( slow ) bit-oriented approach */ declare BITS_PER_BYTE literally '8'; crc32: procedure ( bufferPtr, bufferLength, bufferSeed ) UInt32_t public; declare bufferPtr pointer, buffer based bufferPtr (*) byte, bufferLength integer, bufferSeed UInt32_t; declare bitIndex integer, bufferIndex integer; declare bufferByte byte; declare crcreg UInt32_t; crcreg = bufferSeed; foreachByte: do bufferIndex = 0 to bufferLength - 1; bufferByte = buffer( bufferIndex ); foreachBit: do bitIndex = 0 to BITS_PER_BYTE-1; if ( ( crcreg xor bufferByte ) and 1 ) then do; crcreg = shr( crcreg, 1 ) xor CRCPOLY; end; else do; crcreg = shr( crcreg, 1 ); end; bufferByte = shr( bufferByte, 1 ); end foreachBit; end foreachByte; /* in the buffer */ return ( crcreg xor FINALXOR ); end crc32; $endif end CRC32Module;