pst-ttuf.h 21 KB

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