unpack.asm 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  1. ;-----------------------------------------------------------------------
  2. ;INTRODUCTION:
  3. ;
  4. ; This is a 100% assembly version of the ttunpack routine, which is
  5. ; based on code by Pasi 'Albert' Ojala, albert@cs.tut.fi, then
  6. ; reduced by Thomas Nussbaumer to fit his needs. For a full details
  7. ; on the algorithm see:
  8. ;
  9. ; http://www.cs.tut.fi/~albert/Dev/pucrunch/index.html
  10. ;
  11. ; Version 2.28 Fast
  12. ;
  13. ;
  14. ;THE LICENSE:
  15. ;
  16. ; Copyright (C) 2004-2005 Samuel Stearley
  17. ;
  18. ; wxWindows Library Licence, Version 3.1
  19. ; ======================================
  20. ;
  21. ; Copyright (C) 1998-2005 Julian Smart, Robert Roebling et al
  22. ;
  23. ; Everyone is permitted to copy and distribute verbatim copies
  24. ; of this licence document, but changing it is not allowed.
  25. ;
  26. ; WXWINDOWS LIBRARY LICENCE
  27. ; TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
  28. ;
  29. ; This library is free software; you can redistribute it and/or modify it
  30. ; under the terms of the GNU Library General Public Licence as published by
  31. ; the Free Software Foundation; either version 2 of the Licence, or (at
  32. ; your option) any later version.
  33. ;
  34. ; This library is distributed in the hope that it will be useful, but
  35. ; WITHOUT ANY WARRANTY; without even the implied warranty of
  36. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library
  37. ; General Public Licence for more details.
  38. ;
  39. ; You should have received a copy of the GNU Library General Public Licence
  40. ; along with this software, usually in a file named COPYING.LIB. If not,
  41. ; write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  42. ; Boston, MA 02111-1307 USA.
  43. ;
  44. ; EXCEPTION NOTICE
  45. ;
  46. ; 1. As a special exception, the copyright holders of this library give
  47. ; permission for additional uses of the text contained in this release of
  48. ; the library as licenced under the wxWindows Library Licence, applying
  49. ; either version 3.1 of the Licence, or (at your option) any later version of
  50. ; the Licence as published by the copyright holders of version
  51. ; 3.1 of the Licence document.
  52. ;
  53. ; 2. The exception is that you may use, copy, link, modify and distribute
  54. ; under your own terms, binary object code versions of works based
  55. ; on the Library.
  56. ;
  57. ; 3. If you copy code from files distributed under the terms of the GNU
  58. ; General Public Licence or the GNU Library General Public Licence into a
  59. ; copy of this library, as this licence permits, the exception does not
  60. ; apply to the code that you add in this way. To avoid misleading anyone as
  61. ; to the status of such modified files, you must delete this exception
  62. ; notice from such code and/or adjust the licensing conditions notice
  63. ; accordingly.
  64. ;
  65. ; 4. If you write modifications of your own for this library, it is your
  66. ; choice whether to permit this exception to apply to your modifications.
  67. ; If you do not wish that, you must delete the exception notice from such
  68. ; code and/or adjust the licensing conditions notice accordingly.
  69. ;
  70. ;
  71. ;NOTES:
  72. ;
  73. ;1) There were several other names associated with this, but not
  74. ; anymore ;)
  75. ;
  76. ;
  77. ;2) There should be an unpack.c distributed with this that has
  78. ; additional comments that will help clarify what this is doing.
  79. ; But maybe not. It depends on where you got this. you should
  80. ; always be able to find this on my site: http://www.nyall.net
  81. ;
  82. ;
  83. ;3) If caller wants, they can alter the default int priority to
  84. ; speed up execution before calling this routine.
  85. ;
  86. ;
  87. ;4) The code was written with wordpad. It might look better if
  88. ; opened with that program.
  89. ;
  90. ;
  91. ;5) A version of this is included as a hex array for use with programs
  92. ; written with tigcc. OR you can use this file directly with a
  93. ; tigcc project: add it to the project and remove the ';' from
  94. ; before the 'CALL_DIRECTLY' below. Be sure to have the latest
  95. ; version of tigcc when doing this.
  96. ;----------------------------------------------------------------------
  97. ;CALL_DIRECTLY ;if this label is defined then this code can be used
  98. ; directly as part of a tigcc project.
  99. DELTA_LZ ;If defined it will include code to do DELTA lz decompression
  100. ; ebooks and ppg compressed programs currently do not take advantage of
  101. ; the -fdelta option of the compressor.
  102. ;UNROLL_RLE
  103. ;UNROLL_LZ
  104. ifd CALL_DIRECTLY
  105. public ttunpack_decompress
  106. endc
  107. ifnd CALL_DIRECTLY
  108. include "os.h"
  109. xdef _ti89
  110. xdef _nostub
  111. endc
  112. osize_lo equ 0 ;original size lowbyte
  113. osize_hi equ 1 ;original size highbyte
  114. magic1 equ 2 ;must be equal to UNPACK_MAGIC1
  115. magic2 equ 3 ;must be equal to UNPACK_MAGIC2
  116. csize_lo equ 4 ;compressed size lowbyte
  117. csize_hi equ 5 ;compressed size lowbyte
  118. esc1 equ 6 ;escape >> (8-escBits)
  119. notused3 equ 7 ;
  120. notused4 equ 8 ;
  121. esc2 equ 9 ;escBits
  122. gamma1 equ 10 ;maxGamma + 1
  123. gamma2 equ 11 ;(1<<maxGamma)
  124. extralz equ 12 ;extraLZPosBits
  125. notused1 equ 13 ;
  126. notused2 equ 14 ;
  127. rleentries equ 15 ;rleUsed
  128. HEADER_SIZE equ 16
  129. __MAGIC_CHAR1 equ $54
  130. __MAGIC_CHAR2 equ $50
  131. __ERRPCK_OKAY equ 0
  132. __ERRPCK_NOESCFOUND equ 8 ;248
  133. __ERRPCK_ESCBITS equ 7 ;249
  134. __ERRPCK_MAXGAMMA equ 6 ;250
  135. __ERRPCK_EXTRALZP equ 5 ;251
  136. __ERRPCK_NOMAGIC equ 4 ;252
  137. __ERRPCK_OUTBUFOVERRUN equ 3 ;253
  138. __ERRPCK_LZPOSUNDERRUN equ 2 ;254
  139. ;-----------------------------------------------------------------------
  140. ;Notes on register useage, might be good Idea to print this.
  141. ;
  142. ; a0 => trashing, but may not be used by the subroutines
  143. ; a1 => extra z position bits
  144. ; a2 => a table that maps a byte to the highest bit set in it.
  145. ; a3 => the bytecodevec table
  146. ; a4 => The point to jump to when doing a continue
  147. ; a5 => the destination buffer
  148. ; a6 => points to the next byte of the compressed data.
  149. ; updated when d7 overflows.
  150. ;
  151. ; d0 => trashing, output of __GetBits and __GetValue
  152. ; d1 => trashing, input to __GetBits
  153. ; d2 => prepared mask for isolating # of escape bits
  154. ; d3 => trashing but only by the main routine, not the subroutines
  155. ; It is usually the prepared count.
  156. ; d4 => # of escape bits
  157. ; d5 => start escape
  158. ; d6 => the current compressed byte, updated when d7 overflows.
  159. ; d7 => which bit we are at in the compressed data.
  160. ;-----------------------------------------------------------------------
  161. CORRECT_IN_MASK MACRO
  162. tst.b d7
  163. bne.s \@fun
  164. moveq #8,d7
  165. move.b (a6)+,d6
  166. \@fun
  167. ENDM
  168. ttunpack_decompress:
  169. ifnd CALL_DIRECTLY
  170. dc.b "UNPACK_0"
  171. endc
  172. movem.l d3-d7/a2-a6,-(a7)
  173. move.l 4+10*4(a7),a6
  174. move.l 8+10*4(a7),a5
  175. ;--------------------------------------------------------
  176. ; startesc = cth->esc1; //d5
  177. ; bytecodevec = &src[15]; //a3
  178. ; __imask__ = 0x80; //d7
  179. ;
  180. ;These are initialized here to insure that certain
  181. ;branches can use the short form.
  182. ;--------------------------------------------------------
  183. lea 15(a6),a3 ;'bytecodevec'
  184. moveq #0,d5
  185. move.b esc1(a6),d5 ;'StartEsc'
  186. moveq #8,d7 ;which bit i am at
  187. ;-------------------------------------------------------------------------------------------------
  188. ; if (cth->magic1 != __MAGIC_CHAR1 || cth->magic2 != __MAGIC_CHAR2) return __ERRPCK_NOMAGIC;
  189. ; if (cth->gamma1 != 8 || cth->gamma2 != 128) return __ERRPCK_MAXGAMMA;
  190. ; if ((escbits = cth->esc2) > 8) return __ERRPCK_ESCBITS;
  191. ; if ((extralzposbits = cth->extralz) > 4) return __ERRPCK_EXTRALZP;
  192. ;-------------------------------------------------------------------------------------------------
  193. moveq #__ERRPCK_NOMAGIC,d0
  194. cmp.b #__MAGIC_CHAR1,magic1(a6) ;these could be optimized into 1 word compare
  195. bne.s __ReturnError ; if evenly aligned.
  196. cmp.b #__MAGIC_CHAR2,magic2(a6)
  197. bne.s __ReturnError
  198. moveq #__ERRPCK_MAXGAMMA,d0
  199. cmp.b #8,gamma1(a6)
  200. bne.s __ReturnError
  201. cmp.b #128,gamma2(a6)
  202. bne.s __ReturnError
  203. moveq #__ERRPCK_ESCBITS,d0
  204. moveq #0,d1
  205. move.b esc2(a6),d1
  206. move.l d1,d4
  207. subq.w #8,d1
  208. bhi.s __ReturnError
  209. moveq #__ERRPCK_EXTRALZP,d0
  210. moveq #0,d1
  211. move.b extralz(a6),d1
  212. move.l d1,a1 ;extralz pos bits
  213. subq.w #5,d1
  214. bgt.s __ReturnError
  215. ;--------------------------------------------------------
  216. ; escbits8 = 8 - escbits; //not used
  217. ; __ibuffer__ = src + sizeof(__PACKHEADER) + cth->rleentries; //a6
  218. ;--------------------------------------------------------
  219. moveq #0,d2
  220. bset d4,d2
  221. subq.w #1,d2 ;the mask for the number of escape bits
  222. ror.b d4,d2 ;set the upper bits
  223. ror.b d4,d5 ;shift up start escape
  224. moveq #0,d0
  225. move.b (a3),d0
  226. lea HEADER_SIZE(a6,d0),a6
  227. ;--------------------------------------------------------
  228. ;To remove checking if escbits == 0 in the literal byte
  229. ; loop, there are two points used for continuing.
  230. ;--------------------------------------------------------
  231. lea __ReturnPointForNonZeroEscapeBits(pc),a4
  232. tst.b d4
  233. bne.s __Skipper
  234. lea __SelIsStartEscape(pc),a4
  235. __Skipper:
  236. ;--------------------------------------------------------
  237. ;a2 will point to a table that maps a byte to the
  238. ; highest bit set in it. 0 will be mapped to zero,
  239. ; this is important.
  240. ;--------------------------------------------------------
  241. lea -260(a7),a7
  242. move.l a7,a2
  243. clr.b (a2)+
  244. moveq #0,d0
  245. moveq #7,d1
  246. AllBytes:
  247. moveq #0,d3
  248. bset d0,d3
  249. ThisByte:
  250. move.b d0,(a2)+
  251. subq.w #1,d3
  252. bne.s ThisByte
  253. addq.w #1,d0
  254. dbra d1,AllBytes
  255. move.l a7,a2
  256. move.b (a6)+,d6 ;very first byte of compressed data
  257. jmp (a4) ;jump into the loop
  258. ;---------------------------------------------------------
  259. ;And when all is done branch here
  260. ;---------------------------------------------------------
  261. __WeAreDone:
  262. moveq #0,d0 ;return value
  263. lea 260(a7),a7
  264. __ReturnError:
  265. neg.b d0 ;turn loaded error code into actual value
  266. movem.l (a7)+,d3-d7/a2-a6
  267. rts
  268. ;---------------------------------------------------------
  269. ; *outbuffer++ = (sel<<escbits8) | __GetBits(escbits8);
  270. ; continue;
  271. ;---------------------------------------------------------
  272. __SelIsNOTStartEscape:
  273. move.b d0,(a5)+ ;put litteral byte to the output
  274. ;---------------------------------------------------------
  275. ;The while(1) loop:
  276. ;
  277. ; sel = (escbits) ? __GetBits(escbits) : startesc;
  278. ; if (sel == startesc) {
  279. ;---------------------------------------------------------
  280. __ReturnPointForNonZeroEscapeBits
  281. move.b d6,-(a7)
  282. move.w (a7)+,d0
  283. move.b (a6)+,d6
  284. move.b d6,d0
  285. lsr.w d7,d0 ;__get8bits() done
  286. move.b d2,d1
  287. and.b d0,d1 ;isolate the upper escape bits
  288. cmp.b d5,d1 ;are they 'startesc'
  289. bne.s __SelIsNOTStartEscape
  290. subq.l #2,a6
  291. move.b (a6)+,d6
  292. sub.w d4,d7
  293. bhi.s __StillInSameByte2
  294. move.b (a6)+,d6
  295. addq.w #8,d7
  296. __StillInSameByte2:
  297. ;---------------------------------------------------------
  298. ;The following code is entered if sel == startesc
  299. ;but it does not actually use the sel variable
  300. ;
  301. ; lzlen = __GetValue();
  302. ; if (lzlen != 1) {
  303. ;---------------------------------------------------------
  304. __SelIsStartEscape:
  305. bsr __GetValue ;get a value for 'lzlen'
  306. move.w d0,d3 ;save 'lzlen'
  307. subq.w #1,d0 ;does 'lzlen' == 1 ?
  308. beq.s __RleDecoding
  309. ;---------------------------------------------------------
  310. ;Zip decoding
  311. ;
  312. ; lzposhi = __GetValue() - 1;
  313. ; if (lzposhi == 254) {
  314. ;---------------------------------------------------------
  315. ifnd DELTA_LZ
  316. bsr __GetValue ;if it equals 254, then lzlen must be > 3 because
  317. addq.b #1,d0 ; there is no other possiblity because Delta decompression
  318. beq.s __WeAreDone ; is not being used. It the branch is not taken it
  319. endc ; drops through to the __LzPosHi_IsNot254
  320. ifd DELTA_LZ
  321. bsr __GetValue ;get 'lzposhi', dont subtract 1 yet
  322. addq.b #1,d0 ;does 'lzposhi' == 254, remember it has not yet subtracted 1
  323. bne.s __LzPosHi_IsNot254
  324. subq.w #4,d3 ;is 'lzlen' greater than 3?
  325. bcs.s __WeAreDone ;destination is above
  326. ;---------------------------------------------------------
  327. ; add = __Get8Bit(); //put into d1
  328. ; lzpos = __Get8Bit() ^ 0xff; //put into d0
  329. ;
  330. ;take advantage of the fact that two __Get8Bit's are used
  331. ;sequentially by inlining them.
  332. ;
  333. ;the bit inverstion and the pointer subtraction will be
  334. ; combined
  335. ;---------------------------------------------------------
  336. addq.w #4,d3 ;undo above subq.w
  337. move.b d6,d1 ;put current byte into d1
  338. swap d1 ;put it in the upper word
  339. move.b (a6)+,-(a7) ;get the second byte
  340. move.w (a7)+,d1 ;put it in d1
  341. move.b (a6)+,d1 ;the third byte
  342. move.b d1,d6
  343. lsr.l d7,d1
  344. moveq #-1,d0
  345. move.b d1,d0 ;d0 is -'lzpos' +1
  346. move.w d1,-(a7)
  347. move.b (a7)+,d1 ;shift it 8 bits to the right
  348. ;---------------------------------------------------------
  349. ; for (i=0; i<=lzlen; i++) {
  350. ; *outbuffer = *(outbuffer - lzpos - 1) + add;
  351. ; outbuffer++;
  352. ; }
  353. ;---------------------------------------------------------
  354. lea 0(a5,d0.w),a0
  355. __WriteDataLoop2:
  356. move.b (a0)+,d0
  357. add.b d1,d0
  358. move.b d0,(a5)+
  359. dbra d3,__WriteDataLoop2
  360. jmp (a4) ;continue
  361. endc
  362. ;----------------------------------------------------------------------------------------
  363. ; if (extralzposbits) lzposhi = (lzposhi<<extralzposbits) | __GetBits(extralzposbits);
  364. ; lzposlo = __Get8Bit() ^ 0xff;
  365. ; lzpos = COMBINE_LOWHIGH(lzposlo,lzposhi);
  366. ;
  367. ; d0= lzPosHi, d3.w = lzlen, d1.l =lzpos
  368. ;----------------------------------------------------------------------------------------
  369. __LzPosHi_IsNot254:
  370. subq.b #2,d0 ;undo the addq.b #1
  371. move.w a1,d1 ;is 'extralzposbits' == 0?
  372. beq.s __extralZposBitsIsZero
  373. lsl.w d1,d0 ;shift it by 'extralzposbits'
  374. moveq #0,d1
  375. bset.w d7,d1
  376. subq.w #1,d1
  377. and.b d6,d1
  378. sub.w a1,d7
  379. bhi.s __StillInSameByte61
  380. move.b (a6)+,d6
  381. move.b d1,-(a7)
  382. move.w (a7)+,d1
  383. move.b d6,d1
  384. addq.w #8,d7
  385. __StillInSameByte61:
  386. lsr.w d7,d1
  387. or.w d1,d0 ;or them back together
  388. __extralZposBitsIsZero: ;at this point d0.b == 'lzposhi'
  389. moveq #0,d1
  390. move.b d0,-(a7) ;a faster way to do lsl.w #8
  391. move.w (a7)+,d1 ;shift it into the high byte of 'lzpos', first step of COMBINE_LOWHIGH
  392. move.b d6,-(a7) ;start the __Get8Bit
  393. move.w (a7)+,d0
  394. move.b (a6)+,d6
  395. move.b d6,d0
  396. lsr.w d7,d0 ;get 8 bit done
  397. move.b d0,d1 ;COMBINE_LOWHIGH
  398. not.b d1
  399. not.l d1
  400. ;-----------------------------------------------------------------------------------
  401. ; for (i=0; i<=lzlen; i++) {
  402. ; *outbuffer = *(outbuffer - lzpos - 1); //no 'add' variable
  403. ; outbuffer++;
  404. ; }
  405. ;
  406. ; d2.l must be -lzpos+1
  407. ; d3.w must be lzlen
  408. ;------------------------------------------------------------------------------------
  409. lea 0(a5,d1.l),a0
  410. ifd UNROLL_LZ
  411. lsr.w #1,d3
  412. bcc.s __FirstByte
  413. __WriteDataLoop:
  414. move.b (a0)+,(a5)+
  415. __FirstByte:
  416. move.b (a0)+,(a5)+
  417. dbra d3,__WriteDataLoop
  418. endc
  419. ifnd UNROLL_LZ
  420. __WriteDataLoop:
  421. move.b (a0)+,(a5)+
  422. dbra d3,__WriteDataLoop
  423. endc
  424. jmp (a4) ;continue
  425. ;----------------------------------------------------------------------
  426. ;'lzlen' = 1
  427. ; RLE decoding, OR 2 byte zip, OR escape from the escape
  428. ;----------------------------------------------------------------------
  429. __RleDecoding:
  430. subq.b #1,d7
  431. btst.b d7,d6
  432. beq.s __NextBitClear_DoZipAfterAll
  433. CORRECT_IN_MASK
  434. ;The second NEXT_BIT_SET()
  435. subq.b #1,d7
  436. btst.b d7,d6
  437. beq __NextBitIsClear_EscapeFromEscape
  438. ;-----------------------------------------------------------------
  439. ; rlelen = __GetValue();
  440. ; if (rlelen >= 128) {
  441. ; rlelen = ((rlelen-128)<<1) | __GetBits(1);
  442. ; rlelen |= (((__GetValue())-1)<<8);
  443. ; }
  444. ;------------------------------------------------------------------
  445. __NextBitIsSet_RunLengthEncoding:
  446. CORRECT_IN_MASK
  447. bsr.s __GetValue ;get 'rlelen' into d0, limited to 8 bit values.
  448. move.b d0,d3 ;copy it and check sign bit to see if >= 128
  449. bpl.s __LessThan128
  450. ; sub.w #128,d3 ;not needed
  451. add.b d3,d3 ;double it, this clears the high bit so there is no need to subtract 128
  452. ;-----An Inlined version of __GetBits optimized for an input of 1 --------
  453. subq.b #1,d7
  454. btst.b d7,d6
  455. sne d0
  456. sub.b d0,d3 ;subtract -1 if the bit was set = add 1
  457. CORRECT_IN_MASK
  458. bsr.s __GetValue
  459. subq.b #1,d0
  460. move.w d3,-(a7)
  461. move.b d0,(a7)
  462. move.w (a7)+,d3
  463. ;-------------------------------------------------------------------
  464. ;Need the byte to copy
  465. ;
  466. ; bytecode = __GetValue();
  467. ; if (bytecode < 32) byte = bytecodevec[bytecode];
  468. ; else byte = ((bytecode-32)<<3) | __GetBits(3); //subracting 32 not needed
  469. ;-------------------------------------------------------------------
  470. __LessThan128:
  471. bsr.s __GetValue ;get bytecode
  472. cmp.b #32,d0
  473. bcc.s __GreaterThanOrEqual32
  474. move.b 0(a3,d0.w),d0 ;byte = bytecodevec[bytecode];
  475. bra.s __RleCopy
  476. __GreaterThanOrEqual32:
  477. ;-----An Inlined version of GetBits that is optimized for an input of 3-------
  478. lsl.b #3,d0
  479. move.b d6,d1
  480. subq.w #3,d7
  481. bhi.s __StillInSameByte2345
  482. move.b (a6)+,d6
  483. move.b d1,-(a7)
  484. move.w (a7)+,d1
  485. move.b d6,d1
  486. addq.w #8,d7
  487. __StillInSameByte2345:
  488. lsr.w d7,d1
  489. and.b #$7,d1
  490. or.b d1,d0
  491. ;--------------------------------------------------------
  492. ; for (i=0; i<=rlelen; i++) *outbuffer++ = byte;
  493. ; continue; // continue the main loop ...
  494. ;
  495. ;Rle loop expects
  496. ; d0 = byte
  497. ; d3 = number of em to copy, no need to subtract 1 for
  498. ; dbra
  499. ;--------------------------------------------------------
  500. __RleCopy:
  501. ifd UNROLL_RLE
  502. lsr.w #1,d3
  503. bcc.s __FirstRleByte
  504. __RleLoop:
  505. move.b d0,(a5)+
  506. __FirstRleByte:
  507. move.b d0,(a5)+
  508. dbra d3,__RleLoop
  509. endc
  510. ifnd UNROLL_RLE
  511. __RleLoop:
  512. move.b d0,(a5)+
  513. dbra d3,__RleLoop
  514. endc
  515. jmp (a4)
  516. ;---------------------------------------------------------
  517. ; lzpos = __Get8Bit() ^ 0xff;
  518. ;---------------------------------------------------------
  519. __NextBitClear_DoZipAfterAll:
  520. CORRECT_IN_MASK
  521. move.b d6,-(a7) ;current byte
  522. move.w (a7)+,d1
  523. move.b (a6)+,d6 ;next byte
  524. move.b d6,d1
  525. lsr.w d7,d1
  526. moveq #-1,d3
  527. move.b d1,d3
  528. lea 0(a5,d3.l),a0
  529. move.b (a0)+,(a5)+
  530. move.b (a0)+,(a5)+ ;'lzlen' is 1, means 2 byte copy.
  531. jmp (a4) ;continue
  532. ;-------------------------------------------------------------
  533. ; __GetValue returns a value in d0.l
  534. ; __GetBits takes as its input d1.b, returns a value in d0.l
  535. ;
  536. ; The outputs can be manipulated as:
  537. ; unsigned character,
  538. ; unsigned shorts,
  539. ; unsigned longs
  540. ;
  541. ; They may update
  542. ; d6, d7, a6
  543. ;
  544. ; They may not destroy
  545. ; d3-d5/a0-a5
  546. ;
  547. ; They expect a2 to be a table that tells the number of the
  548. ; highest bit that is set
  549. ;
  550. ;--------------------------------------------------------------
  551. __GetValue: ;This function has a goal of counting till it finds
  552. moveq #0,d0
  553. move.w d7,d1
  554. bset.w d7,d0
  555. subq.w #1,d0 ;made the mask
  556. and.b d0,d6 ;mask out bits of interest, clear bits that we have already
  557. ; passed by
  558. eor.b d6,d0 ;invert the bits of interest
  559. bne.s __BitsSetInThisByte
  560. move.b (a6),d0
  561. not.b d0
  562. addq.w #8,d1
  563. __BitsSetInThisByte:
  564. sub.b 0(a2,d0.w),d1
  565. cmp.b #8,d1
  566. bcs.s __LessThan7
  567. moveq #8,d1
  568. addq.w #1,d7
  569. __LessThan7:
  570. sub.w d1,d7
  571. bhi.s __SameByte
  572. addq.w #8,d7
  573. move.b (a6)+,d6
  574. __SameByte:
  575. moveq #0,d0
  576. subq.b #1,d1
  577. beq.s __inl_exit4
  578. bset.w d7,d0
  579. subq.w #1,d0
  580. and.b d6,d0
  581. sub.w d1,d7
  582. bhi.s __StillInSameByte4
  583. move.b (a6)+,d6
  584. move.b d0,-(a7)
  585. move.w (a7)+,d0
  586. move.b d6,d0
  587. addq.w #8,d7
  588. __StillInSameByte4:
  589. lsr.w d7,d0
  590. __inl_exit4:
  591. bset.b d1,d0
  592. rts
  593. ;-----------------------------------------------------------------
  594. ; newesc = __GetBits(escbits);
  595. ; *outbuffer++ = (startesc<<escbits8) | __GetBits(escbits8);
  596. ; startesc = newesc;
  597. ; continue;
  598. ;-----------------------------------------------------------------
  599. __NextBitIsClear_EscapeFromEscape:
  600. CORRECT_IN_MASK
  601. move.b d6,-(a7)
  602. move.w (a7)+,d0
  603. move.b (a6)+,d0
  604. move.b d0,d6
  605. lsr.w d7,d0 ;get8bits done
  606. move.b d5,d1 ;save old 'startesc'
  607. move.b d2,d5
  608. and.b d0,d5 ;set the new start esc
  609. not.b d2
  610. and.b d2,d0 ;isolate the lower bits
  611. not.b d2
  612. or.b d1,d0 ;recombine
  613. move.b d0,(a5)+
  614. jmp (a4)
  615. ifnd CALL_DIRECTLY
  616. dc.b "UNPACK_1"
  617. endc