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