Subversion Repositories Kolibri OS

Rev

Rev 135 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;
  2. ; MHC archiver for MenuetOS - very fast compression tool
  3. ;
  4. ; version 0.09
  5. ;
  6. ; Written by Nikita Lesnikov (nlo_one@mail.ru, Republic of Belarus, Sluck)
  7. ;
  8.  
  9. ;==============================================================================
  10.  
  11. ;
  12. ; Brief file format description:
  13. ;
  14. ;                  +-----------+------------------------+
  15. ;  File structure: | Method ID | Compressed data        |
  16. ;                  +-----------+------------------------+
  17. ;
  18. ;  Methods list:
  19. ;
  20. ;    0. LZP (order-2 specified specially for *.ASM,*.RAW and MeOS executables)
  21. ;
  22. ;  New methods can be easily added without loss of compatibility
  23. ; with older versions
  24. ;
  25.  
  26. ;==============================================================================
  27.  
  28. ; SYSTEM HEADER
  29.  
  30. use32
  31.  
  32.   org 0x0
  33.   db "MENUET01"
  34.   dd 0x01
  35.   dd ENTRANCE
  36.   dd MHC_END
  37.   dd 0x300000  ; 3 megs of memory needed
  38.   dd 0x2FF000
  39.   dd 0x0
  40.   dd 0x0
  41.  
  42. include 'lang.inc'
  43. include '..\..\..\macros.inc'
  44. ; CODE AREA
  45.  
  46. ENTRANCE:
  47.  
  48. ; ======== user interface =========
  49.  
  50.  
  51.  call draw_window             ; draw the window
  52.  
  53.  still:
  54.  
  55.  mov eax,10                   ; wait for event
  56.  mcall
  57.  
  58.  cmp eax,1                    ; redraw?
  59.  jnz no_redraw
  60.  call draw_window
  61.  no_redraw:
  62.  
  63.  cmp eax,2                    ; key pressed?
  64.  jz key
  65.  
  66.  cmp eax,3                    ; button pressed?
  67.  jz button
  68.  
  69.  jmp still
  70.  
  71.  ; Key handler
  72.  
  73.  key:
  74.  mov eax,2   ; read it
  75.  mcall
  76.  shr eax,8
  77.  
  78.  cmp byte [editstate],0
  79.  jz  still
  80.  
  81.  cmp al,8    ; backspace
  82.  jnz no_bksp
  83.  cmp byte [editpos],0
  84.  jz  no_del_last
  85.  dec byte [editpos]
  86.  xor ebx,ebx
  87.  mov bl,byte [editpos]
  88.  add ebx,cmfile
  89.  cmp byte [editstate],2
  90.  jnz no_add_base_1
  91.  add ebx,12
  92.  no_add_base_1:
  93.  mov byte [ebx],32
  94.  no_del_last:
  95.  call draw_info
  96.  jmp still
  97.  no_bksp:
  98.  
  99.  cmp al,13            ; enter
  100.  jnz no_enter
  101.  mov byte [editstate],0
  102.  call draw_info
  103.  jmp still
  104.  no_enter:
  105.  
  106.  cmp eax,dword 31
  107.  jbe no_lit
  108.  cmp eax,dword 95
  109.  jb  capital
  110.  sub eax,32
  111.  capital:
  112.  xor ebx,ebx
  113.  mov bl,byte [editpos]
  114.  add ebx,cmfile
  115.  cmp byte [editstate],2
  116.  jnz no_add_base_2
  117.  add ebx,12
  118.  no_add_base_2:
  119.  mov byte [ebx],al
  120.  inc byte [editpos]
  121.  cmp byte [editpos],12
  122.  jnz no_null_state
  123.  mov byte [editstate],0
  124.  no_null_state:
  125.  call draw_info
  126.  no_lit:
  127.  
  128.  jmp still
  129.  
  130.  ; Button handler
  131.  
  132.  button:
  133.  
  134.  mov eax,17
  135.  mcall
  136.  
  137.  cmp ah,1
  138.  jnz no_quit
  139.  mov eax,-1
  140.  mcall
  141.  no_quit:
  142.  
  143.  cmp ah,4
  144.  jnz nofirst
  145.  cld
  146.  mov byte [editstate],1
  147.  mov edi,cmfile
  148.  mov eax,0x20202020
  149.  mov ecx,3
  150.  rep stosd
  151.  mov byte [editpos],0
  152.  mov byte [msgid],0
  153.  call draw_info
  154.  nofirst:
  155.  
  156.  cmp ah,5
  157.  jnz nosecond
  158.  cld
  159.  mov byte [editstate],2
  160.  mov edi,iofile
  161.  mov eax,0x20202020
  162.  mov ecx,3
  163.  rep stosd
  164.  mov byte [editpos],0
  165.  mov byte [msgid],0
  166.  call draw_info
  167.  nosecond:
  168.  
  169.  cmp ah,2
  170.  jnz no_compress
  171.  call compress
  172.  no_compress:
  173.  
  174.  cmp ah,3
  175.  jnz no_decompress
  176.  call decompress
  177.  no_decompress:
  178.  
  179.  cmp ah,6
  180.  jnz no_delete_io
  181.  pusha
  182.  mov eax,32
  183.  mov ebx,iofile
  184.  mcall
  185.  popa
  186.  no_delete_io:
  187.  
  188.  cmp ah,7
  189.  jnz  no_delete_archive
  190.  pusha
  191.  mov eax,32
  192.  mov ebx,cmfile
  193.  mcall
  194.  popa
  195.  no_delete_archive:
  196.  
  197.  jmp still
  198.  
  199.  ; WINDOW DRAW
  200.  
  201.  draw_window:
  202.  
  203.  mov eax,12  ; Start redrawing
  204.  mov ebx,1
  205.  mcall
  206.  
  207.  xor eax,eax           ; Define window
  208.  mov ebx,100*65536+240
  209.  mov ecx,100*65536+130
  210.  mov edx,0x03AAAAAA
  211.  mov esi,0x80777777
  212.  mov edi,0x00777777
  213.  mcall
  214.  
  215.  mov eax,4              ; Draw all needed texts
  216.  mov ebx,8*65536+8
  217.  mov ecx,0x00FFFFFF
  218.  mov edx,title
  219.  mov esi,arclab-title
  220.  mcall
  221.  
  222.  xor ecx,ecx
  223.  mov edx,arclab
  224.  mov esi,unplab-arclab
  225.  add ebx,10*65536+28
  226.  mcall
  227.  
  228.  mov edx,unplab
  229.  mov esi,fin_text-unplab
  230.  add ebx,18
  231.  mcall
  232.  
  233.  pusha
  234.  
  235. ; mov eax,8            ; Buttons
  236. ; mov ebx,222*65536+10
  237. ; mov ecx,6*65536+10
  238. ; mov edx,1
  239. ; mov esi,0x555555
  240. ; mcall
  241.  
  242.  mov eax,8
  243.  mov ebx,15*65536+100
  244.  mov ecx,70*65536+13
  245.  mov edx,2
  246.  mcall
  247.  
  248.  inc edx
  249.  add ebx,110*65536
  250.  mcall
  251.  
  252.  inc edx
  253.  mov ebx,214*65536+11
  254.  mov ecx,33*65536+11
  255.  mcall
  256.  
  257.  inc edx
  258.  add ecx,18*65536
  259.  mcall
  260.  
  261.  inc edx
  262.  mov ebx,15*65536+100
  263.  mov ecx,86*65536+13
  264.  mcall
  265.  
  266.  inc edx
  267.  add ebx,110*65536
  268.  mcall
  269.  
  270.  popa
  271.  
  272.  mov ecx,0x00FFFFFF
  273.  mov edx,keylab
  274.  mov esi,dellab-keylab
  275.  add ebx,19
  276.  mcall
  277.  
  278.  mov edx,dellab
  279.  mov esi,title-dellab
  280.  add ebx,16
  281.  mcall
  282.  
  283.  call draw_info
  284.  
  285.  mov eax,12          ; Finish redrawing
  286.  mov ebx,2
  287.  mcall
  288.  
  289.  ret
  290.  
  291.  draw_info:          ; Draw filenames and compressor state
  292.  
  293.  activecolor equ 0x00112299
  294.  
  295.  pusha ; Save registers
  296.  
  297.  mov eax,13               ; Clean draw area
  298.  mov ebx,127*65536+85
  299.  mov ecx,33*65536+33
  300.  mov edx,0x00AAAAAA
  301.  mcall
  302.  
  303.  mov eax,4 ; Draw filenames
  304.  mov ebx,134*65536+36
  305.  mov edx,cmfile
  306.  xor ecx,ecx
  307.  mov esi,12
  308.  cmp byte [editstate],1
  309.  jnz no_active_1
  310.  mov ecx,activecolor
  311.  no_active_1:
  312.  mcall
  313.  xor ecx,ecx
  314.  cmp byte [editstate],2
  315.  jnz no_active_2
  316.  mov ecx,activecolor
  317.  no_active_2:
  318.  add ebx,18
  319.  add edx,12
  320.  mcall
  321.  
  322.  mov eax,13             ; Clean info area
  323.  mov ebx,14*65536+210
  324.  mov ecx,107*65536+14
  325.  mov edx,0x00AAAAAA
  326.  mcall
  327.  
  328.  cmp byte [msgid],0     ; Draw info string
  329.  jz notype
  330.  mov ebx,16*65536+110
  331.  xor ecx,ecx
  332.  mov esi,16
  333.  mov al, byte [msgid]
  334.  dec al
  335.  shl al,4
  336.  xor ah,ah
  337.  xor edx,edx
  338.  mov dx,ax
  339.  add edx,msgtable
  340.  mov eax,4
  341.  mcall
  342.  notype:
  343.  
  344.  popa ; Restore registers
  345.  
  346.  ret
  347.  
  348.  ; interface data
  349.  
  350.  if lang eq de
  351.  keylab db "    PACKEN           ENTPACKEN"
  352.  dellab db "   LOESCHE I/O      LOESCHE *.MHC"
  353.  title  db "MHC 0.09"
  354.  arclab db "GEOACJTE DATEI:"
  355.  unplab db "EIN/AUSGABE DATEI:"
  356.  fin_text:
  357.  
  358.  cmfile db "FILENAME.MHC"
  359.  iofile db "FILENAME.XYZ"
  360.  
  361.  msgtable:
  362.  db "PACKE...        "
  363.  db "ENTPACKE...     "
  364.  db "KEIN I/O!       "
  365.  db "KEINE *.MHC!    "
  366.  db "FALSCHE METHODe!"
  367.  
  368.  else
  369.  keylab db "    COMPRESS         DECOMPRESS"
  370.  dellab db "   DELETE I/O       DELETE *.MHC"
  371.  title  db "MHC 0.09"
  372.  arclab db "COMPRESSED FILE:"
  373.  unplab db "INPUT/OUTPUT FILE:"
  374.  fin_text:
  375.  
  376.  cmfile db "FILENAME.MHC"
  377.  iofile db "FILENAME.XYZ"
  378.  
  379.  msgtable:
  380.  db "COMPRESSING...  "
  381.  db "DECOMPRESSING..."
  382.  db "I/O NOT FOUND!  "
  383.  db "*.MHC NOT FOUND!"
  384.  db "INVALID METHOD! "
  385.  
  386.  end if
  387.  
  388.  
  389.  editstate db 0
  390.  editpos db 0
  391.  msgid db 0
  392.  
  393.  
  394. ; ======== compression/decompression engine ========
  395.  
  396. ; Adresses declaration
  397.  
  398.  hashtable equ  MHC_END
  399.  ifile     equ  hashtable+65536*4
  400.  ofile     equ  ifile+1000000
  401.  
  402.  compress:   ; File compression
  403.  
  404.  call fill_filebufs
  405.  
  406.  mov eax,6
  407.  mov ebx,iofile
  408.  xor ecx,ecx
  409.  mov edx,ecx
  410.  not edx
  411.  mov esi,ifile
  412.  mcall
  413.  
  414.  cmp eax,0xFFFFFFFF
  415.  jnz  compress_filefound              ; i/o file not found
  416.  mov byte [msgid],3
  417.  call draw_info
  418.  ret
  419.  
  420.  compress_filefound:
  421.  
  422.  mov byte [msgid],1
  423.  call draw_info
  424.  
  425.  jmp lzp_compress                    ; compress with order-2 LZP
  426.  compress_dumpdata:
  427.  
  428.  push edx
  429.  
  430.  mov eax,32
  431.  mov ebx,cmfile
  432.  mcall
  433.  
  434.  mov eax,33
  435.  pop edx
  436.  mov ebx,cmfile
  437.  mov ecx,ofile
  438.  xor esi,esi
  439.  mcall
  440.  
  441.  mov byte [msgid],0
  442.  call draw_info
  443.  
  444.  ret
  445.  
  446.  
  447.  decompress: ; File decompression
  448.  
  449.  call fill_filebufs
  450.  
  451.  mov  eax,6
  452.  mov ebx,cmfile
  453.  xor ecx,ecx
  454.  mov edx,ecx
  455.  not edx
  456.  mov esi,ofile
  457.  mcall
  458.  
  459.  cmp eax,0xFFFFFFFF
  460.  jnz  decompress_filefound              ; *.mhc file not found
  461.  mov byte [msgid],4
  462.  call draw_info
  463.  ret
  464.  
  465.  decompress_filefound:
  466.  
  467.  cmp byte [ofile],0                     ; Invalid method!
  468.  jz  right_method
  469.  mov byte [msgid],5
  470.  call draw_info
  471.  ret
  472.  
  473.  right_method:
  474.  mov byte [msgid],2
  475.  call draw_info
  476.  
  477.  jmp lzp_decompress
  478.  decompress_dumpdata:
  479.  
  480.  push edx
  481.  
  482.  mov eax,32
  483.  mov ebx,iofile
  484.  mcall
  485.  
  486.  mov eax,33
  487.  pop edx
  488.  mov ebx,iofile
  489.  mov ecx,ifile
  490.  xor esi,esi
  491.  mcall
  492.  
  493.  mov byte [msgid],0
  494.  call draw_info
  495.  
  496.  ret
  497.  
  498.  fill_filebufs:             ; Fill filebufs with garbage to simplify matching
  499.  pusha
  500.  cld
  501.  mov eax,0xF7D9A03F         ; <- "magic number" :) just garbage...
  502.  mov ecx,2000000/4
  503.  mov edi,ifile
  504.  rep stosd
  505.  popa
  506.  ret
  507.  
  508. ; ==== algorithms section ====
  509.  
  510. ; Method 0: LZP compression algorithm
  511.  
  512.  lzp_compress:           ; EDX - how much bytes to dump
  513.  
  514.  cld                     ; clear direction flag
  515.  
  516.  mov esi,ifile           ; init pointers
  517.  mov edi,ofile
  518.  
  519.  push eax                ; write header: ID0+4bfilesize => total 5 bytes
  520.  xor eax,eax
  521.  stosb
  522.  pop eax
  523.  stosd
  524.  
  525.  pusha                   ; fill hash table
  526.  mov eax,ifile
  527.  mov edi,hashtable
  528.  mov ecx,65536
  529.  rep stosd
  530.  popa
  531.  
  532.  add eax,esi              ; calculate endpointer
  533.  mov dword [endpointer],eax
  534.  
  535.  movsw                    ; copy three bytes
  536.  movsb
  537.  
  538.  mov dword [controlp],edi
  539.  inc edi
  540.  
  541.  mov byte [controld],0
  542.  mov byte [controlb],0
  543.  
  544.  c_loop:
  545.  cmp dword [endpointer],esi  ; check end of file
  546.  ja  c_loop_ok
  547.  jmp finish_c_loop
  548.  c_loop_ok:
  549.  
  550.  call chash
  551.  call compare
  552.  jz   two_match_c
  553.  
  554.  lodsb
  555.  mov byte [literal],al
  556.  call chash
  557.  call compare
  558.  jz   lit_match_c
  559.  
  560.  mov  al,0
  561.  call putbit
  562.  mov  al,byte [literal]
  563.  stosb
  564.  movsb
  565.  jmp  end_c_loop
  566.  
  567.  lit_match_c:
  568.  mov al,1
  569.  call putbit
  570.  mov al,0
  571.  call putbit
  572.  mov al,byte [literal]
  573.  stosb
  574.  jmp encode_match
  575.  
  576.  two_match_c:
  577.  mov al,1
  578.  call putbit
  579.  call putbit
  580.  
  581.  encode_match:
  582.  call incpos
  583.  call compare
  584.  jz one_c
  585.  mov al,0
  586.  call putbit
  587.  jmp end_c_loop
  588.  one_c:
  589.  
  590.  call incpos
  591.  mov  al,1
  592.  call putbit
  593.  
  594.  call compare
  595.  jnz ec1
  596.  call incpos
  597.  call compare
  598.  jnz ec2
  599.  call incpos
  600.  call compare
  601.  jnz ec3
  602.  call incpos
  603.  mov al,1
  604.  call putbit
  605.  call putbit
  606.  call compare
  607.  jnz ec4
  608.  call incpos
  609.  call compare
  610.  jnz ec5
  611.  call incpos
  612.  call compare
  613.  jnz ec6
  614.  call incpos
  615.  call compare
  616.  jnz ec7
  617.  call incpos
  618.  call compare
  619.  jnz ec8
  620.  call incpos
  621.  call compare
  622.  jnz ec9
  623.  call incpos
  624.  call compare
  625.  jnz ec10
  626.  call incpos
  627.  
  628.  mov al,1
  629.  call putbit
  630.  call putbit
  631.  call putbit
  632.  xor  ecx,ecx
  633.  
  634.  match_loop_c:
  635.  cmp  esi,dword [endpointer]
  636.  jae   out_match_loop_c
  637.  call compare
  638.  jnz  out_match_loop_c
  639.  inc  ecx
  640.  call incpos
  641.  jmp  match_loop_c
  642.  out_match_loop_c:
  643.  
  644.  mov al,0xFF
  645.  out_lg:
  646.  cmp ecx,255
  647.  jb  out_lg_out
  648.  stosb
  649.  sub ecx,255
  650.  jmp out_lg
  651.  out_lg_out:
  652.  mov al,cl
  653.  stosb
  654.  jmp end_c_loop
  655.  
  656.  ec10:
  657.  mov al,1
  658.  call putbit
  659.  call putbit
  660.  mov al,0
  661.  call putbit
  662.  jmp end_c_loop
  663.  
  664.  ec9:
  665.  mov al,1
  666.  call putbit
  667.  mov al,0
  668.  call putbit
  669.  mov al,1
  670.  call putbit
  671.  jmp end_c_loop
  672.  
  673.  ec8:
  674.  mov al,1
  675.  call putbit
  676.  mov al,0
  677.  call putbit
  678.  call putbit
  679.  jmp end_c_loop
  680.  
  681.  ec7:
  682.  mov al,0
  683.  call putbit
  684.  mov al,1
  685.  call putbit
  686.  call putbit
  687.  jmp end_c_loop
  688.  
  689.  ec6:
  690.  mov al,0
  691.  call putbit
  692.  mov al,1
  693.  call putbit
  694.  mov al,0
  695.  call putbit
  696.  jmp end_c_loop
  697.  
  698.  ec5:
  699.  mov al,0
  700.  call putbit
  701.  call putbit
  702.  mov al,1
  703.  call putbit
  704.  jmp end_c_loop
  705.  
  706.  ec4:
  707.  mov al,0
  708.  call putbit
  709.  call putbit
  710.  call putbit
  711.  jmp end_c_loop
  712.  
  713.  ec3:
  714.  mov al,1
  715.  call putbit
  716.  mov al,0
  717.  call putbit
  718.  jmp end_c_loop
  719.  
  720.  ec2:
  721.  mov al,0
  722.  call putbit
  723.  mov al,1
  724.  call putbit
  725.  jmp end_c_loop
  726.  
  727.  ec1:
  728.  mov al,0
  729.  call putbit
  730.  call putbit
  731.  
  732.  end_c_loop:
  733.  jmp c_loop
  734.  
  735.  finish_c_loop:
  736.  
  737.  mov eax,dword [controlp] ; store last tagbyte
  738.  mov bl,byte [controld]
  739.  mov [eax], byte bl
  740.  
  741.  sub edi,ofile ; calculate dump size
  742.  mov edx,edi
  743.  
  744.  jmp compress_dumpdata
  745.  
  746. ; LZP decompression algorithm
  747.  
  748.  lzp_decompress:                        ; EDX - how much bytes to dump
  749.  
  750.  cld
  751.  
  752.  mov edi,ifile
  753.  mov esi,ofile+1
  754.  
  755.  pusha                   ; fill hash table
  756.  mov eax,ifile
  757.  mov edi,hashtable
  758.  mov ecx,65536
  759.  rep stosd
  760.  popa
  761.  
  762.  lodsd
  763.  
  764.  mov ebx,edi
  765.  add ebx,eax
  766.  mov dword [endpointer],ebx
  767.  
  768.  movsw
  769.  movsb
  770.  
  771.  lodsb
  772.  mov byte [controld],al
  773.  mov byte [controlb],0
  774.  
  775.  d_loop:
  776.  cmp dword [endpointer],edi
  777.  ja d_loop_ok
  778.  jmp finish_d_loop
  779.  d_loop_ok:
  780.  
  781.  call getbit
  782.  cmp  al,0
  783.  jnz  match_d
  784.  call dhash
  785.  movsb
  786.  call dhash
  787.  movsb
  788.  jmp end_d_loop
  789.  
  790.  match_d:
  791.  
  792.  call getbit
  793.  cmp  al,0
  794.  jnz  no_literal_before_match
  795.  call dhash
  796.  movsb
  797.  no_literal_before_match:
  798.  
  799.  call dhash
  800.  mov ecx,1
  801.  call copymatch
  802.  
  803.  call getbit
  804.  cmp  al,0
  805.  jz   end_d_loop
  806.  mov  ecx,1
  807.  call copymatch
  808.  call getbit
  809.  cmp  al,0
  810.  jz   dc2
  811.  mov  ecx,2
  812.  call copymatch
  813.  call getbit
  814.  cmp  al,0
  815.  jz   end_d_loop
  816.  mov  ecx,1
  817.  call copymatch
  818.  call getbit
  819.  cmp  al,0
  820.  jz   dc4
  821.  mov  ecx,4
  822.  call copymatch
  823.  call getbit
  824.  cmp  al,0
  825.  jz   dc5
  826.  call getbit
  827.  cmp  al,0
  828.  jz   dc6
  829.  mov  ecx,3
  830.  call copymatch
  831.  
  832.  do:
  833.  lodsb
  834.  xor  ecx,ecx
  835.  mov  cl,al
  836.  call copymatch
  837.  cmp  al,0xFF
  838.  jnz  end_do
  839.  jmp do
  840.  end_do:
  841.  jmp end_d_loop
  842.  
  843.  dc6:
  844.  mov ecx,2
  845.  call copymatch
  846.  jmp  end_d_loop
  847.  
  848.  dc5:
  849.  call getbit
  850.  cmp  al,0
  851.  jz   ndc5
  852.  mov  ecx,1
  853.  call copymatch
  854.  ndc5:
  855.  jmp  end_d_loop
  856.  
  857.  dc4:
  858.  call getbit
  859.  cmp  al,0
  860.  jz   ndc4
  861.  call getbit
  862.  mov  ecx,3
  863.  cmp  al,1
  864.  jz   ndcc4
  865.  dec  ecx
  866.  ndcc4:
  867.  call copymatch
  868.  jmp  end_d_loop
  869.  ndc4:
  870.  call getbit
  871.  cmp  al,0
  872.  jz   ndccc4
  873.  mov  ecx,1
  874.  call copymatch
  875.  ndccc4:
  876.  jmp  end_d_loop
  877.  
  878.  dc2:
  879.  call getbit
  880.  cmp al,0
  881.  jz  ndc2
  882.  mov ecx,1
  883.  call copymatch
  884.  ndc2:
  885.  
  886.  end_d_loop:
  887.  jmp d_loop
  888.  finish_d_loop:
  889.  
  890.  mov edx, dword [ofile+1]
  891.  
  892.  jmp decompress_dumpdata
  893.  
  894. ; LZP subroutines
  895.  
  896.  putbit:                  ; bit -> byte tag, AL holds bit for output
  897.  pusha
  898.  mov cl,byte [controlb]
  899.  shl al,cl
  900.  mov bl,byte [controld]
  901.  or  bl,al
  902.  mov byte [controld],bl
  903.  inc cl
  904.  cmp cl,8
  905.  jnz just_increment
  906.  mov byte [controlb],0
  907.  mov byte [controld],0
  908.  push edi
  909.  mov  edi, dword [controlp]
  910.  mov  al,bl
  911.  stosb
  912.  pop  edi
  913.  mov dword [controlp],edi
  914.  popa
  915.  inc edi
  916.  ret
  917.  just_increment:
  918.  mov byte [controlb],cl
  919.  popa
  920.  ret
  921.  
  922.  getbit:                       ; tag byte -> bit, AL holds input
  923.  push ecx
  924.  mov al,byte [controld]
  925.  mov cl,byte [controlb]
  926.  shr al,cl
  927.  and al,1
  928.  inc cl
  929.  cmp cl,8
  930.  jnz just_increment_d
  931.  mov byte [controlb],0
  932.  push eax
  933.  lodsb
  934.  mov byte [controld],al
  935.  pop  eax
  936.  pop  ecx
  937.  ret
  938.  just_increment_d:
  939.  mov byte [controlb],cl
  940.  pop ecx
  941.  ret
  942.  
  943.  chash:                        ; calculate hash -> mp -> fill position
  944.  pusha
  945.  xor  eax,eax
  946.  mov  al, byte [esi-1]
  947.  mov  ah, byte [esi-2]
  948.  shl  eax,2
  949.  add  eax,hashtable
  950.  mov  edx,dword [eax]
  951.  mov  dword [mp],edx
  952.  mov  dword [eax],esi
  953.  popa
  954.  ret
  955.  
  956.  dhash:                        ; calculate hash -> mp -> fill position
  957.  pusha
  958.  xor  eax,eax
  959.  mov  al, byte [edi-1]
  960.  mov  ah, byte [edi-2]
  961.  shl  eax,2
  962.  add  eax,hashtable
  963.  mov  edx,dword [eax]
  964.  mov  dword [mp],edx
  965.  mov  dword [eax],edi
  966.  popa
  967.  ret
  968.  
  969.  copymatch:                    ; ECX bytes from [mp] to [rp]
  970.  push esi
  971.  mov  esi,dword [mp]
  972.  rep  movsb
  973.  mov  dword [mp],esi
  974.  pop  esi
  975.  ret
  976.  
  977.  compare:                      ; compare [mp] with [cpos]
  978.  push edi
  979.  push esi
  980.  mov  edi,dword [mp]
  981.  cmpsb
  982.  pop  esi
  983.  pop  edi
  984.  ret
  985.  
  986.  incpos:
  987.  inc  dword [mp]
  988.  inc  esi
  989.  ret
  990.  
  991.  
  992. ; LZP algorithm data
  993.  
  994.  endpointer     dd      0
  995.  controlp       dd      0
  996.  controlb       db      0
  997.  controld       db      0
  998.  mp  dd 0
  999.  literal        db      0
  1000.  
  1001. MHC_END: ; the end... - Nikita Lesnikov (nlo_one)
  1002.