APACK2.A 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. (*
  2. Copyright (C) 1989,1990 Jensen & Partners International
  3. *)
  4. module apack2
  5. stats? = 0 (* count hash collisions and table resets *)
  6. reset? = 1 (* possible values are 0,1 *)
  7. ebit = 3 (* possible values are 0,1,3 *)
  8. buf_size = 3800H
  9. shift2 = ebit & 1
  10. shift4 = ( ebit & 2 ) / 2
  11. period = 8 / (ebit+1)
  12. max_hash = power2 (ebit+10 ) - 1
  13. max_code = power2 (ebit+9 ) - 1
  14. re_hash = 113
  15. segment APACK2_DATA(FAR_DATA,28H)
  16. public apack2@prfx: org 2*(max_hash+1) + 4 (* must be at 0 in actual segment !! *)
  17. prfx = 0
  18. public apack2@reset_count: org 2
  19. public apack2@collision_count : org 2
  20. public lim: org 2 (* limit for si *)
  21. public apack2@p: org (buf_size/8) * ( 9 + ebit )
  22. public char: org max_hash+1 + 2
  23. public code: org 2*(max_hash+1) + 4
  24. segment APACK2_TEXT( CODE, 28H )
  25. ClearTable:
  26. push ax; push cx; push di; push es
  27. push ds; pop es
  28. mov di, prfx
  29. mov cx, max_hash+1
  30. mov ax, -1
  31. rep; stosw
  32. pop es; pop di; pop cx; pop ax
  33. ret 0
  34. public apack2$Pack: in = 6 ; n = 10
  35. (* Current register usage:
  36. al : input char
  37. ah : zero
  38. bx : hash table index
  39. cl : free bit count for ch
  40. ch : holds extra bits
  41. dx : current code or 256+number of codes output since reset
  42. es:si : input pointer
  43. ds:di : output pointer
  44. *)
  45. push bp
  46. mov bp, sp
  47. push si; push di; push ds; push es
  48. mov ax, APACK2_DATA
  49. mov ds, ax
  50. (*%T stats?*)
  51. mov word [apack2@reset_count], 0
  52. mov word [apack2@collision_count],0
  53. (*%E*)
  54. call ClearTable
  55. les si, [bp][in]
  56. mov dx, si
  57. add dx,[bp][n]
  58. mov [lim],dx
  59. db 26H; lodsb
  60. sub ah,ah
  61. mov dx,ax
  62. mov word bp, 256
  63. mov di, apack2@p+1
  64. mov ch,0
  65. mov cl,period
  66. jmp loop1
  67. shift_zero:
  68. mov [di][-(period+1)], ch
  69. inc di
  70. mov cx,period
  71. (*%F reset?*)
  72. cmp bp, max_code
  73. jne shift_zero_done
  74. mov bp,[lim]
  75. jmp near _output_done
  76. (*%E*)
  77. (*%T reset?*)
  78. jmp shift_zero_done
  79. (*%E*)
  80. (*%T reset?*)
  81. clear:
  82. (*%T stats?*) inc word [apack2@reset_count] (*%E*)
  83. call ClearTable
  84. mov bp, 256
  85. jmp output_done
  86. (*%E*)
  87. else1:
  88. (*%T stats?*) inc word [apack2@collision_count] (*%E*)
  89. shl bx, 1
  90. add bx, re_hash*2
  91. jmp loop2
  92. exit1x:
  93. jmp near exit1
  94. match:
  95. shr bx,1
  96. cmp[char][bx], al
  97. jne else1
  98. shl bx,1
  99. mov dx, [code][bx]
  100. (*jmp loop1*) (*unrolled once*)
  101. cmp si,[lim]
  102. je exit1x
  103. db 26H; lodsb
  104. mov bx,dx
  105. add bl,al
  106. add bh,al
  107. (*loop2:*)
  108. and bx, max_hash*2
  109. cmp [prfx][bx], dx
  110. je match
  111. cmp word [prfx][bx],-1
  112. jne collide
  113. output:
  114. shl ch,1
  115. (*%T shift2*) shl ch,1 (*%E*)
  116. (*%T shift4*) shl ch,1 (*%E*)
  117. (*%T shift4*) shl ch,1 (*%E*)
  118. add ch, dh
  119. mov [di], dl
  120. inc di
  121. dec cl
  122. jz shift_zero
  123. shift_zero_done:
  124. mov [prfx][bx],dx
  125. mov [code][bx],bp
  126. shr bx,1
  127. mov [char][bx],al
  128. inc bp
  129. (*%T reset?*)
  130. cmp bp, max_code+1
  131. je clear
  132. (*%E*)
  133. output_done:
  134. mov dx,ax
  135. loop1:
  136. cmp si,[lim]
  137. je exit1
  138. db 26H; lodsb
  139. mov bx,dx
  140. add bl,al
  141. add bh,al
  142. loop2:
  143. and bx, max_hash*2
  144. cmp word [prfx][bx],-1
  145. je output
  146. cmp [prfx][bx], dx
  147. je match
  148. collide:
  149. (*%T stats?*) inc word [apack2@collision_count] (*%E*)
  150. add bx, re_hash*2
  151. (*jmp loop2*) (*unroll 1*)
  152. and bh, max_hash / 128
  153. cmp word [prfx][bx],-1
  154. je output
  155. cmp [prfx][bx], dx
  156. je match
  157. (*%T stats?*) inc word [apack2@collision_count] (*%E*)
  158. add bx, re_hash*2
  159. (*jmp loop2*) (*unroll 2*)
  160. and bh, max_hash / 128
  161. cmp word [prfx][bx],-1
  162. je output
  163. cmp [prfx][bx], dx
  164. je match
  165. (*%T stats?*) inc word [apack2@collision_count] (*%E*)
  166. add bx, re_hash*2
  167. jmp loop2 (*end unroll*)
  168. exit1:
  169. shl ch,1
  170. (*%T shift2*) shl ch,1 (*%E*)
  171. (*%T shift4*) shl ch,1 (*%E*)
  172. (*%T shift4*) shl ch,1 (*%E*)
  173. add ch, dh
  174. mov [di], dl
  175. inc di
  176. dec cl
  177. mov ax, di
  178. sub ax, apack2@p
  179. mov dl, ch
  180. sub ch,ch
  181. add di,cx
  182. (*%T shift2*) shl cl,1 (*%E*)
  183. (*%T shift4*) shl cl,1 (*%E*)
  184. shl dl,cl
  185. mov [di][-(period+1)], dl
  186. pop es; pop ds; pop di; pop si
  187. pop bp;
  188. ret far 6
  189. (*%F reset?*)
  190. _shift_zero:
  191. mov [di][-(period+1)], ch
  192. inc di
  193. mov cx,period
  194. jmp _shift_zero_done
  195. _else1:
  196. (*%T stats?*) inc word [apack2@collision_count] (*%E*)
  197. shl bx, 1
  198. add bx, re_hash*2
  199. jmp _loop2
  200. _exit1:
  201. jmp exit1
  202. _match:
  203. shr bx,1
  204. cmp[char][bx], al
  205. jne _else1
  206. shl bx,1
  207. mov dx, [code][bx]
  208. (*jmp _loop1*) (* unrolled copy of loop1*)
  209. cmp si,bp
  210. je exit1
  211. db 26H; lodsb
  212. mov bx,dx
  213. add bl,al
  214. add bh,al
  215. (*_loop2:*)
  216. and bx, max_hash*2
  217. cmp [prfx][bx], dx
  218. je _match
  219. cmp word [prfx][bx],-1
  220. jne _collide
  221. _output:
  222. shl ch,1
  223. (*%T shift2*) shl ch,1 (*%E*)
  224. (*%T shift4*) shl ch,1 (*%E*)
  225. (*%T shift4*) shl ch,1 (*%E*)
  226. add ch, dh
  227. mov [di], dl
  228. inc di
  229. dec cl
  230. jz _shift_zero
  231. _shift_zero_done:
  232. _output_done:
  233. mov dx,ax
  234. _loop1:
  235. cmp si,bp
  236. je _exit1
  237. db 26H; lodsb
  238. mov bx,dx
  239. add bl,al
  240. add bh,al
  241. _loop2:
  242. and bx, max_hash*2
  243. cmp word [prfx][bx],-1
  244. je _output
  245. cmp [prfx][bx], dx
  246. je _match
  247. _collide:
  248. (*%T stats?*) inc word [apack2@collision_count] (*%E*)
  249. add bx, re_hash*2
  250. (*jmp loop2*) (*unroll 1*)
  251. and bh, max_hash / 128
  252. cmp word [prfx][bx],-1
  253. je _output
  254. cmp [prfx][bx], dx
  255. je _match
  256. (*%T stats?*) inc word [apack2@collision_count] (*%E*)
  257. add bx, re_hash*2
  258. (*jmp loop2*) (*unroll 2*)
  259. and bh, max_hash / 128
  260. cmp word [prfx][bx],-1
  261. je _output
  262. cmp [prfx][bx], dx
  263. je _match
  264. (*%T stats?*) inc word [apack2@collision_count] (*%E*)
  265. add bx, re_hash*2
  266. jmp _loop2 (*end unroll*)
  267. (*%E*) (*reset?*)
  268. errmsg: db 'Unpack error'
  269. public apack2$Unpack: out = 16; n = 20
  270. k = 10
  271. sub sp, 2
  272. push si; push di; push ds; push es
  273. push bp
  274. mov bp,sp
  275. mov ax, APACK2_DATA ; mov ds, ax
  276. les di, [bp][out]
  277. add [bp][n], di
  278. mov si, apack2@p
  279. (* new shift *)
  280. mov cl,period
  281. mov ch,[si]
  282. inc si
  283. (* get first code *)
  284. lodsb
  285. sub ah,ah
  286. shl ch,1 ; rcl ah,1
  287. (*%T shift2*) shl ch,1; rcl ah,1 (*%E*)
  288. (*%T shift4*) shl ch,1; rcl ah,1 (*%E*)
  289. (*%T shift4*) shl ch,1; rcl ah,1 (*%E*)
  290. (* reset *)
  291. mov bx, 256
  292. mov [code][512],ax
  293. mov [bp][k],al
  294. stosb
  295. jmp uloop1
  296. more:
  297. pop ax
  298. stosw
  299. uloop1:
  300. cmp sp, bp
  301. jne more
  302. cmp di, [bp][n]
  303. jae uexit1
  304. dec cl
  305. jz new_shift
  306. new_shift_done:
  307. lodsb
  308. sub ah,ah
  309. shl ch,1 ; rcl ah,1
  310. (*%T shift2*) shl ch,1; rcl ah,1 (*%E*)
  311. (*%T shift4*) shl ch,1; rcl ah,1 (*%E*)
  312. (*%T shift4*) shl ch,1; rcl ah,1 (*%E*)
  313. (*%T reset?*)
  314. cmp bx, max_code
  315. je reset
  316. (*%E*)
  317. mov dx,bx
  318. shl bx,1
  319. mov [code][bx][2],ax
  320. cmp ax,dx
  321. jae special_case
  322. mov bx,ax
  323. uloop22_test:
  324. cmp bx, 256
  325. jae uloop21
  326. mov [bp][k], bx
  327. mov al, bl
  328. stosb
  329. xchg bx,dx
  330. (*%F reset?*)
  331. cmp bx, max_code+1
  332. je _uloop1
  333. (*%E*)
  334. mov [char][bx],dl
  335. inc bx
  336. jmp uloop1
  337. uloop21:
  338. mov ah, [char][bx]
  339. shl bx,1
  340. mov bx, [code][bx]
  341. uloop21_test:
  342. cmp bx, 256
  343. jae uloop2_continue
  344. mov [bp][k], bx
  345. mov al,bl
  346. stosw
  347. xchg bx,dx
  348. (*%F reset?*)
  349. cmp bx, max_code+1
  350. je _uloop1
  351. (*%E*)
  352. mov [char][bx],dl
  353. inc bx
  354. jmp uloop1
  355. uloop2_continue:
  356. mov al, [char][bx]
  357. push ax
  358. shl bx,1
  359. mov bx, [code][bx]
  360. jmp uloop22_test
  361. new_shift:
  362. mov cl,period
  363. mov ch,[si]
  364. inc si
  365. jmp new_shift_done
  366. uexit1:
  367. ja unpack_error
  368. pop bp
  369. pop es; pop ds; pop di; pop si
  370. add sp, 2
  371. ret far 6
  372. (*%T reset?*)
  373. reset:
  374. mov bx, 256
  375. mov [code][512],ax
  376. mov [bp][k],al
  377. stosb
  378. jmp uloop1
  379. (*%E*)
  380. special_case:
  381. ja unpack_error
  382. mov ah, [bp][k]
  383. mov bx, [code][bx]
  384. jmp uloop21_test
  385. unpack_error:
  386. (*
  387. mov ax, unpack_error - errmsg
  388. push ax
  389. mov ax, errmsg
  390. push cs
  391. push ax
  392. extrn AsmLib$FatalError
  393. call far AsmLib$FatalError
  394. *)
  395. (**)
  396. xor ax,ax
  397. push ax
  398. push ax
  399. push ax
  400. extrn __FatalError
  401. call far __FatalError
  402. (**)
  403. (*%F reset?*)
  404. _more:
  405. pop ax
  406. stosw
  407. _uloop1:
  408. cmp sp, bp
  409. jne _more
  410. cmp di, [bp][n]
  411. jae uexit1
  412. dec cl
  413. jz _new_shift
  414. _new_shift_done:
  415. lodsb
  416. sub ah,ah
  417. shl ch,1 ; rcl ah,1
  418. (*%T shift2*) shl ch,1; rcl ah,1 (*%E*)
  419. (*%T shift4*) shl ch,1; rcl ah,1 (*%E*)
  420. (*%T shift4*) shl ch,1; rcl ah,1 (*%E*)
  421. mov dx,bx
  422. shl bx,1
  423. mov [code][bx][2],ax
  424. cmp ax,dx
  425. jae _special_case
  426. mov bx,ax
  427. _uloop22_test:
  428. cmp bx, 256
  429. jae _uloop21
  430. mov [bp][k], bx
  431. mov al, bl
  432. stosb
  433. xchg bx,dx
  434. jmp _uloop1
  435. _uloop21:
  436. mov ah, [char][bx]
  437. shl bx,1
  438. mov bx, [code][bx]
  439. _uloop21_test:
  440. cmp bx, 256
  441. jae _uloop2_continue
  442. mov [bp][k], bx
  443. mov al,bl
  444. stosw
  445. xchg bx,dx
  446. jmp _uloop1
  447. _uloop2_continue:
  448. mov al, [char][bx]
  449. push ax
  450. shl bx,1
  451. mov bx, [code][bx]
  452. jmp _uloop22_test
  453. _new_shift:
  454. mov cl,period
  455. mov ch,[si]
  456. inc si
  457. jmp _new_shift_done
  458. _special_case:
  459. ja unpack_error
  460. mov ah, [bp][k]
  461. mov bx, [code][bx]
  462. jmp _uloop21_test
  463. (*%E*) (* reset? *)
  464. end
  465.