Metropoli BBS
VIEWER: unzipmi.sal MODE: TEXT (ASCII)
unit UnZipMem

db   13, 10, 'ZiPPAS V4.1 (c) 1993-95 by Solar Designer', 9

public UnZipIntProc, ProgramDS 

Extrn  WriteUnpacked:DWord, WriteNew:DWord, QueryUnpack:DWord, SelfPtr:DWord
Extrn  ZipMessages:Byte, UnpackMemSize:Word
Extrn  ReadStart:DWord 

Handle        equ  0C0DEh

ProgramDS     dw   ?                   ; Pascal program's data segment

ReadHandle    dw   ?                   ; Input file handle 

UnZipIntProc proc                      ; This procedure should be called
                                       ; instead of INT 21h 
 
   cmp  ah,4Ch                         ; Terminate ? 
   $if  = 
      push ax 
      mov  bx,ReadHandle
      mov  ah,3Eh                      ; Close input file 
      int  21h
      pop  ax
      $if  c                           ; Error ? 
         or   al,al
         $if  =0                       ; Return "I/O Error" if 
            mov  al,2                  ; there weren't any other errors 
         $endif    
      $endif
      mov  ds,cs:ProgramDS       
      mov  dx,ds:UnpackMemSize
      sub  dx,1+4
      mov  sp,dx          
      retf                             ; Return to Pascal program 
   $endif
   cmp  ah,3Dh                         ; Open file ? 
   $if  = 
      push ax 
      and  al,7
      or   al,al
      $if  =0                          ; For reading ? 
         pop  ax 
         int  21h
         $If nc 
            mov  ReadHandle,ax         ; Store handle
            Store ax, bx, cx, dx, ds
               mov  bx,ax 
               mov  ds,cs:ProgramDS 
               mov  dx,word ptr ds:ReadStart
               mov  cx,word ptr ds:ReadStart+2
               mov  ax,4200h
               int  21h 
            Restore
         $EndIf       
         retf 2 
      $endif
      cmp  al,01h                      ; For writing ? 
      pop  ax 
      $if  = 
         mov  ax,Handle                ; Return the unique value 
         clc
         retf 2 
      $endif    
   $endif
   cmp  ah,3Ch                         ; Create file ? 
   $if  = 
      Store es, ds, di, si, dx, cx, bx
      
      mov  si,ds
       
      mov  ds,cs:ProgramDS
      les  di,ds:SelfPtr
      push es, di 
      call ds:WriteNew                 ; Pascal method to store name 

      Restore 
       
      mov  ax,Handle                   ; Return the unique value 
      clc
      retf 2 
   $endif
   cmp  ah,3Eh                         ; Close file ? 
   $if  = 
      cmp  bx,Handle                   ; Output file ? 
      $if  = 
         clc                           ; It wasn't opened in reality
         retf 2 
      $endif 
   $endif
   cmp  ax,4200h
   $If  =
      Store ds, cx 
         mov  ds,cs:ProgramDS
         add  dx,word ptr ds:ReadStart
         adc  cx,word ptr ds:ReadStart+2
         int  21h
         $If  nc 
            sub  ax,word ptr ds:ReadStart
            sbb  dx,word ptr ds:ReadStart+2
         $EndIf             
      Restore
      retf 2 
   $EndIf 
   cmp  ah,02h                         ; Display character? 
   $if  = 
      iret                             ; It is not needed 
   $endif
   cmp  ah,0Ch                         ; Keyboard input ? 
   $if  =
      mov  al,'N'                      ; "No" to the "Overwrite" question 
      iret                             ; so the Pascal program can skip 
                                       ; some files 
   $endif
   cmp  ah,57h                         ; Set file date/time ? 
   $if  = 
      clc                              ; It is not needed
      retf 2 
   $endif
   cmp  ah,40h                         ; Write file ? 
   $if  = 
      or   cx,cx                        
      $if  <>0 
         cmp  bx,1                     ; To screen ? 
         $if  <>                       ; No, to output file 
            Store es, ds, di, si, dx, cx, bx
            push cx
            
            mov  si,ds
             
            mov  ds,cs:ProgramDS
            les  di,ds:SelfPtr
            push es, di 
            call ds:WriteUnpacked      ; Pascal method to store unpacked data 
            
            clc
            pop  ax
            Restore 
         $else                         ; Message to screen ? 
            push ds
            mov  ds,cs:ProgramDS 
            cmp  ds:ZipMessages,0
            pop  ds 
            $if  <>                    ; Are messages allowed ? 
               int  21h
               retf 2   
            $endif
         $endif              
      $endif 
      clc                              ; Return "All the bytes are written 
      mov  ax,cx                       ; successfully"
      retf 2 
   $endif    
   cmp  ah,43h                         ; Set file attribute ? 
   $if  = 
      mov  cx,20h                      ; Return normal attribute 
      clc
      retf 2 
   $endif
   cmp  ah,4Eh                         ; Find first ? 
   $if  =
      Store es, ds, di, si, dx, cx, bx 
      
      mov  si,ds
       
      mov  ds,cs:ProgramDS
      les  di,ds:SelfPtr
      push es, di 
      call ds:QueryUnpack              ; Pascal method to query name 

      Restore 
       
      or   al,al
      $If  <>0 
         mov  ax,2                     ; Return "File not found" & unpack 
         stc
      $Else
         clc                           ; Return "File exists" & skip 
      $EndIf
      retf 2   
   $endif 
     
   int  21h                            ; Any other function
   retf 2 
UnZipIntProc endp 
[ RETURN TO DIRECTORY ]