{
;nasm -f win32 lzx042.nas
;   KUMAamp project(仮称)
;   Copyright (C) Mamiya 2000.
;   License:GPL
;   ---------------------------------------------------------------------------
;   LZX decoder
;   lzx042.nas

Pascal呼び出しルーチン by Moonlight.
}

unit _MXDRVm_LZX043;

interface

uses
  Types;

function GetunLZXSize(var MDXbuf:array of byte;offset:integer):integer;
procedure LZXdecord(var MDXbuf:array of byte;LZXOffset:integer;var unLZXbuf:array of byte);

implementation

{ Decompress SampleCode
var
  MDXbuf,unLZXbuf:array of byte;
  MDXSize,LZXOffset,unLZXSize:integer;
  cnt:integer;
begin
  LZXOffset:=$43; // PDXファイル名の後のオフセットアドレス
  unLZXSize:=GetunLZXSize(MDXbuf,LZXOffset);
  if unLZXSize<>0 then begin
    SetLength(unLZXbuf,unLZXSize+1);
    LZXdecord(MDXbuf,LZXOffset,unLZXbuf);
    MDXSize:=LZXOffset+unLZXSize;
    SetLength(MDXbuf,MDXSize+1);
    for cnt:=0 to unLZXSize do begin
      MDXbuf[LZXOffset+cnt]:=unLZXbuf[cnt];
    end;
  end;
end;
}

function GetunLZXSize(var MDXbuf:array of byte;offset:integer):integer;
begin
  if (MDXbuf[offset+$04+0]=byte('L')) and (MDXbuf[offset+$04+1]=byte('Z')) and (MDXbuf[offset+$04+2]=byte('X')) and (MDXbuf[offset+$04+3]=byte(' ')) then begin
    Result:=(dword(MDXbuf[offset+$12+0]) shl 24)+(dword(MDXbuf[offset+$12+1]) shl 16)+(dword(MDXbuf[offset+$12+2]) shl 8)+dword(MDXbuf[offset+$12+3]);
    end else begin
    Result:=0;
  end;
end;

procedure LZXdecord(var MDXbuf:array of byte;LZXOffset:integer;var unLZXbuf:array of byte);
begin
  asm
    @_lzx042:
      CLD
      PUSH  EBX
      PUSH  EDI
      PUSH  ESI
      MOV  EDX,MDXbuf
      MOV  EDI,unLZXbuf
      ADD  EDX,LZXOffset
      ADD  EDX,24H
    @SLP:
      ADD  EDX,2
      CMP  DWORD [EDX],4CFFFF7FH
      JNE  @SLP
      ADD  EDX,4
      MOV  BL,BYTE [EDX]
      INC  EDX
      MOV  BH,8
      JMP  @L26

    @L00:
      DEC  BH
      JNS  @NLD1
      MOV  BL,BYTE [EDX]
      INC  EDX
      MOV  BH,7
    @NLD1:
      ADD  BL,BL
      ADC  CL,CL
      DEC  BH
      JNS  @NLD3
      MOV  BL,BYTE [EDX]
      INC  EDX
      MOV  BH,7
    @NLD3:
      ADD  BL,BL
      ADC  CL,CL
      MOV  AL,BYTE [EDX]
      INC  EDX
    @L1A:
      INC  CL
    @L1C:
      LEA  ESI,[EDI+EAX]
      INC  ECX
      REP  MOVSB
    @L26:
      DEC  BH
      JNS  @NLD4
      MOV  BL,BYTE [EDX]
      INC  EDX
      MOV  BH,7
    @NLD4:
      ADD  BL,BL
      JNC     @L36
      MOV  AL,BYTE [EDX]
      INC  EDX
      STOSB
      JMP  @L26

    @L36:
      MOV  EAX,-1
      XOR  ECX,ECX
      DEC  BH
      JNS  @NLD5
      MOV  BL,BYTE [EDX]
      INC  EDX
      MOV  BH,7
    @NLD5:
      ADD  BL,BL
      JNC  @L00
      MOV  AH,BYTE [EDX]
      INC  EDX
      MOV  AL,BYTE [EDX]
      INC  EDX
      MOV  CL,AL
      SAR  EAX,3
      AND  CL,7
      JNZ  @L1A
      MOV  CL,BYTE [EDX]
      INC  EDX
      OR   CL,CL
      JNZ  @L1C
      POP  ESI
      POP  EDI
      POP  EBX
      XOR  EAX,EAX
  end;
end;

end.

