Subversion Repositories pentevo

Rev

Rev 796 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include "std.h"
  2.  
  3. #include "emul.h"
  4. #include "vars.h"
  5. #include "wd93crc.h"
  6.  
  7. #include "util.h"
  8.  
  9. int FDD::write_td0(FILE *ff)
  10. {
  11.    unsigned char zerosec[256] = { 0 };
  12.    unsigned char td0hdr[12] = { 0 };
  13.  
  14.    *(unsigned short*)td0hdr = WORD2('T','D');
  15.    td0hdr[4] = 21; td0hdr[6] = 2; td0hdr[9] = (unsigned char)sides;
  16.    if (*dsc) td0hdr[7] = 0x80;
  17.    *(unsigned short*)(td0hdr + 10) = crc16(td0hdr, 10);
  18.    fwrite(td0hdr, 1, 12, ff);
  19.    if (*dsc) {
  20.       unsigned char inf[0x200] = { 0 };
  21.       strcpy((char*)inf+10, dsc);
  22.       unsigned len = unsigned(strlen(dsc)+1);
  23.       *(unsigned*)(inf+2) = len;
  24.       *(unsigned short*)inf = crc16(inf+2, len+8);
  25.       fwrite(inf, 1, len+10, ff);
  26.    }
  27.  
  28.    unsigned c; //Alone Coder 0.36.7
  29.    for (/*unsigned*/ c = 0; c < cyls; c++)
  30.       for (unsigned s = 0; s < sides; s++) {
  31.          t.seek(this,c,s,LOAD_SECTORS);
  32.          unsigned char bf[16];
  33.          *bf = u8(t.s);
  34.          bf[1] = u8(c); bf[2] = u8(s);
  35.          bf[3] = (unsigned char)crc16(bf, 3);
  36.          fwrite(bf, 1, 4, ff);
  37.          for (unsigned sec = 0; sec < t.s; sec++) {
  38.              if(!t.hdr[sec].data)
  39.              {
  40.                  t.hdr[sec].data = zerosec;
  41.                  t.hdr[sec].datlen = 256;
  42.                  t.hdr[sec].l = 1;
  43.              }
  44.             *(unsigned*)bf = *(unsigned*)&t.hdr[sec];
  45.             bf[4] = 0; // flags
  46.             bf[5] = (unsigned char)crc16(t.hdr[sec].data, t.hdr[sec].datlen);
  47.             *(unsigned short*)(bf+6) = u16(t.hdr[sec].datlen + 1);
  48.             bf[8] = 0; // compression type = none
  49.             fwrite(bf, 1, 9, ff);
  50.             if (fwrite(t.hdr[sec].data, 1, t.hdr[sec].datlen, ff) != t.hdr[sec].datlen) return 0;
  51.          }
  52.       }
  53.    c = WORD4(0xFF,0,0,0);
  54.    if (fwrite(&c, 1, 4, ff) != 4) return 0;
  55.    return 1;
  56. }
  57.  
  58.  
  59. unsigned unpack_lzh(unsigned char *src, unsigned size, unsigned char *buf);
  60.  
  61. // No ID address field was present for this sector,
  62. // but there is a data field. The sector information in
  63. // the header represents fabricated information.
  64. const ULONG TD0_SEC_NO_ID = 0x40;
  65.  
  66. // This sector's data field is missing; no sector data follows this header.
  67. const ULONG TD0_SEC_NO_DATA = 0x20;
  68.  
  69. // A DOS sector copy was requested; this sector was not allocated.
  70. // In this case, no sector data follows this header.
  71. const ULONG TD0_SEC_NO_DATA2 = 0x10;
  72.  
  73. #pragma pack(push, 1)
  74. struct TTd0Sec
  75. {
  76.     u8 c;
  77.     u8 h;
  78.     u8 s;
  79.     u8 n;
  80.     u8 flags;
  81.     u8 crc;
  82. };
  83. #pragma pack(pop)
  84.  
  85. int FDD::read_td0()
  86. {
  87.    if (*(short*)snbuf == WORD2('t','d'))
  88.    { // packed disk
  89.       unsigned char *tmp = (unsigned char*)malloc(snapsize);
  90.       memcpy(tmp, snbuf+12, snapsize-12);
  91.       snapsize = 12+unpack_lzh(tmp, snapsize-12, snbuf+12);
  92.       ::free(tmp);
  93.       //*(short*)snbuf = WORD2('T','D');
  94.    }
  95.  
  96.    char dscbuffer[sizeof(dsc)];
  97.    *dscbuffer = 0;
  98.  
  99.    unsigned char *start = snbuf+12;
  100.    if (snbuf[7] & 0x80) // coment record
  101.    {
  102.       start += 10;
  103.       unsigned len = *(unsigned short*)(snbuf+14);
  104.       start += len;
  105.       if (len >= sizeof dsc)
  106.           len = sizeof(dsc)-1;
  107.       memcpy(dscbuffer, snbuf+12+10, len);
  108.       dscbuffer[len] = 0;
  109.    }
  110.    unsigned char *td0_src = start;
  111.  
  112.    unsigned sides = (snbuf[9] == 1 ? 1 : 2);
  113.    unsigned max_cyl = 0;
  114.  
  115.    for (;;)
  116.    {
  117.       unsigned char s = *td0_src; // Sectors
  118.       if (s == 0xFF)
  119.           break;
  120.       max_cyl = max(max_cyl, unsigned(td0_src[1])); // PhysTrack
  121.       td0_src += 4; // sizeof(track_rec)
  122.       for (; s; s--)
  123.       {
  124.          unsigned char flags = td0_src[4];
  125.          td0_src += 6; // sizeof(sec_rec)
  126.  
  127.          assert(td0_src <= snbuf + snapsize);
  128.  
  129.          if (td0_src > snbuf + snapsize)
  130.              return 0;
  131.          td0_src += *(unsigned short*)td0_src + 2; // data_len
  132.       }
  133.    }
  134.  
  135.    if(max_cyl+1 > MAX_CYLS)
  136.    {
  137.        err_printf("cylinders (%d) > MAX_CYLS(%d)", max_cyl, MAX_CYLS);
  138.        return 0;
  139.    }
  140.  
  141.    newdisk(max_cyl+1, sides);
  142.    memcpy(dsc, dscbuffer, sizeof dsc);
  143.  
  144.    td0_src = start;
  145.    for (;;)
  146.    {
  147.       unsigned char t0[16384];
  148.       unsigned char *dst = t0;
  149.       unsigned char *trkh = td0_src;
  150.       td0_src += 4; // sizeof(track_rec)
  151.  
  152.       if(*trkh == 0xFF)
  153.           break;
  154.  
  155.       t.seek(this, trkh[1], trkh[2], JUST_SEEK);
  156.  
  157.       unsigned s = 0;
  158.       for (unsigned se = 0; se < trkh[0]; se++)
  159.       {
  160.          TTd0Sec *SecHdr = (TTd0Sec *)td0_src;
  161.          unsigned sec_size = 128U << (SecHdr->n & 3); // [vv]
  162.          unsigned char flags = SecHdr->flags;
  163. //         printf("fl=%x\n", flags);
  164. //         printf("c=%d, h=%d, s=%d, n=%d\n", SecHdr->c, SecHdr->h, SecHdr->s, SecHdr->n);
  165.          if(flags & (TD0_SEC_NO_ID | TD0_SEC_NO_DATA | TD0_SEC_NO_DATA2)) // skip sectors with no data & sectors without headers
  166.          {
  167.              td0_src += sizeof(TTd0Sec); // sizeof(sec_rec)
  168.  
  169.              unsigned src_size = *(unsigned short*)td0_src;
  170. //             printf("sz=%d\n", src_size);
  171.              td0_src += 2; // data_len
  172.              unsigned char *end_packed_data = td0_src + src_size;
  173. /*
  174.              u8 method = *td0_src++;
  175.              printf("m=%d\n", method);
  176.              switch(method)
  177.              {
  178.              case 0:
  179.                  {
  180.                      char name[MAX_PATH];
  181.                      sprintf(name, "%02d-%d-%03d-%d.trk", SecHdr->c, SecHdr->h, SecHdr->s, SecHdr->n);
  182.                      FILE *f = fopen(name, "wb");
  183.                      fwrite(td0_src, 1, src_size - 1, f);
  184.                      fclose(f);
  185.                      break;
  186.                  }
  187.              case 1:
  188.                  {
  189.                      unsigned n = *(unsigned short*)td0_src;
  190.                      td0_src += 2;
  191.                      unsigned short data = *(unsigned short*)td0_src;
  192.                      printf("len=%d, data=%04X\n", n, data);
  193.                      break;
  194.                  }
  195.              }
  196. */
  197.              td0_src = end_packed_data;
  198.              continue;
  199.          }
  200.  
  201.           // c, h, s, n
  202.          t.hdr[s].c = SecHdr->c;
  203.          t.hdr[s].s = SecHdr->h;
  204.          t.hdr[s].n = SecHdr->s;
  205.          t.hdr[s].l = SecHdr->n;
  206.          t.hdr[s].c1 = t.hdr[s].c2 = 0;
  207.          t.hdr[s].data = dst;
  208.  
  209.          td0_src += sizeof(TTd0Sec); // sizeof(sec_rec)
  210.  
  211.          unsigned src_size = *(unsigned short*)td0_src;
  212.          td0_src += 2; // data_len
  213.          unsigned char *end_packed_data = td0_src + src_size;
  214.  
  215.          if(src_size == 0)
  216.          {
  217.              printf("sector data size is zero\n");
  218.              goto shit;
  219.          }
  220.  
  221.          if(src_size > sec_size + 1)
  222.          {
  223.              printf("sector overflow: src_size=%u > (sec_size+1)=%u\n", src_size, sec_size + 1);
  224.              goto shit;
  225.          }
  226.  
  227.          memset(dst, 0, sec_size);
  228.  
  229.          switch (*td0_src++) // Method
  230.          {
  231.             case 0:  // raw sector
  232.                memcpy(dst, td0_src, src_size-1);
  233.                break;
  234.             case 1:  // repeated 2-byte pattern
  235.             {
  236.                unsigned n = *(unsigned short*)td0_src;
  237.                td0_src += 2;
  238.                unsigned short data = *(unsigned short*)td0_src;
  239.                for (unsigned i = 0; i < n; i++)
  240.                   *(unsigned short*)(dst+2*i) = data;
  241.                break;
  242.             }
  243.             case 2: // RLE block
  244.             {
  245.                u8 n;
  246.                unsigned char *d0 = dst;
  247.                do
  248.                {
  249.                   u8 RleData[510];
  250.                   u8 l = 2 * (*td0_src++);
  251.                   if(l == 0) // Zero count means a literal data block
  252.                   {
  253.                       n = *td0_src++;
  254.                       if(dst + n > d0 + sec_size)
  255.                       {
  256.                           printf("sector overflow: pos=0x%x, l=%u, n=%u, sec_size=%u, src_size=%u\n",
  257.                               unsigned(td0_src - 2 - snbuf), unsigned(l), unsigned(n), sec_size, src_size);
  258.                           goto shit;
  259.                       }
  260.                       memcpy(dst, td0_src, n);
  261.                       td0_src += n;
  262.                       dst += n;
  263.                   }
  264.                   else // repeated fragment
  265.                   {
  266.                       n = *td0_src++;
  267.                       memcpy(RleData, td0_src, l);
  268.                       td0_src += l;
  269.                       for ( ; n; n--)
  270.                       {
  271.                           if(dst + l > d0 + sec_size)
  272.                           {
  273.                               printf("sector overflow: pos=0x%x, dpos=0x%x, l=%u, sec_size=%u, src_size=%u\n",
  274.                                   unsigned(td0_src - 2 - snbuf), unsigned((dst + l) - d0), unsigned(l), sec_size, src_size);
  275.                               goto shit;
  276.                           }
  277.                           memcpy(dst, RleData, l);
  278.                           dst += l;
  279.                       }
  280.                   }
  281.                } while (td0_src < end_packed_data);
  282.                dst = d0;
  283.                break;
  284.             }
  285.             default: // error!
  286.             errmsg("unknown block type");
  287.  
  288.             shit:
  289.                errmsg("bad TD0 file");
  290.                return 0;
  291.          }
  292.          dst += sec_size;
  293.          td0_src = end_packed_data;
  294.          s++;
  295.       }
  296.       t.s = s;
  297.       t.format();
  298.    }
  299.    return 1;
  300. }
  301.  
  302. // ------------------------------------------------------ LZH unpacker
  303.  
  304.  
  305. static unsigned char *packed_ptr, *packed_end;
  306.  
  307. static unsigned readChar()
  308. {
  309.     if(packed_ptr < packed_end)
  310.     {
  311.         return *packed_ptr++;
  312.     }
  313.     else
  314.     {
  315.         return -1U;
  316.     }
  317. }
  318.  
  319. static unsigned char d_code[256] =
  320. {
  321.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  322.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  323.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  324.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  325.         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  326.         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  327.         0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
  328.         0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
  329.         0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  330.         0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  331.         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  332.         0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  333.         0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  334.         0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  335.         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  336.         0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
  337.         0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
  338.         0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
  339.         0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
  340.         0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
  341.         0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
  342.         0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
  343.         0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
  344.         0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
  345.         0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B,
  346.         0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F,
  347.         0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23,
  348.         0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
  349.         0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B,
  350.         0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F,
  351.         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  352.         0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
  353. };
  354.  
  355. static unsigned char d_len[256] =
  356. {
  357.         0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  358.         0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  359.         0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  360.         0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  361.         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  362.         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  363.         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  364.         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  365.         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  366.         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  367.         0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  368.         0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  369.         0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  370.         0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  371.         0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  372.         0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  373.         0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  374.         0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  375.         0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  376.         0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  377.         0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  378.         0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  379.         0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  380.         0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  381.         0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  382.         0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  383.         0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  384.         0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  385.         0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  386.         0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  387.         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  388.         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  389. };
  390.  
  391.  
  392. const int N = 4096;     // buffer size
  393. const int F = 60;       // lookahead buffer size
  394. const int THRESHOLD =   2;
  395. const int NIL = N;      // leaf of tree
  396.  
  397. static unsigned char text_buf[N + F - 1];
  398.  
  399. const int N_CHAR = (256 - THRESHOLD + F);       // kinds of characters (character code = 0..N_CHAR-1)
  400. const int T =   (N_CHAR * 2 - 1);       // size of table
  401. const int R = (T - 1);                  // position of root
  402. const int MAX_FREQ = 0x8000;            // updates tree when the
  403.                                     // root frequency comes to this value.
  404.  
  405. static unsigned short freq[T + 1];        // frequency table
  406.  
  407. static short prnt[T + N_CHAR]; // pointers to parent nodes, except for the
  408.                         // elements [T..T + N_CHAR - 1] which are used to get
  409.                         // the positions of leaves corresponding to the codes.
  410. static short son[T];           // pointers to child nodes (son[], son[] + 1)
  411.  
  412.  
  413. static int r;
  414.  
  415. static unsigned getbuf;
  416. static unsigned char getlen;
  417.  
  418. static int GetBit()      /* get one bit */
  419. {
  420.   unsigned i;
  421.  
  422.   while (getlen <= 8)
  423.   {
  424.       if((i = readChar()) == -1U)
  425.       {
  426.           i = 0;
  427.       }
  428.       getbuf |= unsigned(i << (8 - getlen));
  429.       getlen += 8;
  430.   }
  431.   i = getbuf;
  432.   getbuf <<= 1;
  433.   getlen--;
  434.   return ((i>>15) & 1);
  435. }
  436.  
  437. static int GetByte()     /* get one byte */
  438. {
  439.   unsigned i;
  440.  
  441.   while (getlen <= 8)
  442.   {
  443.       if((i = readChar()) == -1U)
  444.       {
  445.           i = 0;
  446.       }
  447.       getbuf |= unsigned(i << (8 - getlen));
  448.       getlen += 8;
  449.   }
  450.   i = getbuf;
  451.   getbuf <<= 8;
  452.   getlen -= 8;
  453.   return (i >> 8) & 0xFF;
  454. }
  455.  
  456. static void StartHuff()
  457. {
  458.   int i, j;
  459.  
  460.   getbuf = 0; getlen = 0;
  461.   for (i = 0; i < N_CHAR; i++) {
  462.     freq[i] = 1;
  463.     son[i] = i16(i + T);
  464.     prnt[i + T] = i16(i);
  465.   }
  466.   i = 0; j = N_CHAR;
  467.   while (j <= R) {
  468.     freq[j] = freq[i] + freq[i + 1];
  469.     son[j] = i16(i);
  470.     prnt[i] = prnt[i + 1] = i16(j);
  471.     i += 2; j++;
  472.   }
  473.   freq[T] = 0xffff;
  474.   prnt[R] = 0;
  475.  
  476.   for (i = 0; i < N - F; i++) text_buf[i] = ' ';
  477.   r = N - F;
  478. }
  479.  
  480. /* reconstruction of tree */
  481. static void reconst()
  482. {
  483.   int i, j, k;
  484.   int f;
  485.  
  486.   /* collect leaf nodes in the first half of the table */
  487.   /* and replace the freq by (freq + 1) / 2. */
  488.   j = 0;
  489.   for(i = 0; i < T; i++)
  490.   {
  491.     if(son[i] >= T)
  492.     {
  493.       freq[j] = (freq[i] + 1) / 2;
  494.       son[j] = son[i];
  495.       j++;
  496.     }
  497.   }
  498.   /* begin constructing tree by connecting sons */
  499.   for(i = 0, j = N_CHAR; j < T; i += 2, j++)
  500.   {
  501.     k = i + 1;
  502.     f = freq[j] = freq[i] + freq[k];
  503.     for(k = j - 1; f < freq[k]; k--);
  504.     k++;
  505.     size_t l = unsigned(j - k) * sizeof(*freq);
  506.     MoveMemory(&freq[k + 1], &freq[k], l);
  507.     freq[k] = u16(f);
  508.     MoveMemory(&son[k + 1], &son[k], l);
  509.     son[k] = i16(i);
  510.   }
  511.   /* connect prnt */
  512.   for (i = 0; i < T; i++)
  513.     if ((k = son[i]) >= T) prnt[k] = i16(i);
  514.     else prnt[k] = prnt[k + 1] = i16(i);
  515. }
  516.  
  517.  
  518. /* increment frequency of given code by one, and update tree */
  519.  
  520. static void update(int c)
  521. {
  522.   int i, j, k, l;
  523.  
  524.   if(freq[R] == MAX_FREQ) reconst();
  525.  
  526.   c = prnt[c + T];
  527.   do {
  528.     k = ++freq[c];
  529.  
  530.     /* if the order is disturbed, exchange nodes */
  531.     if (k > freq[l = c + 1])
  532.     {
  533.       while (k > freq[++l]);
  534.       l--;
  535.       freq[c] = freq[l];
  536.       freq[l] = u16(k);
  537.  
  538.       i = son[c];
  539.       prnt[i] = i16(l);
  540.       if (i < T) prnt[i + 1] = i16(l);
  541.  
  542.       j = son[l];
  543.       son[l] = i16(i);
  544.  
  545.       prnt[j] = i16(c);
  546.       if (j < T) prnt[j + 1] = i16(c);
  547.       son[c] = i16(j);
  548.  
  549.       c = l;
  550.     }
  551.   } while ((c = prnt[c]) != 0);  /* repeat up to root */
  552. }
  553.  
  554. static int DecodeChar()
  555. {
  556.   int c;
  557.  
  558.   c = son[R];
  559.  
  560.   /* travel from root to leaf, */
  561.   /* choosing the smaller child node (son[]) if the read bit is 0, */
  562.   /* the bigger (son[]+1} if 1 */
  563.   while(c < T) c = son[c + GetBit()];
  564.   c -= T;
  565.   update(c);
  566.   return c;
  567. }
  568.  
  569. static int DecodePosition()
  570. {
  571.   int i, j, c;
  572.  
  573.   /* recover upper 6 bits from table */
  574.   i = GetByte();
  575.   c = (int)d_code[i] << 6;
  576.   j = d_len[i];
  577.   /* read lower 6 bits verbatim */
  578.   j -= 2;
  579.   while (j--) i = (i << 1) + GetBit();
  580.   return c | (i & 0x3f);
  581. }
  582.  
  583. unsigned unpack_lzh(unsigned char *src, unsigned size, unsigned char *buf)
  584. {
  585.   packed_ptr = src; packed_end = src+size;
  586.   int  i, j, k, c;
  587.   unsigned count = 0;
  588.   StartHuff();
  589.  
  590. //  while (count < textsize)  // textsize - sizeof unpacked data
  591.   while (packed_ptr < packed_end)
  592.   {
  593.     c = DecodeChar();
  594.     if(c < 256)
  595.     {
  596.       *buf++ = u8(c);
  597.       text_buf[r++] = u8(c);
  598.       r &= (N - 1);
  599.       count++;
  600.     } else {
  601.       i = (r - DecodePosition() - 1) & (N - 1);
  602.       j = c - 255 + THRESHOLD;
  603.       for (k = 0; k < j; k++)
  604.       {
  605.         c = text_buf[(i + k) & (N - 1)];
  606.         *buf++ = u8(c);
  607.         text_buf[r++] = u8(c);
  608.         r &= (N - 1);
  609.         count++;
  610.       }
  611.     }
  612.   }
  613.   return count;
  614. }
  615.