home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / UTILITY / ARCHIVE / PKV100.ZIP / PKV100.ASM next >
Encoding:
Assembly Source File  |  1990-10-14  |  29.6 KB  |  615 lines

  1. .SEQ
  2. Name    PKV
  3. Page    51,132
  4. Title   PKV.ASM
  5.  
  6. Comment |
  7. Author  BF Gavin, Online Reference BBS.  All rights reserved.
  8. Format  Standard .COM file format.
  9. Intent  View contents of ZIP file using local file headers.
  10.  
  11. Usage
  12. Origin  14OCT90  Version 1.00
  13. Update
  14. Remark  Use .SEQ or Assemble with /S parm for segments in source file order.
  15.  
  16.         |
  17.  
  18.  
  19. Code    Segment Para Public 'Code'
  20.  
  21.                 Org     100H                    ; .COM type entry point
  22.                 Assume  CS:CODE
  23.                 Assume  DS:CODE
  24.                 Assume  ES:CODE
  25.  
  26. Cr              Equ     13                      ; Carriage return
  27. Lf              Equ     10                      ; Line feed
  28.  
  29.  
  30. Entry:          Jmp     Main_Line
  31.  
  32.                 Db      Cr,Lf,Lf
  33.                 Db      'PKV - v1.00',Cr,Lf
  34.                 Db      '(C) BF Gavin - All rights reserved',Cr,Lf
  35.                 Db      'Release date is 14OCT90',Cr,Lf
  36.                 Db      'Written entirely in TURBO ASM v2.00',Cr,Lf
  37.                 Db      1Ah
  38.  
  39. Include         Pkv100.Var                      ; Program variables
  40. Include         Pkv100.Inc                      ; Generic subroutines
  41.  
  42.  
  43.  
  44.  
  45.  
  46. Parse_Parms     Proc    Near
  47.         Mov     SI,81h                          ; 1st command line parm
  48.         Call    Leading_Blanks                  ; Get first non-blank char
  49.         Jnc     _parse_cmdline                  ; NC = non-blank command line
  50.         Lea     DX,NoParm$                      ; Point at error message
  51.         Jmp     Error_Exit                      ; Display message and quit
  52.  
  53.   _parse_cmdline:
  54.         Lea     DI,ZipFile                      ; Input file name
  55.         Call    Upper_Case                      ; Convert AL to upper case
  56.         Stosb                                   ; Store 1st parm byte
  57.  
  58.   _parse_copyloop:
  59.         Lodsb                                   ; Read command line parm bytes
  60.         Cmp     AL,20h                          ; Blank space?
  61.         Jz      _parse_copydone                 ; Yes - parm is done
  62.         Cmp     AL,09h                          ; Tab?
  63.         Jz      _parse_copydone                 ; Yes - parm is done
  64.         Cmp     AL,Cr                           ; Carriage return?
  65.         Jz      _parse_copydone                 ; Yes - parm is done
  66.         Call    Upper_Case                      ; Convert AL to upper case
  67.         Stosb                                   ; No  - store byte in ZipFile
  68.         Jmp     Short _parse_copyloop           ; Go again
  69.  
  70.   _parse_copydone:
  71.         Xor     AX,AX                           ; Fast zero of AX
  72.         Stosw                                   ; Append ASCIIZ terminators
  73.         Ret                                     ; To main line
  74. Parse_Parms     Endp
  75.  
  76.  
  77.  
  78.  
  79.  
  80. Open_ZipFile    Proc    Near
  81.         Xor     AL,AL                           ; Fast zero of AL
  82.         Mov     CX,0FFFFh                       ; Scan counter
  83.         Lea     DI,ZipFile                      ; Scan input file name
  84.         Repne   Scasb                           ; Scan input for ASCIIZ
  85.         Not     CX                              ; Get length of ZipFile
  86.         Mov     BX,CX                           ; Save length in BX
  87.         Dec     BX                              ; Adjust it -1
  88.  
  89.         Mov     AL,'.'                          ; Scan for dot
  90.         Lea     DI,ZipFile                      ; Scan input file name
  91.         Repne   Scasb                           ; Scan for dot
  92.         Or      CX,CX                           ; Was file extent found?
  93.         Jnz     _open_input                     ; Yes - dot was found
  94.  
  95.   ;Add .ZIP file extent
  96.         Lea     DI,ZipFile                      ; Start of input file name
  97.         Add     DI,BX                           ; Point at ASCIIZ terminator
  98.         Mov     AX,'Z.'                         ; Reversed for STOSW
  99.         Stosw                                   ; Append '.Z'
  100.         Mov     AX,'PI'                         ; Reversed for STOSW
  101.         Stosw                                   ; Append 'IP'
  102.         Xor     AL,AL                           ; Fast setup of ASCIIZ
  103.         Stosb                                   ; Append ASCIIZ
  104.  
  105.   _open_input:
  106.         Mov     AX,3D00h                        ; Open file handle function
  107.         Lea     DX,ZipFile                      ; Input file
  108.         Int     21h                             ; Call DOS
  109.         Jnc     _open_ok                        ; Continue if no error
  110.         Lea     DX,Open_Err$                    ; Point at error message
  111.         Jmp     Error_Exit                      ; Display message and quit
  112.  
  113.   _open_ok:
  114.         Mov     ZIP_Handle,AX                       ; Save the input file handle
  115.         Ret                                     ; To main line
  116. Open_ZipFile    Endp
  117.  
  118.  
  119.  
  120.  
  121.  
  122. Show_Header     Proc    Near
  123.         Lea     DX,Search$                      ; Searching:
  124.         Call    Display_Message                 ; Display it
  125.         Lea     DX,ZipFile                      ; ASCIIZ file name
  126.         Call    Display_Message                 ; Display it
  127.         Lea     DX,Newline                      ; Cr,Lf,0
  128.         Call    Display_Message                 ; Display it
  129.         Call    Display_Message                 ; Display it again
  130.         Lea     DX,Header1$                     ; Top column text
  131.         Call    Display_Message                 ; Display it
  132.         Lea     DX,Header2$                     ; Top column dashes
  133.         Call    Display_Message                 ; Display it
  134.         Ret                                     ; To main line
  135. Show_Header     Endp
  136.  
  137.  
  138.  
  139.  
  140.  
  141. GetRecord       Proc    Near                    ; Filepos = Record at entry
  142.         Mov     AH,3Fh                          ; Read handle function
  143.         Mov     BX,ZIP_Handle                   ; ZipFileopen handle
  144.         Mov     CX,Size ZIP                     ; Size of ZIP variable
  145.         Lea     DX,ZIP                          ; Read into offset zero
  146.         Int     21h                             ; Call DOS
  147.         Jnc     _get_signature                  ; Continue if no errors
  148.         Lea     DX,Read_Err$                    ; Read error message
  149.         Jmp     Error_Exit                      ; Display message and quit
  150.  
  151.   _get_signature:
  152.         Mov     AX,Word Ptr ZIP.Signature
  153.         Mov     DX,Word Ptr ZIP.Signature+2
  154.         Cmp     AX,Word Ptr LocalSignature
  155.         Jnz     _check_dirsig
  156.         Cmp     DX,Word Ptr LocalSignature+2
  157.         Jnz     _check_dirsig
  158.  
  159.   ;Local header signature was found
  160.         Mov     CX,ZIP.FilenameLen              ; Length of compressed file data
  161.         Add     CX,ZIP.XFieldLen                ; Add in extra field length
  162.         Mov     AH,3Fh                          ; Read from file handle
  163.         Mov     BX,ZIP_Handle                   ; Get the open file handle
  164.         Lea     DX,LocalFileName                ; Read into here
  165.         Int     21h                             ; Call DOS
  166.         Jnc     _getrecord_filepointer          ; No error reading filename
  167.         Lea     DX,Hdr_Err$                     ; Set error message
  168.         Jmp     Error_Exit                      ; Display message and quit
  169.  
  170.   _getrecord_filepointer:
  171.   ;Update file position pointer after record, filename, xfield reads
  172.         Mov     BX,AX                           ; Save number of bytes read
  173.         Mov     AX,Word Ptr ZipFilePtr          ; Get file position pointer
  174.         Mov     DX,Word Ptr ZipFilePtr+2        ; Into DX:AX
  175.         Add     AX,Size ZIP                     ; Add size of bytes just read
  176.         Adc     DX,0                            ; Add in carry, if any
  177.         Add     AX,BX                           ; Add in filename,xfield bytes
  178.         Adc     DX,0                            ; Add in carry, if any
  179.         Add     AX,Word Ptr ZIP.CompSize        ; Add in length of member file
  180.         Adc     DX,Word Ptr ZIP.CompSize+2
  181.         Mov     Word Ptr ZipFilePtr,AX          ; Save the updated pointer
  182.         Mov     Word Ptr ZipFilePtr+2,DX
  183.         Mov     CX,DX                           ; Hi order position to CX
  184.         Mov     DX,AX                           ; Lo order position to DX
  185.         Mov     AX,4200h                        ; Move pointer CX:DX from top
  186.         Mov     BX,ZIP_Handle                   ; Set open file handle
  187.         Int     21h                             ; Call DOS
  188.         Jnc     _getrecord_exit                 ; No errors during seek
  189.         Lea     DX,Seek_Err$                    ; Set error message
  190.         Jmp     Error_Exit                      ; Display message and quit
  191.  
  192.   _getrecord_exit:
  193.         Xor     AL,AL                           ; Return 00 for local file sig
  194.         Ret                                     ; To Process_Zipfile
  195.  
  196.   _check_dirsig:
  197.   ;Check for Central Directory signature
  198.         Cmp     AX,Word Ptr DirSignature
  199.         Jnz     _corrupted
  200.         Cmp     DX,Word Ptr DirSignature+2
  201.         Jnz     _corrupted
  202.         Mov     AL,1                            ; Return 01 for Directory sig
  203.         Ret                                     ; To Process_Zipfile
  204.  
  205.   _corrupted:
  206.         Mov     AL,0FFh                         ; Return FF for error
  207.         Ret                                     ; To Process_Zipfile
  208. GetRecord       Endp
  209.  
  210.  
  211.  
  212.  
  213.  
  214. GetRatio        Proc    Near                    ; DX:AX = larger, CX:BX = smaller
  215.         Cmp     AX,BX                           ; LO original = LO zipped?
  216.         Jnz     _getratio_loop                  ; No  - get actual ratios
  217.         Cmp     DX,CX                           ; HI original = HI zipped?
  218.         Jnz     _getratio_loop                  ; No  - get actual ratios
  219.         Xor     AX,AX                           ; Yes - fast exit with 0%
  220.         Mov     DX,AX                           ; Insure HI order is also zero
  221.         Ret                                     ; To caller
  222.  
  223.   ;Get ratio of two sizes:  ratio := ((orig-zipped)*100 / orig)
  224.   ;Shift original size, zipped size >> until both are 16 bit values.
  225.   ;This allows using hardware DIV instead of doing 32 bit divide in software.
  226.  
  227.   _getratio_loop:
  228.         Or      DX,DX                           ; HI original size = zero?
  229.         Jz      _getratio_rotate_done           ; Yes - now find ratio
  230.  
  231.   _getratio_rotate:                             ; 32 bit divide by two
  232.         Clc                                     ; Clear carry flag
  233.         Rcr     DX,1                            ; HI(orig-zipped)*100
  234.         Rcr     AX,1                            ; LO(orig-zipped)*100
  235.  
  236.         Clc                                     ; Clear carry flag
  237.         Rcr     CX,1                            ; HI(orig)
  238.         Rcr     BX,1                            ; LO(orig)
  239.         Jmp     Short _getratio_loop            ; Go again until both HI=0
  240.  
  241.   _getratio_rotate_done:
  242.   ;Get (orig-zipped)*100   as 16 bit values
  243.         Push    AX                              ; Original size as 16 bit value
  244.         Sub     AX,BX                           ; Assume LO remainder <= FFFFh
  245.         Sbb     DX,CX                           ; Assume HI remainder DX = 0
  246.         Mov     DX,100                          ; Multiplier
  247.         Mul     DX                              ; DX:AX = AX * DX
  248.  
  249.   ;Divide all 16 bit values:  ((orig-zipped)*100) / orig)
  250.         Pop     BX                              ; Original size as 16 bit value
  251.         Div     BX                              ; AX(Ratio) = DX:AX / BX
  252.         Or      DX,DX                           ; Is remainder zero?
  253.         Jz      _getratio_exit                  ; Yes - don't fudge AX +1
  254.         Inc     AX                              ; No  - set next higher percent
  255.  
  256.   _getratio_exit:
  257.         Xor     DX,DX                           ; Insure HI order is also zero
  258.         Ret                                     ; To caller with AX %
  259. GetRatio        Endp
  260.  
  261.  
  262.  
  263.  
  264.  
  265. Display_Record  Proc    Near
  266.         Mov     AL,20h                          ; Blanks
  267.         Lea     DI,@Length                      ; Start of display buffer
  268.         Mov     CX,80                           ; Length of display buffer
  269.         Rep     Stosb                           ; Clear the display buffer
  270.         Xor     AL,AL                           ; ASCIIZ
  271.         Stosb                                   ; Append it to display buffer
  272.  
  273.   ;Length = Uncompressed Size
  274.         Mov     AX,Word Ptr ZIP.UnCompSize
  275.         Mov     DX,Word Ptr ZIP.UnCompSize+2
  276.         Lea     DI,@TBuffer                     ; Temp 10 byte AXDX2Dec buffer
  277.         Stc                                     ; Want leading blanks
  278.         Call    AXDX2Dec                        ; Convert DX:AX to ASCII
  279.         Lea     SI,@TBuffer                     ; Temp buffer
  280.         Add     SI,3                            ; Drop first 3 bytes
  281.         Lea     DI,@Length                      ; Display buffer field
  282.         Mov     CX,7                            ; Length of display buffer
  283.         Rep     Movsb                           ; Copy temp buffer to display
  284.  
  285.   ;Get compression method
  286.         Mov     AX,ZIP.CompMethod               ; Get the compression method
  287.         Cmp     AX,6                            ; Valid range is 0..6
  288.         Jbe     _getratio_method_setup          ; Range is good - continue
  289.         Mov     AX,7                            ; Bad value, force 'Unknown'
  290.  
  291.   _getratio_method_setup:
  292.   ;Set compression method into display buffer
  293.         Shl     AX,1                            ; Convert to WORD offset
  294.         Lea     BX,MethodTbl                    ; Get base of jump table
  295.         Add     BX,AX                           ; Add in the offset
  296.         Mov     SI,[BX]                         ; Get pointer to method string
  297.         Lea     DI,@Method                      ; Destination in display buffer
  298.         Mov     CX,8                            ; All strings 8 bytes long
  299.         Rep     Movsb                           ; Copy into display buffer
  300.  
  301.   ;Size = Compressed Size
  302.         Mov     AX,Word Ptr ZIP.CompSize
  303.         Mov     DX,Word Ptr ZIP.CompSize+2
  304.         Lea     DI,@TBuffer                     ; Temp 10 byte AXDX2Dec buffer
  305.         Stc                                     ; Want leading blanks
  306.         Call    AXDX2Dec                        ; Convert DX:AX to ASCII
  307.         Lea     SI,@TBuffer                     ; Temp buffer
  308.         Add     SI,3                            ; Drop first 3 bytes
  309.         Lea     DI,@Size                        ; Display buffer field
  310.         Mov     CX,7                            ; Length of display buffer
  311.         Rep     Movsb                           ; Copy temp buffer to display
  312.         Xor     AX,AX                           ; Assume STORED compression method
  313.  
  314.         Mov     AX,Word Ptr ZIP.UncompSize      ; LO original size
  315.         Mov     DX,Word Ptr ZIP.UncompSize+2    ; HI original size
  316.         Mov     BX,Word Ptr ZIP.CompSize        ; LO zipped size
  317.         Mov     CX,Word Ptr ZIP.CompSize+2      ; HI zipped size
  318.         Call    GetRatio                        ; Set DX:AX ratio
  319.  
  320.         Lea     DI,@TBuffer                     ; Point at temp buffer
  321.         Stc                                     ; Setup for leading blanks
  322.         Call    AXDX2Dec                        ; Convert DX:AX in @TBuffer
  323.         Mov     SI,DI                           ; Start of @TBuffer
  324.         Add     SI,8                            ; Last two bytes of @TBuffer
  325.         Lea     DI,@Ratio                       ; Ratio in display buffer
  326.         Mov     CX,2                            ; Move two bytes
  327.         Rep     Movsb                           ; Copy into display buffer
  328.         Mov     AL,'%'                          ; Percent sign
  329.         Stosb                                   ; Append to ratio
  330.  
  331.   ;Get ZIP file data
  332.   ;ZIP_File_Month:
  333.         Mov     AX,ZIP.DateStamp                ; Get ZIP file date word
  334.         And     AX,01E0h                        ; Isolate month bits
  335.         Mov     CL,5                            ; Shift count
  336.         Shr     AX,CL                           ; Shift month bits into AL
  337.         Xor     DX,DX                           ; Zero hi order
  338.         Stc                                     ; Ask for leading blanks
  339.         Lea     DI,@TBuffer                     ; Point at temp buffer
  340.         Call    AXDX2Dec                        ; Convert AL to ASCII in AX
  341.         Lea     DI,@Date                        ; Start of date field
  342.         Lea     SI,@TBuffer                     ; Start of temp buffer
  343.         Add     SI,8                            ; Get last two digits
  344.         Lodsw                                   ; Read from temp buffer
  345.         Stosw                                   ; Store in display buffer
  346.  
  347.   ;ZIP_File_Day:
  348.         Mov     AX,ZIP.DateStamp                ; Get ZIP file date word
  349.         And     AX,001Fh                        ; Isolate day bits
  350.         Xor     DX,DX                           ; Zero hi order
  351.         Clc                                     ; Ask for leading zeros
  352.         Lea     DI,@TBuffer                     ; Point at temp buffer
  353.         Call    AXDX2Dec                        ; Convert AL to ASCII in AX
  354.         Lea     DI,@Date                        ; Start of date field
  355.         Add     DI,2                            ; Dash before day field
  356.         Mov     AL,'-'                          ; Dash
  357.         Stosb                                   ; Store in day field
  358.         Lea     SI,@TBuffer                     ; Start of temp buffer
  359.         Add     SI,8                            ; Get last two digits
  360.         Lodsw                                   ; Read from temp buffer
  361.         Stosw                                   ; Store in display buffer
  362.  
  363.   ;ZIP_File_Year:
  364.         Mov     AX,ZIP.DateStamp                ; Get ZIP file date word
  365.         Shr     AH,1                            ; Shift into lo bits
  366.         Add     AH,80                           ; Base year is 1980
  367.         Cmp     AH,100                          ; Check of correction needed
  368.         Jb      _zip_fileyear1                  ; No correction necessary
  369.         Sub     AH,100                          ; Correct for next century
  370.  
  371.   _zip_fileyear1:
  372.         Mov     AL,AH                           ; Put bits into AL
  373.         Lea     DI,@TBuffer                     ; Start of temp buffer
  374.         Xor     AH,AH                           ; Zero hi nybble
  375.         Xor     DX,DX                           ; Zero hi order
  376.         Clc                                     ; Ask for leading zeros
  377.         Call    AXDX2Dec                        ; Convert AL to ASCII in AX
  378.         Lea     DI,@Date                        ; Start of date field
  379.         Add     DI,5                            ; Dash before year field
  380.         Lea     SI,@TBuffer                     ; Start of temp buffer
  381.         Add     SI,8                            ; Get last two digits
  382.         Mov     AL,'-'                          ; Year dash
  383.         Stosb                                   ; Store in display buffer
  384.         Lodsw                                   ; Read from temp buffer
  385.         Stosw                                   ; Store in display buffer
  386.  
  387.   ;File time stamp
  388.         Mov     AX,ZIP.TimeStamp                ; Get ZIP file time word
  389.         And     AX,0F800h                       ; Isolate hour bits
  390.         Mov     CL,11                           ; Shift count
  391.         Shr     AX,CL                           ; Shift bits to lo order
  392.         Xor     DX,DX                           ; Zero hi order
  393.         Clc                                     ; Ask for leading zeros
  394.         Lea     DI,@TBuffer                     ; Point at temp buffer
  395.         Call    AXDX2Dec                        ; Convert AL to ASCII in AX
  396.         Lea     DI,@Time                        ; Start of time field
  397.         Lea     SI,@TBuffer                     ; Start of temp buffer
  398.         Add     SI,8                            ; Get last two digits
  399.         Lodsw                                   ; Read from temp buffer
  400.         Stosw                                   ; Store in display buffer
  401.         Mov     AL,':'                          ; Time separator
  402.         Stosb                                   ; Store in display buffer
  403.  
  404.   ;_zip_fileminute:
  405.         Mov     AX,ZIP.TimeStamp                ; Get ZIP file time word
  406.         And     AX,07E0h                        ; Isolate minute bits
  407.         Mov     CL,5                            ; Shift count
  408.         Shr     AX,CL                           ; Shift into low order bits
  409.         Xor     DX,DX                           ; Zero hi order
  410.         Clc                                     ; Ask for leading zeros
  411.         Lea     DI,@TBuffer                     ; Point at temp buffer
  412.         Call    AXDX2Dec                        ; Convert AL to ASCII in AX
  413.         Lea     DI,@Time                        ; Start of time field
  414.         Add     DI,3                            ; Point to minutes field
  415.         Lea     SI,@TBuffer                     ; Start of temp buffer
  416.         Add     SI,8                            ; Get last two digits
  417.         Lodsw                                   ; Read from temp buffer
  418.         Stosw                                   ; Store in display buffer
  419.  
  420.   ;Set CRC-32 in display buffer
  421.         Mov     AX,Word Ptr ZIP.Crc32           ; CRC word LO
  422.         Mov     DX,Word Ptr ZIP.Crc32+2         ; CRC word HI
  423.         Lea     DI,@CRC                         ; CRC field in display buffer
  424.         Clc                                     ; Request leading zeros
  425.         Call    AXDX2Hex                        ; Convert to ASCII Hex display
  426.  
  427.   ;Dummy up the attribute field
  428.         Lea     DI,@Attr
  429.         Mov     AL,'-'
  430.         Stosb
  431.         Stosb
  432.         Stosb
  433.  
  434.   ;Display ZIP local filename
  435.         Mov     CX,Word Ptr ZIP.FilenameLen; Length of file name
  436.         Lea     SI,LocalFileName                ; Name from ZIP data
  437.         Lea     DI,@Name                        ; Name in display buffer
  438.         Rep     Movsb                           ; Copy to display buffer
  439.         Mov     AX,0A0Dh                        ; Reserved CRLF for STOSW
  440.         Stosw                                   ; Store CRLF in display buffer
  441.         Xor     AL,AL                           ; ASCII terminator
  442.         Stosb                                   ; Append to display buffer
  443.         Lea     DX,@Length                      ; Point at display buffer
  444.         Call    Display_Message                 ; Display it
  445.         Ret                                     ; To Process_Zipfile
  446. Display_Record  Endp
  447.  
  448.  
  449.  
  450.  
  451.  
  452. UpdateStats     Proc    Near
  453.         Mov     AX,Word Ptr TotalLength         ; Get total uncompressed bytes
  454.         Mov     DX,Word Ptr TotalLength+2
  455.         Add     AX,Word Ptr ZIP.UnCompSize      ; Add in this member size
  456.         Adc     DX,Word Ptr ZIP.UnCompSize+2
  457.         Mov     Word Ptr TotalLength,AX         ; Save the updated total
  458.         Mov     Word Ptr TotalLength+2,DX
  459.  
  460.         Mov     AX,Word Ptr TotalSize           ; Get total compressed bytes
  461.         Mov     DX,Word Ptr TotalSize+2
  462.         Add     AX,Word Ptr ZIP.CompSize        ; Add in this member size
  463.         Adc     DX,Word Ptr ZIP.CompSize+2
  464.         Mov     Word Ptr TotalSize,AX           ; Save the update total
  465.         Mov     Word Ptr TotalSize+2,DX
  466.  
  467.         Inc     TotalFiles                      ; Bump number of member files
  468.  
  469.         Ret                                     ; To Process_Zipfile
  470. UpdateStats     Endp
  471.  
  472.  
  473.  
  474.  
  475.  
  476. Process_Zipfile Proc    Near
  477.         Call    GetRecord                       ; Get local file header
  478.         Or      AL,AL                           ; Is AL zero?
  479.         Jnz     _process_01                     ; No - check for 01h
  480.         Call    UpdateStats                     ; Update files totals
  481.         Call    Display_Record                  ; Display ZIP member file
  482.         Jmp     Short Process_Zipfile           ; Go until Central Dir found
  483.  
  484.   _process_01:
  485.         Cmp     AL,01h                          ; Central Dir signature?
  486.         Jnz     _process_FF                     ; No - must be an error
  487.         Ret                                     ; To main line - all done
  488.  
  489.   _process_FF:
  490.         Lea     DX,Bad_Zip$                     ; Invalid header message
  491.         Jmp     Error_Exit                      ; Display message and quit
  492. Process_Zipfile Endp
  493.  
  494.  
  495.  
  496.  
  497.  
  498. Show_Trailer    Proc    Near
  499.         Cld                                     ; Ascending direction
  500.         Cli                                     ; Interrupts off
  501.         Push    BP                              ; Create stack framer
  502.         Sub     SP,100                          ; Create 100 byte buffer
  503.         Mov     BP,SP                           ; For temp display buffer
  504.         Sti                                     ; Interrupts on
  505.         Push    AX                              ; Move stack pointer for safety
  506.  
  507.         Mov     AL,20h                          ; Double blanks
  508.         Mov     CX,78                           ; Byte count
  509.         Mov     DI,BP                           ; Start of display buffer
  510.         Rep     Stosb                           ; Blank the display buffer
  511.         Mov     AX,0A0Dh                        ; Reversed CRLF for Stosw
  512.         Stosw                                   ; Store it
  513.         Xor     AX,AX                           ; ASCIIZ terminator
  514.         Stosw                                   ; Store it
  515.  
  516.         Lea     DX,Trailer1$                    ; Point at trailer string
  517.         Call    Display_Message                 ; Display it
  518.  
  519.   ;Display in reverse order to avoid display buffer overwrite
  520.   ;Display total count of members in ZIP file
  521.         Mov     DI,BP                           ; Start of display buffer
  522.         Add     DI,61                           ; Total files field
  523.         Mov     AX,Word Ptr TotalFiles          ; Get total compressed bytes
  524.         Xor     DX,DX                           ; Zero the high order
  525.         Stc                                     ; Request leading blanks
  526.         Call    AXDX2Dec                        ; Convert it in display buffer
  527.  
  528.   ;Display average compression ratio
  529.         Mov     DI,BP                           ; Start of display buffer
  530.         Add     DI,20                           ; Ratio field
  531.         Mov     AX,Word Ptr TotalLength         ; LO total original length
  532.         Mov     DX,Word Ptr TotalLength+2       ; HI total original length
  533.         Mov     BX,Word Ptr TotalSize           ; LO total zipped size
  534.         Mov     CX,Word Ptr TotalSize+2         ; HI total zipped size
  535.         Call    GetRatio                        ; Set DX:AX = ratio
  536.  
  537.         Stc                                     ; Request leading blanks
  538.         Call    AXDX2Dec                        ; Convert it in display buffer
  539.         Mov     Byte Ptr [BP+30],'%'            ; Store the percent sign
  540.  
  541.   ;Display total compressed size
  542.         Mov     DI,BP                           ; Start of display buffer
  543.         Add     DI,16                           ; Point at size field
  544.         Mov     AX,Word Ptr TotalSize           ; Get total compressed bytes
  545.         Mov     DX,Word Ptr TotalSize+2
  546.         Stc                                     ; Request leading blanks
  547.         Call    AXDX2Dec                        ; Convert it in display buffer
  548.  
  549.   ;Display total uncompressed length
  550.         Mov     DI,BP                           ; Start of display buffer
  551.         Mov     AX,Word Ptr TotalLength         ; Get total uncompressed bytes
  552.         Mov     DX,Word Ptr TotalLength+2
  553.         Stc                                     ; Request leading blanks
  554.         Call    AXDX2Dec                        ; Convert it in display buffer
  555.  
  556.         Mov     DX,BP                           ; Base of display buffer
  557.         Add     DX,3                            ; Drop 3 leading characters
  558.         Call    Display_Message
  559.  
  560.         Cli                                     ; Interrupts off
  561.         Mov     SP,BP                           ; Restore the stack frame
  562.         Add     SP,100                          ; Restore stack pointer
  563.         Sti                                     ; Interrupts on
  564.         Pop     BP                              ; Restore entry value
  565.         Ret                                     ; To main line
  566. Show_Trailer    Endp
  567.  
  568.  
  569.  
  570.  
  571.  
  572. Close_ZipFile   Proc    Near
  573.         Mov     AH,3Eh                          ; Close handle function
  574.         Mov     BX,ZIP_Handle                   ; Get file handle
  575.         Int     21h                             ; Call DOS
  576.         Ret                                     ; To main line
  577. Close_ZipFile   Endp
  578.  
  579.  
  580.  
  581.  
  582.  
  583. Main_Line       Proc    Near
  584.         Cld                                     ; Ascending direction
  585.  
  586.         Call    DOS_Version                     ; Check for DOS 2 or higher
  587.         Call    Parse_Parms                     ; Get command line name
  588.         Call    Open_ZipFile                    ; Open the input ZIP file
  589.         Call    Show_Header                     ; Display top columns
  590.         Call    Process_Zipfile                 ; Display ZIP members
  591.         Call    Show_Trailer                    ; Display totals
  592.         Call    Close_ZipFile                   ; Close the input ZIP file
  593.  
  594.   Exit:
  595.         Mov     AX,4C00h                        ; Return code = 0
  596.         Int     21h                             ; Call DOS
  597.  
  598.   Error_Exit:
  599.         Call    Display_Message                 ; Error message at [DX]
  600.         Mov     AX,4C01h                        ; Return code = 1
  601.         Int     21h                             ; Call DOS
  602. Main_Line       Endp
  603.  
  604. Code            Ends
  605. End             Entry                           ; Required for COM entry point
  606.  
  607.  
  608.  
  609.  
  610.  
  611.  
  612.  
  613.  
  614.  
  615.