Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. // this is not a code to be separately compiled!
  2. // instead, it is included in mhmt-depack.c several times and depends on existing at include moment #define's to generate some compiling code
  3. //
  4. //                   // example defines:
  5. //#define DPK_CHECK  // check input stream for consistency
  6. //#define DPK_DEPACK // do depacking
  7. //#define DPK_REPERR // report errors via printf
  8. {
  9.         LONG i;
  10.  
  11.         ULONG check;
  12.         ULONG byte,bits;//,bitlen;
  13.  
  14.         LONG   disp=0;
  15.         LONG length=0; // if -3 - insertion match, if 0 - nothing to do
  16.  
  17.         ULONG skipdisp,skiplen;
  18.  
  19.         ULONG disptype;
  20. // fetch byte and add to existing disp
  21. #define DISP_PLUSBYTE 0
  22. // fetch 5 bits to disp
  23. #define DISP_ABCDE    1
  24. // common disp for 3+ lengthes
  25. #define DISP_COMMON   2
  26.  
  27.         ULONG docopy; // do copy from input instead of repeating
  28.  
  29.         ULONG expbitlen = 2; // expandable displacement
  30.  
  31.  
  32.         ULONG stop;
  33.  
  34.  
  35.         ULONG success = 1;
  36.  
  37.  
  38.  
  39.  
  40.  
  41.         // rewind input stream
  42.         //
  43.         check = depack_getbyte(DEPACK_GETBYTE_REWIND);
  44. #ifdef DPK_CHECK
  45.         if( 0xFFFFFFFF == check )
  46.         {
  47.  #ifdef DPK_REPERR
  48.                 printf("mhmt-depack-hrust.c:{} - Can't rewind input stream!\n");
  49.  #endif
  50.                 return 0;
  51.         }
  52. #endif
  53.  
  54.  
  55.         // manage zx header if needed
  56.         if( wrk.zxheader )
  57.         {
  58.                 // check for "HR" in beginning
  59.                 check = depack_getbyte(DEPACK_GETBYTE_NEXT);
  60. #ifdef DPK_CHECK
  61.                 if( 0xFFFFFFFF == check ) goto NO_BYTE_HST;
  62.                 if( check != 'H' )
  63.                 {
  64.  #ifdef DPK_REPERR
  65.                         printf("mhmt-depack-hrust.c:{} - Bad zx-header!\n");
  66.  #endif
  67.                         return 0;
  68.                 }
  69. #endif
  70.                 check = depack_getbyte(DEPACK_GETBYTE_NEXT);
  71. #ifdef DPK_CHECK
  72.                 if( 0xFFFFFFFF == check ) goto NO_BYTE_HST;
  73.                 if( check != 'R' )
  74.                 {
  75.  #ifdef DPK_REPERR
  76.                         printf("mhmt-depack-hrust.c:{} - Bad zx-header!\n");
  77.  #endif
  78.                         return 0;
  79.                 }
  80. #endif
  81.  
  82.                 // skip 10 bytes
  83.                 for(i=0;i<10;i++)
  84.                 {
  85.                         check = depack_getbyte(DEPACK_GETBYTE_NEXT);
  86. #ifdef DPK_CHECK
  87.                         if( 0xFFFFFFFF == check ) goto NO_BYTE_HST;
  88. #endif
  89.                 }
  90.         }
  91.  
  92.  
  93.  
  94.         // initialize bitstream first
  95.         //
  96.         check = depack_getbits(16,DEPACK_GETBITS_FORCE); // number 16 is ignored! - just for convenience here...
  97. #ifdef DPK_CHECK
  98.         if( 0xFFFFFFFF == check )
  99.         {
  100. NO_BITS_HST:
  101.  #ifdef DPK_REPERR
  102.                 printf("mhmt-depack-hrust.c:{} - Can't get bits from input stream!\n");
  103.  #endif
  104.                 return 0;
  105.         }
  106. #endif
  107.  
  108.  
  109.  
  110.         // then byte of input stream goes to the output unchanged
  111.         //
  112.         byte = depack_getbyte(DEPACK_GETBYTE_NEXT);
  113. #ifdef DPK_CHECK
  114.         if( 0xFFFFFFFF == byte )
  115.         {
  116. NO_BYTE_HST:
  117.  #ifdef DPK_REPERR
  118.                 printf("mhmt-depack-hrust.c:{} - Can't get byte from input stream!\n");
  119.  #endif
  120.                 return 0;
  121.         }
  122. #endif
  123.  
  124. #ifdef DPK_DEPACK
  125.         success = success && depack_outbyte( (UBYTE)(0x00FF&byte), DEPACK_OUTBYTE_ADD );
  126. #endif
  127.  
  128.  
  129.  
  130.         // now normal depacking loop
  131.         //
  132.         stop = 0;
  133.         while( (!stop) && success )
  134.         {
  135.                 skiplen  = 0;
  136.                 skipdisp = 0;
  137.                 disptype = DISP_PLUSBYTE;
  138.                 docopy = 0;
  139.  
  140.                 bits = depack_getbits(1,DEPACK_GETBITS_NEXT);
  141. #ifdef DPK_CHECK
  142.                 if( 0xFFFFFFFF == bits )
  143.                 {
  144.                         #ifdef DBG
  145.                         printf("line %d\n",__LINE__);
  146.                         #endif
  147.                         goto NO_BITS_HST;
  148.                 }
  149. #endif
  150.  
  151.                 if( 1&bits ) // %1<byte>
  152.                 {
  153.                         docopy = 1;
  154.                         length = 1;
  155.                 }
  156.                 else // %0xx
  157.                 {
  158.                         bits = depack_getbits(2,DEPACK_GETBITS_NEXT);
  159. #ifdef DPK_CHECK
  160.                         if( 0xFFFFFFFF == bits )
  161.                         {
  162.                                 #ifdef DBG
  163.                                 printf("line %d\n",__LINE__);
  164.                                 #endif
  165.                                 goto NO_BITS_HST;
  166.                         }
  167. #endif
  168.  
  169.                         switch( bits&3 )
  170.                         {
  171.                         case 0: // %000xxx
  172.  
  173.                                 bits = depack_getbits(3,DEPACK_GETBITS_NEXT);
  174. #ifdef DPK_CHECK
  175.                                 if( 0xFFFFFFFF == bits )
  176.                                 {
  177.                                         #ifdef DBG
  178.                                         printf("line %d\n",__LINE__);
  179.                                         #endif
  180.                                         goto NO_BITS_HST;
  181.                                 }
  182. #endif
  183.  
  184.                                 disp = (-8) | (bits&0x07); // FFFFFFF8..FFFFFFFF (-8..-1)
  185.                                 length = 1;
  186.  
  187.                                 skiplen  = 1;
  188.                                 skipdisp = 1;
  189.  
  190.                                 break;
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.                         case 1: // %001 - 2 bytes or insertion match part 1
  198.  
  199.                                 length = 2;
  200.                                 skiplen = 1;
  201.  
  202.                                 bits = depack_getbits(2,DEPACK_GETBITS_NEXT);
  203. #ifdef DPK_CHECK
  204.                                         if( 0xFFFFFFFF == bits )
  205.                                         {
  206.                                                 #ifdef DBG
  207.                                                 printf("line %d\n",__LINE__);
  208.                                                 #endif
  209.                                                 goto NO_BITS_HST;
  210.                                         }
  211. #endif
  212.  
  213.                                 switch( bits&3 )
  214.                                 {
  215.                                 case 0: // %001 00 - disp FDxx
  216.                                         //disptype = DISP_PLUSBYTE; // default value
  217.                                         disp = (-768);
  218.  
  219.                                         break;
  220.  
  221.                                 case 1: // %001 01 - disp FExx
  222.                                         //disptype = DISP_PLUSBYTE; // default value
  223.                                         disp = (-512);
  224.  
  225.                                         break;
  226.  
  227.                                 case 2: // %001 10 - ff00..ffdf or insertion match
  228.  
  229.                                         byte = depack_getbyte(DEPACK_GETBYTE_NEXT);
  230. #ifdef DPK_CHECK
  231.                                         if( 0xFFFFFFFF == byte ) goto NO_BYTE_HST;
  232. #endif
  233.                                         skipdisp = 1;
  234.  
  235.                                         if( byte<0x00E0 ) // ff00..ffdf
  236.                                         {
  237.                                                 disp = (-256) | (byte&0x00FF);
  238.                                         }
  239.                                         else if( byte==0x00FE ) // expand bitlen of expandable displacement
  240.                                         {
  241.                                                 #ifdef DBG
  242.                                                         printf("expansion\n");
  243.                                                 #endif
  244.  
  245.                                                 length = 0; // nothing to do
  246.                                                 expbitlen++;
  247. //#ifdef DPK_CHECK
  248. //                                              if( expbitlen>8 )
  249. //                                              {
  250. // #ifdef DPK_REPERR
  251. //                                                      printf("mhmt-depack-hrust.c:{} - bitlen of expandable displacement expanded more than 16 bits!\n");
  252. // #endif
  253. //                                                      return 0;
  254. //                                              }
  255. //#endif
  256.                                                 // this is the fix to mimic Z80 depacker (what seems to be perfectly correct!)
  257.                                                 if( expbitlen > 8 )
  258.                                                         expbitlen = 1;
  259.                                         }
  260.                                         else // insertion match - xor 2
  261.                                         {
  262.                                                 length = (-3); // mark insertion match
  263.  
  264.                                                 byte = ((byte<<1)&0x00FE) | ((byte>>7)&0x01); // byte<<<1
  265.                                                 byte ^= 0x02;
  266.                                                 byte -= 15;
  267.  
  268.                                                 disp = (-256) | (byte&0x00FF);
  269.                                         }
  270.                                         break;
  271.  
  272.                                 case 3: // %001 11 - disp FFE0+[abcde]
  273.  
  274.                                         disptype = DISP_ABCDE;
  275.  
  276.                                         break;
  277.                                 }
  278.  
  279.                                 break;
  280.  
  281.  
  282.  
  283.                         case 2: // %010 - 3 bytes or something
  284.  
  285.                                 length = 3;
  286.                                 skiplen = 1;
  287.                                 disptype = DISP_COMMON;
  288.  
  289.                                 break;
  290.  
  291.  
  292.                         case 3: // %011 - varlen
  293.  
  294.                                 disptype = DISP_COMMON;
  295.  
  296.                                 break;
  297.                         }
  298.                 }
  299.  
  300.                         if( (!stop) && (!skiplen) && (!docopy) )
  301.                         {
  302.                                 // read variable length
  303.                                 bits = depack_getbits(2,DEPACK_GETBITS_NEXT);
  304. #ifdef DPK_CHECK
  305.                                 if( 0xFFFFFFFF == bits )
  306.                                 {
  307.                                         #ifdef DBG
  308.                                         printf("line %d\n",__LINE__);
  309.                                         #endif
  310.                                         goto NO_BITS_HST;
  311.                                 }
  312. #endif                                                                                
  313.                                 switch( bits&3 )
  314.                                 {
  315.                                 case 0: // special cases
  316.  
  317.                                         bits = depack_getbits(1,DEPACK_GETBITS_NEXT);
  318. #ifdef DPK_CHECK
  319.                                         if( 0xFFFFFFFF == bits )
  320.                                         {
  321.                                                 #ifdef DBG
  322.                                                 printf("line %d\n",__LINE__);
  323.                                                 #endif
  324.                                                 goto NO_BITS_HST;
  325.                                         }
  326. #endif
  327.                                         if( bits&1 ) // %011 001abcd<byte> - insertion match, displacements -1..-16
  328.                                         {
  329.                                                 bits = depack_getbits(4,DEPACK_GETBITS_NEXT);
  330. #ifdef DPK_CHECK
  331.                                                 if( 0xFFFFFFFF == bits )
  332.                                                 {
  333.                                                         #ifdef DBG
  334.                                                         printf("line %d\n",__LINE__);
  335.                                                         #endif
  336.                                                         goto NO_BITS_HST;
  337.                                                 }
  338. #endif
  339.                                                 length = (-3); // mark insertion match
  340.  
  341.                                                 skipdisp = 1; // prepare displacement
  342.                                                 disp = (-16) | (bits&15);
  343.                                         }
  344.                                         else
  345.                                         {
  346.                                                 bits = depack_getbits(1,DEPACK_GETBITS_NEXT);
  347. #ifdef DPK_CHECK
  348.                                                 if( 0xFFFFFFFF == bits )
  349.                                                 {
  350.                                                         #ifdef DBG
  351.                                                         printf("line %d\n",__LINE__);
  352.                                                         #endif
  353.                                                         goto NO_BITS_HST;
  354.                                                 }
  355. #endif
  356.                                                 if( bits&1 ) // %011 0001abcd - copy-many-bytes
  357.                                                 {
  358.                                                         bits = depack_getbits(4,DEPACK_GETBITS_NEXT);
  359. #ifdef DPK_CHECK
  360.                                                         if( 0xFFFFFFFF == bits )
  361.                                                         {
  362.                                                                 #ifdef DBG
  363.                                                                 printf("line %d\n",__LINE__);
  364.                                                                 #endif
  365.                                                                 goto NO_BITS_HST;
  366.                                                         }
  367. #endif
  368.                                                         length = ((bits&15)+6)<<1;
  369.                                                         skipdisp = 1;
  370.                                                         docopy = 1;
  371.                                                 }
  372.                                                 else // %011 0000abcdefg[<byte>] - longer lengthes
  373.                                                 {
  374.                                                         bits = depack_getbits(7,DEPACK_GETBITS_NEXT);
  375. #ifdef DPK_CHECK
  376.                                                         if( 0xFFFFFFFF == bits )
  377.                                                         {
  378.                                                                 #ifdef DBG
  379.                                                                 printf("line %d\n",__LINE__);
  380.                                                                 #endif
  381.                                                                 goto NO_BITS_HST;
  382.                                                         }
  383. #endif
  384.                                                         bits &= 127;
  385.  
  386.                                                         if( bits==15 ) // stop depack
  387.                                                         {
  388.                                                                 stop=1;
  389.                                                         }
  390.                                                         else if( bits>15 ) // 16..127
  391.                                                         {
  392.                                                                 length = bits;
  393.                                                         }
  394.                                                         else // 0..14: longer lengthes
  395.                                                         {
  396.                                                                 byte = depack_getbyte(DEPACK_GETBYTE_NEXT);
  397. #ifdef DPK_CHECK
  398.                                                                 if( 0xFFFFFFFF == byte ) goto NO_BYTE_HST;
  399. #endif
  400.                                                                 length = (bits<<8) + (byte&0x00FF);
  401.                                                         }
  402.                                                 }
  403.                                         }
  404.                                         break;
  405.                                 case 1: // %01101
  406.                                         length = 4;
  407.                                         break;
  408.                                 case 2: // %01110
  409.                                         length = 5;
  410.                                         break;
  411.                                 case 3: // variable length (6-15), %01111...
  412.  
  413.                                         length = 6;
  414.                                         do
  415.                                         {
  416.                                                 bits = depack_getbits(2,DEPACK_GETBITS_NEXT);
  417. #ifdef DPK_CHECK
  418.                                                 if( 0xFFFFFFFF == bits )
  419.                                                 {
  420.                                                         #ifdef DBG
  421.                                                         printf("line %d\n",__LINE__);
  422.                                                         #endif
  423.                                                         goto NO_BITS_HST;
  424.                                                 }
  425. #endif                                                                                  
  426.                                                 bits &= 3;
  427.                                                 length += bits;
  428.  
  429.                                         } while( (bits==3) && (length<15) );
  430.                                         break;
  431.                                 }
  432.                         }
  433.  
  434.                         if( (!stop) && (!skipdisp) && (!docopy) )
  435.                         {
  436.                                 // extract displacement
  437.  
  438.                                 switch( disptype )
  439.                                 {
  440.                                 case DISP_COMMON:
  441.  
  442.                                         bits = depack_getbits(2,DEPACK_GETBITS_NEXT);
  443. #ifdef DPK_CHECK
  444.                                         if( 0xFFFFFFFF == bits )
  445.                                         {
  446.                                                 #ifdef DBG
  447.                                                 printf("line %d\n",__LINE__);
  448.                                                 #endif
  449.                                                 goto NO_BITS_HST;
  450.                                         }
  451. #endif                                                                                  
  452.                                         bits &= 3;
  453.                                         if( !bits ) // %00<byte> - fe00..feff
  454.                                         {
  455.                                                 disp = (-512);
  456.                                                 disptype=DISP_PLUSBYTE; // we fall in next section and there is check
  457.                                                 // NO break!
  458.                                         }
  459.                                         else if( bits==1 ) // %01<byte> - ff00..ffdf
  460.                                         {
  461.                                                 disp = (-256);
  462.                                                 // NO break!
  463.                                                 // no check for byte in range e0..ff here - but in next switch section!
  464.                                         }
  465.                                         else if( bits==2 ) // %10abcde - ffe0..ffff
  466.                                         {
  467.                                                 bits = depack_getbits(5,DEPACK_GETBITS_NEXT);
  468. #ifdef DPK_CHECK
  469.                                                 if( 0xFFFFFFFF == bits )
  470.                                                 {
  471.                                                         #ifdef DBG
  472.                                                         printf("line %d\n",__LINE__);
  473.                                                         #endif
  474.                                                         goto NO_BITS_HST;
  475.                                                 }
  476. #endif                                                                                  
  477.                                                 disp = (-32) | (bits&31);
  478.  
  479.                                                 break;
  480.                                         }
  481.                                         else // %11... - expanding displacement
  482.                                         {
  483.                                                 bits = depack_getbits(expbitlen,DEPACK_GETBITS_NEXT);
  484. #ifdef DPK_CHECK
  485.                                                 if( 0xFFFFFFFF == bits )
  486.                                                 {
  487.                                                         #ifdef DBG
  488.                                                         printf("line %d\n",__LINE__);
  489.                                                         #endif
  490.                                                         goto NO_BITS_HST;
  491.                                                 }
  492. #endif                                                                                  
  493.                                                 disp = (-1)<<expbitlen;
  494.                                                 disp |= (bits&(~disp));
  495.  
  496.                                                 disp <<= 8;
  497.  
  498.                                                 disptype = DISP_PLUSBYTE;
  499.                                                 // NO break!
  500.                                         }
  501.                                         __attribute__ ((fallthrough));
  502.                                 case DISP_PLUSBYTE:
  503.                                         byte = depack_getbyte(DEPACK_GETBYTE_NEXT);
  504. #ifdef DPK_CHECK
  505.                                         if( 0xFFFFFFFF == byte ) goto NO_BYTE_HST;
  506. #endif
  507.                                         if( disptype==DISP_COMMON ) // if we here from previous section of switch()
  508.                                         {                           // we must check for insertion match!
  509.  
  510.                                                 if( byte<0x00E0 ) // ff00..ffdf
  511.                                                 {
  512.                                                         disp = (-256) | (byte&0x00FF);
  513.                                                 }
  514.                                                 else // insertion match - xor 3
  515.                                                 {
  516.                                                         length = (-3); // mark insertion match
  517.  
  518.                                                         byte = ((byte<<1)&0x00FE) | ((byte>>7)&0x01); // byte<<<1
  519.                                                         byte ^= 0x03;
  520.                                                         byte -= 15;
  521.  
  522.                                                         disp = (-256) | (byte&0x00FF);
  523.                                                 }
  524.                                         }
  525.                                         else
  526.                                         {
  527.                                                 disp = disp + (byte&0x00FF);
  528.                                         }
  529.  
  530.                                         break;
  531.  
  532.                                 case DISP_ABCDE:
  533.                                         bits = depack_getbits(5,DEPACK_GETBITS_NEXT);
  534. #ifdef DPK_CHECK
  535.                                         if( 0xFFFFFFFF == bits )
  536.                                         {
  537.                                                 #ifdef DBG
  538.                                                 printf("line %d\n",__LINE__);
  539.                                                 #endif
  540.                                                 goto NO_BITS_HST;
  541.                                         }
  542. #endif
  543.                                         disp = (-32) | (bits&31);
  544.  
  545.                                         break;
  546.  
  547.                                 default:
  548. #ifdef DPK_CHECK
  549.  #ifdef DPK_REPERR
  550.                                         printf("mhmt-depack-hrust.c:{} - Wrong displacement in disptype!\n");
  551.  #endif
  552.                                         return 0;
  553. #endif
  554.                                         break;
  555.                                 }
  556.                         }
  557.  
  558.  
  559. #ifdef DPK_CHECK
  560.                         if( success && (!docopy) && (!stop) && ((ULONG)(-disp)>wrk.maxwin) )
  561.                         {
  562. WRONG_DISP_HST:
  563.  #ifdef DPK_REPERR
  564.                                 printf("mhmt-depack-hrust.c:{} - Wrong lookback displacement of %d, greater than maxwin\n",(-disp) );
  565.  #endif
  566.                                 return 0;
  567.                         }
  568. #endif
  569.  
  570.  
  571.                         if( docopy && (!stop) )
  572.                         {
  573.                                 #ifdef DBG
  574.                                         printf("copy.len=%d\n",length);
  575.                                 #endif
  576.                                 for(i=0;i<length;i++)
  577.                                 {
  578.                                         byte = depack_getbyte(DEPACK_GETBYTE_NEXT);
  579. #ifdef DPK_CHECK
  580.                                         if( 0xFFFFFFFF == byte ) goto NO_BYTE_HST;
  581. #endif
  582.  
  583.  
  584. #ifdef DPK_DEPACK
  585.                                         success = success && depack_outbyte( (UBYTE)(0x00FF&byte), DEPACK_OUTBYTE_ADD );
  586. #endif
  587.                                 }
  588.                         }
  589.                         else if( (!docopy) && (!stop) )// not do-copy
  590.                         {
  591.                                 if( length!=(-3) )
  592.                                 {
  593.                                         #ifdef DBG
  594.                                         if(length) printf("match.len=%d,disp=%d\n",length,disp);
  595.                                         #endif
  596.  
  597. #ifdef DPK_DEPACK
  598.                                         if( length )
  599.                                                 success = success && depack_repeat(disp,length);
  600. #endif
  601.                                 }
  602.                                 else // (-3)
  603.                                 {
  604.                                         byte = depack_getbyte(DEPACK_GETBYTE_NEXT);
  605. #ifdef DPK_CHECK
  606.                                         if( 0xFFFFFFFF == byte ) goto NO_BYTE_HST;
  607. #endif
  608.                                         #ifdef DBG
  609.                                                 printf("insert-match.len=%d,disp=%d\n",(-length),disp);
  610.                                         #endif
  611.  
  612.  
  613. #ifdef DPK_DEPACK
  614.                                         success = success && depack_repeat(disp,1);
  615.                                         success = success && depack_outbyte( (UBYTE)(0x00FF&byte), DEPACK_OUTBYTE_ADD );
  616.                                         success = success && depack_repeat(disp,1);
  617. #endif
  618.                                 }
  619.  
  620.                         }
  621.         }
  622.  
  623.  
  624.         #ifdef DBG
  625.         printf("got stop symbol!\n");
  626.         #endif
  627.  
  628.  
  629.         //manage zxheader again (copy to the end of output)
  630. #ifdef DPK_DEPACK
  631.         if( wrk.zxheader )
  632.         {
  633.                 check = depack_getbyte(DEPACK_GETBYTE_REWIND);
  634.  #ifdef DPK_CHECK
  635.                 if( 0xFFFFFFFF == check )
  636.                 {
  637.   #ifdef DPK_REPERR
  638.                         printf("mhmt-depack-hrust.c:{} - Can't rewind input stream!\n");
  639.   #endif
  640.                         return 0;
  641.                 }
  642.  #endif
  643.  
  644.                 for(i=0;i<6;i++) // skip bytes
  645.                 {
  646.                         byte = depack_getbyte(DEPACK_GETBYTE_NEXT);
  647.  #ifdef DPK_CHECK
  648.                         if( 0xFFFFFFFF == check ) goto NO_BYTE_HST;
  649.  #endif
  650.                 }
  651.                 // place 6 bytes of header to the end
  652.                 for(i=0;i<6;i++)
  653.                 {
  654.                         byte = depack_getbyte(DEPACK_GETBYTE_NEXT);
  655.  #ifdef DPK_CHECK
  656.                         if( 0xFFFFFFFF == check ) goto NO_BYTE_HST;
  657.  #endif
  658.                         success = success && depack_outbyte( (UBYTE)(0x00FF&byte), DEPACK_OUTBYTE_ADD );
  659.                 }
  660.         }
  661. #endif
  662.  
  663.         return success;
  664. }
  665.  
  666.