home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_progs / fileutil / scan.lha / src / decodeit.asm < prev    next >
Encoding:
Assembly Source File  |  1992-05-21  |  11.9 KB  |  462 lines

  1. ;
  2. ; Copyright © 1991, 1992 by Walter Rothe. You may freely use and modify this
  3. ; program, but not for commercial profit. A modest fee for distribution is
  4. ; allowed. Derivative works must be released with source along with the
  5. ; executable or provisions made to provide the user source, if requested.
  6. ; Uploading source to a major bulletin board system within 6 months of the
  7. ; time of the request satisfies this requirement. This copyright notice
  8. ; must not be deleted from the source.
  9. ;
  10. ;:ts=8
  11.         far     data
  12.         machine mc68020
  13. ;/* decodes up to 'count' chars (but no more than WinSiz) into supplied
  14. ;buffer; returns actual count.  */
  15. ;
  16. ;#include "lh5.h"
  17. ;#define NP (DICBIT + 1)
  18. ;#define NT (CODE_BIT + 3)
  19. ;extern BufRead(), read_pt_len(), read_c_len();
  20. ;extern long BCount, HWinSiz, WinSiz;
  21. ;extern ulong bitbuf;
  22. ;extern int bitcount, decoded;
  23. ;extern uint jb, blocksize;
  24. ;extern ushort left[], right[], c_table[], pt_table[], LZBuf[];
  25. ;extern uchar c_len[], pt_len[];
  26. ;
  27. ;long decodeit( count, buffer)
  28. ;uint count;
  29. ;uchar buffer[];
  30. ;{
  31.         xdef    _decodeit
  32. _decodeit:
  33.         link    a5,#.2
  34.         movem.l .3,-(sp)
  35. ;   static uchar *savepi;
  36.         bss     .10001,4
  37. ;   register uint i;
  38. ;   register ulong bitbfr = bitbuf;
  39. ;   register int ct = bitcount, n;
  40. ;   uint mask;
  41. ;   uchar *bstrt  = &buffer[0], *bend = &buffer[count];
  42. ;   uchar *bguard = &buffer[WinSiz - 258], *blst = &buffer[WinSiz - 1];
  43. ;   register uchar *bufpi  = savepi, *bufpr = bstrt;
  44. ;   register uchar *bufend = bstrt + jb;
  45. ;   register uint blksz = blocksize;
  46. ;   register ushort *inbf = &LZBuf[ BCount ];
  47. ;   ushort *winend = &LZBuf[ HWinSiz ];
  48. ;
  49. ;   while (bufpr < bufend) {
  50.         move.l  _bitbuf,d3
  51.         move.l  _bitcount,d4
  52.         move.l  12(a5),-8(a5)
  53.         move.l  8(a5),d0
  54.         add.l   12(a5),d0
  55.         move.l  d0,-12(a5)
  56.         move.l  12(a5),-16(a5)
  57.         move.l  -16(a5),a0
  58.         add.l   _WinSiz,a0
  59.         move.l  a0,-16(a5)
  60.         sub.l   #258,-16(a5)
  61.         move.l  12(a5),-20(a5)
  62.         move.l  -20(a5),a0
  63.         add.l   _WinSiz,a0
  64.         move.l  a0,-20(a5)
  65.         sub.l   #1,-20(a5)
  66.         move.l  .10001,a2
  67.         move.l  -8(a5),a3
  68.         move.l  _jb,d6
  69.         add.l   -8(a5),d6
  70.         move.l  _blocksize,d7
  71.         move.l  _BCount,d0
  72.         add.l   d0,d0
  73.         lea.l   _LZBuf,a1
  74.         add.l   d0,a1
  75.         move.l  _HWinSiz,d0
  76.         add.l   d0,d0
  77.         lea.l   _LZBuf,a0
  78.         add.l   a0,d0
  79.         move.l  d0,-28(a5)
  80. ; Clear upper half of d2 and it should not be modified
  81.         move.l  #0,d2
  82.         move.l  #0,d5
  83. .10002
  84.         cmp.l   d6,a3
  85.         bcc     .10003
  86. ;      *bufpr++ = *bufpi++;
  87.         move.b  (a2)+,(a3)+
  88. ;      if( bufpi > blst ) bufpi = bstrt;
  89.         cmp.l   -20(a5),a2
  90.         bls     .10004
  91.         move.l  -8(a5),a2
  92. ;      if (bufpr == bend) goto savret;
  93. .10004
  94.         cmp.l   -12(a5),a3
  95.         beq     .10005
  96. ;   }
  97.         bra     .10002
  98. .10003
  99. ;   for ( ; ; ) {
  100. .10006
  101. ;      /* decode character */
  102. ;      if (--blksz == 0) {
  103.         sub.l   #1,d7
  104.         bne     .10008
  105. ;         bitbuf = bitbfr; bitcount = ct; BCount = (inbf - &LZBuf[0]);
  106.         move.l  d3,_bitbuf
  107.         move.l  d4,_bitcount
  108.         sub.l   #_LZBuf,a1
  109.         move.l  a1,d0
  110.         lsr.l   #1,d0
  111.         move.l  d0,_BCount
  112. ;         blksz = getbits(16);
  113.         pea     16
  114.         jsr     _getbits
  115.         move.l  d0,d7
  116. ;         if (blksz == 0) {
  117.         tst.l   d7
  118.         add.w   #4,sp
  119.         bne     .10009
  120. ;            blocksize = blksz; savepi = bufpi; jb = bufend - bufpr; return 0;
  121.         move.l  d7,_blocksize
  122.         move.l  a2,.10001
  123.         move.l  d6,d0
  124.         sub.l   a3,d0
  125.         move.l  d0,_jb
  126.         move.l  #0,d0
  127. .4
  128.         movem.l (sp)+,.3
  129.         unlk    a5
  130.         rts
  131. ;         }
  132. ;         read_pt_len(NT, 5, 3); /* 5=smallest int so that 1<<5 > NT */
  133. .10009
  134.         pea     3
  135.         pea     5
  136.         pea     19
  137.         jsr     _read_pt_len
  138. ;         read_c_len();
  139.         jsr     _read_c_len
  140. ;         read_pt_len(NP, 4, -1); /* 4=smallest int so that 1<<4 > NP */
  141.         pea     -1
  142.         pea     4
  143.         pea     14
  144.         jsr     _read_pt_len
  145. ;         bitbfr = bitbuf; ct = bitcount; inbf = &LZBuf[ BCount ];
  146.         move.l  _bitbuf,d3
  147.         move.l  _bitcount,d4
  148.         move.l  _BCount,a1
  149.         add.l   a1,a1
  150.         add.l   #_LZBuf,a1
  151. ;      }
  152. ;      i = c_table[bitbfr >> (BITBUFSIZ - 12)];
  153.         lea     24(sp),sp
  154. .10008
  155.         move.l  d3,d0
  156.         move.l  #20,d1
  157.         lsr.l   d1,d0
  158.         add.l   d0,d0
  159.         lea     _c_table,a0
  160.         move.w  (a0,d0.w),d2
  161. ;      if (i >= NC) {
  162.         cmp.l   #510,d2
  163.         bcs     .10010
  164. ;         mask = (unsigned) 1 << (BITBUFSIZ - 1 - 12);
  165.         move.l  #524288,-4(a5)
  166. ;         do {
  167. .10013
  168. ;            if (bitbfr & mask) i = right[i];
  169.         move.l  d3,d0
  170.         and.l   -4(a5),d0
  171.         beq     .10014
  172.         move.l  d2,d0
  173.         add.l   d0,d0
  174.         lea     _right,a0
  175.         move.l  #0,d1
  176.         move.w  (a0,d0.l),d1
  177.         move.l  d1,d2
  178. ;            else               i = left [i];
  179.         bra     .10015
  180. .10014
  181.         move.l  d2,d0
  182.         add.l   d0,d0
  183.         lea     _left,a0
  184.         move.l  #0,d1
  185.         move.w  (a0,d0.l),d1
  186.         move.l  d1,d2
  187. .10015
  188. ;            mask >>= 1;
  189.         move.l  -4(a5),d0
  190.         lsr.l   #1,d0
  191.         move.l  d0,-4(a5)
  192. ;         } while (i >= NC);
  193. .10011
  194.         cmp.l   #510,d2
  195.         bcc     .10013
  196. .10012
  197. ;      }
  198. ;      n = c_len[i];
  199. .10010
  200.         lea     _c_len,a0
  201.         move.b  (a0,d2.w),d5
  202. ;      bitbfr <<= n;
  203.         asl.l   d5,d3
  204. ;      ct += n;
  205.         add.l   d5,d4
  206. ;      if ( ct >= 16) {
  207.         cmp.l   #16,d4
  208.         blt     .10016
  209. ;         ct -= 16;
  210.         sub.l   #16,d4
  211. ;         if( inbf == winend ) { BufRead(); inbf = &LZBuf[0]; }
  212.         cmp.l   -28(a5),a1
  213.         bne     .10017
  214.         jsr     _BufRead
  215.         lea.l   _LZBuf,a1
  216. ;         bitbfr = ( *inbf++ | ((bitbfr >> ct) & 0xffff0000)) << ct;
  217. .10017
  218.         lsr.l   d4,d3
  219.         move.w  (a1)+,d3
  220.         asl.l   d4,d3
  221. ;      }
  222. ;      if (i <= UCHAR_MAX) { *bufpr++ = i; if( bufpr == bend) goto savret; }
  223. .10016
  224.         cmp.l   #255,d2
  225.         bhi     .10018
  226.         move.b  d2,(a3)+
  227.         cmp.l   -12(a5),a3
  228.         bne     .10006
  229. ;      else {
  230.         bra     .10005
  231. .10018
  232. ;         bufend = bufpr + i - (UCHAR_MAX + 1 - THRESHOLD);
  233.         move.l  d2,d6
  234.         add.l   a3,d6
  235.         add.l   #-253,d6
  236. ;         /* decode position */
  237. ;         i = pt_table[bitbfr >> (BITBUFSIZ - 8)];
  238.         move.l  d3,d0
  239.         move.l  #24,d1
  240.         lsr.l   d1,d0
  241.         add.l   d0,d0
  242.         lea     _pt_table,a0
  243.         move.w  (a0,d0.w),d2
  244. ;         if (i >= NP) {
  245.         cmp.l   #14,d2
  246.         bcs     .10020
  247. ;            mask = (unsigned) 1 << (BITBUFSIZ - 1 - 8);
  248.         move.l  #8388608,-4(a5)
  249. ;            do {
  250. .10023
  251. ;               if (bitbfr & mask) i = right[i];
  252.         move.l  d3,d0
  253.         and.l   -4(a5),d0
  254.         beq     .10024
  255.         move.l  d2,d0
  256.         add.l   d0,d0
  257.         lea     _right,a0
  258.         move.l  #0,d1
  259.         move.w  (a0,d0.l),d1
  260.         move.l  d1,d2
  261. ;               else               i = left [i];
  262.         bra     .10025
  263. .10024
  264.         move.l  d2,d0
  265.         add.l   d0,d0
  266.         lea     _left,a0
  267.         move.l  #0,d1
  268.         move.w  (a0,d0.l),d1
  269.         move.l  d1,d2
  270. .10025
  271. ;               mask >>= 1;
  272.         move.l  -4(a5),d0
  273.         lsr.l   #1,d0
  274.         move.l  d0,-4(a5)
  275. ;            } while (i >= NP);
  276. .10021
  277.         cmp.l   #14,d2
  278.         bcc     .10023
  279. .10022
  280. ;         }
  281. ;         n = pt_len[i];
  282. .10020
  283.         lea     _pt_len,a0
  284.         move.b  (a0,d2.w),d5
  285. ;         bitbfr <<= n;
  286.         asl.l   d5,d3
  287. ;         ct += n;
  288.         add.l   d5,d4
  289. ;         if ( ct >= 16) {
  290.         cmp.l   #16,d4
  291.         blt     .10026
  292. ;            ct -= 16;
  293.         sub.l   #16,d4
  294. ;            if( inbf == winend ) { BufRead(); inbf = &LZBuf[0]; }
  295.         cmp.l   -28(a5),a1
  296.         bne     .10027
  297.         jsr     _BufRead
  298.         lea.l   _LZBuf,a1
  299. ;            bitbfr = ( *inbf++ | ((bitbfr >> ct) & 0xffff0000)) << ct;
  300. .10027
  301.         lsr.l   d4,d3
  302.         move.w  (a1)+,d3
  303.         asl.l   d4,d3
  304. ;         }
  305. ;         if (i != 0) {
  306. .10026
  307.         tst.l   d2
  308.         beq     .10028
  309. ;            n = i - 1;
  310.         move.l  d2,d5
  311.         sub.l   #1,d5
  312. ;            i = ((unsigned) 1 << n) + (bitbfr >> (BITBUFSIZ - n));
  313. ;            bitbfr <<= n;
  314.         move.l  d3,d2
  315.         rol.l   d5,d2
  316.         lsl.l   d5,d3
  317.         eor.l   d3,d2
  318.         bset.l  d5,d2
  319. ;            ct += n;
  320.         add.l   d5,d4
  321. ;            if ( ct >= 16) {
  322.         cmp.l   #16,d4
  323.         blt     .10029
  324. ;               ct -= 16;
  325.         sub.l   #16,d4
  326. ;               if( inbf == winend ) { BufRead(); inbf = &LZBuf[0]; }
  327.         cmp.l   -28(a5),a1
  328.         bne     .10030
  329.         jsr     _BufRead
  330.         lea.l   _LZBuf,a1
  331. ;               bitbfr = ( *inbf++ | ((bitbfr >> ct) & 0xffff0000))<<ct;
  332. .10030
  333.         lsr.l   d4,d3
  334.         move.w  (a1)+,d3
  335.         asl.l   d4,d3
  336. ;            }
  337. ;         }
  338. .10029
  339. ;         bufpi = bufpr - i - 1;
  340. .10028
  341.         move.l  a3,a2
  342.         sub.l   d2,a2
  343.         add.l   #-1,a2
  344. ;         if( bufpi >= bstrt ) {
  345.         cmp.l   -8(a5),a2
  346.         bcs     .10031
  347. ;            if( bufend < bend ) {
  348.         cmp.l   -12(a5),d6
  349.         bcc     .10032
  350. ;               *bufpr++ = *bufpi++;
  351.         move.b  (a2)+,(a3)+
  352. ;               *bufpr++ = *bufpi++;
  353.         move.b  (a2)+,(a3)+
  354. ;               do *bufpr++ = *bufpi++; while (bufpr < bufend);
  355. .10035
  356.         move.b  (a2)+,(a3)+
  357.         cmp.l   d6,a3
  358.         bcs     .10035
  359. ;            }
  360. ;            else { while( bufpr < bend ) *bufpr++ = *bufpi++; goto savret; }
  361.         bra     .10006
  362. .10032
  363.         cmp.l   -12(a5),a3
  364.         bcc     .10005
  365.         move.b  (a2)+,(a3)+
  366.         bra     .10032
  367. ;         }
  368. ;         else {
  369. .10031
  370. ;            bufpi += WinSiz;
  371.         add.l   _WinSiz,a2
  372. ;            if( bufpi < bguard ) {
  373.         cmp.l   -16(a5),a2
  374.         bcc     .10040
  375. ;               if( bufend < bend ) {
  376.         cmp.l   -12(a5),d6
  377.         bcc     .10041
  378. ;                  *bufpr++ = *bufpi++;
  379.         move.b  (a2)+,(a3)+
  380. ;                  *bufpr++ = *bufpi++;
  381.         move.b  (a2)+,(a3)+
  382. ;                  do *bufpr++ = *bufpi++; while (bufpr < bufend);
  383. .10044
  384.         move.b  (a2)+,(a3)+
  385.         cmp.l   d6,a3
  386.         bcs     .10044
  387. ;               }
  388. ;               else { while( bufpr < bend ) *bufpr++ = *bufpi++; goto savret; }
  389.         bra     .10006
  390. .10041
  391.         cmp.l   -12(a5),a3
  392.         bcc     .10005
  393.         move.b  (a2)+,(a3)+
  394.         bra     .10041
  395. ;            }
  396. ;            else {
  397. .10040
  398. ;               while (bufpr < bufend) {
  399. .10049
  400.         cmp.l   d6,a3
  401.         bcc     .10006
  402. ;                  *bufpr++ = *bufpi++;
  403.         move.b  (a2)+,(a3)+
  404. ;                  if( bufpi > blst ) bufpi = bstrt;
  405.         cmp.l   -20(a5),a2
  406.         bls     .10051
  407.         move.l  -8(a5),a2
  408. ;                  if (bufpr == bend) goto savret;
  409. .10051
  410.         cmp.l   -12(a5),a3
  411.         beq     .10005
  412. ;               }
  413.         bra     .10049
  414. ;            }
  415. ;         }
  416. ;      }
  417. ;   }
  418. ;   savret: bitbuf = bitbfr; bitcount = ct; jb = bufend - bufpr;
  419. .10005
  420.         move.l  d3,_bitbuf
  421.         move.l  d4,_bitcount
  422.         move.l  d6,d0
  423.         sub.l   a3,d0
  424.         move.l  d0,_jb
  425. ;   BCount = (inbf - &LZBuf[0]);
  426.         sub.l   #_LZBuf,a1
  427.         move.l  a1,d0
  428.         asr.l   #1,d0
  429.         move.l  d0,_BCount
  430. ;   savepi = bufpi; blocksize = blksz;
  431.         move.l  a2,.10001
  432.         move.l  d7,_blocksize
  433. ;   return (long)(bufpr - bstrt);
  434.         move.l  a3,d0
  435.         sub.l   -8(a5),d0
  436.         bra     .4
  437. ;}
  438. .2      equ     -28
  439. .3      reg     d2/d3/d4/d5/d6/d7/a2/a3
  440. ;
  441.         xref    _read_c_len
  442.         xref    _read_pt_len
  443.         xref    _BufRead
  444.         xref    _getbits
  445.         xref    .begin
  446.         dseg
  447.         xref    _pt_len
  448.         xref    _c_len
  449.         xref    _LZBuf
  450.         xref    _pt_table
  451.         xref    _c_table
  452.         xref    _blocksize
  453.         xref    _jb
  454.         xref    _bitcount
  455.         xref    _HWinSiz
  456.         xref    _WinSiz
  457.         xref    _BCount
  458.         xref    _right
  459.         xref    _left
  460.         xref    _bitbuf
  461.         end
  462.