koshik вот есть например такой

koshik
вот есть например такой утиль:)


(*  $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.

a вот скомпилированный вариант
www-user.tu-cottbus.de/~kannegv/programm/sysodeco.arj