zcomp.z80 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. zcomp:
  2. ld (zcomp_input_base),hl
  3. ld (zcomp_input_size),bc
  4. push de
  5. ;initialize the frequency table
  6. ld hl,zcomp_freq_table
  7. ld bc,0
  8. _:
  9. ld (hl),c
  10. inc hl
  11. ld (hl),c
  12. inc hl
  13. ld (hl),b
  14. inc hl
  15. inc b
  16. jr nz,-_
  17. ;Now count the frequencies
  18. ld hl,(zcomp_input_base)
  19. ld bc,(zcomp_input_size)
  20. zcomp_freq_loop:
  21. push hl
  22. push bc
  23. ld b,0
  24. ld c,(hl)
  25. ld hl,zcomp_freq_table
  26. add hl,bc
  27. add hl,bc
  28. add hl,bc
  29. inc (hl)
  30. jr nz,$+4
  31. inc hl
  32. inc (hl)
  33. pop bc
  34. pop hl
  35. cpi
  36. jp pe,zcomp_freq_loop
  37. ;Now sort by frequency
  38. ld ix,zcomp_sort
  39. ld bc,256
  40. call heapsort
  41. ;Count the number of unique bytes
  42. ld c,0
  43. ld hl,zcomp_freq_table+766
  44. _:
  45. ld a,(hl)
  46. dec hl
  47. or (hl)
  48. jr z,+_
  49. dec hl
  50. dec hl
  51. inc c
  52. jr nz,-_
  53. _:
  54. ld a,c
  55. ld (zcomp_table_len),a
  56. ;count the size of the first partition
  57. ld hl,(zcomp_freq_table+765)
  58. ld (zcomp_part0_size),hl
  59. ex de,hl
  60. ld hl,(zcomp_input_size)
  61. ;or a
  62. sbc hl,de
  63. ld (zcomp_part1_size),hl
  64. ;Set up the partitions
  65. ld hl,-1
  66. ld (zcomp_best_size),hl
  67. ld (zcomp_best_size+1),hl
  68. ld a,1
  69. ld (zcomp_partition_len),a
  70. ld hl,zcomp_freq_table+765
  71. push hl
  72. partition_loop:
  73. call zcomp_getsize
  74. ld a,(zcomp_partition_len)
  75. ld b,a
  76. add a,a
  77. ld (zcomp_partition_len),a
  78. ld hl,(zcomp_best_size)
  79. ld a,(zcomp_best_size+2)
  80. ;or a
  81. sbc hl,de
  82. sbc a,c
  83. jr c,zcomp_partition_found
  84. or h
  85. or l
  86. jr z,zcomp_partition_found
  87. ld a,c
  88. ld (zcomp_best_size),de
  89. ld (zcomp_best_size+2),a
  90. ex (sp),hl
  91. push bc
  92. _:
  93. push bc
  94. dec hl
  95. dec hl
  96. ld b,(hl)
  97. dec hl
  98. ld c,(hl)
  99. push hl
  100. ld hl,(zcomp_part0_size)
  101. add hl,bc
  102. ld (zcomp_part0_size),hl
  103. ld hl,(zcomp_part1_size)
  104. ;or a
  105. sbc hl,bc
  106. ld (zcomp_part1_size),hl
  107. pop hl
  108. pop bc
  109. djnz -_
  110. pop af
  111. ex (sp),hl
  112. ;check if 2a<zcomp_table_len
  113. add a,a
  114. jr c,zcomp_partition_found
  115. ld hl,zcomp_table_len
  116. sub (hl)
  117. jr c,partition_loop
  118. zcomp_partition_found:
  119. pop hl
  120. pop hl
  121. ;Now we write the key to the output
  122. ;first is the size of the key
  123. ld a,(zcomp_table_len)
  124. ld b,a
  125. ld (hl),a
  126. inc hl
  127. ;next is the size of the first partition
  128. ld a,(zcomp_partition_len)
  129. rrca
  130. ld (hl),a
  131. push hl
  132. inc hl
  133. ;Now we write the actual key
  134. ld de,zcomp_freq_table+767
  135. _:
  136. ld a,(de)
  137. ld (hl),a
  138. inc hl
  139. dec de
  140. dec de
  141. dec de
  142. djnz -_
  143. ;Before we continue, let's make an LUT to map each byte to its code
  144. pop hl
  145. ld a,(hl)
  146. inc hl
  147. push af
  148. ld b,a
  149. ld c,0
  150. dec a
  151. jr z,+_
  152. inc c
  153. srl a
  154. jr nz,$-3
  155. _:
  156. sla c
  157. ld d,zcomp_keymap>>8
  158. zcomp_keymap_loop_0:
  159. ld e,(hl)
  160. inc hl
  161. ex de,hl
  162. ld (hl),c
  163. inc h
  164. ld (hl),a
  165. dec h
  166. ex de,hl
  167. inc a
  168. djnz zcomp_keymap_loop_0
  169. pop bc ;B is the size of the first partition
  170. ld a,(zcomp_table_len)
  171. sub b
  172. ld b,a
  173. ld c,0
  174. dec a
  175. jr z,+_
  176. inc c
  177. srl a
  178. jr nz,$-3
  179. _:
  180. sla c
  181. inc c
  182. zcomp_keymap_loop_1:
  183. ld e,(hl)
  184. inc hl
  185. ex de,hl
  186. ld (hl),c
  187. inc h
  188. ld (hl),a
  189. dec h
  190. ex de,hl
  191. inc a
  192. djnz zcomp_keymap_loop_1
  193. ;Write the size of the uncompressed data
  194. ld bc,(zcomp_input_size)
  195. ld (hl),c
  196. inc hl
  197. ld (hl),b
  198. inc hl
  199. ;Now start compressing and writing out the data
  200. ld de,(zcomp_input_base)
  201. ld (hl),1
  202. zcomp_output_loop:
  203. ld a,(de)
  204. inc de
  205. push de
  206. push bc
  207. ld d,zcomp_keymap>>8
  208. ld e,a
  209. ld a,(de)
  210. srl a
  211. rl (hl)
  212. jr nc,+_
  213. inc hl
  214. ld (hl),1
  215. _:
  216. ;A is the number of bits in the code
  217. or a
  218. jr z,zcomp_output_loop_end
  219. inc d
  220. ld b,a
  221. ld a,8
  222. sub b
  223. ld c,a
  224. ld a,(de)
  225. jr z,+_
  226. add a,a
  227. dec c
  228. jr nz,$-2
  229. _:
  230. add a,a
  231. rl (hl)
  232. jr nc,$+5
  233. inc hl
  234. ld (hl),1
  235. djnz -_
  236. zcomp_output_loop_end:
  237. pop bc
  238. pop de
  239. dec bc
  240. ld a,b
  241. or c
  242. jr nz,zcomp_output_loop
  243. _:
  244. sla (hl)
  245. jr nc,-_
  246. inc hl
  247. ex de,hl
  248. ret
  249. zcomp_getsize:
  250. ;zcomp_part0_size*log2(zcomp_partition_len);+zcomp_part1_size*log2(zcomp_table_len-zcomp_partition_len)
  251. ld a,(zcomp_partition_len)
  252. ld b,a
  253. ld c,a
  254. xor a
  255. ld h,a
  256. ld l,a
  257. ld de,(zcomp_part0_size)
  258. _:
  259. add hl,de
  260. adc a,0
  261. srl b
  262. jr nz,-_
  263. ld b,a
  264. inc b
  265. ld a,(zcomp_table_len)
  266. sub c
  267. ld c,a
  268. ld a,b
  269. ld de,(zcomp_part1_size)
  270. _:
  271. add hl,de
  272. adc a,0
  273. srl c
  274. jr nz,-_
  275. add hl,de
  276. adc a,c
  277. ex de,hl
  278. ld c,a
  279. ret
  280. zcomp_sort:
  281. rla
  282. ex de,hl
  283. ld hl,zcomp_freq_table
  284. add hl,de
  285. add hl,de
  286. add hl,de
  287. ;HL points to the first element
  288. ex de,hl
  289. ld hl,zcomp_freq_table
  290. add hl,bc
  291. add hl,bc
  292. add hl,bc
  293. rra
  294. jr c,zcomp_sort_swap
  295. zcomp_sort_cmp:
  296. ;compare the element at DE to the element at HL
  297. inc hl
  298. inc de
  299. ld a,(de)
  300. cp (hl)
  301. ret nz
  302. dec hl
  303. dec de
  304. ld a,(de)
  305. cp (hl)
  306. ret
  307. zcomp_sort_swap:
  308. ;swap the 3 bytes at HL with the 3 bytes at DE
  309. ld a,(de)
  310. ldi
  311. dec hl
  312. ld (hl),a
  313. inc hl
  314. ld a,(de)
  315. ldi
  316. dec hl
  317. ld (hl),a
  318. inc hl
  319. ld a,(de)
  320. ldi
  321. dec hl
  322. ld (hl),a
  323. ret