Advertisement
Zeda

zlz_comp

Jan 22nd, 2020
1,455
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. saveSScreen = 86ECh
  2. #define zlz_vars saveSScreen
  3. #define ZLZ_MIN_RUN 4
  4.  
  5. zlz_base      = zlz_vars
  6. zlz_runstart  = zlz_vars+2
  7. zlz_match_base= zlz_vars+4
  8. zlz_match_size= zlz_vars+6
  9. zlz_top       = zlz_vars+8
  10. zlz_match_loc = zlz_vars+10
  11. zlz_head      = zlz_vars+12
  12.  
  13. zlz_comp:
  14. ;Inputs:
  15. ;   HL points to the input data
  16. ;   DE points to the output
  17. ;   BC is the size of the input
  18. ;Outputs:
  19. ;   HL points to the byte after the input
  20. ;   DE points to the byte afterthe compressed data
  21. ;   BC is 0
  22. ;Destroys:
  23. ;   AF,IX
  24. ;
  25. ;This routine has input and output like LDIR,
  26. ;except if LDIR as compressing as it goes.
  27. ;
  28.   ld a,ZLZ_MIN_RUN
  29.   inc b
  30.   dec b
  31.   jr nz,+_
  32.   cp c
  33.   jr z,$+4
  34.   jr c,+_
  35.   ld a,c
  36.   ld (de),a
  37.   inc de
  38.   inc c
  39.   dec c
  40.   ret z
  41.   ldir
  42.   ret
  43. _:
  44.   ld (zlz_base),hl
  45.   ld (zlz_runstart),hl
  46.   add a,l
  47.   ld l,a
  48.   jr nc,$+3
  49.   inc h
  50.  
  51.   ld a,c
  52.   sub ZLZ_MIN_RUN
  53.   ld c,a
  54.   jr nc,$+3
  55.   dec b
  56.  
  57. zlz_comp_loop:
  58.   push bc
  59.   ld (zlz_head),hl
  60.   call zlz_findmatch
  61.   inc b
  62.   dec b
  63.   jr nz,zlz_matched
  64.   ld a,c
  65.   cp ZLZ_MIN_RUN
  66.   jr nc,zlz_matched
  67.   ld hl,(zlz_head)
  68.   pop bc
  69.   cpi
  70.   jp pe,zlz_comp_loop
  71.  
  72. zlz_write_run:
  73. ;need to write the run from (zlz_head), size HL-(zlz_head)
  74.   push hl
  75.   push bc
  76.   ld hl,(zlz_head)
  77.   ld bc,(zlz_runstart)
  78.   or a
  79.   sbc hl,bc
  80.   jr z,zlz_write_run_done
  81.   ld b,h
  82.   ld c,l
  83.  
  84.   ld a,l
  85.   add a,a \ rl h
  86.   add a,a \ rl h
  87.   jr z,+_
  88.   scf
  89. _:
  90.   rra
  91.   rra
  92.   ld (de),a
  93.   inc de
  94.   jr z,+_
  95.   ld a,h
  96.   ld (de),a
  97.   inc de
  98. _:
  99.   ld hl,(zlz_runstart)
  100.   ldir
  101. zlz_write_run_done:
  102.   pop bc
  103.   pop hl
  104.   ld (zlz_runstart),hl
  105.   ret
  106.  
  107.  
  108. zlz_matched:
  109.   push bc
  110.   call zlz_write_run
  111.   pop bc
  112.   push bc
  113.  
  114. ;size then pointer
  115. ;Make sure the size doesn't exceed 13 bits
  116.   ld a,c
  117.   add a,a \ rl b
  118.   add a,a \ rl b
  119.   jr z,+_
  120.   scf
  121. _:
  122.   rra
  123.   scf
  124.   rra
  125.   ld (de),a
  126.   inc de
  127.   jr z,+_
  128.   ld a,b
  129.   ld (de),a
  130.   inc de
  131. _:
  132.  
  133. ;Now we need to write the pointer
  134. ;this is an offset back from the data
  135. ;we want (zlz_head)-HL
  136.   ld b,h
  137.   ld c,l
  138.   ld hl,(zlz_head)
  139.   ;or a   ;the rra above will reset the carry since the bottom bit of A was 0
  140.   sbc hl,bc
  141.   ld a,l
  142.   add a,a \ rl h
  143.   jr z,+_
  144.   scf
  145. _:
  146.   rra
  147.   ld (de),a
  148.   inc de
  149.   jr z,+_
  150.   ld a,h
  151.   ld (de),a
  152.   inc de
  153. _:
  154.  
  155.   pop bc
  156.   ld hl,(zlz_head)
  157.   add hl,bc
  158.   ex (sp),hl
  159.   ;or a
  160.   sbc hl,bc
  161.   ld b,h
  162.   ld c,l
  163.   pop hl
  164.   ld (zlz_runstart),hl
  165.   jp nz,zlz_comp_loop
  166.   ret
  167.  
  168. zlz_findmatch:
  169.   push de
  170.   ld (zlz_match_base),hl
  171.   add hl,bc
  172.   ld (zlz_top),hl
  173.   sbc hl,bc
  174.   ld de,(zlz_base)
  175.   xor a
  176.   ld (zlz_match_size),a
  177.   ld (zlz_match_size+1),a
  178.   sbc hl,de
  179.   ld bc,1-ZLZ_MIN_RUN
  180.   add hl,bc
  181.   ld b,h
  182.   ld c,l
  183.   ex de,hl
  184.   jr zlz_findmatch_loop_begin
  185. zlz_findmatch_loop:
  186.   push hl
  187.   push bc
  188.   call +_
  189.   pop bc
  190.   pop hl
  191. zlz_findmatch_loop_begin:
  192. ;DE points to the data to find
  193. ;HL points to the data to search
  194. ;BC is the size of the data to search
  195.   ld de,(zlz_match_base)
  196.   ld a,(de)
  197.   cpir
  198.   jp pe,zlz_findmatch_loop
  199. zlz_findmatch_done:
  200.   ld bc,(zlz_match_size)
  201.   ld hl,(zlz_match_loc)
  202.   pop de
  203.   ret
  204. _:
  205. ;now we compare the rest of the string
  206.   push hl
  207.   inc de
  208.   ld hl,(zlz_top)
  209.   or a
  210.   sbc hl,de
  211.   ld b,h
  212.   ld c,l
  213.   pop hl
  214.   jr z,zlz_match_complete
  215.   push hl
  216. _:
  217.   ld a,(de)
  218.   inc de
  219.   cpi
  220.   jp po,+_
  221.   jr z,-_
  222. _:
  223.   ld hl,(zlz_match_base)
  224.   ex de,hl
  225.   ;or a
  226.   sbc hl,de
  227.   ld bc,(zlz_match_size)
  228.   ;if HL>=BC, save the new match (if it is the same size as the previous match, then this one is closer, which can be better)
  229.   scf
  230.   sbc hl,bc
  231.   pop de
  232.   ret c
  233.   add hl,bc
  234.   ld (zlz_match_size),hl
  235.   dec de
  236.   ld (zlz_match_loc),de
  237.   ret
  238.  
  239.  
  240. zlz_match_complete:
  241. ;can't get better than this, so we'll exit early
  242.   ld hl,(zlz_match_base)
  243.   ex de,hl
  244.   ;or a
  245.   sbc hl,de
  246.   ld b,h
  247.   ld c,l
  248.   pop af  ;return address
  249.   pop af  ;size left
  250.   pop hl  ;pointer to match
  251.   pop de  ;saved DE
  252.   ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement