#include <perms.h>

//          Edinburgh IMP77 Compiler - Version 8.4
//
//     1  !%include "crc32.inc"
//     2
//     3  ! crc32.imp -- compute the CRC-32 of a data stream
//     4  ! Copyright (C) 1995-1998 Mark Adler
//     5  ! For conditions of distribution and use, see copyright notice in zlib.h
//     6
//     7  ! ========================================================================
//     8  ! Table of CRC-32's of all single-byte values (made by make_crc table)
//     9
//    10  %own %integer %array crc table(0:255) =

static int CRCTABLE[256] = {
    0,           1996959894,  -301047508,  -1727442502, 124634137,   1886057615,  -379345611,  -1637575261, 249268274,
    2044508324,  -522852066,  -1747789432, 162941995,   2125561021,  -407360249,  -1866523247, 498536548,   1789927666,
    -205950648,  -2067906082, 450548861,   1843258603,  -187386543,  -2083289657, 325883990,   1684777152,  -43845254,
    -1973040660, 335633487,   1661365465,  -99664541,   -1928851979, 997073096,   1281953886,  -715111964,  -1570279054,
    1006888145,  1258607687,  -770865667,  -1526024853, 901097722,   1119000684,  -608450090,  -1396901568, 853044451,
    1172266101,  -589951537,  -1412350631, 651767980,   1373503546,  -925412992,  -1076862698, 565507253,   1454621731,
    -809855591,  -1195530993, 671266974,   1594198024,  -972236366,  -1324619484, 795835527,   1483230225,  -1050600021,
    -1234817731, 1994146192,  31158534,    -1731059524, -271249366,  1907459465,  112637215,   -1614814043, -390540237,
    2013776290,  251722036,   -1777751922, -519137256,  2137656763,  141376813,   -1855689577, -429695999,  1802195444,
    476864866,   -2056965928, -228458418,  1812370925,  453092731,   -2113342271, -183516073,  1706088902,  314042704,
    -1950435094, -54949764,   1658658271,  366619977,   -1932296973, -69972891,   1303535960,  984961486,   -1547960204,
    -725929758,  1256170817,  1037604311,  -1529756563, -740887301,  1131014506,  879679996,   -1385723834, -631195440,
    1141124467,  855842277,   -1442165665, -586318647,  1342533948,  654459306,   -1106571248, -921952122,  1466479909,
    544179635,   -1184443383, -832445281,  1591671054,  702138776,   -1328506846, -942167884,  1504918807,  783551873,
    -1212326853, -1061524307, -306674912,  -1698712650, 62317068,    1957810842,  -355121351,  -1647151185, 81470997,
    1943803523,  -480048366,  -1805370492, 225274430,   2053790376,  -468791541,  -1828061283, 167816743,   2097651377,
    -267414716,  -2029476910, 503444072,   1762050814,  -144550051,  -2140837941, 426522225,   1852507879,  -19653770,
    -1982649376, 282753626,   1742555852,  -105259153,  -1900089351, 397917763,   1622183637,  -690576408,  -1580100738,
    953729732,   1340076626,  -776247311,  -1497606297, 1068828381,  1219638859,  -670225446,  -1358292148, 906185462,
    1090812512,  -547295293,  -1469587627, 829329135,   1181335161,  -882789492,  -1134132454, 628085408,   1382605366,
    -871598187,  -1156888829, 570562233,   1426400815,  -977650754,  -1296233688, 733239954,   1555261956,  -1026031705,
    -1244606671, 752459403,   1541320221,  -1687895376, -328994266,  1969922972,  40735498,    -1677130071, -351390145,
    1913087877,  83908371,    -1782625662, -491226604,  2075208622,  213261112,   -1831694693, -438977011,  2094854071,
    198958881,   -2032938284, -237706686,  1759359992,  534414190,   -2118248755, -155638181,  1873836001,  414664567,
    -2012718362, -15766928,   1711684554,  285281116,   -1889165569, -127750551,  1634467795,  376229701,   -1609899400,
    -686959890,  1308918612,  956543938,   -1486412191, -799009033,  1231636301,  1047427035,  -1362007478, -640263460,
    1088359270,  936918000,   -1447252397, -558129467,  1202900863,  817233897,   -1111625188, -893730166,  1404277552,
    615818150,   -1160759803, -841546093,  1423857449,  601450431,   -1285129682, -1000256840, 1567103746,  711928724,
    -1274298825, -1022587231, 1510334235,  755167117};
struct _imp_dv CRCTABLE_dv = {CRCTABLE, sizeof(int) /*, dims, <bounds> */};

//    11+   16_00000000, 16_77073096, 16_ee0e612c, 16_990951ba, 16_076dc419,
//    12+   16_706af48f, 16_e963a535, 16_9e6495a3, 16_0edb8832, 16_79dcb8a4,
//    13+   16_e0d5e91e, 16_97d2d988, 16_09b64c2b, 16_7eb17cbd, 16_e7b82d07,
//    14+   16_90bf1d91, 16_1db71064, 16_6ab020f2, 16_f3b97148, 16_84be41de,
//    15+   16_1adad47d, 16_6ddde4eb, 16_f4d4b551, 16_83d385c7, 16_136c9856,
//    16+   16_646ba8c0, 16_fd62f97a, 16_8a65c9ec, 16_14015c4f, 16_63066cd9,
//    17+   16_fa0f3d63, 16_8d080df5, 16_3b6e20c8, 16_4c69105e, 16_d56041e4,
//    18+   16_a2677172, 16_3c03e4d1, 16_4b04d447, 16_d20d85fd, 16_a50ab56b,
//    19+   16_35b5a8fa, 16_42b2986c, 16_dbbbc9d6, 16_acbcf940, 16_32d86ce3,
//    20+   16_45df5c75, 16_dcd60dcf, 16_abd13d59, 16_26d930ac, 16_51de003a,
//    21+   16_c8d75180, 16_bfd06116, 16_21b4f4b5, 16_56b3c423, 16_cfba9599,
//    22+   16_b8bda50f, 16_2802b89e, 16_5f058808, 16_c60cd9b2, 16_b10be924,
//    23+   16_2f6f7c87, 16_58684c11, 16_c1611dab, 16_b6662d3d, 16_76dc4190,
//    24+   16_01db7106, 16_98d220bc, 16_efd5102a, 16_71b18589, 16_06b6b51f,
//    25+   16_9fbfe4a5, 16_e8b8d433, 16_7807c9a2, 16_0f00f934, 16_9609a88e,
//    26+   16_e10e9818, 16_7f6a0dbb, 16_086d3d2d, 16_91646c97, 16_e6635c01,
//    27+   16_6b6b51f4, 16_1c6c6162, 16_856530d8, 16_f262004e, 16_6c0695ed,
//    28+   16_1b01a57b, 16_8208f4c1, 16_f50fc457, 16_65b0d9c6, 16_12b7e950,
//    29+   16_8bbeb8ea, 16_fcb9887c, 16_62dd1ddf, 16_15da2d49, 16_8cd37cf3,
//    30+   16_fbd44c65, 16_4db26158, 16_3ab551ce, 16_a3bc0074, 16_d4bb30e2,
//    31+   16_4adfa541, 16_3dd895d7, 16_a4d1c46d, 16_d3d6f4fb, 16_4369e96a,
//    32+   16_346ed9fc, 16_ad678846, 16_da60b8d0, 16_44042d73, 16_33031de5,
//    33+   16_aa0a4c5f, 16_dd0d7cc9, 16_5005713c, 16_270241aa, 16_be0b1010,
//    34+   16_c90c2086, 16_5768b525, 16_206f85b3, 16_b966d409, 16_ce61e49f,
//    35+   16_5edef90e, 16_29d9c998, 16_b0d09822, 16_c7d7a8b4, 16_59b33d17,
//    36+   16_2eb40d81, 16_b7bd5c3b, 16_c0ba6cad, 16_edb88320, 16_9abfb3b6,
//    37+   16_03b6e20c, 16_74b1d29a, 16_ead54739, 16_9dd277af, 16_04db2615,
//    38+   16_73dc1683, 16_e3630b12, 16_94643b84, 16_0d6d6a3e, 16_7a6a5aa8,
//    39+   16_e40ecf0b, 16_9309ff9d, 16_0a00ae27, 16_7d079eb1, 16_f00f9344,
//    40+   16_8708a3d2, 16_1e01f268, 16_6906c2fe, 16_f762575d, 16_806567cb,
//    41+   16_196c3671, 16_6e6b06e7, 16_fed41b76, 16_89d32be0, 16_10da7a5a,
//    42+   16_67dd4acc, 16_f9b9df6f, 16_8ebeeff9, 16_17b7be43, 16_60b08ed5,
//    43+   16_d6d6a3e8, 16_a1d1937e, 16_38d8c2c4, 16_4fdff252, 16_d1bb67f1,
//    44+   16_a6bc5767, 16_3fb506dd, 16_48b2364b, 16_d80d2bda, 16_af0a1b4c,
//    45+   16_36034af6, 16_41047a60, 16_df60efc3, 16_a867df55, 16_316e8eef,
//    46+   16_4669be79, 16_cb61b38c, 16_bc66831a, 16_256fd2a0, 16_5268e236,
//    47+   16_cc0c7795, 16_bb0b4703, 16_220216b9, 16_5505262f, 16_c5ba3bbe,
//    48+   16_b2bd0b28, 16_2bb45a92, 16_5cb36a04, 16_c2d7ffa7, 16_b5d0cf31,
//    49+   16_2cd99e8b, 16_5bdeae1d, 16_9b64c2b0, 16_ec63f226, 16_756aa39c,
//    50+   16_026d930a, 16_9c0906a9, 16_eb0e363f, 16_72076785, 16_05005713,
//    51+   16_95bf4a82, 16_e2b87a14, 16_7bb12bae, 16_0cb61b38, 16_92d28e9b,
//    52+   16_e5d5be0d, 16_7cdcefb7, 16_0bdbdf21, 16_86d3d2d4, 16_f1d4e242,
//    53+   16_68ddb3f8, 16_1fda836e, 16_81be16cd, 16_f6b9265b, 16_6fb077e1,
//    54+   16_18b74777, 16_88085ae6, 16_ff0f6a70, 16_66063bca, 16_11010b5c,
//    55+   16_8f659eff, 16_f862ae69, 16_616bffd3, 16_166ccf45, 16_a00ae278,
//    56+   16_d70dd2ee, 16_4e048354, 16_3903b3c2, 16_a7672661, 16_d06016f7,
//    57+   16_4969474d, 16_3e6e77db, 16_aed16a4a, 16_d9d65adc, 16_40df0b66,
//    58+   16_37d83bf0, 16_a9bcae53, 16_debb9ec5, 16_47b2cf7f, 16_30b5ffe9,
//    59+   16_bdbdf21c, 16_cabac28a, 16_53b39330, 16_24b4a3a6, 16_bad03605,
//    60+   16_cdd70693, 16_54de5729, 16_23d967bf, 16_b3667a2e, 16_c4614ab8,
//    61+   16_5d681b02, 16_2a6f2b94, 16_b40bbe37, 16_c30c8ea1, 16_5a05df1b,
//    62+   16_2d02ef8d
//    63
//    64
//    65  ! =========================================================================
//    66
//    67  %external %long %fn crc32 ch (%long crc, %byte %integer c)

long int CRC32CH(long int CRC, unsigned char C) {
  //    68    crc = crc !! 16_FFFFFFFF

  CRC = CRC ^ (-1);

  //    69    !printstring("> crc = crc table((");write(crc,0);printstring(" !! ");write(c,0);printstring(") & 16_ff) !! (");write(crc,0);printstring(" >> 8)");newline
  //    70    crc = crc table((crc !! c) & 16_ff) !! (crc >> 8)

  CRC = CRCTABLE[(CRC ^ C) & 255] ^ (unsigned int)CRC >> 8;

  //    71    !printstring("< crc = crc table((");write((crc!!c)&255,0);printstring(") !! ");write(crc>>8,0);newline
  //    72    %result = crc !! 16_FFFFFFFF

  return CRC ^ (-1);

  //    73  %end

} /* end of CRC32CH */

//    74
//    75  %external %long %fn crc32 mem (%long crc, %integer memp, %integer length)

long int CRC32MEM(long int CRC, int MEMP, int LENGTH) {
  //    76  !printstring("addr: "); write(memp,0);
  //    77  !newline
  //    78  !printstring("length: "); write(length,0);
  //    79  !newline
  //    80    %while length > 0 %cycle

L_0001:;
  if (LENGTH <= 0) goto L_0002;

    //    81      crc = crc32 ch(crc, byteinteger(memp))

  CRC = CRC32CH(CRC, *_imp_BYTEINTEGER(MEMP));

  //    82      memp = memp+1

  MEMP = MEMP + 1;

  //    83      length = length-1

  LENGTH = LENGTH - 1;

  //    84    %repeat

  goto L_0001;
L_0002:;

//    85  !printstring("result: "); write(crc,0);newline
//    86    %result = crc

  return CRC;

  //    87  %end

} /* end of CRC32MEM */

//    88
//    89  %external %long %fn crc32 (%name memp, %integer length)

long int CRC32(_imp_name *MEMP, int LENGTH) {
  //    90    %integer crc = 0

  int CRC;
  CRC = 0;

  //    91    %result = crc32 mem(crc, ADDR(memp), length)

  return CRC32MEM(CRC, _imp_ADDR(MEMP), LENGTH);

  //    92  %end

} /* end of CRC32 */

//    93
//    94  !%begin
//    95  !  print string("test: "); write(crc32(crc table, 256*4), 0); newline
//    96  !%end %of %program
//    97
//    98  %end %of %file