Delphi-Quellcode:
{$IFDEF PIC}
// I assume this line exists in the original to use the code from a class
// with a custom lookup table which is not possible with pure pascal
{$MESSAGE ERROR 'MOV ESI,[EBX].FCRC16 ??'}
{$ELSE}
PIC steht für Position Independent Code. Für Kylix hat man das benötigt, da man unter Linux nicht so einfach auf globale Variablen zugreifen kann. Jeder Zugriff auf globale Variablen muss über die GOT (Global Offset Table) gehen. Und diese steht in EBX, weswegen das EBX Register nicht verloren gehen darf, da man sonst nicht mehr auf globale Variablen zugreifen kann.
Ansonsten sieht deine CRC16 genau so aus wie meine
Hier schon mal
Delphi-Quellcode:
function CRCCode(
var CRCDef: TCRCDef;
const Buffer; Size: Cardinal): Cardinal;
// do the CRC computation
var
P: PByte;
Value: Byte;
begin
Result := CRCDef.CRC;
P := @Buffer;
if (Size <> 0)
and (P <>
nil)
then
begin
if CRCDef.Inverse
then
begin
repeat
Value := P^
xor Byte(Result);
Result := (Result
shr 8)
xor CRCDef.Table[Value];
Inc(P);
Dec(Size);
until Size = 0;
end
else
begin
Value := Byte(CRCDef.Shift);
// move to local variable => cpu register
repeat
Result := (Result
shl 8)
xor CRCDef.Table[Byte(Result
shr Value)
xor P^];
Inc(P);
Dec(Size);
until Size = 0;
end;
CRCDef.CRC := Result;
Result := (Result
xor CRCDef.FinalVector)
and CRCDef.Mask;
end;
end;
function CRCDone(
var CRCDef: TCRCDef): Cardinal;
// finalize CRCDef after a computation
begin
Result := CRCDef.CRC;
CRCDef.CRC := CRCDef.InitVector;
Result := (Result
xor CRCDef.FinalVector)
and CRCDef.Mask;
end;
function CRC16(CRC: Word;
const Buffer; Size: Cardinal): Word;
var
LCRC16: PCRCDef;
P: PByte;
CRC32: LongWord;
Value: Byte;
begin
if Size <> 0
then
begin
LCRC16 := FCRC16;
if LCRC16 =
nil then
LCRC16 := CRC16Init;
CRC32 := CRC;
P := @Buffer;
repeat
Value := P^
xor Byte(CRC32);
CRC32 := (CRC32
shr 8)
xor LCRC16.Table[Value];
Inc(P);
Dec(Size);
until Size = 0;
Result := Word(CRC32);
end
else
Result := CRC;
end;
function CRC32(CRC: Cardinal;
const Buffer; Size: Cardinal): Cardinal;
var
LCRC32: PCRCDef;
P: PByte;
CRC32: LongWord;
Value: Byte;
begin
if Size <> 0
then
begin
LCRC32 := FCRC32;
if LCRC32 =
nil then
LCRC32 := CRC32Init;
CRC32 :=
not CRC;
// inverse Input CRC
P := @Buffer;
repeat
Value := P^
xor Byte(CRC32);
CRC32 := (CRC32
shr 8)
xor LCRC32.Table[Value];
Inc(P);
Dec(Size);
until Size = 0;
Result :=
not CRC32;
// inverse Output CRC
end
else
Result := CRC;
end;
Jetzt fehlt nur noch das Geschoss von CRCSetup.