(* $R+*)
(*&Use32+*)
program systemsoft_decoder;
(* 2000.06.11 Veit Kannegieser *)
(* 2000.12.08 stOpen->stOpenRead *)
uses
Dos,
Objects,
Strings,
VpUtils;
(*$IFNDEF VirtualPascal*)
type
smallword =word;
(*$ENDIF*)
const
datum='2000.06.11..2000.12.08';
var
d1,d2 :pBufStream;
zielverzeichnis,
zielname :string;
kopf :
packed record
sig_ee_88 :smallword;
name_ :array[0..7] of char;
w_0a :smallword; (* or 10 wenn dd 88 vorhanden ist *)
laenge_eingepackt :smallword;
zieloffset :smallword;
zielsegment :smallword;
pruefsumme :smallword;
end;
zusatzinformationen :
packed record
sig_dd_88 :smallword;
i :array[0..30] of char;
end;
anzahl_zusatzinformationen,
pruefsumme :smallword;
z,z2 :word;
b0,b1 :byte;
start_position :longint;
datenstart :longint;
entpackt :array[0..50000-1] of byte;
laenge :word;
uebrig :word;
rueckwaerts :word;
schreibposition :word;
dateizaehler :word;
label
nicht_gefunden;
procedure kopiere_byteweise(const quelle,ziel;const anzahl:word);
(*$IFDEF VirtualPascal*)
assembler;(*$Uses ESI,EDI,ECX*)(*$Frame-*)
asm
mov esi,quelle
mov edi,ziel
mov ecx,anzahl
cld
rep movsb
end;
(*$ELSE*)
.
(*$ENDIF*)
begin
WriteLn('р SYSODECO * Veit Kannegieser * ',datum);
dateizaehler:=0;
if (ParamCount<1) or (ParamCount>2) then
begin
WriteLn('usage: SYSODECO []');
WriteLn('Benutzung: SYSODECO [ ]');
Halt(1);
end;
d1:=New(pBufStream,Init(ParamStr(1),stOpenRead,8*1024));
zielverzeichnis:=FExpand(ParamStr(2));
if not (zielverzeichnis[Length(zielverzeichnis)] in ['\','/']) then
zielverzeichnis:=zielverzeichnis+'\';
b0:=0;
repeat
d1^.Read(b1,1);
if d1^.Status<>StOk then
Break;
if (b0=$ee) and (b1=$88) then
begin
start_position:=d1^.GetPos-2;
d1^.Read(kopf.name_,SizeOf(kopf)-1-1);
if (not (kopf.name_[0] in ['A'..'Z' ]))
or (not (kopf.name_[1] in ['A'..'Z' ]))
or (not (kopf.name_[2] in ['A'..'Z',' ',#0]))
then
begin
d1^.Seek(start_position+2);
goto nicht_gefunden;
end;
zielname:=Copy(StrPas(kopf.name_),1,8);
WriteLn('ю $',Int2Hex(start_position,8),' ',zielname);
anzahl_zusatzinformationen:=(kopf.w_0a shr 4) and 7;
for z:=1 to anzahl_zusatzinformationen do
begin
d1^.Read(zusatzinformationen,SizeOf(zusatzinformationen));
if zusatzinformationen.sig_dd_88=$88dd then
with zusatzinformationen do
begin
for z2:=Low(i) to High(i)-1 do
if i[z2]=#0 then i[z2]:=' ';
i[High(i)]:=#0;
WriteLn('ъ ',StrPas(@zusatzinformationen.i[0]));
end;
end;
datenstart:=d1^.GetPos;
pruefsumme:=0;
for z:=1 to kopf.laenge_eingepackt do
begin
d1^.Read(b0,1);
Inc(pruefsumme,b0);
end;
if pruefsumme<>kopf.pruefsumme then
begin
d1^.Seek(start_position+2);
goto nicht_gefunden;
end;
d1^.Seek(datenstart);
Inc(dateizaehler);
while Pos(' ',zielname)<>0 do
zielname[Pos(' ',zielname)]:='_';
d2:=New(pBufStream,Init(zielverzeichnis+zielname+'.'+Int2Str(dateizaehler),stCreate,8*1024));
Write('* $',Int2Hex(kopf.zielsegment,4),':$',Int2Hex(kopf.zieloffset,4),' $',Int2Hex(kopf.laenge_eingepackt,4),' -> ');
FillChar(entpackt,SizeOf(entpackt),0);
schreibposition:=0;
uebrig:=kopf.laenge_eingepackt;
while uebrig>0 do
begin
(*Write('$',Int2Hex(schreibposition,4),^h^h^h^h^h);*)
if schreibposition>High(entpackt) then
RunError(1);
d1^.Read(b0,1);
Dec(uebrig);
if b0<=$f then
begin
laenge:=b0+1;
d1^.Read(entpackt[schreibposition],laenge);
Dec(uebrig,laenge);
Inc(schreibposition,laenge)
end
else
begin
d1^.Read(b1,1);
Dec(uebrig);
rueckwaerts:=(b0 and $0f) shl 8 + b1;
if rueckwaerts>schreibposition then
RunError(1);
laenge:=b0 shr 4+1;
kopiere_byteweise(entpackt[schreibposition-rueckwaerts],entpackt[schreibposition],laenge);
Inc(schreibposition,laenge)
end;
end; (* while *)
d2^.Write(entpackt[0],schreibposition);
d2^.Done;
WriteLn('$',Int2Hex(schreibposition,4));
nicht_gefunden:
b0:=0;
b1:=0;
end; (* ee 88 *)
b0:=b1;
until false;
d1^.Done;
end.
koshik
вот есть например такой утиль
a вот скомпилированный вариант
www-user.tu-cottbus.de/~kannegv/programm/sysodeco.arj