Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | 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.  int 0x40
  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.  int 0x40
  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.  int 0x40
  136.  
  137.  cmp ah,1
  138.  jnz no_quit
  139.  mov eax,-1
  140.  int 0x40
  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.  int 0x40
  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.  int 0x40
  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.  int 0x40
  206.  
  207.  xor eax,eax           ; Define window
  208.  mov ebx,100*65536+240
  209.  mov ecx,100*65536+130
  210.  mov edx,0x02AAAAAA
  211.  mov esi,0x80777777
  212.  mov edi,0x00777777
  213.  int 0x40
  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.  int 0x40
  221.  
  222.  xor ecx,ecx
  223.  mov edx,arclab
  224.  mov esi,unplab-arclab
  225.  add ebx,10*65536+28
  226.  int 0x40
  227.  
  228.  mov edx,unplab
  229.  mov esi,fin_text-unplab
  230.  add ebx,18
  231.  int 0x40
  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.  int 0x40
  241.  
  242.  mov ebx,15*65536+100
  243.  mov ecx,70*65536+13
  244.  inc edx
  245.  int 0x40
  246.  
  247.  inc edx
  248.  add ebx,110*65536
  249.  int 0x40
  250.  
  251.  inc edx
  252.  mov ebx,214*65536+11
  253.  mov ecx,33*65536+11
  254.  int 0x40
  255.  
  256.  inc edx
  257.  add ecx,18*65536
  258.  int 0x40
  259.  
  260.  inc edx
  261.  mov ebx,15*65536+100
  262.  mov ecx,86*65536+13
  263.  int 0x40
  264.  
  265.  inc edx
  266.  add ebx,110*65536
  267.  int 0x40
  268.  
  269.  popa
  270.  
  271.  mov ecx,0x00FFFFFF
  272.  mov edx,keylab
  273.  mov esi,dellab-keylab
  274.  add ebx,19
  275.  int 0x40
  276.  
  277.  mov edx,dellab
  278.  mov esi,title-dellab
  279.  add ebx,16
  280.  int 0x40
  281.  
  282.  call draw_info
  283.  
  284.  mov eax,12          ; Finish redrawing
  285.  mov ebx,2
  286.  int 0x40
  287.  
  288.  ret
  289.  
  290.  draw_info:          ; Draw filenames and compressor state
  291.  
  292.  activecolor equ 0x00112299
  293.  
  294.  pusha ; Save registers
  295.  
  296.  mov eax,13               ; Clean draw area
  297.  mov ebx,127*65536+85
  298.  mov ecx,33*65536+33
  299.  mov edx,0x00AAAAAA
  300.  int 0x40
  301.  
  302.  mov eax,4 ; Draw filenames
  303.  mov ebx,134*65536+36
  304.  mov edx,cmfile
  305.  xor ecx,ecx
  306.  mov esi,12
  307.  cmp byte [editstate],1
  308.  jnz no_active_1
  309.  mov ecx,activecolor
  310.  no_active_1:
  311.  int 0x40
  312.  xor ecx,ecx
  313.  cmp byte [editstate],2
  314.  jnz no_active_2
  315.  mov ecx,activecolor
  316.  no_active_2:
  317.  add ebx,18
  318.  add edx,12
  319.  int 0x40
  320.  
  321.  mov eax,13             ; Clean info area
  322.  mov ebx,14*65536+210
  323.  mov ecx,107*65536+14
  324.  mov edx,0x00AAAAAA
  325.  int 0x40
  326.  
  327.  cmp byte [msgid],0     ; Draw info string
  328.  jz notype
  329.  mov ebx,16*65536+110
  330.  xor ecx,ecx
  331.  mov esi,16
  332.  mov al, byte [msgid]
  333.  dec al
  334.  shl al,4
  335.  xor ah,ah
  336.  xor edx,edx
  337.  mov dx,ax
  338.  add edx,msgtable
  339.  mov eax,4
  340.  int 0x40
  341.  notype:
  342.  
  343.  popa ; Restore registers
  344.  
  345.  ret
  346.  
  347.  ; interface data
  348.  
  349.  keylab db "    COMPRESS         DECOMPRESS"
  350.  dellab db "   DELETE I/O       DELETE *.MHC"
  351.  title  db "MHC 0.09"
  352.  arclab db "COMPRESSED FILE:"
  353.  unplab db "INPUT/OUTPUT FILE:"
  354.  fin_text:
  355.  
  356.  cmfile db "FILENAME.MHC"
  357.  iofile db "FILENAME.XYZ"
  358.  
  359.  editstate db 0
  360.  editpos db 0
  361.  msgid db 0
  362.  
  363.  msgtable:
  364.  db "COMPRESSING...  "
  365.  db "DECOMPRESSING..."
  366.  db "I/O NOT FOUND!  "
  367.  db "*.MHC NOT FOUND!"
  368.  db "INVALID METHOD! "
  369.  
  370. ; ======== compression/decompression engine ========
  371.  
  372. ; Adresses declaration
  373.  
  374.  hashtable equ  MHC_END
  375.  ifile     equ  hashtable+65536*4
  376.  ofile     equ  ifile+1000000
  377.  
  378.  compress:   ; File compression
  379.  
  380.  call fill_filebufs
  381.  
  382.  mov eax,6
  383.  mov ebx,iofile
  384.  xor ecx,ecx
  385.  mov edx,ecx
  386.  not edx
  387.  mov esi,ifile
  388.  int 0x40
  389.  
  390.  cmp eax,0xFFFFFFFF
  391.  jnz  compress_filefound              ; i/o file not found
  392.  mov byte [msgid],3
  393.  call draw_info
  394.  ret
  395.  
  396.  compress_filefound:
  397.  
  398.  mov byte [msgid],1
  399.  call draw_info
  400.  
  401.  jmp lzp_compress                    ; compress with order-2 LZP
  402.  compress_dumpdata:
  403.  
  404.  push edx
  405.  
  406.  mov eax,32
  407.  mov ebx,cmfile
  408.  int 0x40
  409.  
  410.  mov eax,33
  411.  pop edx
  412.  mov ebx,cmfile
  413.  mov ecx,ofile
  414.  xor esi,esi
  415.  int 0x40
  416.  
  417.  mov byte [msgid],0
  418.  call draw_info
  419.  
  420.  ret
  421.  
  422.  
  423.  decompress: ; File decompression
  424.  
  425.  call fill_filebufs
  426.  
  427.  mov  eax,6
  428.  mov ebx,cmfile
  429.  xor ecx,ecx
  430.  mov edx,ecx
  431.  not edx
  432.  mov esi,ofile
  433.  int 0x40
  434.  
  435.  cmp eax,0xFFFFFFFF
  436.  jnz  decompress_filefound              ; *.mhc file not found
  437.  mov byte [msgid],4
  438.  call draw_info
  439.  ret
  440.  
  441.  decompress_filefound:
  442.  
  443.  cmp byte [ofile],0                     ; Invalid method!
  444.  jz  right_method
  445.  mov byte [msgid],5
  446.  call draw_info
  447.  ret
  448.  
  449.  right_method:
  450.  mov byte [msgid],2
  451.  call draw_info
  452.  
  453.  jmp lzp_decompress
  454.  decompress_dumpdata:
  455.  
  456.  push edx
  457.  
  458.  mov eax,32
  459.  mov ebx,iofile
  460.  int 0x40
  461.  
  462.  mov eax,33
  463.  pop edx
  464.  mov ebx,iofile
  465.  mov ecx,ifile
  466.  xor esi,esi
  467.  int 0x40
  468.  
  469.  mov byte [msgid],0
  470.  call draw_info
  471.  
  472.  ret
  473.  
  474.  fill_filebufs:             ; Fill filebufs with garbage to simplify matching
  475.  pusha
  476.  cld
  477.  mov eax,0xF7D9A03F         ; <- "magic number" :) just garbage...
  478.  mov ecx,2000000/4
  479.  mov edi,ifile
  480.  rep stosd
  481.  popa
  482.  ret
  483.  
  484. ; ==== algorithms section ====
  485.  
  486. ; Method 0: LZP compression algorithm
  487.  
  488.  lzp_compress:           ; EDX - how much bytes to dump
  489.  
  490.  cld                     ; clear direction flag
  491.  
  492.  mov esi,ifile           ; init pointers
  493.  mov edi,ofile
  494.  
  495.  push eax                ; write header: ID0+4bfilesize => total 5 bytes
  496.  xor eax,eax
  497.  stosb
  498.  pop eax
  499.  stosd
  500.  
  501.  pusha                   ; fill hash table
  502.  mov eax,ifile
  503.  mov edi,hashtable
  504.  mov ecx,65536
  505.  rep stosd
  506.  popa
  507.  
  508.  add eax,esi              ; calculate endpointer
  509.  mov dword [endpointer],eax
  510.  
  511.  movsw                    ; copy three bytes
  512.  movsb
  513.  
  514.  mov dword [controlp],edi
  515.  inc edi
  516.  
  517.  mov byte [controld],0
  518.  mov byte [controlb],0
  519.  
  520.  c_loop:
  521.  cmp dword [endpointer],esi  ; check end of file
  522.  ja  c_loop_ok
  523.  jmp finish_c_loop
  524.  c_loop_ok:
  525.  
  526.  call chash
  527.  call compare
  528.  jz   two_match_c
  529.  
  530.  lodsb
  531.  mov byte [literal],al
  532.  call chash
  533.  call compare
  534.  jz   lit_match_c
  535.  
  536.  mov  al,0
  537.  call putbit
  538.  mov  al,byte [literal]
  539.  stosb
  540.  movsb
  541.  jmp  end_c_loop
  542.  
  543.  lit_match_c:
  544.  mov al,1
  545.  call putbit
  546.  mov al,0
  547.  call putbit
  548.  mov al,byte [literal]
  549.  stosb
  550.  jmp encode_match
  551.  
  552.  two_match_c:
  553.  mov al,1
  554.  call putbit
  555.  call putbit
  556.  
  557.  encode_match:
  558.  call incpos
  559.  call compare
  560.  jz one_c
  561.  mov al,0
  562.  call putbit
  563.  jmp end_c_loop
  564.  one_c:
  565.  
  566.  call incpos
  567.  mov  al,1
  568.  call putbit
  569.  
  570.  call compare
  571.  jnz ec1
  572.  call incpos
  573.  call compare
  574.  jnz ec2
  575.  call incpos
  576.  call compare
  577.  jnz ec3
  578.  call incpos
  579.  mov al,1
  580.  call putbit
  581.  call putbit
  582.  call compare
  583.  jnz ec4
  584.  call incpos
  585.  call compare
  586.  jnz ec5
  587.  call incpos
  588.  call compare
  589.  jnz ec6
  590.  call incpos
  591.  call compare
  592.  jnz ec7
  593.  call incpos
  594.  call compare
  595.  jnz ec8
  596.  call incpos
  597.  call compare
  598.  jnz ec9
  599.  call incpos
  600.  call compare
  601.  jnz ec10
  602.  call incpos
  603.  
  604.  mov al,1
  605.  call putbit
  606.  call putbit
  607.  call putbit
  608.  xor  ecx,ecx
  609.  
  610.  match_loop_c:
  611.  cmp  esi,dword [endpointer]
  612.  jae   out_match_loop_c
  613.  call compare
  614.  jnz  out_match_loop_c
  615.  inc  ecx
  616.  call incpos
  617.  jmp  match_loop_c
  618.  out_match_loop_c:
  619.  
  620.  mov al,0xFF
  621.  out_lg:
  622.  cmp ecx,255
  623.  jb  out_lg_out
  624.  stosb
  625.  sub ecx,255
  626.  jmp out_lg
  627.  out_lg_out:
  628.  mov al,cl
  629.  stosb
  630.  jmp end_c_loop
  631.  
  632.  ec10:
  633.  mov al,1
  634.  call putbit
  635.  call putbit
  636.  mov al,0
  637.  call putbit
  638.  jmp end_c_loop
  639.  
  640.  ec9:
  641.  mov al,1
  642.  call putbit
  643.  mov al,0
  644.  call putbit
  645.  mov al,1
  646.  call putbit
  647.  jmp end_c_loop
  648.  
  649.  ec8:
  650.  mov al,1
  651.  call putbit
  652.  mov al,0
  653.  call putbit
  654.  call putbit
  655.  jmp end_c_loop
  656.  
  657.  ec7:
  658.  mov al,0
  659.  call putbit
  660.  mov al,1
  661.  call putbit
  662.  call putbit
  663.  jmp end_c_loop
  664.  
  665.  ec6:
  666.  mov al,0
  667.  call putbit
  668.  mov al,1
  669.  call putbit
  670.  mov al,0
  671.  call putbit
  672.  jmp end_c_loop
  673.  
  674.  ec5:
  675.  mov al,0
  676.  call putbit
  677.  call putbit
  678.  mov al,1
  679.  call putbit
  680.  jmp end_c_loop
  681.  
  682.  ec4:
  683.  mov al,0
  684.  call putbit
  685.  call putbit
  686.  call putbit
  687.  jmp end_c_loop
  688.  
  689.  ec3:
  690.  mov al,1
  691.  call putbit
  692.  mov al,0
  693.  call putbit
  694.  jmp end_c_loop
  695.  
  696.  ec2:
  697.  mov al,0
  698.  call putbit
  699.  mov al,1
  700.  call putbit
  701.  jmp end_c_loop
  702.  
  703.  ec1:
  704.  mov al,0
  705.  call putbit
  706.  call putbit
  707.  
  708.  end_c_loop:
  709.  jmp c_loop
  710.  
  711.  finish_c_loop:
  712.  
  713.  mov eax,dword [controlp] ; store last tagbyte
  714.  mov bl,byte [controld]
  715.  mov [eax], byte bl
  716.  
  717.  sub edi,ofile ; calculate dump size
  718.  mov edx,edi
  719.  
  720.  jmp compress_dumpdata
  721.  
  722. ; LZP decompression algorithm
  723.  
  724.  lzp_decompress:                        ; EDX - how much bytes to dump
  725.  
  726.  cld
  727.  
  728.  mov edi,ifile
  729.  mov esi,ofile+1
  730.  
  731.  pusha                   ; fill hash table
  732.  mov eax,ifile
  733.  mov edi,hashtable
  734.  mov ecx,65536
  735.  rep stosd
  736.  popa
  737.  
  738.  lodsd
  739.  
  740.  mov ebx,edi
  741.  add ebx,eax
  742.  mov dword [endpointer],ebx
  743.  
  744.  movsw
  745.  movsb
  746.  
  747.  lodsb
  748.  mov byte [controld],al
  749.  mov byte [controlb],0
  750.  
  751.  d_loop:
  752.  cmp dword [endpointer],edi
  753.  ja d_loop_ok
  754.  jmp finish_d_loop
  755.  d_loop_ok:
  756.  
  757.  call getbit
  758.  cmp  al,0
  759.  jnz  match_d
  760.  call dhash
  761.  movsb
  762.  call dhash
  763.  movsb
  764.  jmp end_d_loop
  765.  
  766.  match_d:
  767.  
  768.  call getbit
  769.  cmp  al,0
  770.  jnz  no_literal_before_match
  771.  call dhash
  772.  movsb
  773.  no_literal_before_match:
  774.  
  775.  call dhash
  776.  mov ecx,1
  777.  call copymatch
  778.  
  779.  call getbit
  780.  cmp  al,0
  781.  jz   end_d_loop
  782.  mov  ecx,1
  783.  call copymatch
  784.  call getbit
  785.  cmp  al,0
  786.  jz   dc2
  787.  mov  ecx,2
  788.  call copymatch
  789.  call getbit
  790.  cmp  al,0
  791.  jz   end_d_loop
  792.  mov  ecx,1
  793.  call copymatch
  794.  call getbit
  795.  cmp  al,0
  796.  jz   dc4
  797.  mov  ecx,4
  798.  call copymatch
  799.  call getbit
  800.  cmp  al,0
  801.  jz   dc5
  802.  call getbit
  803.  cmp  al,0
  804.  jz   dc6
  805.  mov  ecx,3
  806.  call copymatch
  807.  
  808.  do:
  809.  lodsb
  810.  xor  ecx,ecx
  811.  mov  cl,al
  812.  call copymatch
  813.  cmp  al,0xFF
  814.  jnz  end_do
  815.  jmp do
  816.  end_do:
  817.  jmp end_d_loop
  818.  
  819.  dc6:
  820.  mov ecx,2
  821.  call copymatch
  822.  jmp  end_d_loop
  823.  
  824.  dc5:
  825.  call getbit
  826.  cmp  al,0
  827.  jz   ndc5
  828.  mov  ecx,1
  829.  call copymatch
  830.  ndc5:
  831.  jmp  end_d_loop
  832.  
  833.  dc4:
  834.  call getbit
  835.  cmp  al,0
  836.  jz   ndc4
  837.  call getbit
  838.  mov  ecx,3
  839.  cmp  al,1
  840.  jz   ndcc4
  841.  dec  ecx
  842.  ndcc4:
  843.  call copymatch
  844.  jmp  end_d_loop
  845.  ndc4:
  846.  call getbit
  847.  cmp  al,0
  848.  jz   ndccc4
  849.  mov  ecx,1
  850.  call copymatch
  851.  ndccc4:
  852.  jmp  end_d_loop
  853.  
  854.  dc2:
  855.  call getbit
  856.  cmp al,0
  857.  jz  ndc2
  858.  mov ecx,1
  859.  call copymatch
  860.  ndc2:
  861.  
  862.  end_d_loop:
  863.  jmp d_loop
  864.  finish_d_loop:
  865.  
  866.  mov edx, dword [ofile+1]
  867.  
  868.  jmp decompress_dumpdata
  869.  
  870. ; LZP subroutines
  871.  
  872.  putbit:                  ; bit -> byte tag, AL holds bit for output
  873.  pusha
  874.  mov cl,byte [controlb]
  875.  shl al,cl
  876.  mov bl,byte [controld]
  877.  or  bl,al
  878.  mov byte [controld],bl
  879.  inc cl
  880.  cmp cl,8
  881.  jnz just_increment
  882.  mov byte [controlb],0
  883.  mov byte [controld],0
  884.  push edi
  885.  mov  edi, dword [controlp]
  886.  mov  al,bl
  887.  stosb
  888.  pop  edi
  889.  mov dword [controlp],edi
  890.  popa
  891.  inc edi
  892.  ret
  893.  just_increment:
  894.  mov byte [controlb],cl
  895.  popa
  896.  ret
  897.  
  898.  getbit:                       ; tag byte -> bit, AL holds input
  899.  push ecx
  900.  mov al,byte [controld]
  901.  mov cl,byte [controlb]
  902.  shr al,cl
  903.  and al,1
  904.  inc cl
  905.  cmp cl,8
  906.  jnz just_increment_d
  907.  mov byte [controlb],0
  908.  push eax
  909.  lodsb
  910.  mov byte [controld],al
  911.  pop  eax
  912.  pop  ecx
  913.  ret
  914.  just_increment_d:
  915.  mov byte [controlb],cl
  916.  pop ecx
  917.  ret
  918.  
  919.  chash:                        ; calculate hash -> mp -> fill position
  920.  pusha
  921.  xor  eax,eax
  922.  mov  al, byte [esi-1]
  923.  mov  ah, byte [esi-2]
  924.  shl  eax,2
  925.  add  eax,hashtable
  926.  mov  edx,dword [eax]
  927.  mov  dword [mp],edx
  928.  mov  dword [eax],esi
  929.  popa
  930.  ret
  931.  
  932.  dhash:                        ; calculate hash -> mp -> fill position
  933.  pusha
  934.  xor  eax,eax
  935.  mov  al, byte [edi-1]
  936.  mov  ah, byte [edi-2]
  937.  shl  eax,2
  938.  add  eax,hashtable
  939.  mov  edx,dword [eax]
  940.  mov  dword [mp],edx
  941.  mov  dword [eax],edi
  942.  popa
  943.  ret
  944.  
  945.  copymatch:                    ; ECX bytes from [mp] to [rp]
  946.  push esi
  947.  mov  esi,dword [mp]
  948.  rep  movsb
  949.  mov  dword [mp],esi
  950.  pop  esi
  951.  ret
  952.  
  953.  compare:                      ; compare [mp] with [cpos]
  954.  push edi
  955.  push esi
  956.  mov  edi,dword [mp]
  957.  cmpsb
  958.  pop  esi
  959.  pop  edi
  960.  ret
  961.  
  962.  incpos:
  963.  inc  dword [mp]
  964.  inc  esi
  965.  ret
  966.  
  967.  
  968. ; LZP algorithm data
  969.  
  970.  endpointer     dd      0
  971.  controlp       dd      0
  972.  controlb       db      0
  973.  controld       db      0
  974.  mp  dd 0
  975.  literal        db      0
  976.  
  977. MHC_END: ; the end... - Nikita Lesnikov (nlo_one)
  978.