Advertisement
Guest User

Untitled

a guest
Apr 28th, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. /*
  3.     A1 - input - always WORD reads
  4.     A5 - output - always WORD writes
  5.    
  6.     D1 - unused
  7.    
  8.     D2 - num bits remaining
  9.     D3 - bits from to process. input always read into here
  10.    
  11.     D4 - used to output. Holds last word decoded? Except in write loop where lower byte overwritten from D5
  12.     D5 - used to output. Mostly the same as D4, except 15th bit flipped occasionally.
  13.    
  14.     D6 - Has two meanings depending on inner loop or shunt loop
  15.             inner loop: used as offset for write aheads
  16.             shunt loop: counter for later
  17.            
  18.     Notes:
  19.     ------
  20.     groups of 5 bits seems to come up often
  21.    
  22. */
  23.  
  24. D2 = ram[F730]
  25. D3 = ram[F732]
  26.  
  27. repeat all:
  28.  
  29. D2 -= 5
  30. if (D2 > 0)
  31. {
  32.     // top prep A
  33.    
  34.     // more than 5 bits left in registers
  35.    
  36.     rotate D3.w << 5
  37.     D7.w = D3.w
  38. }
  39. else if (D2 == 0)
  40. {
  41.     // top prep B
  42.    
  43.     // Exactly 5 bits left in registers
  44.    
  45.     D2 = 16
  46.     rotate D3.w << 5
  47.     D7.w = D3.w
  48.     D3.w = input++
  49. }
  50. else
  51. {
  52.     // top prep C
  53.     // less than 5 bits left in registers
  54.    
  55.     D7 = D2
  56.     D2 += 5
  57.     D3 << D2
  58.    
  59.     D3.w = input++
  60.     D7 = -D7
  61.     D7 << D3
  62.     D2 += 11
  63.     D7 = D3
  64.     swap D7
  65. }
  66.  
  67. // common top prep
  68.  
  69. D7.w &= 001F // zero all but bottom 5 bits
  70. D7 >> 1
  71.  
  72. if (shunted 1)
  73. {
  74.     // pre inner loop
  75.    
  76.     D4.w = D7
  77.     output++ = D4.w
  78.     D5.w = D4
  79.    
  80.     D5 set bit 15
  81.     D6 = 0
  82.    
  83.     // Inner Loop
  84.     while (true)
  85.     {
  86.         D2 -= 2
  87.        
  88.         if (D2 > 0)
  89.         {
  90.             // inner branch A
  91.            
  92.             rotate D3 << 2
  93.             D7.w = D3
  94.         }
  95.         else if (D2 == 0)
  96.         {
  97.             // inner branch B
  98.            
  99.             D2 = 16
  100.            
  101.             rotate D3 << 2
  102.            
  103.             D7.w = D3
  104.            
  105.             D3.w = input++
  106.         }
  107.         else
  108.         {
  109.             // inner branch C
  110.            
  111.             D2 = $F
  112.            
  113.             D3 *= 2
  114.             D3.w = input++
  115.             ADDX.w D3, D3
  116.            
  117.             D7.w = D3
  118.             ADDX.w D7, D7
  119.         }
  120.        
  121.         // after inner branch
  122.        
  123.         D7 &= 0x3 // mask off all but lower two bits
  124.        
  125.         if (D7 == 0)
  126.         {
  127.             // inner continues
  128.            
  129.             D2--
  130.             if (D2 == 0)
  131.             {
  132.                 // inner reinit
  133.                
  134.                 D2 = 16
  135.                 D3 *= 2
  136.                 D3 = input++
  137.                 ROXR.w D3 >> 1      // rotate-extended-right
  138.             }
  139.            
  140.             ADDX.w D3, D3
  141.             if (carry not set) // Branch on carry clear
  142.             {
  143.                 // Break out of inner loop, ready for shunt loop
  144.                 // NB: Only place we can escape the inner loop
  145.                 break;
  146.             }
  147.            
  148.             D2--
  149.             if (D2 == 0)
  150.             {
  151.                 // re-read before write ahead
  152.                 D2 = 16
  153.                
  154.                 D3.w *= 2       // push top bit into Xtend flag?
  155.                 D3.w = input++
  156.                 ROXR D3.w >> 1
  157.             }
  158.            
  159.             ADDX D3, D3
  160.             if (carry set)
  161.             {
  162.                 // write ahead method 3
  163.                 D6 += $14 // dec 20
  164.                 output[-1+D6] = D5.w
  165.                
  166.                 // will restart inner loop now
  167.             }
  168.             else
  169.             {
  170.                 // write ahead method 2
  171.                 D6 += $C // dec 12
  172.                 output[-2+D6] = D5.w
  173.                
  174.                 // will restart inner loop now
  175.             }
  176.         }
  177.         else
  178.         {
  179.             // write ahead method 1
  180.            
  181.             D7 += 6
  182.             D7 *= 2
  183.             D7 += D6
  184.             output[-2+D6] = D5
  185.         }
  186.     } // end inner loop
  187. }
  188. else
  189. {
  190.     // inner loop replacement
  191.    
  192.     D4.w = D7.w
  193.     output++ = D4.w
  194.     D5.w = D4.w
  195.    
  196.     D5 set bit 15
  197. }
  198.  
  199. // Prep for shunt loop
  200.  
  201. D7 = 0
  202. D6 = 1
  203.  
  204. // Shunt loop
  205. while (true)
  206. {
  207.     D7++
  208.     D6 << 1
  209.     D2--
  210.    
  211.     if (D2 > 0)
  212.     {
  213.         // Get more bits
  214.         // reset D2 bit counter, read input, shunt, then exit if shunted 0
  215.        
  216.         D2 = 0x10
  217.         D3 << 1
  218.        
  219.         D3 = input++ // nb: actually inside following if/else twice but more readable here
  220.        
  221.         if (shunted 0)
  222.             break;
  223.     }
  224.     else
  225.     {
  226.         // has more bits
  227.        
  228.         D3 << 1
  229.        
  230.         if (shunted 0)
  231.             break;
  232.     }
  233. }
  234.  
  235. // After shunt loop
  236.  
  237. // Prep for write
  238.  
  239. bool isD2Greater = (D2 > D7)
  240. bool isD2Equal = (D2 == D7)
  241.  
  242. D2 -= D7
  243.  
  244. if (isD2Greater)
  245. {
  246.     // write prep A
  247.    
  248.     swap D3
  249.     clear lower word of D3
  250.     rotate D3 << D7
  251.     D7.w = D3.w
  252.     swap D3
  253. }
  254. else if (isD2Equal)
  255. {
  256.     // write prep B
  257.    
  258.     D2 = 0x10
  259.    
  260.     swap D3
  261.     clear lower word of D3
  262.     rotate D3 << D7
  263.     D7.w = D3.w
  264.    
  265.     D3.w = input++
  266. }
  267. else
  268. {
  269.     // write prep C
  270.     clear upper word of D3
  271.     D2 += D7 // undo sub at top of write prep
  272.     D3 << D2 // shift left by D2 bits
  273.     D3.w = input++
  274.     D7 -= D2
  275.     D3 << D7
  276.     D2 = 0x10
  277.     D2 -= D7
  278.     D7 = D3
  279.     swap D7
  280. }
  281.    
  282. // finish write prep
  283.  
  284. D6 += D7
  285. D6 -= 3
  286.  
  287. // Anything to loop?
  288. if (D6 > 0)     // todo: check if > or >=
  289. {
  290.     // Write loop
  291.    
  292.     for (int i=0; i<D6; i++)
  293.     {
  294.         D7 = peek output
  295.        
  296.         if (bit 31 of D7 set)
  297.         {
  298.             D5.w = D7.w
  299.             D4.b = D5.b
  300.         }
  301.        
  302.         output = D4.w
  303.         output++
  304.     }
  305. }
  306.  
  307. // Check if buffer full?
  308. if output buffer not full
  309.     jump to repeat
  310.  
  311. // Save decompression state
  312.  
  313. ram[F730] = D2
  314. ram[F732] = D3
  315.  
  316. // nb: output pointer is maintained in register A0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement