Every // ---- section banner dies (132 -> 0): names carry the WHAT. Narration deleted (filename restatements, run-with lines, what-the- next-line-does); every ref/hare cite, task cite, divergence, ABI/ layout contract, and ownership qualifier kept (borrowed-view lines restored where the sweep over-cut). Comment-only proven: all 442 walk-workdir .s and 32 import-probe .s byte-identical before/after; libbyteid 56-roster all-ID.
41 lines
1.2 KiB
Plaintext
41 lines
1.2 KiB
Plaintext
// Inline polynomial-shift per byte (no precomputed tables). Slower
|
|
// than a table-driven CRC by ~8x per byte but matches the
|
|
// table-driven answer bit-for-bit.
|
|
//
|
|
// Polynomials are given in reversed form, matching Hare.
|
|
|
|
package crc16;
|
|
|
|
def CCITT: u16 = 0x8408u16; // X.25, Bluetooth, XMODEM
|
|
def CMDA2000: u16 = 0xE613u16; // CDMA2000 infra
|
|
def DECT: u16 = 0x91A0u16; // DECT cordless
|
|
def ANSI: u16 = 0xA001u16; // Modbus, USB, ANSI X3.28
|
|
|
|
// sum16 — fold `buf` under `poly` and return ~cval. Initial value is
|
|
// ~0u16, matching the streaming CRC-16 contract for a single
|
|
// write-then-sum.
|
|
export fn sum16(buf: []u8, poly: u16) u16 = {
|
|
let c: u16 = 0xFFFFu16;
|
|
let i: i32 = 0;
|
|
for (i < buf.len) {
|
|
let t: u16 = (c & 0xFFu16) ^ (buf[i]: u16);
|
|
let z: i32 = 0;
|
|
for (z < 8) {
|
|
if ((t & 1u16) == 1u16) {
|
|
t = (t >> 1u16) ^ poly;
|
|
} else {
|
|
t = t >> 1u16;
|
|
};
|
|
z += 1;
|
|
};
|
|
c = t ^ (c >> 8u16);
|
|
i += 1;
|
|
};
|
|
return ~c;
|
|
};
|
|
|
|
export fn sum16ccitt(buf: []u8) u16 = { return sum16(buf, CCITT); };
|
|
export fn sum16cmda2000(buf: []u8) u16 = { return sum16(buf, CMDA2000); };
|
|
export fn sum16dect(buf: []u8) u16 = { return sum16(buf, DECT); };
|
|
export fn sum16ansi(buf: []u8) u16 = { return sum16(buf, ANSI); };
|