1 /******************************************************************************/
2 /* Mednafen Fast SNES Emulation Module                                        */
3 /******************************************************************************/
4 /* sdd1.cpp:
5 **  Copyright (C) 2019 Mednafen Team
6 **
7 ** This program is free software; you can redistribute it and/or
8 ** modify it under the terms of the GNU General Public License
9 ** as published by the Free Software Foundation; either version 2
10 ** of the License, or (at your option) any later version.
11 **
12 ** This program is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ** GNU General Public License for more details.
16 **
17 ** You should have received a copy of the GNU General Public License
18 ** along with this program; if not, write to the Free Software Foundation, Inc.,
19 ** 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 */
21 
22 /*
23  TODO:
24 	Decompression DMA stuff is probably not correct.
25 
26 	Check register readability.
27 */
28 
29 #include "common.h"
30 #include "sdd1.h"
31 
32 namespace MDFN_IEN_SNES_FAUST
33 {
34 
35 static uint8 ROMBank[4];
36 static uintptr_t ROMPtr[8];
37 
RecalcROMPtr(size_t rbi)38 static INLINE void RecalcROMPtr(size_t rbi)
39 {
40  ROMPtr[0 + rbi] = (uintptr_t)&Cart.ROM[(ROMBank[rbi] & 0x80) ? ((ROMBank[rbi] & 0x7) << 20) : (rbi << 20)];
41  ROMPtr[4 + rbi] = (uintptr_t)&Cart.ROM[(ROMBank[rbi] & 0x7) << 20] - ((0xC0 + (rbi << 4)) << 16);
42 }
43 
44 static uint8 DMAEnable[2];
45 static uint8 DMARegs[0x80];
46 
47 struct EvTableS
48 {
49  EvTableS* next[2];
50  unsigned golomb_n;
51  bool mps_update_mask;
52 };
53 
54 static struct
55 {
56  uint32 dma_trigger_addr;
57  uint32 dma_count;
58  //
59  uint32 depth;
60  uint32 depth_planes;
61 
62  uint32 input_addr;
63  uint32 input_bits;
64  uint32 input_bits_count;
65 
66  uint32 prev_bits_mask[2];
67  uint32 prev_bits[8];
68 
69  uint32 output_buf_pos;
70  uint32 output_buf_pos_mask;
71  uint8 output_buf[0x40];
72 
73  struct
74  {
75   uint8 run_counter;
76   bool run_end_bit;
77  } bitgen[8];
78 
79  struct
80  {
81   bool mps;
82   EvTableS* pred;
83  } contexts[0x20];
84  //
85  //
86  //
87  uint8 rev_inv_table[0x100];
88  EvTableS ev_table[0x21];
89 } Decomp;
90 
91 
ReadROM(uint32 A)92 static INLINE uint8 ReadROM(uint32 A)
93 {
94  return *(uint8*)(*(ROMPtr + 4 + ((A >> 20) & 0x3)) + A);
95 }
96 
ReadyInputBits(unsigned count)97 static INLINE void ReadyInputBits(unsigned count)
98 {
99  if(Decomp.input_bits_count < count)
100  {
101   Decomp.input_bits |= ReadROM(Decomp.input_addr) << (8 - Decomp.input_bits_count);
102   Decomp.input_addr++;
103   Decomp.input_bits_count += 8;
104  }
105 }
106 
AdvanceInputBits(unsigned count)107 static INLINE void AdvanceInputBits(unsigned count)
108 {
109  Decomp.input_bits <<= count;
110  Decomp.input_bits_count -= count;
111 }
112 
GetInputBits(unsigned count=1)113 static INLINE uint8 GetInputBits(unsigned count = 1)
114 {
115  //assert(count <= 8);
116  //
117  uint8 ret;
118 
119  ReadyInputBits(count);
120 
121  ret = (Decomp.input_bits >> (16 - count)) & ((1U << count) - 1);
122  AdvanceInputBits(count);
123 
124  return ret;
125 }
126 
PeekInputByte(void)127 static INLINE uint8 PeekInputByte(void)
128 {
129  ReadyInputBits(8);
130 
131  return Decomp.input_bits >> 8;
132 }
133 
InitDecomp(const uint32 addr)134 static void InitDecomp(const uint32 addr)
135 {
136  for(unsigned c = 0; c < 0x20; c++)
137  {
138   Decomp.contexts[c].mps = false;
139   Decomp.contexts[c].pred = &Decomp.ev_table[0x20];
140  }
141 
142  for(unsigned p = 0; p < 8; p++)
143  {
144   Decomp.prev_bits[p] = 0;
145  }
146 
147  for(unsigned bg = 0; bg < 8; bg++)
148  {
149   Decomp.bitgen[bg].run_counter = 0;
150   Decomp.bitgen[bg].run_end_bit = false;
151  }
152  //
153  //
154  //
155  Decomp.input_addr = addr;
156  Decomp.input_bits = 0;
157  Decomp.input_bits_count = 0;
158 
159  Decomp.output_buf_pos = 0;
160  //
161  //
162  //
163  uint32 prevsel;
164 
165  SNES_DBG("[SDD1] Decompression start; addr=0x%06x\n", addr);
166  //assert(Decomp.input_addr >= 0xC00000);
167 
168  Decomp.depth = GetInputBits(2);
169  prevsel = GetInputBits(2);
170  SNES_DBG("[SDD1]  depth=%u, prevsel=%u\n", Decomp.depth, prevsel);
171  //
172  switch(Decomp.depth)
173  {
174   case 0: Decomp.output_buf_pos_mask = 0x0F; Decomp.depth_planes = 2; break;
175   case 2: Decomp.output_buf_pos_mask = 0x1F; Decomp.depth_planes = 4; break;
176 
177   case 1: Decomp.output_buf_pos_mask = 0x3F; Decomp.depth_planes = 8; break;
178   case 3: Decomp.output_buf_pos_mask = 0x3F; Decomp.depth_planes = 8; break;
179  }
180  //
181  Decomp.prev_bits_mask[0] = 0x1;
182  switch(prevsel)
183  {
184   case 0: Decomp.prev_bits_mask[1] = 0x7 << 1; break;
185   case 1: Decomp.prev_bits_mask[1] = 0x6 << 1; break;
186   case 2: Decomp.prev_bits_mask[1] = 0x3 << 1; break;
187   case 3: Decomp.prev_bits_mask[1] = 0x6 << 1; Decomp.prev_bits_mask[0] = 0x3; break;
188  }
189 }
190 
DecompBit(unsigned plane)191 static INLINE bool DecompBit(unsigned plane)
192 {
193  uint32* prev_bits = &Decomp.prev_bits[plane];
194  bool ret;
195  uint32 c;
196 
197 /*
198  c  = pl->prev_bits & 0x1;
199  c |= (plane & 0x1) << 4;
200 
201  switch(Decomp.prevsel)
202  {
203   case 0:
204 	c |= ((pl->prev_bits >> 6) & 0x7) << 1;
205 	break
206 
207   case 1:
208 	c |= ((pl->prev_bits >> 6) & 0x6) << 1;
209 	break;
210 
211   case 2:
212 	c |= ((pl->prev_bits >> 6) & 0x3) << 1;
213 	break;
214 
215   case 3:
216 	c |= (pl->prev_bits & 0x2);
217 	c |= ((pl->prev_bits >> 6) & 0x6) << 1;
218 	break;
219  }
220 */
221 // c = (((pl->prev_bits >> 0) & 1) << 0) | (((pl->prev_bits >> 6) & 1) << 1) | (((pl->prev_bits >> 7) & 1) << 2) | (((pl->prev_bits >> 8) & 1) << 3);
222  //c = (((pl->prev_bits >> 0) & 1) << 0) | (((pl->prev_bits >> 6) & 1) << 1) | (((pl->prev_bits >> 7) & 1) << 2) | (((pl->prev_bits >> 8) & 1) << 3);
223  //c = (((pl->prev_bits >> 0) & 1) << 0) | (((pl->prev_bits >> 1) & 1) << 1) | (((pl->prev_bits >> 7) & 1) << 2) | (((pl->prev_bits >> 8) & 1) << 3);
224  c = (*prev_bits & Decomp.prev_bits_mask[0]) | ((*prev_bits >> 5) & Decomp.prev_bits_mask[1]);
225  c |= (plane & 0x1) << 4;
226  //
227  //
228  auto* ctx = &Decomp.contexts[c];
229  const unsigned gn = ctx->pred->golomb_n;
230  auto* bg = &Decomp.bitgen[gn];
231 
232  ret = ctx->mps;
233 
234  if(!bg->run_counter)
235  {
236 /*
237   bool b = GetInputBits(1);
238 
239   bg->run_end_bit = b;
240   if(!b)
241    bg->run_counter = 1U << gn;
242   else
243   {
244    const unsigned shift = 8 - gn;
245 
246    bg->run_counter = 1 + (Decomp.rev_inv_table[GetInputBits(gn) << shift] & ((1U << gn) - 1));
247   }
248 */
249   uint8 tmp = PeekInputByte();
250   bg->run_end_bit = tmp >> 7;
251   bg->run_counter = 1 + (Decomp.rev_inv_table[tmp] & ((1U << gn) - 1));
252   AdvanceInputBits(1 + (gn & ((int8)tmp >> 7)));
253  }
254  bg->run_counter--;
255  if(!bg->run_counter)
256  {
257   ret ^= bg->run_end_bit;
258   ctx->mps ^= bg->run_end_bit & ctx->pred->mps_update_mask;
259   ctx->pred = ctx->pred->next[bg->run_end_bit];
260  }
261  //
262  *prev_bits = (*prev_bits << 1) | ret;
263 
264  return ret;
265 }
266 
DoDecomp(void)267 static void DoDecomp(void)
268 {
269  if(Decomp.depth == 3)
270  {
271   for(uint32 i = 0; i < 64; i++)
272   {
273    uint8 tmp = 0;
274 
275    for(uint32 p = 0; p < 8; p++)
276    {
277     DecompBit(p);
278     tmp |= (Decomp.prev_bits[p] & 1) << p;
279    }
280 
281    Decomp.output_buf[i] = tmp;
282   }
283  }
284  else
285  {
286   for(uint32 p = 0; p < Decomp.depth_planes; p += 2)
287   {
288    for(uint32 y = 0; y < 8; y++)
289    {
290     for(uint32 x = 0; x < 8; x++)
291     {
292      DecompBit(p + 0);
293      DecompBit(p + 1);
294     }
295     Decomp.output_buf[(p << 3) + (y << 1) + 0] = Decomp.prev_bits[p + 0];
296     Decomp.output_buf[(p << 3) + (y << 1) + 1] = Decomp.prev_bits[p + 1];
297    }
298   }
299  }
300 }
301 
DecompByte(void)302 static INLINE uint8 DecompByte(void)
303 {
304  uint8 ret = 0;
305 
306  if(!Decomp.output_buf_pos)
307   DoDecomp();
308 
309  ret = Decomp.output_buf[Decomp.output_buf_pos];
310  Decomp.output_buf_pos = (Decomp.output_buf_pos + 1) & Decomp.output_buf_pos_mask;
311  //
312  Decomp.dma_count--;
313  if(!Decomp.dma_count)
314   Decomp.dma_trigger_addr = ~0U;
315 
316  return ret;
317 }
318 
319 
320 template<unsigned T_offs>
DEFWRITE(SDD1_Write_43xx)321 static DEFWRITE(SDD1_Write_43xx)
322 {
323  static_assert(T_offs == 0 || T_offs == 2 || T_offs == 3 || T_offs == 4 || T_offs == 5 || T_offs == 6, "wrong offs");
324  switch(T_offs)
325  {
326   case 0: DMA_Write_43x0(A, V); break;
327   case 2: DMA_Write_43x2(A, V); break;
328   case 3: DMA_Write_43x3(A, V); break;
329   case 4: DMA_Write_43x4(A, V); break;
330   case 5: DMA_Write_43x5(A, V); break;
331   case 6: DMA_Write_43x6(A, V); break;
332  }
333 
334  DMARegs[((A >> 1) & 0x78) + (A & 0x7)] = V;
335 }
336 
337 /*
338 static INLINE uint8 ReadROM(size_t region, uint32 A)
339 {
340  if(region < 0x4)
341   return *(uint8*)(ROMPtr[region] + (A & 0x7FFF) + ((A >> 1) & 0xF8000));
342  else
343   return *(uint8*)(ROMPtr[region] + A);
344 }
345 */
346 
347 template<signed cyc>
DEFREAD(MainCPU_ReadLoROM)348 static DEFREAD(MainCPU_ReadLoROM)
349 {
350  if(MDFN_LIKELY(!DBG_InHLRead))
351  {
352   CPUM.timestamp += (cyc >= 0) ? cyc : CPUM.MemSelectCycles;
353  }
354  //
355  //
356  return *(uint8*)(*(ROMPtr + 0 + ((A >> 21) & 0x3)) + (A & 0x7FFF) + ((A >> 1) & 0xF8000));
357 }
358 
359 template<signed cyc>
DEFREAD(MainCPU_ReadHiROM)360 static DEFREAD(MainCPU_ReadHiROM)
361 {
362  if(MDFN_LIKELY(!DBG_InHLRead))
363  {
364   CPUM.timestamp += (cyc >= 0) ? cyc : CPUM.MemSelectCycles;
365  }
366  //
367  //
368  if(A == Decomp.dma_trigger_addr)
369   return DecompByte();
370 
371  return *(uint8*)(*(ROMPtr + 4 + ((A >> 20) & 0x3)) + A);
372 }
373 
374 template<signed cyc, unsigned w>
DEFWRITE(MainCPU_WriteIO)375 static DEFWRITE(MainCPU_WriteIO)
376 {
377  CPUM.timestamp += (cyc >= 0) ? cyc : CPUM.MemSelectCycles;
378  //
379  //
380  SNES_DBG("[SDD1] IO write 0x%06x 0x%02x\n", A, V);
381 
382  switch(w)
383  {
384   case 0x0:
385 	DMAEnable[0] = V;
386 	break;
387 
388   case 0x1:
389 	DMAEnable[1] = V;
390 	//
391 	Decomp.dma_trigger_addr = ~0U;
392         for(unsigned ch = 0; ch < 8; ch++)
393         {
394          if((DMAEnable[0] & DMAEnable[1] & (1U << ch)) && (DMARegs[(ch << 3) + 0] & 0x88) == 0x08)
395 	 {
396 	  //assert(Decomp.dma_trigger_addr == ~0U);
397 
398 	  Decomp.dma_trigger_addr = MDFN_de24lsb(&DMARegs[(ch << 3) + 2]);
399 	  Decomp.dma_count = MDFN_de16lsb(&DMARegs[(ch << 3) + 5]);
400 	  //
401  	  InitDecomp(Decomp.dma_trigger_addr);
402 	  break;
403 	 }
404 	}
405 	break;
406 
407   case 0x4:
408   case 0x5:
409   case 0x6:
410   case 0x7:
411 	{
412 	 size_t rbi = w & 0x3;
413 	 ROMBank[rbi] = V;
414 	 RecalcROMPtr(rbi);
415 	}
416 	break;
417  }
418 }
419 
420 template<signed cyc, unsigned w>
DEFREAD(MainCPU_ReadIO)421 static DEFREAD(MainCPU_ReadIO)
422 {
423  if(MDFN_LIKELY(!DBG_InHLRead))
424  {
425   CPUM.timestamp += (cyc >= 0) ? cyc : CPUM.MemSelectCycles;
426  }
427  //
428  //
429  uint8 ret = 0;
430 
431  SNES_DBG("[SDD1] IO read 0x%06x\n", A);
432 
433  switch(w)
434  {
435   case 0x0:
436 	ret = DMAEnable[0];
437 	break;
438 
439   case 0x4:
440   case 0x5:
441   case 0x6:
442   case 0x7:
443 	ret = ROMBank[w & 0x3];
444 	break;
445  }
446 
447  return ret;
448 }
449 
450 template<size_t mask = SIZE_MAX>
DEFREAD(MainCPU_ReadSRAM)451 static DEFREAD(MainCPU_ReadSRAM)
452 {
453  if(MDFN_UNLIKELY(DBG_InHLRead))
454  {
455   return Cart.RAM[A & mask & Cart.RAM_Mask];
456  }
457  //
458  CPUM.timestamp += MEMCYC_SLOW;
459  //
460  return Cart.RAM[A & mask & Cart.RAM_Mask];
461 }
462 
463 template<size_t mask = SIZE_MAX>
DEFWRITE(MainCPU_WriteSRAM)464 static DEFWRITE(MainCPU_WriteSRAM)
465 {
466  CPUM.timestamp += MEMCYC_SLOW;
467  //
468  Cart.RAM[A & mask & Cart.RAM_Mask] = V;
469 }
470 
Reset(bool powering_up)471 static MDFN_COLD void Reset(bool powering_up)
472 {
473  for(size_t rbi = 0; rbi < 4; rbi++)
474  {
475   ROMBank[rbi] = rbi;
476   RecalcROMPtr(rbi);
477  }
478 
479  DMAEnable[0] = 0;
480  DMAEnable[1] = 0;
481 
482  memset(DMARegs, 0xFF, sizeof(DMARegs));
483 
484  Decomp.dma_trigger_addr = 0;
485  Decomp.dma_count = 0;
486 
487  Decomp.depth = 0;
488  Decomp.depth_planes = 0;
489 
490  Decomp.input_addr = 0;
491  Decomp.input_bits = 0;
492  Decomp.input_bits_count = 0;
493 
494  for(unsigned i = 0; i < 2; i++)
495   Decomp.prev_bits_mask[i] = 0;
496 
497  for(unsigned i = 0; i < 8; i++)
498   Decomp.prev_bits[i] = 0;
499 
500  Decomp.output_buf_pos = 0;
501  Decomp.output_buf_pos_mask = 0;
502  memset(Decomp.output_buf, 0x00, sizeof(Decomp.output_buf));
503 
504  for(unsigned i = 0; i < 8; i++)
505  {
506   Decomp.bitgen[i].run_counter = 0;
507   Decomp.bitgen[i].run_end_bit = 0;
508  }
509 
510  for(unsigned i = 0; i < 0x20; i++)
511  {
512   Decomp.contexts[i].mps = false;
513   Decomp.contexts[i].pred = &Decomp.ev_table[0x20];
514  }
515 }
516 
StateAction(StateMem * sm,const unsigned load,const bool data_only)517 static void StateAction(StateMem* sm, const unsigned load, const bool data_only)
518 {
519  uint8 contexts_pred[0x20];
520 
521  for(unsigned i = 0; i < 0x20; i++)
522   contexts_pred[i] = Decomp.contexts[i].pred - Decomp.ev_table;
523 
524  SFORMAT StateRegs[] =
525  {
526   SFVAR(ROMBank),
527   SFVAR(DMAEnable),
528   SFVAR(DMARegs),
529   //
530   SFVAR(Decomp.dma_trigger_addr),
531   SFVAR(Decomp.dma_count),
532 
533   SFVAR(Decomp.depth),
534   SFVAR(Decomp.depth_planes),
535 
536   SFVAR(Decomp.input_addr),
537   SFVAR(Decomp.input_bits),
538   SFVAR(Decomp.input_bits_count),
539 
540   SFVAR(Decomp.prev_bits_mask),
541   SFVAR(Decomp.prev_bits),
542 
543   SFVAR(Decomp.output_buf_pos),
544   SFVAR(Decomp.output_buf_pos_mask),
545   SFVAR(Decomp.output_buf),
546 
547   SFVAR(Decomp.bitgen->run_counter, 8, sizeof(*Decomp.bitgen), Decomp.bitgen),
548   SFVAR(Decomp.bitgen->run_end_bit, 8, sizeof(*Decomp.bitgen), Decomp.bitgen),
549 
550   SFVAR(Decomp.contexts->mps, 0x20, sizeof(*Decomp.contexts), Decomp.contexts),
551   SFVAR(contexts_pred),
552   //
553   SFEND
554  };
555 
556  MDFNSS_StateAction(sm, load, data_only, StateRegs, "SDD1");
557 
558  if(load)
559  {
560   for(size_t rbi = 0; rbi < 4; rbi++)
561    RecalcROMPtr(rbi);
562 
563   for(unsigned i = 0; i < 0x20; i++)
564    Decomp.contexts[i].pred = Decomp.ev_table + (contexts_pred[i] % 0x21);
565 
566   Decomp.depth &= 0x3;
567   Decomp.depth_planes = std::min<uint32>(Decomp.depth_planes, 8);
568 
569   Decomp.output_buf_pos_mask &= 0x3F;
570   Decomp.output_buf_pos &= Decomp.output_buf_pos_mask;
571  }
572 }
573 
CART_SDD1_Init(const int32 master_clock)574 void CART_SDD1_Init(const int32 master_clock)
575 {
576  if(Cart.RAM_Size)
577   Set_A_Handlers(0x700000, 0x73FFFF, MainCPU_ReadSRAM, MainCPU_WriteSRAM);
578 
579  for(unsigned bank = 0x00; bank < 0x100; bank++)
580  {
581   if(!(bank & 0x40))
582   {
583    #define SHP(ta) Set_A_Handlers((bank << 16) | (0x4800 + ta), MainCPU_ReadIO<MEMCYC_FAST, ta>, MainCPU_WriteIO<MEMCYC_FAST, ta>);
584    SHP(0x0)
585    SHP(0x1)
586    SHP(0x2)
587    SHP(0x3)
588    SHP(0x4)
589    SHP(0x5)
590    SHP(0x6)
591    SHP(0x7)
592    #undef SHP
593 
594    if(Cart.RAM_Size)
595    {
596     Set_A_Handlers((bank << 16) | 0x6000, (bank << 16) | 0x7FFF,
597 	((bank & 0x80) ? MainCPU_ReadSRAM<0x1FFF> : MainCPU_ReadSRAM<0x1FFF>),
598 	((bank & 0x80) ? MainCPU_WriteSRAM<0x1FFF> : MainCPU_WriteSRAM<0x1FFF>));
599    }
600 
601    Set_A_Handlers((bank << 16) | 0x8000, (bank << 16) | 0xFFFF, (bank & 0x80) ? MainCPU_ReadLoROM<-1> : MainCPU_ReadLoROM<MEMCYC_SLOW>, (bank & 0x80) ? OBWrite_VAR : OBWrite_SLOW);
602    //
603    //
604    for(unsigned ch = 0; ch < 8; ch++)
605    {
606     const uint32 chba = (bank << 16) + 0x4300 + (ch << 4);
607 
608     Set_A_Handlers(chba + 0x0, nullptr, SDD1_Write_43xx<0>);
609     Set_A_Handlers(chba + 0x2, nullptr, SDD1_Write_43xx<2>);
610     Set_A_Handlers(chba + 0x3, nullptr, SDD1_Write_43xx<3>);
611     Set_A_Handlers(chba + 0x4, nullptr, SDD1_Write_43xx<4>);
612     Set_A_Handlers(chba + 0x5, nullptr, SDD1_Write_43xx<5>);
613     Set_A_Handlers(chba + 0x6, nullptr, SDD1_Write_43xx<6>);
614    }
615   }
616   else if(bank & 0x80)
617   {
618    Set_A_Handlers((bank << 16) | 0x0000, (bank << 16) | 0xFFFF, (bank & 0x80) ? MainCPU_ReadHiROM<-1> : MainCPU_ReadHiROM<MEMCYC_SLOW>, (bank & 0x80) ? OBWrite_VAR : OBWrite_SLOW);
619   }
620  }
621  //
622  //
623  //
624  for(int i = 0; i < 0x21; i++)
625  {
626   EvTableS* e = &Decomp.ev_table[i];
627 
628   e->mps_update_mask = !(i & 0x1F);
629 
630   if(i < 0x18)
631   {
632    if(i < 0x10)
633     e->golomb_n = i >> 2;
634    else
635     e->golomb_n = 4 + ((i >> 1) & 0x3);
636 
637    e->next[0] = &Decomp.ev_table[std::min<int>(0x17, i + 1)];
638    e->next[1] = &Decomp.ev_table[std::max<int>(0x00, i - 1)];
639   }
640   else if(i < 0x20)
641   {
642    static const uint8 tab[8] = { 0, 1, 3, 7, 11, 15, 17, 21 };
643    e->golomb_n = i - 0x18;
644    e->next[0] = &Decomp.ev_table[(i == 0x1F) ? 0x17 : i + 1];
645    e->next[1] = &Decomp.ev_table[tab[i & 0x7]];
646   }
647   else
648   {
649    e->golomb_n = 0;
650    e->next[0] = &Decomp.ev_table[0x18];
651    e->next[1] = &Decomp.ev_table[0x18];
652   }
653 
654   //if(i == 24)
655   // e->mps_update_mask = true;
656 
657   //printf("%2u: golomb_n=%u, mps_next=%u, lps_next=%u. update_mask=%u\n", i, e->golomb_n, (unsigned)(e->next[0] - &Decomp.ev_table[0]), (unsigned)(e->next[1] - &Decomp.ev_table[0]), e->mps_update_mask);
658  }
659 
660 /*
661  for(unsigned i = 0; i < 0x100; i++)
662  {
663   const unsigned k = ~i;
664 
665   Decomp.rev_inv_table[i] = ((k >> 7) & 0x1) | ((k >> 5) & 0x2) | ((k >> 3) & 0x4) | ((k >> 1) & 0x8) | ((k << 1) & 0x10) | ((k << 3) & 0x20) | ((k << 5) & 0x40) | ((k << 7) & 0x80);
666  }
667 */
668 
669  for(unsigned i = 0; i < 0x100; i++)
670  {
671   uint8 tmp = 0xFF;
672 
673   if(i & 0x80)
674   {
675    const unsigned k = ~i;
676    tmp = ((k >> 6) & 0x1) | ((k >> 4) & 0x2) | ((k >> 2) & 0x4) | ((k >> 0) & 0x8) | ((k << 2) & 0x10) | ((k << 4) & 0x20) | ((k << 6) & 0x40);
677   }
678 
679   Decomp.rev_inv_table[i] = tmp;
680  }
681  //
682  //
683  //
684  Cart.Reset = Reset;
685  Cart.StateAction = StateAction;
686 }
687 
688 }
689