Rn_deco.asm 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. include include.asm
  2. ;--------------------------------------------------------------------------------------------------
  3. ;-------------------------------------------------------------------------------
  4. ; PROPACK 8086 Source Code for Unpacking RNC Method 1 Packed Files (flat model)
  5. ;
  6. ; Copyright (c) 1991-93 Rob Northen Computing, UK. All Rights Reserved.
  7. ;
  8. ; File: RNC_1FMM.ASM (masm version)
  9. ;
  10. ; Date: 21.04.93
  11. ;-------------------------------------------------------------------------------
  12. ;------------------------------------------------------------------------------
  13. ; UnpackM1 (flat model version, 32-bit addressing)
  14. ;
  15. ; Function Uncompresses an RNC Method 1 Packed File in memory
  16. ;
  17. ; Syntax long UnpackM1(void far *input, void far *output, int key)
  18. ;
  19. ; Remarks Unpack uncompresses an RNC packed file held in the input buffer
  20. ; and writes the uncompressed version of the file to the output
  21. ; buffer. This function performs no disk access. The packed file
  22. ; must be loaded into the input buffer prior to calling this
  23. ; function. Similarly the output buffer is not written to disk
  24. ; after the decompression has taken place.
  25. ;
  26. ; input is the memory address of the input buffer containing the
  27. ; RNC packed file and output is the memory address of the output
  28. ; buffer where the uncompressed version of the file is to be
  29. ; written.
  30. ;
  31. ; int key is the value of the key used when the RNC file was
  32. ; packed, if any other value is used the uncompression will fail.
  33. ; If no key was used when the RNC file was packed then the value
  34. ; passed in int key is ignored.
  35. ;
  36. ; Unpack can be called with the input buffer equal to the output
  37. ; buffer, in which case the compressed version of the file will
  38. ; be overwritten by the uncompressed version.
  39. ;
  40. ; Return Value If successful Unpack returns the length of the uncompressed
  41. ; file. On failure Unpack returns a zero or a negative error code:
  42. ;
  43. ; 0 = the input buffer does not point to an RNC packed file
  44. ; -1 = the packed data in the input buffer has a CRC error
  45. ; -2 = the unpacked data in the output buffer has a CRC error
  46. ;
  47. ; To Call from Assembler,
  48. ;
  49. ; push key ; word
  50. ; push output ; dword
  51. ; push input ; dword
  52. ; call UnpackM1
  53. ; add esp,10
  54. ;
  55. ; On exit,
  56. ; carry flag = result, 0 = success, 1 = fail
  57. ; AX = length of unpacked file in bytes OR error code (low word)
  58. ; DX = length of unpacked file in bytes OR error code (high word)
  59. ; 0 = the input buffer does not point to an RNC packed file
  60. ; -1 = the packed data in the input buffer has a CRC error
  61. ; -2 = the unpacked data in the output buffer has a CRC error
  62. ;------------------------------------------------------------------------------
  63. ; .386
  64. ;
  65. ; .MODEL FLAT
  66. ;-------------------------------------------------------------------------------
  67. ; Conditional Assembly Flags
  68. ;-------------------------------------------------------------------------------
  69. CHECKSUMS EQU 1 ; set this flag to 1 if you require
  70. ; the data to be validated
  71. PROTECTED EQU 0 ; set this flag to 1 if you are unpacking
  72. ; files packed with the "-K" option
  73. ;-------------------------------------------------------------------------------
  74. ; Return Codes
  75. ;-------------------------------------------------------------------------------
  76. NOT_PACKED EQU 0
  77. PACKED_CRC EQU -1
  78. UNPACKED_CRC EQU -2
  79. ;-------------------------------------------------------------------------------
  80. ; Other Equates
  81. ;-------------------------------------------------------------------------------
  82. TABLE_SIZE EQU 16*8
  83. MIN_LENGTH EQU 2
  84. HEADER_LEN EQU 18
  85. ;-------------------------------------------------------------------------------
  86. ; Macros
  87. ;-------------------------------------------------------------------------------
  88. getrawREP MACRO
  89. IFE PROTECTED
  90. rep movsb
  91. ELSE
  92. getrawREP2:
  93. lodsb
  94. xor al,BYTE PTR key
  95. stosb
  96. loop getrawREP2
  97. ror key,1
  98. ENDIF
  99. ENDM
  100. ;-------------------------------------------------------------------------------
  101. ; Data Segment
  102. ;-------------------------------------------------------------------------------
  103. start32data
  104. ; .DATA
  105. raw_table db TABLE_SIZE dup(?)
  106. pos_table db TABLE_SIZE dup(?)
  107. len_table db TABLE_SIZE dup(?)
  108. IF CHECKSUMS
  109. crc_table db 200h dup(?)
  110. ENDIF
  111. unpack_len dd 0
  112. pack_len dd 0
  113. pack_paras dw 0
  114. counts dw 0
  115. bit_buffl dw 0
  116. bit_buffh dw 0
  117. blocks db 0
  118. bit_count db 0
  119. IF CHECKSUMS
  120. crc_u dw 0
  121. crc_p dw 0
  122. ENDIF
  123. end32data
  124. ;-------------------------------------------------------------------------------
  125. ; Code Segment
  126. ;-------------------------------------------------------------------------------
  127. start32code
  128. ; .CODE
  129. PUBLIC C UnpackM1
  130. UnpackM1 PROC NEAR C USES esi edi ds es,input:dword,output:dword
  131. IF PROTECTED
  132. ARG key :WORD ; must be added to above
  133. ENDIF
  134. cld
  135. push ds
  136. pop es ; ensure es=ds
  137. IF CHECKSUMS
  138. call init_crc
  139. ENDIF
  140. mov esi,input ; pointer to packed file
  141. lodsw
  142. cmp ax,4e52h
  143. jne not_pack
  144. lodsw
  145. cmp ax,0143h
  146. jne not_pack
  147. call read_long ; read unpacked file length
  148. mov unpack_len,eax
  149. call read_long ; read packed file length
  150. mov pack_len,eax
  151. mov bl,[esi+5]
  152. mov BYTE PTR blocks,bl
  153. IF CHECKSUMS
  154. call read_long ; read crc's
  155. mov crc_p,ax
  156. ror eax,16
  157. mov crc_u,ax
  158. add esi,HEADER_LEN-16
  159. mov ecx,pack_len
  160. call crc_block ; find packed data crc
  161. cmp crc_p,bx
  162. jne pack_crc ; branch if bad packed data CRC
  163. mov eax,pack_len
  164. mov esi,input
  165. add esi,HEADER_LEN
  166. ELSE
  167. add esi,HEADER_LEN-12
  168. ENDIF
  169. add eax,HEADER_LEN
  170. mov edx,input ; input_lo
  171. mov ebx,output ; output_lo
  172. add edx,eax ; input_hi
  173. cmp edx,ebx
  174. jbe unpack3 ; branch if input_hi <= output_lo
  175. mov edi,input
  176. xor eax,eax
  177. mov al,[edi+16] ; unpack bufsiz
  178. add eax,unpack_len
  179. add ebx,eax ; output_hi
  180. cmp ebx,edx ; branch if output_hi <= input_hi
  181. jbe unpack3
  182. mov esi,edx
  183. mov edi,ebx
  184. sub esi,4
  185. sub edi,4
  186. mov ecx,pack_len
  187. shr ecx,2
  188. std
  189. rep movsd
  190. add esi,4
  191. add edi,4
  192. mov cx,WORD PTR pack_len
  193. and cx,0003h
  194. jcxz unpack2
  195. dec esi
  196. dec edi
  197. rep movsb
  198. inc esi
  199. inc edi
  200. unpack2:
  201. cld
  202. mov esi,edi
  203. unpack3:
  204. mov edi,output
  205. mov bit_count,0 ; init bits in buffer
  206. mov ax,[esi]
  207. mov bit_buffl,ax ; init next two bytes
  208. mov al,2
  209. call input_bits ; input lock and key bits
  210. unpack4:
  211. mov edx,OFFSET raw_table
  212. call make_huftable ; create raw codes table
  213. mov edx,OFFSET pos_table
  214. call make_huftable ; create offset codes table
  215. mov edx,OFFSET len_table
  216. call make_huftable ; create length codes table
  217. mov al,16
  218. call input_bits ; input counts
  219. mov counts,ax
  220. jmp unpack6
  221. unpack5:
  222. mov edx,OFFSET pos_table
  223. call input_value ; input offset
  224. push cx
  225. mov edx,OFFSET len_table
  226. call input_value ; input length
  227. add cx,MIN_LENGTH
  228. xor eax,eax
  229. pop ax
  230. inc ax
  231. mov edx,esi
  232. mov esi,edi
  233. sub esi,eax
  234. rep movsb ; ds:si -> es:di
  235. mov esi,edx
  236. unpack6:
  237. mov edx,OFFSET raw_table
  238. call input_value ; input count
  239. jcxz unpack7 ; branch if count=0
  240. getrawREP
  241. mov cl,bit_count
  242. mov ax,[esi]
  243. mov bx,ax
  244. rol ax,cl
  245. mov dx,1
  246. shl dx,cl
  247. dec dx
  248. and bit_buffl,dx
  249. and dx,ax
  250. mov ax,[esi+2]
  251. shl bx,cl
  252. shl ax,cl
  253. or ax,dx
  254. or bit_buffl,bx
  255. mov bit_buffh,ax
  256. unpack7:
  257. dec counts
  258. jne unpack5 ; branch if block not done
  259. dec BYTE PTR blocks
  260. jne unpack4
  261. IF CHECKSUMS
  262. mov esi,output
  263. mov ecx,unpack_len
  264. call crc_block
  265. cmp crc_u,bx
  266. jne pack_crc ; branch if bad unpacked data CRC
  267. ENDIF
  268. mov eax,unpack_len
  269. clc
  270. jmp unpack_end
  271. not_pack:
  272. mov eax,NOT_PACKED
  273. jmp unpack_cwd
  274. pack_crc:
  275. mov eax,PACKED_CRC
  276. jmp unpack_cwd
  277. unpack_crc:
  278. mov eax,UNPACKED_CRC
  279. unpack_cwd:
  280. stc
  281. unpack_end:
  282. ret
  283. UnpackM1 ENDP
  284. ;------------------------------------------------------------------------------
  285. ; read next long word from packed file converting to little endian
  286. ; on exit,
  287. ; eax = dword
  288. ;------------------------------------------------------------------------------
  289. read_long PROC
  290. lodsd
  291. xchg ah,al
  292. rol eax,16
  293. xchg ah,al
  294. ret
  295. read_long ENDP
  296. ;------------------------------------------------------------------------------
  297. ; input value from packed data
  298. ; on entry,
  299. ; dx = offset to huffman table in work segment
  300. ; on exit,
  301. ; cx = value
  302. ;------------------------------------------------------------------------------
  303. input_value PROC
  304. xchg edx,esi
  305. mov cx,bit_buffl
  306. input_value2:
  307. lodsw
  308. mov bx,ax
  309. and bx,cx
  310. lodsw
  311. cmp ax,bx
  312. jne input_value2
  313. mov cx,[esi+16*4-4]
  314. xchg edx,esi
  315. mov al,ch ; code bit length
  316. call input_bits
  317. xor ch,ch
  318. cmp cl,2
  319. jb input_value3 ; branch if 0 or 1
  320. dec cl
  321. mov al,cl
  322. call input_bits
  323. mov bx,1
  324. shl bx,cl
  325. or ax,bx
  326. mov cx,ax
  327. input_value3:
  328. ret
  329. input_value ENDP
  330. ;------------------------------------------------------------------------------
  331. ; input data bits from the packed file
  332. ; on entry,
  333. ; al = no. of bits to read (1-16)
  334. ; on exit,
  335. ; ax = data bits
  336. ;------------------------------------------------------------------------------
  337. input_bits PROC
  338. push cx
  339. mov cl,al
  340. mov ax,bit_buffh ; bit_buffer (hi word)
  341. mov bx,bit_buffl ; bit buffer (lo word)
  342. mov ch,bit_count ; bit count (0-16)
  343. mov dx,1
  344. shl dx,cl
  345. dec dx
  346. and dx,bx ; mask required bits from buffer
  347. push dx ; return value
  348. sub ch,cl ; update no. of bits left in buffer
  349. jae input_bits3 ; branch if enough bits in buffer
  350. add ch,cl
  351. input_bits2:
  352. xchg cl,ch
  353. mov dx,1
  354. shl dx,cl
  355. dec dx
  356. and dx,ax
  357. ror dx,cl
  358. shr ax,cl
  359. shr bx,cl
  360. or bx,dx
  361. add esi,2
  362. mov ax,[esi] ; read packed word
  363. xchg cl,ch
  364. sub cl,ch
  365. mov ch,16
  366. sub ch,cl
  367. input_bits3:
  368. mov dx,1
  369. shl dx,cl
  370. dec dx
  371. and dx,ax
  372. ror dx,cl
  373. shr ax,cl
  374. shr bx,cl
  375. or bx,dx
  376. mov bit_buffh,ax ; bit_buffer (hi word)
  377. mov bit_buffl,bx ; bit buffer (lo word)
  378. mov bit_count,ch ; bit count
  379. pop ax
  380. pop cx
  381. ret
  382. input_bits ENDP
  383. ;------------------------------------------------------------------------------
  384. ; read huffman code bit lengths and create huffman code table
  385. ; on entry,
  386. ; edx = offset of start of table in work segment
  387. ;------------------------------------------------------------------------------
  388. make_huftable PROC
  389. push edi
  390. push edx
  391. sub esp,16 ; reserve space for bit lengths
  392. mov edi,esp
  393. mov al,5
  394. call input_bits ; read no. of codes
  395. xor ecx,ecx
  396. mov cx,ax
  397. jcxz make_huftable7 ; branch if 0 entries
  398. push ecx
  399. make_huftable2:
  400. mov al,4
  401. call input_bits ; read huffman code bit length
  402. mov ss:[edi],al
  403. inc edi
  404. loop make_huftable2
  405. pop ecx
  406. push esi
  407. mov esi,esp
  408. add esi,4
  409. mov edi,ss:[esi+16] ; pointer to huffman table
  410. mov al,1 ; init bit length
  411. xor bx,bx ; huff code
  412. mov dx,8000h ; huff base
  413. make_huftable3:
  414. push cx ; no. of huffman codes
  415. push esi
  416. make_huftable4:
  417. cmp al,ss:[esi]
  418. jne make_huftable6 ; branch if not same bit length
  419. push ax
  420. push bx
  421. push cx
  422. mov cl,al
  423. mov ax,1
  424. shl ax,cl
  425. dec ax
  426. stosw ; code mask
  427. mov al,cl
  428. mov cl,16
  429. sub cl,al
  430. shr bx,cl
  431. mov cl,al
  432. xor ax,ax
  433. make_huftable5:
  434. rcr bx,1
  435. rcl ax,1
  436. loop make_huftable5
  437. stosw ; huffman code
  438. mov eax,esi
  439. sub eax,esp
  440. sub ax,16 ; 4 word pushs + 2 dword pushs
  441. mov ah,ss:[esi] ; code bit length
  442. mov [edi+16*4-4],ax
  443. pop cx
  444. pop bx
  445. pop ax
  446. add bx,dx ; update huff code
  447. make_huftable6:
  448. inc esi
  449. loop make_huftable4
  450. pop esi
  451. pop cx
  452. shr dx,1
  453. inc al
  454. cmp al,17
  455. jne make_huftable3
  456. pop esi
  457. make_huftable7:
  458. add esp,16
  459. pop edx
  460. pop edi
  461. ret
  462. make_huftable ENDP
  463. ;------------------------------------------------------------------------------
  464. ; initialise the crc lookup table
  465. ;------------------------------------------------------------------------------
  466. IF CHECKSUMS
  467. init_crc PROC
  468. mov edi,OFFSET crc_table
  469. xor bx,bx
  470. init_crc2:
  471. mov ax,bx
  472. mov ecx,8
  473. init_crc3:
  474. shr ax,1
  475. jnc init_crc4
  476. xor ax,0a001h
  477. init_crc4:
  478. loop init_crc3
  479. stosw
  480. inc bl
  481. jne init_crc2
  482. ret
  483. init_crc ENDP
  484. ;------------------------------------------------------------------------------
  485. ; calculate a 16 bit crc of a block of memory
  486. ; on entry,
  487. ; esi = pointer to start of block
  488. ; ecx = size of block in bytes
  489. ; on exit,
  490. ; bx = 16 bit crc
  491. ;------------------------------------------------------------------------------
  492. crc_block PROC
  493. mov edi,OFFSET crc_table ; pointer to crc table
  494. xor ebx,ebx
  495. crc_block2:
  496. lodsb ; read byte from block
  497. xor bl,al
  498. mov al,bh
  499. xor bh,bh
  500. shl bx,1
  501. mov bx,[edi+ebx] ; lookup crc value
  502. xor bl,al
  503. loop crc_block2
  504. ret
  505. crc_block ENDP
  506. ENDIF
  507. end32code
  508. END
  509.