aboutsummaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorJoão Silva2017-08-13 06:02:24 +0100
committerJoão Silva2017-08-13 06:02:24 +0100
commitfdaf2925f1353b07cd957ae47b0e6793648559be (patch)
tree64adbe13da0fe83d85097c5e4492b4b2634e3d95 /source
parente18e3e55bbe96eb2e415ef0ba0ea743460ec0b7b (diff)
downloadsnesemu-fdaf2925f1353b07cd957ae47b0e6793648559be.tar.gz
snesemu-fdaf2925f1353b07cd957ae47b0e6793648559be.tar.bz2
snesemu-fdaf2925f1353b07cd957ae47b0e6793648559be.zip
Copied SPC7110 emulation from snes9x_3ds.
Diffstat (limited to 'source')
-rw-r--r--source/dma.c120
-rw-r--r--source/dma.h1
-rw-r--r--source/dsp1.c11
-rw-r--r--source/getset.h7
-rw-r--r--source/memmap.c3
-rw-r--r--source/spc7110.c1328
-rw-r--r--source/spc7110.h19
-rw-r--r--source/spc7110dec.c619
-rw-r--r--source/spc7110dec.h28
-rw-r--r--source/srtc.c133
-rw-r--r--source/srtc.h7
11 files changed, 860 insertions, 1416 deletions
diff --git a/source/dma.c b/source/dma.c
index eefe135..63aab98 100644
--- a/source/dma.c
+++ b/source/dma.c
@@ -7,8 +7,9 @@
#include "dma.h"
#include "apu.h"
#include "sa1.h"
-#include "spc7110.h"
#include "sdd1emu.h"
+#include "spc7110.h"
+#include "spc7110dec.h"
static uint8_t sdd1_decode_buffer[0x10000];
@@ -17,7 +18,7 @@ extern uint8_t* HDMAMemPointers [8];
extern uint8_t* HDMABasePointers [8];
/**********************************************************************************************/
-/* S9xDoDMA() */
+/* S9xDoDMA() */
/* This function preforms the general dma transfer */
/**********************************************************************************************/
void S9xDoDMA(uint8_t Channel)
@@ -36,7 +37,6 @@ void S9xDoDMA(uint8_t Channel)
CPU.InDMA = true;
d = &DMA[Channel];
-
count = d->TransferBytes;
// Prepare for custom chip DMA
@@ -66,7 +66,7 @@ void S9xDoDMA(uint8_t Channel)
{
if (d->AAddressFixed && Memory.FillRAM [0x4801] > 0)
{
- uint8_t *in_ptr;
+ uint8_t* in_ptr;
// XXX: Should probably verify that we're DMAing from ROM?
// And somewhere we should make sure we're not running across a mapping boundary too.
@@ -85,43 +85,23 @@ void S9xDoDMA(uint8_t Channel)
}
if (Settings.SPC7110 && (d->AAddress == 0x4800 || d->ABank == 0x50))
{
- uint32_t i;
- int32_t icount;
- i = (s7r.reg4805 | (s7r.reg4806 << 8));
- i *= s7r.AlignBy;
- i += s7r.bank50Internal;
- i %= DECOMP_BUFFER_SIZE;
- if ((i + d->TransferBytes) < DECOMP_BUFFER_SIZE)
- spc7110_dma = &s7r.bank50[i];
- else
- {
- uint32_t j;
-
- spc7110_dma = (uint8_t*)malloc(d->TransferBytes);
- j = DECOMP_BUFFER_SIZE - i;
- memcpy(spc7110_dma, &s7r.bank50[i], j);
- memcpy(&spc7110_dma[j], s7r.bank50, d->TransferBytes - j);
- s7_wrap = true;
- }
-
- icount = s7r.reg4809 | (s7r.reg480A << 8);
- icount -= d->TransferBytes;
+ int32_t c;
+ spc7110_dma = &s7r.bank50[0];
+ for(c = 0; c < count; c++)
+ s7r.bank50[c] = spc7110dec_read();
+ int32_t icount = (s7r.reg4809 | (s7r.reg480A << 8)) - count;
s7r.reg4809 = 0x00ff & icount;
s7r.reg480A = (0xff00 & icount) >> 8;
-
- s7r.bank50Internal += d->TransferBytes;
- s7r.bank50Internal %= DECOMP_BUFFER_SIZE;
inc = 1;
d->AAddress -= count;
}
if (d->BAddress == 0x18 && SA1.in_char_dma && (d->ABank & 0xf0) == 0x40)
{
- int32_t i;
// Perform packed bitmap to PPU character format conversion on the
// data before transmitting it to V-RAM via-DMA.
+ int32_t i;
int32_t num_chars = 1 << ((Memory.FillRAM [0x2231] >> 2) & 7);
- int32_t depth = (Memory.FillRAM [0x2231] & 3) == 0 ? 8 :
- (Memory.FillRAM [0x2231] & 3) == 1 ? 4 : 2;
+ int32_t depth = (Memory.FillRAM [0x2231] & 3) == 0 ? 8 : (Memory.FillRAM [0x2231] & 3) == 1 ? 4 : 2;
int32_t bytes_per_char = 8 * depth;
int32_t bytes_per_line = depth * num_chars;
@@ -138,13 +118,11 @@ void S9xDoDMA(uint8_t Channel)
switch (depth)
{
case 2:
- for (i = 0; i < count; i += inc, base += char_line_bytes,
- inc = char_line_bytes, char_count = num_chars)
+ for (i = 0 ; i < count ; i += inc, base += char_line_bytes, inc = char_line_bytes, char_count = num_chars)
{
uint32_t j;
uint8_t* line = base + (num_chars - char_count) * 2;
- for (j = 0; j < char_count && p - buffer < count;
- j++, line += 2)
+ for (j = 0 ; j < char_count && p - buffer < count ; j++, line += 2)
{
int32_t b, l;
uint8_t* q = line;
@@ -168,13 +146,11 @@ void S9xDoDMA(uint8_t Channel)
}
break;
case 4:
- for (i = 0; i < count; i += inc, base += char_line_bytes,
- inc = char_line_bytes, char_count = num_chars)
+ for (i = 0 ; i < count ; i += inc, base += char_line_bytes, inc = char_line_bytes, char_count = num_chars)
{
uint32_t j;
uint8_t* line = base + (num_chars - char_count) * 4;
- for (j = 0; j < char_count && p - buffer < count;
- j++, line += 4)
+ for (j = 0 ; j < char_count && p - buffer < count ; j++, line += 4)
{
uint8_t* q = line;
int32_t b, l;
@@ -199,13 +175,11 @@ void S9xDoDMA(uint8_t Channel)
}
break;
case 8:
- for (i = 0; i < count; i += inc, base += char_line_bytes,
- inc = char_line_bytes, char_count = num_chars)
+ for(i = 0 ; i < count ; i += inc, base += char_line_bytes, inc = char_line_bytes, char_count = num_chars)
{
uint8_t* line = base + (num_chars - char_count) * 8;
uint32_t j;
- for (j = 0; j < char_count && p - buffer < count;
- j++, line += 8)
+ for(j = 0 ; j < char_count && p - buffer < count ; j++, line += 8)
{
uint8_t* q = line;
int32_t b, l;
@@ -242,7 +216,7 @@ void S9xDoDMA(uint8_t Channel)
* XXX: GetBasePointer whenever we cross a boundry, and when
* XXX: GetBasePointer returns (0) to take the 'slow path' and use
* XXX: S9xGetByte instead of *base. GetBasePointer() would want to
- * XXX: return (0) for MAP_PPU and whatever else is a register range
+ * XXX: return 0 for MAP_PPU and whatever else is a register range
* XXX: rather than a RAM/ROM block, and we'd want to detect MAP_PPU
* XXX: (or specifically, Address Bus B addresses $2100-$21FF in
* XXX: banks $00-$3F) specially and treat it as MAP_NONE (since
@@ -289,8 +263,7 @@ void S9xDoDMA(uint8_t Channel)
Work = *(base + p);
REGISTER_2104(Work);
p += inc;
- }
- while (--count > 0);
+ } while (--count > 0);
break;
case 0x18:
IPPU.FirstVRAMRead = true;
@@ -301,8 +274,7 @@ void S9xDoDMA(uint8_t Channel)
Work = *(base + p);
REGISTER_2118_linear(Work);
p += inc;
- }
- while (--count > 0);
+ } while (--count > 0);
}
else
{
@@ -311,8 +283,7 @@ void S9xDoDMA(uint8_t Channel)
Work = *(base + p);
REGISTER_2118_tile(Work);
p += inc;
- }
- while (--count > 0);
+ } while (--count > 0);
}
break;
case 0x19:
@@ -324,8 +295,7 @@ void S9xDoDMA(uint8_t Channel)
Work = *(base + p);
REGISTER_2119_linear(Work);
p += inc;
- }
- while (--count > 0);
+ } while (--count > 0);
}
else
{
@@ -334,8 +304,7 @@ void S9xDoDMA(uint8_t Channel)
Work = *(base + p);
REGISTER_2119_tile(Work);
p += inc;
- }
- while (--count > 0);
+ } while (--count > 0);
}
break;
case 0x22:
@@ -344,8 +313,7 @@ void S9xDoDMA(uint8_t Channel)
Work = *(base + p);
REGISTER_2122(Work);
p += inc;
- }
- while (--count > 0);
+ } while (--count > 0);
break;
case 0x80:
do
@@ -353,8 +321,7 @@ void S9xDoDMA(uint8_t Channel)
Work = *(base + p);
REGISTER_2180(Work);
p += inc;
- }
- while (--count > 0);
+ } while (--count > 0);
break;
default:
do
@@ -362,8 +329,7 @@ void S9xDoDMA(uint8_t Channel)
Work = *(base + p);
S9xSetPPU(Work, 0x2100 + d->BAddress);
p += inc;
- }
- while (--count > 0);
+ } while (--count > 0);
break;
}
}
@@ -459,8 +425,7 @@ void S9xDoDMA(uint8_t Channel)
S9xSetPPU(Work, 0x2101 + d->BAddress);
p += inc;
count -= 4;
- }
- while (count > 0);
+ } while (count > 0);
}
else if (d->TransferMode == 4)
{
@@ -488,8 +453,7 @@ void S9xDoDMA(uint8_t Channel)
S9xSetPPU(Work, 0x2103 + d->BAddress);
p += inc;
count -= 4;
- }
- while (count > 0);
+ } while (count > 0);
}
}
else
@@ -549,7 +513,6 @@ void S9xDoDMA(uint8_t Channel)
d->AAddress += inc;
count--;
break;
-
case 4:
Work = S9xGetPPU(0x2100 + d->BAddress);
S9xSetByte(Work, (d->ABank << 16) + d->AAddress);
@@ -574,13 +537,11 @@ void S9xDoDMA(uint8_t Channel)
d->AAddress += inc;
count--;
break;
-
default:
count = 0;
break;
}
- }
- while (count);
+ } while (count);
}
#ifndef USE_BLARGG_APU
IAPU.APUExecuting = Settings.APUEnabled;
@@ -593,20 +554,15 @@ void S9xDoDMA(uint8_t Channel)
while (CPU.Cycles > CPU.NextEvent)
S9xDoHBlankProcessing_NoSFX();
- if (Settings.SPC7110 && spc7110_dma)
- {
- if (spc7110_dma && s7_wrap)
- free(spc7110_dma);
- }
+ if (Settings.SPC7110 && spc7110_dma && s7_wrap)
+ free(spc7110_dma);
update_address:
- // Super Punch-Out requires that the A-BUS address be updated after the
- // DMA transfer.
+ // Super Punch-Out requires that the A-BUS address be updated after the DMA transfer.
Memory.FillRAM[0x4302 + (Channel << 4)] = (uint8_t) d->AAddress;
Memory.FillRAM[0x4303 + (Channel << 4)] = d->AAddress >> 8;
- // Secret of the Mana requires that the DMA bytes transfer count be set to
- // zero when DMA has completed.
+ // Secret of the Mana requires that the DMA bytes transfer count be set to zero when DMA has completed.
Memory.FillRAM [0x4305 + (Channel << 4)] = 0;
Memory.FillRAM [0x4306 + (Channel << 4)] = 0;
@@ -619,13 +575,8 @@ update_address:
void S9xStartHDMA()
{
uint8_t i;
+ IPPU.HDMA = Memory.FillRAM [0x420c];
- if (Settings.DisableHDMA)
- IPPU.HDMA = 0;
- else
- IPPU.HDMA = Memory.FillRAM [0x420c];
-
- //per anomie timing post
if (IPPU.HDMA != 0)
CPU.Cycles += ONE_CYCLE * 3;
@@ -718,8 +669,7 @@ uint8_t S9xDoHDMA(uint8_t byte)
p->IndirectAddress = p->Address;
}
- if (!(HDMABasePointers [d] = HDMAMemPointers [d] =
- S9xGetMemPointer((p->IndirectBank << 16) + p->IndirectAddress)))
+ if (!(HDMABasePointers [d] = HDMAMemPointers [d] = S9xGetMemPointer((p->IndirectBank << 16) + p->IndirectAddress)))
{
/* XXX: Instead of this, goto a slow path that first
* XXX: verifies src!=Address Bus B, then uses
diff --git a/source/dma.h b/source/dma.h
index c2ab8d2..f9ad36f 100644
--- a/source/dma.h
+++ b/source/dma.h
@@ -7,5 +7,4 @@ void S9xResetDMA(void);
uint8_t S9xDoHDMA(uint8_t);
void S9xStartHDMA(void);
void S9xDoDMA(uint8_t);
-
#endif
diff --git a/source/dsp1.c b/source/dsp1.c
index 98c0077..6a7a6b6 100644
--- a/source/dsp1.c
+++ b/source/dsp1.c
@@ -21,10 +21,7 @@ void S9xResetDSP1()
uint8_t S9xGetDSP(uint16_t address)
{
- uint8_t t;
-
- t = (*GetDSP)(address);
- return (t);
+ return (*GetDSP)(address);
}
void S9xSetDSP(uint8_t byte, uint16_t address)
@@ -48,8 +45,7 @@ void DSP1SetByte(uint8_t byte, uint16_t address)
DSP1.in_index = 0;
DSP1.waiting4command = false;
DSP1.first_parameter = true;
- // Mario Kart uses 0x00, 0x02, 0x06, 0x0c, 0x28, 0x0a
- switch (byte)
+ switch (byte) // Mario Kart uses 0x00, 0x02, 0x06, 0x0c, 0x28, 0x0a
{
case 0x07:
case 0x0a:
@@ -628,8 +624,7 @@ void DSP2SetByte(uint8_t byte, uint16_t address)
uint32_t temp;
#endif
- if ((address & 0xf000) == 0x6000 ||
- (address >= 0x8000 && address < 0xc000))
+ if ((address & 0xf000) == 0x6000 || (address >= 0x8000 && address < 0xc000))
{
if (DSP1.waiting4command)
{
diff --git a/source/getset.h b/source/getset.h
index ebf996f..ab2186d 100644
--- a/source/getset.h
+++ b/source/getset.h
@@ -199,9 +199,6 @@ inline void S9xSetByte(uint8_t Byte, uint32_t Address)
case MAP_C4:
S9xSetC4(Byte, Address & 0xffff);
return;
- case MAP_SPC7110_DRAM:
- s7r.bank50[(Address & 0xffff)] = (uint8_t) Byte;
- break;
case MAP_OBC_RAM:
SetOBC1(Byte, Address & 0xFFFF);
return;
@@ -297,10 +294,6 @@ inline void S9xSetWord(uint16_t Word, uint32_t Address)
#endif
CPU.SRAMModified = true;
return;
- case MAP_SPC7110_DRAM:
- s7r.bank50[(Address & 0xffff)] = (uint8_t) Word;
- s7r.bank50[((Address + 1) & 0xffff)] = (uint8_t) Word;
- break;
case MAP_SA1RAM:
*(Memory.SRAM + (Address & 0xffff)) = (uint8_t) Word;
*(Memory.SRAM + ((Address + 1) & 0xffff)) = (uint8_t)(Word >> 8);
diff --git a/source/memmap.c b/source/memmap.c
index 5efeacb..9011f90 100644
--- a/source/memmap.c
+++ b/source/memmap.c
@@ -578,8 +578,7 @@ bool LoadROM(
uint8_t* RomHeader = Memory.ROM;
Memory.ExtendedFormat = NOPE;
- if (CleanUp7110 != NULL)
- (*CleanUp7110)();
+ Del7110Gfx();
memset(&SNESGameFixes, 0, sizeof(SNESGameFixes));
SNESGameFixes.SRAMInitialValue = 0x60;
diff --git a/source/spc7110.c b/source/spc7110.c
index bdeb7be..f2dc0e7 100644
--- a/source/spc7110.c
+++ b/source/spc7110.c
@@ -1,87 +1,19 @@
#include "../copyright"
#include "spc7110.h"
+#include "spc7110dec.h"
#include "memmap.h"
#include <time.h>
-#include <sys/stat.h>
-
-//Windows includes
-#ifdef __WIN32__
-#ifndef _XBOX // chdir and getcwd not supported on Xbox hardware
-#include <direct.h>
-#define chdir _chdir
-#define getcwd _getcwd
-#endif
-
-#ifndef PATH_MAX
-#ifdef MAX_PATH
-#define PATH_MAX MAX_PATH
-#else
-#define PATH_MAX 1024
-#endif
-#endif
-
-#else // Unix
-#include "display.h"
-#include <limits.h>
-#include <unistd.h>
-#endif
const char* S9xGetFilename(const char*);
-char* osd_GetPackDir(void);
-//really not needed, but usually MS adds the _ to POSIX functions,
-//while *nix doesn't, so this was to "un-M$" the function.
-#define splitpath _splitpath
-
-//not much headroom, but FEOEZ has 41 tables, I think, and SPL4 has 38.
-#define MAX_TABLES 48
-
-//default to using 5 megs of RAM for method 3 caching.
-uint16_t cacheMegs = 5;
-
-//using function pointers to initialize cache management
-void (*CleanUp7110)(void) = NULL;
-void (*LoadUp7110)(char*) = &SPC7110Load;
-void (*Copy7110)(void) = NULL;
-
-//size and offset of the pack data
-//offset and size of reads from pack
-typedef struct
-{
- uint32_t offset;
- uint32_t size;
- uint16_t used_offset;
- uint16_t used_len;
-} Data7110;
-
-//this maps an index.bin table to the decompression pack
-typedef struct
-{
- int32_t table;
- bool is_file;
- Data7110 location[256];
-} Index7110;
-
-//this contains all the data for the decompression pack.
-typedef struct
-{
- uint8_t* binfiles[MAX_TABLES];
- Index7110 tableEnts[MAX_TABLES];
- int32_t last_table;
- int32_t idx;
- uint8_t last_idx;
- uint16_t last_offset;
-} Pack7110;
-char pfold[9]; // Hack variable for log naming (each game makes a different log)
-Pack7110* decompack = NULL; // Decompression pack uses a fair chunk of RAM, so dynalloc it.
SPC7110Regs s7r; // SPC7110 registers, about 33KB
S7RTC rtc_f9; // FEOEZ (and Shounen Jump no SHou) RTC
-void S9xUpdateRTC(void); // S-RTC function hacked to work with the RTC
+void S9xUpdateRTC(void); // S-RTC function hacked to work with the RTC
-//Emulate power on state
-void S9xSpc7110Init(void)
+void S9xSpc7110Init(void) // Emulate power on state
{
+ spc7110dec_init();
s7r.DataRomOffset = 0x00100000; //handy constant!
s7r.DataRomSize = Memory.CalculatedSize - s7r.DataRomOffset;
s7r.reg4800 = 0;
@@ -132,308 +64,10 @@ void S9xSpc7110Init(void)
s7r.written = 0;
s7r.offset_add = 0;
s7r.AlignBy = 1;
-
- (*LoadUp7110)(osd_GetPackDir());
-
s7r.bank50Internal = 0;
memset(s7r.bank50, 0x00, DECOMP_BUFFER_SIZE);
}
-//full cache decompression routine (memcpy) Method 1
-void MovePackData(void)
-{
- //log the last entry
- Data7110* log = &(decompack->tableEnts[decompack->idx].location[decompack->last_idx]);
- if ((log->used_len + log->used_offset) < (decompack->last_offset +
- (uint16_t)s7r.bank50Internal))
- {
- log->used_len = s7r.bank50Internal;
- log->used_offset = decompack->last_offset;
- }
-
- //set up for next logging
- decompack->last_offset = (s7r.reg4805) | (s7r.reg4806 << 8);
-
- decompack->last_idx = s7r.reg4804;
-
- //start decompression
- int32_t table = (s7r.reg4803 << 16) | (s7r.reg4802 << 8) | s7r.reg4801;
-
- //the table is a offset multiplier byte and a big-endian pointer
- int32_t j = 4 * s7r.reg4804;
- j += s7r.DataRomOffset;
- j += table;
-
- //set proper offsetting.
- if (s7r.reg480B == 0)
- s7r.AlignBy = 0;
- else
- {
- switch (Memory.ROM[j])
- {
- case 0x03:
- s7r.AlignBy = 8;
- break;
- case 0x01:
- s7r.AlignBy = 2;
- break;
- case 0x02:
- s7r.AlignBy = 4;
- break;
- case 0x00:
- default:
- s7r.AlignBy = 1;
- break;
- }
- }
- //note that we are still setting up for the next log.
- decompack->last_offset *= s7r.AlignBy;
- decompack->last_offset %= DECOMP_BUFFER_SIZE;
-
- //find the table
- if (table != decompack->last_table)
- {
- int32_t i = 0;
- while (i < MAX_TABLES && decompack->tableEnts[i].table != table)
- i++;
- if (i == MAX_TABLES)
- {
-#ifdef _XBOX
- FILE* fp = fopen("T:\\sp7err.out", "a");
-#else
- FILE* fp = fopen("sp7err.out", "a");
-#endif
-
- fclose(fp);
- return;
- }
- decompack->idx = i;
- decompack->last_table = table;
- }
-
- //copy data
- if (decompack->binfiles[decompack->idx])
- {
- memcpy(s7r.bank50,
- &(decompack->binfiles[decompack->idx][decompack->tableEnts[decompack->idx].location[s7r.reg4804].offset]),
- decompack->tableEnts[decompack->idx].location[s7r.reg4804].size);
- }
-}
-
-// This is similar to the last function, but it keeps the last 5 accessed files open,
-// and reads the data directly. Method 2
-void ReadPackData(void)
-{
- static int32_t table_age_2;
- static int32_t table_age_3;
- static int32_t table_age_4;
- static int32_t table_age_5;
-
- int32_t table = (s7r.reg4803 << 16) | (s7r.reg4802 << 8) | s7r.reg4801;
-
- if (table == 0)
- {
- table_age_2 = table_age_3 = table_age_4 = table_age_5 = MAX_TABLES;
- return;
- }
-
- if (table_age_2 == 0 && table_age_3 == 0 && table_age_4 == 0 && table_age_5 == 0)
- table_age_2 = table_age_3 = table_age_4 = table_age_5 = MAX_TABLES;
- Data7110* log = &(decompack->tableEnts[decompack->idx].location[decompack->last_idx]);
- if ((log->used_len + log->used_offset) < (decompack->last_offset +
- (uint16_t)s7r.bank50Internal))
- {
- log->used_len = s7r.bank50Internal;
- log->used_offset = decompack->last_offset;
- }
-
- decompack->last_offset = (s7r.reg4805) | (s7r.reg4806 << 8);
-
- decompack->last_idx = s7r.reg4804;
-
- int32_t j = 4 * s7r.reg4804;
- j += s7r.DataRomOffset;
- j += table;
-
- if (s7r.reg480B == 0)
- s7r.AlignBy = 0;
- else
- {
- switch (Memory.ROM[j])
- {
- case 0x03:
- s7r.AlignBy = 8;
- break;
- case 0x01:
- s7r.AlignBy = 2;
- break;
- case 0x02:
- s7r.AlignBy = 4;
- break;
- case 0x00:
- default:
- s7r.AlignBy = 1;
- break;
- }
- }
- decompack->last_offset *= s7r.AlignBy;
- decompack->last_offset %= DECOMP_BUFFER_SIZE;
- if (table != decompack->last_table)
- {
- int32_t i = 0;
- while (i < MAX_TABLES && decompack->tableEnts[i].table != table)
- i++;
- if (i == MAX_TABLES)
- {
- FILE* fp = fopen("sp7err.out", "a");
- fclose(fp);
- return;
- }
- if (i != table_age_2 && i != table_age_3 && i != table_age_4 && i != table_age_5)
- {
- if (table_age_5 != MAX_TABLES && decompack->binfiles[table_age_5])
- {
- fclose((FILE*)(decompack->binfiles[table_age_5]));
- (decompack->binfiles[table_age_5]) = NULL;
- }
- table_age_5 = table_age_4;
- table_age_4 = table_age_3;
- table_age_3 = table_age_2;
- table_age_2 = decompack->idx;
- char name[PATH_MAX];
- //open file
- char drive [_MAX_DRIVE + 1];
- char dir [_MAX_DIR + 1];
- char fname [_MAX_FNAME + 1];
- char ext [_MAX_EXT + 1];
-
- splitpath(Memory.ROMFilename, drive, dir, fname, ext);
- strcpy(name, drive);
- strcat(name, dir);
-
- strcat(name, pfold);
- char bfname[11];
- sprintf(bfname, "%06X.bin", table);
- strcat(name, "/");
- strcat(name, bfname);
- decompack->binfiles[i] = (uint8_t*)fopen(name, "rb");
- }
- else
- {
- //fix tables in this case
- if (table_age_5 == i)
- {
- table_age_5 = table_age_4;
- table_age_4 = table_age_3;
- table_age_3 = table_age_2;
- table_age_2 = decompack->idx;
- }
- if (table_age_4 == i)
- {
- table_age_4 = table_age_3;
- table_age_3 = table_age_2;
- table_age_2 = decompack->idx;
- }
- if (table_age_3 == i)
- {
- table_age_3 = table_age_2;
- table_age_2 = decompack->idx;
- }
- if (table_age_2 == i)
- table_age_2 = decompack->idx;
- }
- decompack->idx = i;
- decompack->last_table = table;
- }
- //do read here.
- if (decompack->binfiles[decompack->idx])
- {
- fseek((FILE*)(decompack->binfiles[decompack->idx]),
- decompack->tableEnts[decompack->idx].location[s7r.reg4804].offset, 0);
- fread(s7r.bank50, 1, (
- decompack->tableEnts[decompack->idx].location[s7r.reg4804].size),
- (FILE*)(decompack->binfiles[decompack->idx]));
- }
-}
-
-//Cache Method 3: some entries are cached, others are file handles.
-//use is_file to distinguish.
-void GetPackData(void)
-{
- Data7110* log = &
- (decompack->tableEnts[decompack->idx].location[decompack->last_idx]);
- if ((log->used_len + log->used_offset) < (decompack->last_offset +
- (uint16_t)s7r.bank50Internal))
- {
- log->used_len = s7r.bank50Internal;
- log->used_offset = decompack->last_offset;
- }
-
- decompack->last_offset = (s7r.reg4805) | (s7r.reg4806 << 8);
-
- decompack->last_idx = s7r.reg4804;
- int32_t table = (s7r.reg4803 << 16) | (s7r.reg4802 << 8) | s7r.reg4801;
-
- int32_t j = 4 * s7r.reg4804;
- j += s7r.DataRomOffset;
- j += table;
-
- if (s7r.reg480B == 0)
- s7r.AlignBy = 0;
- else
- {
- switch (Memory.ROM[j])
- {
- case 0x03:
- s7r.AlignBy = 8;
- break;
- case 0x01:
- s7r.AlignBy = 2;
- break;
- case 0x02:
- s7r.AlignBy = 4;
- break;
- case 0x00:
- default:
- s7r.AlignBy = 1;
- break;
- }
- }
- decompack->last_offset *= s7r.AlignBy;
- decompack->last_offset %= DECOMP_BUFFER_SIZE;
- if (table != decompack->last_table)
- {
- int32_t i = 0;
- while (i < MAX_TABLES && decompack->tableEnts[i].table != table)
- i++;
- if (i == MAX_TABLES)
- {
- FILE* fp = fopen("sp7err.out", "a");
- fclose(fp);
- return;
- }
- decompack->idx = i;
- decompack->last_table = table;
- }
- if (decompack->binfiles[decompack->idx])
- {
- if (decompack->tableEnts[decompack->idx].is_file)
- {
- fseek((FILE*)decompack->binfiles[decompack->idx],
- decompack->tableEnts[decompack->idx].location[s7r.reg4804].offset, 0);
- fread(s7r.bank50, 1, (
- decompack->tableEnts[decompack->idx].location[s7r.reg4804].size),
- (FILE*)(decompack->binfiles[decompack->idx]));
- }
- else
- {
- memcpy(s7r.bank50,
- &(decompack->binfiles[decompack->idx][decompack->tableEnts[decompack->idx].location[s7r.reg4804].offset]),
- decompack->tableEnts[decompack->idx].location[s7r.reg4804].size);
- }
- }
-}
-
//reads SPC7110 and RTC registers.
uint8_t S9xGetSPC7110(uint16_t Address)
{
@@ -448,40 +82,27 @@ uint8_t S9xGetSPC7110(uint16_t Address)
case 0x4800:
{
uint16_t count = s7r.reg4809 | (s7r.reg480A << 8);
- uint32_t i, j;
- j = (s7r.reg4805 | (s7r.reg4806 << 8));
- j *= s7r.AlignBy;
- i = j;
+
if (count > 0)
count--;
- else count = 0xFFFF;
+ else
+ count = 0xFFFF;
s7r.reg4809 = 0x00ff & count;
s7r.reg480A = (0xff00 & count) >> 8;
- i += s7r.bank50Internal;
- i %= DECOMP_BUFFER_SIZE;
- s7r.reg4800 = s7r.bank50[i];
-
- s7r.bank50Internal++;
- s7r.bank50Internal %= DECOMP_BUFFER_SIZE;
+ s7r.reg4800 = spc7110dec_read();
+ return s7r.reg4800;
}
- return s7r.reg4800;
- //table register low
- case 0x4801:
+ case 0x4801: //table register low
return s7r.reg4801;
- //table register middle
- case 0x4802:
+ case 0x4802: //table register middle
return s7r.reg4802;
- //table register high
- case 0x4803:
+ case 0x4803: //table register high
return s7r.reg4803;
- //index of pointer in table (each entry is 4 bytes)
- case 0x4804:
+ case 0x4804: //index of pointer in table (each entry is 4 bytes)
return s7r.reg4804;
- //offset register low
- case 0x4805:
+ case 0x4805: //offset register low
return s7r.reg4805;
- //offset register high
- case 0x4806:
+ case 0x4806: //offset register high
return s7r.reg4806;
//DMA channel (not that I see this usually set,
//regardless of what channel DMA is on)
@@ -496,15 +117,13 @@ uint8_t S9xGetSPC7110(uint16_t Address)
//this is set by the ROM, and wraps on bounds.
case 0x4809:
return s7r.reg4809;
- //C Length high
- case 0x480A:
+ case 0x480A: //C Length high
return s7r.reg480A;
//Offset enable.
//if this is zero, 4805-6 are useless. Emulated by setting AlignBy to 0
case 0x480B:
return s7r.reg480B;
- //decompression finished: just emulated by switching each read.
- case 0x480C:
+ case 0x480C: //decompression finished: just emulated by switching each read.
s7r.reg480C ^= 0x80;
return s7r.reg480C ^ 0x80;
//Data access port
@@ -536,7 +155,8 @@ uint8_t S9xGetSPC7110(uint16_t Address)
i += r4814;
if (r4814 != 0xFFFF)
r4814++;
- else r4814 = 0;
+ else
+ r4814 = 0;
s7r.reg4815 = (uint8_t)(r4814 >> 8);
s7r.reg4814 = (uint8_t)(r4814 & 0x00FF);
@@ -553,8 +173,7 @@ uint8_t S9xGetSPC7110(uint16_t Address)
{
if (s7r.reg4818 & 0x04)
{
- int16_t inc;
- inc = (s7r.reg4817 << 8) | s7r.reg4816;
+ int16_t inc = (s7r.reg4817 << 8) | s7r.reg4816;
if (!(s7r.reg4818 & 0x10))
i += inc;
@@ -640,31 +259,23 @@ uint8_t S9xGetSPC7110(uint16_t Address)
s7r.reg4813 = ((i & 0xFF0000) >> 16);
return tmp;
}
- else return 0;
- //direct read address low
- case 0x4811:
+ else
+ return 0;
+ case 0x4811: //direct read address low
return s7r.reg4811;
- //direct read address middle
- case 0x4812:
+ case 0x4812: //direct read address middle
return s7r.reg4812;
- //direct read access high
- case 0x4813:
+ case 0x4813: //direct read access high
return s7r.reg4813;
- //read adjust low
- case 0x4814:
+ case 0x4814: //read adjust low
return s7r.reg4814;
- //read adjust high
- case 0x4815:
+ case 0x4815: //read adjust high
return s7r.reg4815;
- //read increment low
- case 0x4816:
+ case 0x4816: //read increment low
return s7r.reg4816;
- //read increment high
- case 0x4817:
+ case 0x4817: //read increment high
return s7r.reg4817;
- //Data ROM command mode
- //essentially, this controls the insane code of $4810 and $481A
- case 0x4818:
+ case 0x4818: //Data ROM command mode; essentially, this controls the insane code of $4810 and $481A
return s7r.reg4818;
//read after adjust port
//what this does, besides more nasty stuff like 4810,
@@ -675,22 +286,14 @@ uint8_t S9xGetSPC7110(uint16_t Address)
{
uint32_t i = ((s7r.reg4813 << 16) | (s7r.reg4812 << 8) | s7r.reg4811);
if (s7r.reg4818 & 0x08)
- {
- int16_t adj;
- adj = ((int16_t)(s7r.reg4815 << 8)) | s7r.reg4814;
- i += adj;
- }
+ i += ((int16_t)(s7r.reg4815 << 8)) | s7r.reg4814;
else
- {
- uint16_t adj;
- adj = (s7r.reg4815 << 8) | s7r.reg4814;
- i += adj;
- }
+ i += (s7r.reg4815 << 8) | s7r.reg4814;
i %= s7r.DataRomSize;
i += s7r.DataRomOffset;
uint8_t tmp = Memory.ROM[i];
- if (0x60 == (s7r.reg4818 & 0x60))
+ if ((s7r.reg4818 & 0x60) == 0x60)
{
i = ((s7r.reg4813 << 16) | (s7r.reg4812 << 8) | s7r.reg4811);
@@ -733,85 +336,60 @@ uint8_t S9xGetSPC7110(uint16_t Address)
}
return tmp;
}
- else return 0;
-
- //multiplicand low or dividend lowest
- case 0x4820:
+ else
+ return 0;
+ case 0x4820: //multiplicand low or dividend lowest
return s7r.reg4820;
- //multiplicand high or divdend lower
- case 0x4821:
+ case 0x4821: //multiplicand high or divdend lower
return s7r.reg4821;
- //dividend higher
- case 0x4822:
+ case 0x4822: //dividend higher
return s7r.reg4822;
- //dividend highest
- case 0x4823:
+ case 0x4823: //dividend highest
return s7r.reg4823;
- //multiplier low
- case 0x4824:
+ case 0x4824: //multiplier low
return s7r.reg4824;
- //multiplier high
- case 0x4825:
+ case 0x4825: //multiplier high
return s7r.reg4825;
- //divisor low
- case 0x4826:
+ case 0x4826: //divisor low
return s7r.reg4826;
- //divisor high
- case 0x4827:
+ case 0x4827: //divisor high
return s7r.reg4827;
- //result lowest
- case 0x4828:
+ case 0x4828: //result lowest
return s7r.reg4828;
- //result lower
- case 0x4829:
+ case 0x4829: //result lower
return s7r.reg4829;
- //result higher
- case 0x482A:
+ case 0x482A: //result higher
return s7r.reg482A;
- //result highest
- case 0x482B:
+ case 0x482B: //result highest
return s7r.reg482B;
- //remainder (division) low
- case 0x482C:
+ case 0x482C: //remainder (division) low
return s7r.reg482C;
- //remainder (division) high
- case 0x482D:
+ case 0x482D: //remainder (division) high
return s7r.reg482D;
- //signed/unsigned
- case 0x482E:
+ case 0x482E: //signed/unsigned
return s7r.reg482E;
- //finished flag, emulated as an on-read toggle.
- case 0x482F:
+ case 0x482F: //finished flag, emulated as an on-read toggle.
if (s7r.reg482F)
{
s7r.reg482F = 0;
return 0x80;
}
return 0;
- break;
-
- //SRAM toggle
- case 0x4830:
+ case 0x4830: //SRAM toggle
return s7r.reg4830;
- //DX bank mapping
- case 0x4831:
+ case 0x4831: //DX bank mapping
return s7r.reg4831;
- //EX bank mapping
- case 0x4832:
+ case 0x4832: //EX bank mapping
return s7r.reg4832;
- //FX bank mapping
- case 0x4833:
+ case 0x4833: //FX bank mapping
return s7r.reg4833;
- //SRAM mapping? We have no clue!
- case 0x4834:
+ case 0x4834: //SRAM mapping? We have no clue!
return s7r.reg4834;
- //RTC enable
- case 0x4840:
+ case 0x4840: //RTC enable
if (!Settings.SPC7110RTC)
return Address >> 8;
return s7r.reg4840;
- //command/index/value of RTC (essentially, zero unless we're in read mode
- case 0x4841:
+ case 0x4841: //command/index/value of RTC (essentially, zero unless we're in read mode
if (!Settings.SPC7110RTC)
return Address >> 8;
if (rtc_f9.init)
@@ -822,9 +400,9 @@ uint8_t S9xGetSPC7110(uint16_t Address)
rtc_f9.index %= 0x10;
return tmp;
}
- else return 0;
- //RTC done flag
- case 0x4842:
+ else
+ return 0;
+ case 0x4842: //RTC done flag
if (!Settings.SPC7110RTC)
return Address >> 8;
s7r.reg4842 ^= 0x80;
@@ -834,14 +412,21 @@ uint8_t S9xGetSPC7110(uint16_t Address)
}
}
+static uint32_t datarom_addr(uint32_t addr)
+{
+ uint32_t size = Memory.CalculatedSize - 0x100000;
+
+ while(addr >= size)
+ addr -= size;
+ return addr + 0x100000;
+}
+
void S9xSetSPC7110(uint8_t data, uint16_t Address)
{
switch (Address)
{
//Writes to $4800 are undefined.
-
- //table low, middle, and high.
- case 0x4801:
+ case 0x4801: //table low, middle, and high.
s7r.reg4801 = data;
break;
case 0x4802:
@@ -850,54 +435,44 @@ void S9xSetSPC7110(uint8_t data, uint16_t Address)
case 0x4803:
s7r.reg4803 = data;
break;
-
- //table index (4 byte entries, bigendian with a multiplier byte)
- case 0x4804:
+ case 0x4804: //table index (4 byte entries, bigendian with a multiplier byte)
s7r.reg4804 = data;
break;
-
- //offset low
- case 0x4805:
+ case 0x4805: //offset low
s7r.reg4805 = data;
break;
-
- //offset high, starts decompression
- case 0x4806:
+ case 0x4806: //offset high, starts decompression
+ {
+ uint32_t table = (s7r.reg4801 + (s7r.reg4802 << 8) + (s7r.reg4803 << 16));
+ uint32_t index = (s7r.reg4804 << 2);
+ uint32_t addr = datarom_addr(table + index);
+ uint32_t mode = (Memory.ROM[addr + 0]);
+ uint32_t offset = (Memory.ROM[addr + 1] << 16) + (Memory.ROM[addr + 2] << 8) + (Memory.ROM[addr + 3]);
s7r.reg4806 = data;
- (*Copy7110)();
+ spc7110dec_clear(mode, offset, (s7r.reg4805 + (s7r.reg4806 << 8)) << mode);
s7r.bank50Internal = 0;
s7r.reg480C &= 0x7F;
break;
-
- //DMA channel register (Is it used??)
- case 0x4807:
+ }
+ case 0x4807: //DMA channel register (Is it used??)
s7r.reg4807 = data;
break;
-
//C r/w? I have no idea. If you get weird values written here before a bug,
//The Dumper should probably be contacted about running a test.
case 0x4808:
s7r.reg4808 = data;
break;
-
- //C-Length low
- case 0x4809:
+ case 0x4809: //C-Length low
s7r.reg4809 = data;
break;
- //C-Length high
- case 0x480A:
+ case 0x480A: //C-Length high
s7r.reg480A = data;
break;
-
- //Offset enable
- case 0x480B:
+ case 0x480B: //Offset enable
{
s7r.reg480B = data;
int32_t table = (s7r.reg4803 << 16) | (s7r.reg4802 << 8) | s7r.reg4801;
-
- int32_t j = 4 * s7r.reg4804;
- j += s7r.DataRomOffset;
- j += table;
+ int32_t j = 4 * s7r.reg4804 + s7r.DataRomOffset + table;
if (s7r.reg480B == 0)
s7r.AlignBy = 0;
@@ -920,30 +495,21 @@ void S9xSetSPC7110(uint8_t data, uint16_t Address)
break;
}
}
+ break;
}
- break;
- //$4810 is probably read only.
-
- //Data port address low
- case 0x4811:
+ case 0x4811: //Data port address low
s7r.reg4811 = data;
s7r.written |= 0x01;
break;
-
- //data port address middle
- case 0x4812:
+ case 0x4812: //data port address middle
s7r.reg4812 = data;
s7r.written |= 0x02;
break;
-
- //data port address high
- case 0x4813:
+ case 0x4813: //data port address high
s7r.reg4813 = data;
s7r.written |= 0x04;
break;
-
- //data port adjust low (has a funky immediate increment mode)
- case 0x4814:
+ case 0x4814: //data port adjust low (has a funky immediate increment mode)
s7r.reg4814 = data;
if (s7r.reg4818 & 0x02)
{
@@ -952,10 +518,7 @@ void S9xSetSPC7110(uint8_t data, uint16_t Address)
s7r.offset_add |= 0x01;
if (s7r.offset_add == 3)
{
- if (s7r.reg4818 & 0x10)
- {
- }
- else
+ if(!(s7r.reg4818 & 0x10))
{
uint32_t i = (s7r.reg4813 << 16) | (s7r.reg4812 << 8) | s7r.reg4811;
if (s7r.reg4818 & 0x08)
@@ -974,39 +537,25 @@ void S9xSetSPC7110(uint8_t data, uint16_t Address)
s7r.offset_add |= 0x01;
if (s7r.offset_add == 3)
{
- if (s7r.reg4818 & 0x10)
- {
- }
- else
+ if(!(s7r.reg4818 & 0x10))
{
uint32_t i = (s7r.reg4813 << 16) | (s7r.reg4812 << 8) | s7r.reg4811;
if (s7r.reg4818 & 0x08)
- {
- int16_t adj;
- adj = ((int16_t)(s7r.reg4815 << 8)) | s7r.reg4814;
- i += adj;
- }
+ i += ((int16_t)(s7r.reg4815 << 8)) | s7r.reg4814;
else
- {
- uint16_t adj;
- adj = (s7r.reg4815 << 8) | s7r.reg4814;
- i += adj;
- }
+ i += (s7r.reg4815 << 8) | s7r.reg4814;
i %= s7r.DataRomSize;
s7r.reg4811 = i & 0x00FF;
s7r.reg4812 = (i & 0x00FF00) >> 8;
s7r.reg4813 = ((i & 0xFF0000) >> 16);
}
}
-
}
}
s7r.written |= 0x08;
break;
-
- //data port adjust high (has a funky immediate increment mode)
- case 0x4815:
+ case 0x4815: //data port adjust high (has a funky immediate increment mode)
s7r.reg4815 = data;
if (s7r.reg4818 & 0x02)
{
@@ -1015,10 +564,7 @@ void S9xSetSPC7110(uint8_t data, uint16_t Address)
s7r.offset_add |= 0x02;
if (s7r.offset_add == 3)
{
- if (s7r.reg4818 & 0x10)
- {
- }
- else
+ if(!(s7r.reg4818 & 0x10))
{
uint32_t i = (s7r.reg4813 << 16) | (s7r.reg4812 << 8) | s7r.reg4811;
@@ -1038,24 +584,13 @@ void S9xSetSPC7110(uint8_t data, uint16_t Address)
s7r.offset_add |= 0x02;
if (s7r.offset_add == 3)
{
- if (s7r.reg4818 & 0x10)
- {
- }
- else
+ if(!(s7r.reg4818 & 0x10))
{
uint32_t i = (s7r.reg4813 << 16) | (s7r.reg4812 << 8) | s7r.reg4811;
if (s7r.reg4818 & 0x08)
- {
- int16_t adj;
- adj = ((int16_t)(s7r.reg4815 << 8)) | s7r.reg4814;
- i += adj;
- }
+ i += ((int16_t)(s7r.reg4815 << 8)) | s7r.reg4814;
else
- {
- uint16_t adj;
- adj = (s7r.reg4815 << 8) | s7r.reg4814;
- i += adj;
- }
+ i += (s7r.reg4815 << 8) | s7r.reg4814;
i %= s7r.DataRomSize;
s7r.reg4811 = i & 0x00FF;
s7r.reg4812 = (i & 0x00FF00) >> 8;
@@ -1066,15 +601,12 @@ void S9xSetSPC7110(uint8_t data, uint16_t Address)
}
s7r.written |= 0x10;
break;
- //data port increment low
- case 0x4816:
+ case 0x4816: //data port increment low
s7r.reg4816 = data;
break;
- //data port increment high
- case 0x4817:
+ case 0x4817: //data port increment high
s7r.reg4817 = data;
break;
-
//data port mode switches
//note that it starts inactive.
case 0x4818:
@@ -1083,29 +615,22 @@ void S9xSetSPC7110(uint8_t data, uint16_t Address)
s7r.offset_add = 0;
s7r.reg4818 = data;
break;
-
- //multiplicand low or dividend lowest
- case 0x4820:
+ case 0x4820: //multiplicand low or dividend lowest
s7r.reg4820 = data;
break;
- //multiplicand high or dividend lower
- case 0x4821:
+ case 0x4821: //multiplicand high or dividend lower
s7r.reg4821 = data;
break;
- //dividend higher
- case 0x4822:
+ case 0x4822: //dividend higher
s7r.reg4822 = data;
break;
- //dividend highest
- case 0x4823:
+ case 0x4823: //dividend highest
s7r.reg4823 = data;
break;
- //multiplier low
- case 0x4824:
+ case 0x4824: //multiplier low
s7r.reg4824 = data;
break;
- //multiplier high (triggers operation)
- case 0x4825:
+ case 0x4825: //multiplier high (triggers operation)
s7r.reg4825 = data;
if (s7r.reg482E & 0x01)
{
@@ -1129,19 +654,16 @@ void S9xSetSPC7110(uint8_t data, uint16_t Address)
}
s7r.reg482F = 0x80;
break;
- //divisor low
- case 0x4826:
+ case 0x4826: //divisor low
s7r.reg4826 = data;
break;
- //divisor high (triggers operation)
- case 0x4827:
+ case 0x4827: //divisor high (triggers operation)
s7r.reg4827 = data;
if (s7r.reg482E & 0x01)
{
int32_t quotient;
int16_t remainder;
- int32_t dividend = (int32_t)(s7r.reg4820 | (s7r.reg4821 << 8) | (s7r.reg4822 << 16) |
- (s7r.reg4823 << 24));
+ int32_t dividend = (int32_t)(s7r.reg4820 | (s7r.reg4821 << 8) | (s7r.reg4822 << 16) | (s7r.reg4823 << 24));
int16_t divisor = (int16_t)(s7r.reg4826 | (s7r.reg4827 << 8));
if (divisor != 0)
{
@@ -1164,8 +686,7 @@ void S9xSetSPC7110(uint8_t data, uint16_t Address)
{
uint32_t quotient;
uint16_t remainder;
- uint32_t dividend = (uint32_t)(s7r.reg4820 | (s7r.reg4821 << 8) |
- (s7r.reg4822 << 16) | (s7r.reg4823 << 24));
+ uint32_t dividend = (uint32_t)(s7r.reg4820 | (s7r.reg4821 << 8) | (s7r.reg4822 << 16) | (s7r.reg4823 << 24));
uint16_t divisor = (uint16_t)(s7r.reg4826 | (s7r.reg4827 << 8));
if (divisor != 0)
{
@@ -1191,42 +712,30 @@ void S9xSetSPC7110(uint8_t data, uint16_t Address)
//reset: writes here nuke the whole math unit
//Zero indicates unsigned math, resets with non-zero values turn on signed math
case 0x482E:
- s7r.reg4820 = s7r.reg4821 = s7r.reg4822 = s7r.reg4823 = s7r.reg4824 =
- s7r.reg4825 = s7r.reg4826 = s7r.reg4827 = s7r.reg4828 = s7r.reg4829 =
- s7r.reg482A = s7r.reg482B = s7r.reg482C = s7r.reg482D = 0;
+ s7r.reg4820 = s7r.reg4821 = s7r.reg4822 = s7r.reg4823 = s7r.reg4824 = s7r.reg4825 = s7r.reg4826 = s7r.reg4827 = s7r.reg4828 = s7r.reg4829 = s7r.reg482A = s7r.reg482B = s7r.reg482C = s7r.reg482D = 0;
s7r.reg482E = data;
break;
-
- //math status register possibly read only
-
- //SRAM toggle
- case 0x4830:
+ //math status register possibly read only
+ case 0x4830: //SRAM toggle
SPC7110Sram(data);
s7r.reg4830 = data;
break;
- //Bank DX mapping
- case 0x4831:
+ case 0x4831: //Bank DX mapping
s7r.reg4831 = data;
break;
- //Bank EX mapping
- case 0x4832:
+ case 0x4832: //Bank EX mapping
s7r.reg4832 = data;
break;
- //Bank FX mapping
- case 0x4833:
+ case 0x4833: //Bank FX mapping
s7r.reg4833 = data;
break;
- //S-RAM mapping? who knows?
- case 0x4834:
+ case 0x4834: //S-RAM mapping? who knows?
s7r.reg4834 = data;
break;
- //RTC Toggle
- case 0x4840:
- if (0 == data)
- {
+ case 0x4840: //RTC Toggle
+ if(!data)
S9xUpdateRTC();
- }
- if (data & 0x01)
+ else if(data & 0x01)
{
s7r.reg4842 = 0x80;
rtc_f9.init = false;
@@ -1234,11 +743,10 @@ void S9xSetSPC7110(uint8_t data, uint16_t Address)
}
s7r.reg4840 = data;
break;
- //RTC init/command/index register
- case 0x4841:
+ case 0x4841: //RTC init/command/index register
if (rtc_f9.init)
{
- if (-1 == rtc_f9.index)
+ if (rtc_f9.index == -1)
{
rtc_f9.index = data & 0x0F;
break;
@@ -1251,8 +759,7 @@ void S9xSetSPC7110(uint8_t data, uint16_t Address)
}
else
{
-
- if (0x0D == rtc_f9.index)
+ if (rtc_f9.index == 0x0D)
{
if (data & 0x08)
{
@@ -1285,7 +792,7 @@ void S9xSetSPC7110(uint8_t data, uint16_t Address)
}
}
}
- if (0x0F == rtc_f9.index)
+ if (rtc_f9.index == 0x0F)
{
if (data & 0x01 && !(rtc_f9.reg[0x0F] & 0x01))
{
@@ -1315,10 +822,6 @@ void S9xSetSPC7110(uint8_t data, uint16_t Address)
}
}
break;
- //writes to RTC status register aren't expected to be meaningful
- default:
- break;
- //16 BIT MULTIPLIER: ($FF00) high byte, defval:00
}
}
@@ -1352,35 +855,25 @@ uint8_t S9xGetSPC7110Byte(uint32_t Address)
/**********************************************************************************************/
int32_t S9xRTCDaysInMonth(int32_t month, int32_t year)
{
- int32_t mdays;
-
- switch (month)
+ switch(month)
{
case 2:
- if ((year % 4 == 0)) // DKJM2 only uses 199x - 22xx
- mdays = 29;
- else
- mdays = 28;
- break;
-
+ if(year % 4 == 0) // DKJM2 only uses 199x - 22xx
+ return 29;
+ return 28;
case 4:
case 6:
case 9:
case 11:
- mdays = 30;
- break;
-
+ return 30;
default: // months 1,3,5,7,8,10,12
- mdays = 31;
- break;
+ return 31;
}
-
- return mdays;
}
-#define DAYTICKS (60*60*24)
-#define HOURTICKS (60*60)
-#define MINUTETICKS 60
+#define MINUTETICKS 60
+#define HOURTICKS (60 * MINUTETICKS)
+#define DAYTICKS (24 * HOURTICKS)
/**********************************************************************************************/
/* S9xUpdateRTC() */
@@ -1535,296 +1028,12 @@ uint8_t* Get7110BasePtr(uint32_t Address)
return &Memory.ROM[i];
}
-//loads the index into memory.
-//index.bin is little-endian
-//format index (1)-table(3)-file offset(4)-length(4)
-bool Load7110Index(char* filename)
-{
- FILE* fp;
- uint8_t buffer[12];
- int32_t table = 0;
- uint8_t index = 0;
- uint32_t offset = 0;
- uint32_t size = 0;
- int32_t i = 0;
- fp = fopen(filename, "rb");
- if (NULL == fp)
- return false;
-
- int32_t f_len;
- while (1)
- {
- i = 0;
- f_len = fread(buffer, 1, 12, fp);
- if (f_len < 12) break;
-
- table = (buffer[3] << 16) | (buffer[2] << 8) | buffer[1];
- index = buffer[0];
- offset = (buffer[7] << 24) | (buffer[6] << 16) | (buffer[5] << 8) | buffer[4];
- size = (buffer[11] << 24) | (buffer[10] << 16) | (buffer[9] << 8) | buffer[8];
- while (i < MAX_TABLES && decompack->tableEnts[i].table != table
- && decompack->tableEnts[i].table != 0)
- i++;
- if (i == MAX_TABLES)
- return false;
- //added
- decompack->tableEnts[i].table = table;
- //-----
- decompack->tableEnts[i].location[index].offset = offset;
- decompack->tableEnts[i].location[index].size = size;
- decompack->tableEnts[i].location[index].used_len = 0;
- decompack->tableEnts[i].location[index].used_offset = 0;
- }
- fclose(fp);
- return true;
-}
-
-//Cache 1 load function
-void SPC7110Load(char* dirname)
-{
- char temp_path[PATH_MAX];
- int32_t i = 0;
-
- decompack = (Pack7110*)malloc(sizeof(Pack7110));
-
-#if !defined(_XBOX) && !defined(VITA)
- getcwd(temp_path, PATH_MAX);
-#endif
-
- memset(decompack, 0, sizeof(Pack7110));
-
-#if !defined(_XBOX) && !defined(VITA)
- chdir(dirname);
-#endif
-
-#ifndef _XBOX
- Load7110Index("index.bin");
-#else
- // D:\\ is always app.path in Xbox
- Load7110Index("d:\\index.bin");
-#endif
-
- for (i = 0; i < MAX_TABLES; i++)
- {
- if (decompack->tableEnts[i].table != 0)
- {
- char binname[PATH_MAX];
-#ifndef _XBOX
- sprintf(binname, "%06X.bin", decompack->tableEnts[i].table);
-#else
- sprintf(binname, "%s%06X.bin", filename, decompack->tableEnts[i].table);
-#endif
- struct stat buf;
- if (-1 != stat(binname, &buf))
- decompack->binfiles[i] = (uint8_t*)malloc(buf.st_size);
- FILE* fp = fopen(binname, "rb");
- if (fp)
- {
- fread(decompack->binfiles[i], buf.st_size, 1, fp);
- fclose(fp);
- }
- }
- }
-
-#if !defined(_XBOX) && !defined(VITA)
- chdir(temp_path);
-#endif
-
- Copy7110 = &MovePackData;
- CleanUp7110 = &Del7110Gfx;
-
-}
-
-//Cache 2 load function
-void SPC7110Open(char* dirname)
-{
- char temp_path[PATH_MAX];
- int32_t i = 0;
-
- decompack = (Pack7110*)malloc(sizeof(Pack7110));
-
-#if !defined(_XBOX) && !defined(VITA)
- getcwd(temp_path, PATH_MAX);
-#endif
-
- memset(decompack, 0, sizeof(Pack7110));
-
-#if !defined(_XBOX) && !defined(VITA)
- chdir(dirname);
-#endif
-
-#ifndef _XBOX
- Load7110Index("index.bin");
-#else
- // D:\\ is always app.path in Xbox
- Load7110Index("d:\\index.bin");
-#endif
-
- for (i = 0; i < MAX_TABLES; i++)
- decompack->binfiles[i] = NULL;
-
- ReadPackData();
-
-#if !defined(_XBOX) && !defined(VITA)
- chdir(temp_path);
-#endif
-
- Copy7110 = &ReadPackData;
- CleanUp7110 = &Close7110Gfx;
-}
-
-//Cache 3's load function
-void SPC7110Grab(char* dirname)
-{
- char temp_path[PATH_MAX];
- int32_t i = 0;
-
- decompack = (Pack7110*)malloc(sizeof(Pack7110));
-
-#if !defined(_XBOX) && !defined(VITA)
- getcwd(temp_path, PATH_MAX);
-#endif
-
- int32_t buffer_size = 1024 * 1024 * cacheMegs; //*some setting
-
- memset(decompack, 0, sizeof(Pack7110));
-#if !defined(_XBOX) && !defined(VITA)
- chdir(dirname);
-#endif
-
-#ifndef _XBOX
- Load7110Index("index.bin");
-#else
- // D:\\ is always app.path in Xbox
- Load7110Index("d:\\index.bin");
-#endif
-
- for (i = 0; i < MAX_TABLES; i++)
- {
- if (decompack->tableEnts[i].table != 0)
- {
- char binname[PATH_MAX];
-#ifndef _XBOX
- sprintf(binname, "%06X.bin", decompack->tableEnts[i].table);
-#else
- sprintf(binname, "%s%06X.bin", filename, decompack->tableEnts[i].table);
-#endif
- struct stat buf;
- //add load/no load calculations here
- if (-1 != stat(binname, &buf))
- {
- if (buf.st_size < buffer_size)
- decompack->binfiles[i] = (uint8_t*)malloc(buf.st_size);
- FILE* fp = fopen(binname, "rb");
- //use them here
- if (fp)
- {
- if (buf.st_size < buffer_size)
- {
- fread(decompack->binfiles[i], buf.st_size, 1, fp);
- fclose(fp);
- buffer_size -= buf.st_size;
- decompack->tableEnts[i].is_file = false;
- }
- else
- {
- decompack->binfiles[i] = (uint8_t*)fp;
- decompack->tableEnts[i].is_file = true;
- }
- }
- }
- }
- }
-
-#if !defined(_XBOX) && !defined(VITA)
- chdir(temp_path);
-#endif
-
- Copy7110 = &GetPackData;
- CleanUp7110 = &Drop7110Gfx;
-}
-
//Cache 1 clean up function
void Del7110Gfx(void)
{
- int32_t i;
- if (Settings.SPC7110)
- {
- Do7110Logging();
- }
- for (i = 0; i < MAX_TABLES; i++)
- {
- if (decompack->binfiles[i] != NULL)
- {
- free(decompack->binfiles[i]);
- decompack->binfiles[i] = NULL;
- }
- }
+ spc7110dec_deinit();
Settings.SPC7110 = false;
Settings.SPC7110RTC = false;
- if (NULL != decompack)
- free(decompack);
- decompack = NULL;
- CleanUp7110 = NULL;
- Copy7110 = NULL;
-}
-
-//Cache2 cleanup function
-void Close7110Gfx(void)
-{
- int32_t i;
- if (Settings.SPC7110)
- {
- Do7110Logging();
- }
- for (i = 0; i < MAX_TABLES; i++)
- {
- if (decompack->binfiles[i] != NULL)
- {
- fclose((FILE*)decompack->binfiles[i]);
- decompack->binfiles[i] = NULL;
- }
- }
- Settings.SPC7110 = false;
- Settings.SPC7110RTC = false;
- if (NULL != decompack)
- free(decompack);
- decompack = NULL;
- CleanUp7110 = NULL;
- Copy7110 = NULL;
-}
-
-//cache 3's clean-up code
-void Drop7110Gfx(void)
-{
- int32_t i;
- if (Settings.SPC7110)
- {
- Do7110Logging();
- }
- for (i = 0; i < MAX_TABLES; i++)
- {
- if (decompack->binfiles[i] != NULL)
- {
- if (decompack->tableEnts[i].is_file)
- {
- fclose((FILE*)decompack->binfiles[i]);
- decompack->binfiles[i] = NULL;
- }
- else
- {
- free(decompack->binfiles[i]);
- decompack->binfiles[i] = NULL;
- }
- }
- }
- Settings.SPC7110 = false;
- Settings.SPC7110RTC = false;
- if (NULL != decompack)
- free(decompack);
- decompack = NULL;
- CleanUp7110 = NULL;
- Copy7110 = NULL;
}
//emulate a reset.
@@ -1880,266 +1089,5 @@ void S9xSpc7110Reset(void)
s7r.AlignBy = 1;
s7r.bank50Internal = 0;
memset(s7r.bank50, 0x00, DECOMP_BUFFER_SIZE);
-}
-
-//outputs a cumulative log for the game.
-//there's nothing really weird here, just
-//reading the old log, and writing a new one.
-//note the logs are explicitly little-endian, not host byte order.
-void Do7110Logging(void)
-{
- uint8_t ent_temp;
- FILE* flog;
- int32_t entries = 0;
-
- if (Settings.SPC7110)
- {
- //flush last read into logging
- (*Copy7110)();
-
- if (!strncmp((char*)&Memory.ROM [0xffc0], "SUPER POWER LEAG 4 ", 21))
- {
-#ifdef _XBOX
- flog = fopen("T:\\spl4-sp7.dat", "rb");
-#else
- flog = fopen("spl4-sp7.dat", "rb");
-#endif
- }
- else if (!strncmp((char*)&Memory.ROM [0xffc0], "MOMOTETSU HAPPY ", 21))
- {
-#ifdef _XBOX
- flog = fopen("T:\\smht-sp7.dat", "rb");
-#else
- flog = fopen("smht-sp7.dat", "rb");
-#endif
- }
- else if (!strncmp((char*)&Memory.ROM [0xffc0], "HU TENGAI MAKYO ZERO ", 21))
- {
-#ifdef _XBOX
- flog = fopen("T:\\feoezsp7.dat", "rb");
-#else
- flog = fopen("feoezsp7.dat", "rb");
-#endif
- }
- else if (!strncmp((char*)&Memory.ROM [0xffc0], "JUMP TENGAIMAKYO ZERO", 21))
- {
-#ifdef _XBOX
- flog = fopen("T:\\sjumpsp7.dat", "rb");
-#else
- flog = fopen("sjumpsp7.dat", "rb");
-#endif
- }
- else
- {
-#ifdef _XBOX
- flog = fopen("T:\\misc-sp7.dat", "rb");
-#else
- flog = fopen("misc-sp7.dat", "rb");
-#endif
- }
-
- if (flog)
- {
- uint8_t buffer[8];
- int32_t table = 0;
- uint16_t offset = 0;
- uint16_t length = 0;
- fseek(flog, 35, 0);
-
- int32_t f_len;
- while (1)
- {
- int32_t i = 0;
- Data7110* log = NULL;
- f_len = fread(buffer, 1, 8, flog);
- if (f_len < 8) break;
-
- table = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16);
- offset = buffer[6] | (buffer[7] << 8);
- length = buffer[4] | (buffer[5] << 8);
- while (i < MAX_TABLES && log == NULL)
- {
- if (decompack->tableEnts[i].table == table)
- {
- log = &(decompack->tableEnts[i].location[(buffer[3])]);
- if ((log->used_offset + log->used_len) < (offset + length))
- {
- log->used_offset = offset;
- log->used_len = length;
- }
- }
- i++;
- }
- }
- fclose(flog);
- }
-
-
- if (!strncmp((char*)&Memory.ROM [0xffc0], "SUPER POWER LEAG 4 ", 21))
- {
-#ifdef _XBOX // cwd could be the dvd-rom, so write to T:\\ which is storage region for each title
- flog = fopen("T:\\spl4-sp7.dat", "wb");
-#else
- flog = fopen("spl4-sp7.dat", "wb");
-#endif
- }
- else if (!strncmp((char*)&Memory.ROM [0xffc0], "MOMOTETSU HAPPY ", 21))
- {
-#ifdef _XBOX
- flog = fopen("T:\\smht-sp7.dat", "wb");
-#else
- flog = fopen("smht-sp7.dat", "wb");
-#endif
- }
- else if (!strncmp((char*)&Memory.ROM [0xffc0], "HU TENGAI MAKYO ZERO ", 21))
- {
-#ifdef _XBOX
- flog = fopen("T:\\feoezsp7.dat", "wb");
-#else
- flog = fopen("feoezsp7.dat", "wb");
-#endif
- }
- else if (!strncmp((char*)&Memory.ROM [0xffc0], "JUMP TENGAIMAKYO ZERO", 21))
- {
-#ifdef _XBOX
- flog = fopen("T:\\sjumpsp7.dat", "wb");
-#else
- flog = fopen("sjumpsp7.dat", "wb");
-#endif
- }
- else
- {
-#ifdef _XBOX
- flog = fopen("T:\\misc-sp7.dat", "wb");
-#else
- flog = fopen("misc-sp7.dat", "wb");
-#endif
- }
- //count entries
- if (flog)
- {
- int32_t j = 0;
- int32_t temp = 0;
- for (j = 0; j < MAX_TABLES; j++)
- {
- int32_t k;
- for (k = 0; k < 256; k++)
- {
- if (decompack->tableEnts[j].location[k].used_len != 0)
- entries++;
- }
- }
- ent_temp = entries & 0xFF;
- fwrite(&ent_temp, 1, 1, flog);
- ent_temp = (entries >> 8) & 0xFF;
- fwrite(&ent_temp, 1, 1, flog);
- ent_temp = (entries >> 16) & 0xFF;
- fwrite(&ent_temp, 1, 1, flog);
- ent_temp = (entries >> 24) & 0xFF;
- fwrite(&ent_temp, 1, 1, flog);
- fwrite(&temp, 1, 4, flog);
- fwrite(&temp, 1, 4, flog);
- fwrite(&temp, 1, 4, flog);
- fwrite(&temp, 1, 4, flog);
- fwrite(&temp, 1, 4, flog);
- fwrite(&temp, 1, 4, flog);
- fwrite(&temp, 1, 4, flog);
-
- ent_temp = 0;
- fwrite(&ent_temp, 1, 1, flog);
- ent_temp = 0;
- fwrite(&ent_temp, 1, 1, flog);
- ent_temp = 0;
- fwrite(&ent_temp, 1, 1, flog);
-
- for (j = 0; j < MAX_TABLES; j++)
- {
- int32_t k;
- for (k = 0; k < 256; k++)
- {
- if (decompack->tableEnts[j].location[k].used_len != 0)
- {
- ent_temp = decompack->tableEnts[j].table & 0xFF;
- fwrite(&ent_temp, 1, 1, flog); //801
- ent_temp = (decompack->tableEnts[j].table >> 8) & 0xFF;;
- fwrite(&ent_temp, 1, 1, flog); //802
- ent_temp = (decompack->tableEnts[j].table >> 16) & 0xFF;;
- fwrite(&ent_temp, 1, 1, flog); //803
- ent_temp = k & 0xFF;
- fwrite(&ent_temp, 1, 1, flog); //804
- ent_temp = decompack->tableEnts[j].location[k].used_len & 0xFF;
- fwrite(&ent_temp, 1, 1, flog); //lsb of
- ent_temp = (decompack->tableEnts[j].location[k].used_len >> 8) & 0xFF;
- fwrite(&ent_temp, 1, 1, flog); //msb of
- ent_temp = (decompack->tableEnts[j].location[k].used_offset) & 0xFF;
- fwrite(&ent_temp, 1, 1, flog); //lsb of
- ent_temp = (decompack->tableEnts[j].location[k].used_offset >> 8) & 0xFF;
- fwrite(&ent_temp, 1, 1, flog); //msb of
- }
- }
- }
- fwrite(&temp, 1, 4, flog);
- fwrite(&temp, 1, 4, flog);
- fclose(flog);
- }
- }
-}
-
-bool S9xSaveSPC7110RTC(S7RTC* rtc_f9)
-{
- FILE* fp;
-
- if ((fp = fopen(S9xGetFilename("rtc"), "wb")) == NULL)
- return (false);
- int32_t i = 0;
- uint8_t temp = 0;
- for (i = 0; i < 16; i++)
- fwrite(&rtc_f9->reg[i], 1, 1, fp);
- temp = rtc_f9->index & 0x00FF;
- fwrite(&temp, 1, 1, fp);
- temp = (rtc_f9->index) >> 8;
- fwrite(&temp, 1, 1, fp);
- temp = (uint8_t)rtc_f9->control;
- fwrite(&temp, 1, 1, fp);
- temp = (uint8_t)rtc_f9->init;
- fwrite(&temp, 1, 1, fp);
- temp = rtc_f9->last_used & 0x00FF;
- fwrite(&temp, 1, 1, fp);
- temp = (rtc_f9->last_used >> 8) & 0x00FF;
- fwrite(&temp, 1, 1, fp);
- temp = (rtc_f9->last_used >> 16) & 0x00FF;
- fwrite(&temp, 1, 1, fp);
- temp = (rtc_f9->last_used >> 24) & 0x00FF;;
- fwrite(&temp, 1, 1, fp);
- fclose(fp);
- return (true);
-}
-
-bool S9xLoadSPC7110RTC(S7RTC* rtc_f9)
-{
- FILE* fp;
-
- if ((fp = fopen(S9xGetFilename("rtc"), "rb")) == NULL)
- return (false);
- int32_t i;
- for (i = 0; i < 16; i++)
- fread(&(rtc_f9->reg[i]), 1, 1, fp);
- uint8_t temp = 0;
- fread(&temp, 1, 1, fp);
- rtc_f9->index = temp;
- fread(&temp, 1, 1, fp);
- rtc_f9->index |= (temp << 8);
- fread(&rtc_f9->control, 1, 1, fp);
- fread(&rtc_f9->init, 1, 1, fp);
-
- fread(&temp, 1, 1, fp);
- rtc_f9->last_used = temp;
- fread(&temp, 1, 1, fp);
- rtc_f9->last_used |= (temp << 8);
- fread(&temp, 1, 1, fp);
- rtc_f9->last_used |= (temp << 16);
- fread(&temp, 1, 1, fp);
- rtc_f9->last_used |= (temp << 24);
- fclose(fp);
- return (true);
+ spc7110dec_reset();
}
diff --git a/source/spc7110.h b/source/spc7110.h
index dd93d50..a5edea6 100644
--- a/source/spc7110.h
+++ b/source/spc7110.h
@@ -6,15 +6,7 @@
#define DECOMP_BUFFER_SIZE 0x10000
-extern void (*LoadUp7110)(char*);
-extern void (*CleanUp7110)(void);
-extern void (*Copy7110)(void);
-
-extern uint16_t cacheMegs;
-
void Del7110Gfx(void);
-void Close7110Gfx(void);
-void Drop7110Gfx(void);
uint8_t S9xGetSPC7110(uint16_t Address);
uint8_t S9xGetSPC7110Byte(uint32_t Address);
uint8_t* Get7110BasePtr(uint32_t);
@@ -26,12 +18,6 @@ void S9xUpdateRTC(void);
void Do7110Logging(void);
int32_t S9xRTCDaysInMonth(int32_t month, int32_t year);
-//These are platform-dependant functions, but should work on
-//most systems that use GNU compilers, and on Win32.
-void SPC7110Load(char*);
-void SPC7110Open(char*);
-void SPC7110Grab(char*);
-
typedef struct
{
uint8_t reg[16];
@@ -99,9 +85,4 @@ typedef struct
extern SPC7110Regs s7r;
extern S7RTC rtc_f9;
-
-// These are defined in spc7110.cpp
-bool S9xSaveSPC7110RTC(S7RTC* rtc_f9);
-bool S9xLoadSPC7110RTC(S7RTC* rtc_f9);
-
#endif
diff --git a/source/spc7110dec.c b/source/spc7110dec.c
new file mode 100644
index 0000000..8a25684
--- /dev/null
+++ b/source/spc7110dec.c
@@ -0,0 +1,619 @@
+#include "../copyright"
+
+#include "memmap.h"
+#include "spc7110dec.h"
+
+#define SPC7110_DECOMP_BUFFER_SIZE 64 /* must be >= 64, and must be a power of two */
+
+static const uint8_t evolution_table[53][4] = /* { prob, nextlps, nextmps, toggle invert } */
+{
+ {0x5a, 1, 1, 1}, {0x25, 6, 2, 0}, {0x11, 8, 3, 0},
+ {0x08, 10, 4, 0}, {0x03, 12, 5, 0}, {0x01, 15, 5, 0},
+ {0x5a, 7, 7, 1}, {0x3f, 19, 8, 0}, {0x2c, 21, 9, 0},
+ {0x20, 22, 10, 0}, {0x17, 23, 11, 0}, {0x11, 25, 12, 0},
+ {0x0c, 26, 13, 0}, {0x09, 28, 14, 0}, {0x07, 29, 15, 0},
+ {0x05, 31, 16, 0}, {0x04, 32, 17, 0}, {0x03, 34, 18, 0},
+ {0x02, 35, 5, 0}, {0x5a, 20, 20, 1}, {0x48, 39, 21, 0},
+ {0x3a, 40, 22, 0}, {0x2e, 42, 23, 0}, {0x26, 44, 24, 0},
+ {0x1f, 45, 25, 0}, {0x19, 46, 26, 0}, {0x15, 25, 27, 0},
+ {0x11, 26, 28, 0}, {0x0e, 26, 29, 0}, {0x0b, 27, 30, 0},
+ {0x09, 28, 31, 0}, {0x08, 29, 32, 0}, {0x07, 30, 33, 0},
+ {0x05, 31, 34, 0}, {0x04, 33, 35, 0}, {0x04, 33, 36, 0},
+ {0x03, 34, 37, 0}, {0x02, 35, 38, 0}, {0x02, 36, 5, 0},
+ {0x58, 39, 40, 1}, {0x4d, 47, 41, 0}, {0x43, 48, 42, 0},
+ {0x3b, 49, 43, 0}, {0x34, 50, 44, 0}, {0x2e, 51, 45, 0},
+ {0x29, 44, 46, 0}, {0x25, 45, 24, 0}, {0x56, 47, 48, 1},
+ {0x4f, 47, 49, 0}, {0x47, 48, 50, 0}, {0x41, 49, 51, 0},
+ {0x3c, 50, 52, 0}, {0x37, 51, 43, 0},
+};
+
+static const uint8_t mode2_context_table[32][2] = /* { next 0, next 1 } */
+{
+ {1, 2}, {3, 8}, {13, 14}, {15, 16},
+ {17, 18}, {19, 20}, {21, 22}, {23, 24},
+ {25, 26}, {25, 26}, {25, 26}, {25, 26},
+ {25, 26}, {27, 28}, {29, 30}, {31, 31},
+ {31, 31}, {31, 31}, {31, 31}, {31, 31},
+ {31, 31}, {31, 31}, {31, 31}, {31, 31},
+ {31, 31}, {31, 31}, {31, 31}, {31, 31},
+ {31, 31}, {31, 31}, {31, 31}, {31, 31},
+};
+
+typedef struct
+{
+ uint32_t mode;
+ uint32_t offset;
+ uint32_t original_mode;
+ uint32_t original_offset;
+ uint32_t original_index;
+ uint32_t read_counter;
+ uint8_t *buffer;
+ uint32_t buffer_rdoffset;
+ uint32_t buffer_wroffset;
+ uint32_t buffer_length;
+
+ struct ContextState
+ {
+ uint8_t index;
+ uint8_t invert;
+ } context[32];
+
+ uint32_t morton16[2][256];
+ uint32_t morton32[4][256];
+} SPC7110Decomp;
+
+SPC7110Decomp decomp;
+
+uint8_t spc7110dec_read()
+{
+ decomp.read_counter++;
+
+ if(decomp.buffer_length == 0)
+ {
+ switch(decomp.mode)
+ {
+ case 0:
+ spc7110dec_mode0(false);
+ break;
+ case 1:
+ spc7110dec_mode1(false);
+ break;
+ case 2:
+ spc7110dec_mode2(false);
+ break;
+ default:
+ return 0x00;
+ }
+ }
+
+ uint8_t data = decomp.buffer[decomp.buffer_rdoffset++];
+
+ decomp.buffer_rdoffset &= SPC7110_DECOMP_BUFFER_SIZE - 1;
+ decomp.buffer_length--;
+ return data;
+}
+
+void spc7110dec_write(uint8_t data)
+{
+ decomp.buffer[decomp.buffer_wroffset++] = data;
+ decomp.buffer_wroffset &= SPC7110_DECOMP_BUFFER_SIZE - 1;
+ decomp.buffer_length++;
+}
+
+uint8_t spc7110dec_dataread()
+{
+ uint32_t size = Memory.CalculatedSize - 0x100000;
+
+ while(decomp.offset >= size)
+ decomp.offset -= size;
+ return Memory.ROM[0x100000 + decomp.offset++];
+}
+
+void spc7110dec_clear(uint32_t mode, uint32_t offset, uint32_t index)
+{
+ decomp.original_mode = mode;
+ decomp.original_offset = offset;
+ decomp.original_index = index;
+ decomp.mode = mode;
+ decomp.offset = offset;
+ decomp.buffer_rdoffset = 0;
+ decomp.buffer_wroffset = 0;
+ decomp.buffer_length = 0;
+ uint32_t i;
+
+ for(i = 0; i < 32; i++) // reset decomp.context states
+ {
+ decomp.context[i].index = 0;
+ decomp.context[i].invert = 0;
+ }
+
+ switch(decomp.mode)
+ {
+ case 0:
+ spc7110dec_mode0(true);
+ break;
+ case 1:
+ spc7110dec_mode1(true);
+ break;
+ case 2:
+ spc7110dec_mode2(true);
+ break;
+ }
+
+ while(index--) // decompress up to requested output data index
+ spc7110dec_read();
+
+ decomp.read_counter = 0;
+}
+
+void spc7110dec_mode0(bool init)
+{
+ static uint8_t val, in, span;
+ static int32_t out, inverts, lps, in_count;
+
+ if(init)
+ {
+ out = inverts = lps = 0;
+ span = 0xff;
+ val = spc7110dec_dataread();
+ in = spc7110dec_dataread();
+ in_count = 8;
+ return;
+ }
+
+ while(decomp.buffer_length < (SPC7110_DECOMP_BUFFER_SIZE >> 1))
+ {
+ uint32_t bit;
+
+ for(bit = 0; bit < 8; bit++)
+ {
+ /* Get decomp.context */
+ uint8_t mask = (1 << (bit & 3)) - 1;
+ uint8_t con = mask + ((inverts & mask) ^ (lps & mask));
+
+ if(bit > 3)
+ con += 15;
+
+ /* Get prob and mps */
+ uint32_t prob = spc7110dec_probability(con);
+ uint32_t mps = (((out >> 15) & 1) ^ decomp.context[con].invert);
+
+ /* Get bit */
+ uint32_t flag_lps;
+
+ if(val <= span - prob) // mps
+ {
+ span = span - prob;
+ out = (out << 1) + mps;
+ flag_lps = 0;
+ }
+ else // lps
+ {
+ val = val - (span - (prob - 1));
+ span = prob - 1;
+ out = (out << 1) + 1 - mps;
+ flag_lps = 1;
+ }
+
+ /* Renormalize */
+ uint32_t shift = 0;
+
+ while(span < 0x7f)
+ {
+ shift++;
+ span = (span << 1) + 1;
+ val = (val << 1) + (in >> 7);
+ in <<= 1;
+
+ if(--in_count == 0)
+ {
+ in = spc7110dec_dataread();
+ in_count = 8;
+ }
+ }
+
+ /* Update processing info */
+ lps = (lps << 1) + flag_lps;
+ inverts = (inverts << 1) + decomp.context[con].invert;
+
+ /* Update context state */
+ if(flag_lps & spc7110dec_toggle_invert(con))
+ decomp.context[con].invert ^= 1;
+
+ if(flag_lps)
+ decomp.context[con].index = spc7110dec_next_lps(con);
+ else if(shift)
+ decomp.context[con].index = spc7110dec_next_mps(con);
+ }
+
+ /* Save byte */
+ spc7110dec_write(out);
+ }
+}
+
+void spc7110dec_mode1(bool init)
+{
+ static uint32_t pixelorder[4], realorder[4];
+ static uint8_t in, val, span;
+ static int32_t out, inverts, lps, in_count;
+
+ if(init)
+ {
+ uint32_t i;
+
+ for(i = 0; i < 4; i++)
+ pixelorder[i] = i;
+ out = inverts = lps = 0;
+ span = 0xff;
+ val = spc7110dec_dataread();
+ in = spc7110dec_dataread();
+ in_count = 8;
+ return;
+ }
+
+ while(decomp.buffer_length < (SPC7110_DECOMP_BUFFER_SIZE >> 1))
+ {
+ uint32_t pixel;
+
+ for(pixel = 0; pixel < 8; pixel++)
+ {
+ /* Get first symbol decomp.context */
+ uint32_t a = ((out >> (1 * 2)) & 3);
+ uint32_t b = ((out >> (7 * 2)) & 3);
+ uint32_t c = ((out >> (8 * 2)) & 3);
+ uint32_t con = (a == b) ? (b != c) : (b == c) ? 2 : 4 - (a == c);
+
+ /* Update pixel order */
+ uint32_t m, n;
+
+ for(m = 0; m < 4; m++)
+ if(pixelorder[m] == a)
+ break;
+
+ for(n = m; n > 0; n--)
+ pixelorder[n] = pixelorder[n - 1];
+
+ pixelorder[0] = a;
+
+ /* Calculate the real pixel order */
+ for(m = 0; m < 4; m++)
+ realorder[m] = pixelorder[m];
+
+ /* Rotate reference pixel c value to top */
+ for(m = 0; m < 4; m++)
+ if(realorder[m] == c)
+ break;
+
+ for(n = m; n > 0; n--)
+ realorder[n] = realorder[n - 1];
+
+ realorder[0] = c;
+
+ /* Rotate reference pixel b value to top */
+ for(m = 0; m < 4; m++)
+ if(realorder[m] == b)
+ break;
+
+ for(n = m; n > 0; n--)
+ realorder[n] = realorder[n - 1];
+
+ realorder[0] = b;
+
+ /* Rotate reference pixel a value to top */
+ for(m = 0; m < 4; m++)
+ if(realorder[m] == a)
+ break;
+
+ for(n = m; n > 0; n--)
+ realorder[n] = realorder[n - 1];
+
+ realorder[0] = a;
+
+ /* Get 2 symbols */
+ uint32_t bit;
+
+ for(bit = 0; bit < 2; bit++)
+ {
+ /* Get prob */
+ uint32_t prob = spc7110dec_probability(con);
+
+ /* Get symbol */
+ uint32_t flag_lps;
+
+ if(val <= span - prob) // mps
+ {
+ span = span - prob;
+ flag_lps = 0;
+ }
+ else // lps
+ {
+ val = val - (span - (prob - 1));
+ span = prob - 1;
+ flag_lps = 1;
+ }
+
+ /* Renormalize */
+ uint32_t shift = 0;
+
+ while(span < 0x7f)
+ {
+ shift++;
+ span = (span << 1) + 1;
+ val = (val << 1) + (in >> 7);
+ in <<= 1;
+ if(--in_count == 0)
+ {
+ in = spc7110dec_dataread();
+ in_count = 8;
+ }
+ }
+
+ /* Update processing info */
+ lps = (lps << 1) + flag_lps;
+ inverts = (inverts << 1) + decomp.context[con].invert;
+
+ /* Update context state */
+ if(flag_lps & spc7110dec_toggle_invert(con))
+ decomp.context[con].invert ^= 1;
+
+ if(flag_lps)
+ decomp.context[con].index = spc7110dec_next_lps(con);
+ else if(shift)
+ decomp.context[con].index = spc7110dec_next_mps(con);
+
+ /* Get next decomp.context */
+ con = 5 + (con << 1) + ((lps ^ inverts) & 1);
+ }
+
+ /* Get pixel */
+ b = realorder[(lps ^ inverts) & 3];
+ out = (out << 2) + b;
+ }
+
+ /* Turn pixel data into bitplanes */
+ uint32_t data = spc7110dec_morton_2x8(out);
+
+ spc7110dec_write(data >> 8);
+ spc7110dec_write(data >> 0);
+ }
+}
+
+void spc7110dec_mode2(bool init)
+{
+ static uint32_t pixelorder[16], realorder[16];
+ static uint8_t bitplanebuffer[16], buffer_index;
+ static uint8_t in, val, span;
+ static int32_t out0, out1, inverts, lps, in_count;
+
+ if(init)
+ {
+ uint32_t i;
+
+ for(i = 0; i < 16; i++)
+ pixelorder[i] = i;
+ buffer_index = 0;
+ out0 = out1 = inverts = lps = 0;
+ span = 0xff;
+ val = spc7110dec_dataread();
+ in = spc7110dec_dataread();
+ in_count = 8;
+ return;
+ }
+
+ while(decomp.buffer_length < (SPC7110_DECOMP_BUFFER_SIZE >> 1))
+ {
+ uint32_t pixel;
+
+ for(pixel = 0; pixel < 8; pixel++)
+ {
+ /* Get first symbol context */
+ uint32_t a = ((out0 >> (0 * 4)) & 15);
+ uint32_t b = ((out0 >> (7 * 4)) & 15);
+ uint32_t c = ((out1 >> (0 * 4)) & 15);
+ uint32_t con = 0;
+ uint32_t refcon = (a == b) ? (b != c) : (b == c) ? 2 : 4 - (a == c);
+
+ /* Update pixel order */
+ uint32_t m, n;
+
+ for(m = 0; m < 16; m++)
+ if(pixelorder[m] == a)
+ break;
+
+ for(n = m; n > 0; n--)
+ pixelorder[n] = pixelorder[n - 1];
+
+ pixelorder[0] = a;
+
+ /* Calculate the real pixel order */
+ for(m = 0; m < 16; m++)
+ realorder[m] = pixelorder[m];
+
+ /* Rotate reference pixel c value to top */
+ for(m = 0; m < 16; m++)
+ if(realorder[m] == c)
+ break;
+
+ for(n = m; n > 0; n--)
+ realorder[n] = realorder[n - 1];
+
+ realorder[0] = c;
+
+ /* Rotate reference pixel b value to top */
+ for(m = 0; m < 16; m++)
+ if(realorder[m] == b)
+ break;
+
+ for(n = m; n > 0; n--)
+ realorder[n] = realorder[n - 1];
+
+ realorder[0] = b;
+
+ /* Rotate reference pixel a value to top */
+ for(m = 0; m < 16; m++)
+ if(realorder[m] == a)
+ break;
+
+ for(n = m; n > 0; n--)
+ realorder[n] = realorder[n - 1];
+
+ realorder[0] = a;
+
+ /* Get 4 symbols */
+ uint32_t bit;
+
+ for(bit = 0; bit < 4; bit++)
+ {
+ /* Get prob */
+ uint32_t prob = spc7110dec_probability(con);
+
+ /* Get symbol */
+ uint32_t flag_lps;
+
+ if(val <= span - prob) // mps
+ {
+ span = span - prob;
+ flag_lps = 0;
+ }
+ else // lps
+ {
+ val = val - (span - (prob - 1));
+ span = prob - 1;
+ flag_lps = 1;
+ }
+
+ /* Renormalize */
+ uint32_t shift = 0;
+
+ while(span < 0x7f)
+ {
+ shift++;
+ span = (span << 1) + 1;
+ val = (val << 1) + (in >> 7);
+ in <<= 1;
+ if(--in_count == 0)
+ {
+ in = spc7110dec_dataread();
+ in_count = 8;
+ }
+ }
+
+ /* Update processing info */
+ lps = (lps << 1) + flag_lps;
+ uint32_t invertbit = decomp.context[con].invert;
+
+ inverts = (inverts << 1) + invertbit;
+
+ /* Update decomp.context state */
+ if(flag_lps & spc7110dec_toggle_invert(con))
+ decomp.context[con].invert ^= 1;
+
+ if(flag_lps)
+ decomp.context[con].index = spc7110dec_next_lps(con);
+ else if(shift)
+ decomp.context[con].index = spc7110dec_next_mps(con);
+
+ /* Get next decomp.context */
+ con = mode2_context_table[con][flag_lps ^ invertbit] + (con == 1 ? refcon : 0);
+ }
+
+ /* Get pixel */
+ b = realorder[(lps ^ inverts) & 0x0f];
+ out1 = (out1 << 4) + ((out0 >> 28) & 0x0f);
+ out0 = (out0 << 4) + b;
+ }
+
+ /* Convert pixel data into bitplanes */
+ uint32_t data = spc7110dec_morton_4x8(out0);
+
+ spc7110dec_write(data >> 24);
+ spc7110dec_write(data >> 16);
+ bitplanebuffer[buffer_index++] = data >> 8;
+ bitplanebuffer[buffer_index++] = data >> 0;
+
+ if(buffer_index == 16)
+ {
+ uint32_t i;
+
+ for(i = 0; i < 16; i++)
+ spc7110dec_write(bitplanebuffer[i]);
+ buffer_index = 0;
+ }
+ }
+}
+
+uint8_t spc7110dec_probability(uint32_t n)
+{
+ return evolution_table[decomp.context[n].index][0];
+}
+
+uint8_t spc7110dec_next_lps(uint32_t n)
+{
+ return evolution_table[decomp.context[n].index][1];
+}
+
+uint8_t spc7110dec_next_mps(uint32_t n)
+{
+ return evolution_table[decomp.context[n].index][2];
+}
+
+bool spc7110dec_toggle_invert(uint32_t n)
+{
+ return evolution_table[decomp.context[n].index][3];
+}
+
+uint32_t spc7110dec_morton_2x8(uint32_t data)
+{
+ /* Reverse morton lookup: de-interleave two 8-bit values
+ * 15, 13, 11, 9, 7, 5, 3, 1 -> 15-8
+ * 14, 12, 10, 8, 6, 4, 2, 0 -> 7 -0 */
+ return decomp.morton16[0][(data >> 0) & 255] + decomp.morton16[1][(data >> 8) & 255];
+}
+
+uint32_t spc7110dec_morton_4x8(uint32_t data)
+{
+ /* Reverse morton lookup: de-interleave four 8-bit values
+ * 31, 27, 23, 19, 15, 11, 7, 3 -> 31-24
+ * 30, 26, 22, 18, 14, 10, 6, 2 -> 23-16
+ * 29, 25, 21, 17, 13, 9, 5, 1 -> 15-8
+ * 28, 24, 20, 16, 12, 8, 4, 0 -> 7 -0 */
+ return decomp.morton32[0][(data >> 0) & 255] + decomp.morton32[1][(data >> 8) & 255] + decomp.morton32[2][(data >> 16) & 255] + decomp.morton32[3][(data >> 24) & 255];
+}
+
+void spc7110dec_reset()
+{
+ /* Mode 3 is invalid; this is treated as a special case to always return 0x00
+ * set to mode 3 so that reading decomp port before starting first decomp will return 0x00 */
+ decomp.mode = 3;
+ decomp.buffer_rdoffset = 0;
+ decomp.buffer_wroffset = 0;
+ decomp.buffer_length = 0;
+}
+
+void spc7110dec_init()
+{
+ decomp.buffer = malloc(SPC7110_DECOMP_BUFFER_SIZE);
+ spc7110dec_reset();
+
+ /* Initialize reverse morton lookup tables */
+ uint32_t i;
+
+ for(i = 0; i < 256; i++)
+ {
+ #define map(x, y) (((i >> x) & 1) << y)
+ /* 2x8-bit */
+ decomp.morton16[1][i] = map(7, 15) + map(6, 7) + map(5, 14) + map(4, 6) + map(3, 13) + map(2, 5) + map(1, 12) + map(0, 4);
+ decomp.morton16[0][i] = map(7, 11) + map(6, 3) + map(5, 10) + map(4, 2) + map(3, 9) + map(2, 1) + map(1, 8) + map(0, 0);
+ /* 4x8-bit */
+ decomp.morton32[3][i] = map(7, 31) + map(6, 23) + map(5, 15) + map(4, 7) + map(3, 30) + map(2, 22) + map(1, 14) + map(0, 6);
+ decomp.morton32[2][i] = map(7, 29) + map(6, 21) + map(5, 13) + map(4, 5) + map(3, 28) + map(2, 20) + map(1, 12) + map(0, 4);
+ decomp.morton32[1][i] = map(7, 27) + map(6, 19) + map(5, 11) + map(4, 3) + map(3, 26) + map(2, 18) + map(1, 10) + map(0, 2);
+ decomp.morton32[0][i] = map(7, 25) + map(6, 17) + map(5, 9) + map(4, 1) + map(3, 24) + map(2, 16) + map(1, 8) + map(0, 0);
+ #undef map
+ }
+}
+
+void spc7110dec_deinit()
+{
+ free(decomp.buffer);
+}
diff --git a/source/spc7110dec.h b/source/spc7110dec.h
new file mode 100644
index 0000000..e03a855
--- /dev/null
+++ b/source/spc7110dec.h
@@ -0,0 +1,28 @@
+#include "../copyright"
+
+#ifndef _SPC7110DEC_H_
+#define _SPC7110DEC_H_
+#include "port.h"
+
+uint8_t spc7110dec_read(void);
+void spc7110dec_clear(uint32_t mode, uint32_t offset, uint32_t index);
+void spc7110dec_reset(void);
+
+void spc7110dec_init(void);
+void spc7110dec_deinit(void);
+
+void spc7110dec_write(uint8_t data);
+uint8_t spc7110dec_dataread(void);
+
+void spc7110dec_mode0(bool init);
+void spc7110dec_mode1(bool init);
+void spc7110dec_mode2(bool init);
+
+uint8_t spc7110dec_probability(uint32_t n);
+uint8_t spc7110dec_next_lps(uint32_t n);
+uint8_t spc7110dec_next_mps(uint32_t n);
+bool spc7110dec_toggle_invert(uint32_t n);
+
+uint32_t spc7110dec_morton_2x8(uint32_t data);
+uint32_t spc7110dec_morton_4x8(uint32_t data);
+#endif
diff --git a/source/srtc.c b/source/srtc.c
index 9e7c2e9..5de0c8a 100644
--- a/source/srtc.c
+++ b/source/srtc.c
@@ -34,12 +34,10 @@ Index Description Range (nibble)
SRTC_DATA rtc;
-
static int32_t month_keys[12] = { 1, 4, 4, 0, 2, 5, 0, 3, 6, 1, 4, 6 };
/*********************************************************************************************
- *
* Note, if you are doing a save state for this game:
*
* On save:
@@ -50,8 +48,6 @@ static int32_t month_keys[12] = { 1, 4, 4, 0, 2, 5, 0, 3, 6, 1, 4, 6 };
*
* restore the rtc data structure
* rtc.system_timestamp = time (NULL);
- *
- *
*********************************************************************************************/
@@ -68,9 +64,7 @@ void S9xHardResetSRTC(void)
rtc.mode = MODE_READ;
rtc.count_enable = false;
rtc.needs_init = true;
-
- // Get system timestamp
- rtc.system_timestamp = time(NULL);
+ rtc.system_timestamp = time(NULL); // Get system timestamp
}
/**********************************************************************************************/
@@ -83,10 +77,9 @@ uint32_t S9xSRTCComputeDayOfWeek(void)
uint32_t month = rtc.data[8];
uint32_t day = rtc.data[7] * 10 + rtc.data[6];
uint32_t day_of_week;
-
year += (rtc.data[11] - 9) * 100;
- // Range check the month for valid array indicies
+ // Range check the month for valid array indices
if (month > 12)
month = 1;
@@ -102,48 +95,37 @@ uint32_t S9xSRTCComputeDayOfWeek(void)
/**********************************************************************************************/
-/* S9xSRTCDaysInMonth(void) */
+/* S9xSRTCDaysInMonth() */
/* Return the number of days in a specific month for a certain year */
/**********************************************************************************************/
int32_t S9xSRTCDaysInMmonth(int32_t month, int32_t year)
{
- int32_t mdays;
-
- switch (month)
+ switch(month)
{
- case 2:
- if ((year % 4 == 0)) // DKJM2 only uses 199x - 22xx
- mdays = 29;
- else
- mdays = 28;
- break;
-
- case 4:
- case 6:
- case 9:
- case 11:
- mdays = 30;
- break;
-
- default: // months 1,3,5,7,8,10,12
- mdays = 31;
- break;
+ case 2:
+ if((year % 4 == 0)) /* DKJM2 only uses 199x - 22xx */
+ return 29;
+ return 28;
+ case 4:
+ case 6:
+ case 9:
+ case 11:
+ return 30;
+ default:
+ return 31;
}
-
- return mdays;
}
-
-#define DAYTICKS (60*60*24)
-#define HOURTICKS (60*60)
-#define MINUTETICKS 60
+#define MINUTETICKS 60
+#define HOURTICKS (60 * MINUTETICKS)
+#define DAYTICKS (24 * HOURTICKS)
/**********************************************************************************************/
-/* S9xUpdateSrtcTime(void) */
+/* S9xUpdateSrtcTime() */
/* Advance the S-RTC time if counting is enabled */
/**********************************************************************************************/
-void S9xUpdateSrtcTime(void)
+void S9xUpdateSrtcTime(void)
{
time_t cur_systime;
int32_t time_diff;
@@ -160,12 +142,6 @@ void S9xUpdateSrtcTime(void)
if (rtc.count_enable && !rtc.needs_init)
{
cur_systime = time(NULL);
-
- // This method assumes one time_t clock tick is one second
- // which should work on PCs and GNU systems.
- // If your tick interval is different adjust the
- // DAYTICK, HOURTICK, and MINUTETICK defines
-
time_diff = (int32_t)(cur_systime - rtc.system_timestamp);
rtc.system_timestamp = cur_systime;
@@ -178,7 +154,6 @@ void S9xUpdateSrtcTime(void)
int32_t month;
int32_t year;
int32_t temp_days;
-
int32_t year_hundreds;
int32_t year_tens;
int32_t year_ones;
@@ -238,7 +213,6 @@ void S9xUpdateSrtcTime(void)
{
year = rtc.data[10] * 10 + rtc.data[9];
year += (1000 + rtc.data[11] * 100);
-
month = rtc.data[8];
days += (rtc.data[7] * 10 + rtc.data[6]);
while (days > (temp_days = S9xSRTCDaysInMmonth(month, year)))
@@ -256,7 +230,6 @@ void S9xUpdateSrtcTime(void)
year_ones = year_tens % 10;
year_tens /= 10;
year_hundreds = (year - 1000) / 100;
-
rtc.data[6] = days % 10;
rtc.data[7] = days / 10;
rtc.data[8] = month;
@@ -272,7 +245,6 @@ void S9xUpdateSrtcTime(void)
rtc.data[3] = minutes / 10;
rtc.data[4] = hours % 10;
rtc.data[5] = hours / 10;
-
return;
}
}
@@ -287,25 +259,18 @@ void S9xSetSRTC(uint8_t data, uint16_t Address)
{
data &= 0x0F; // Data is only 4-bits, mask out unused bits.
- if (data >= 0xD)
+ if (data >= 0xD) // It's an RTC command
{
- // It's an RTC command
-
switch (data)
{
case 0xD:
rtc.mode = MODE_READ;
rtc.index = -1;
break;
-
case 0xE:
rtc.mode = MODE_COMMAND;
break;
-
default:
- // Ignore the write if it's an 0xF ???
- // Probably should switch back to read mode -- but this
- // sequence never occurs in DKJM2
break;
}
@@ -318,14 +283,10 @@ void S9xSetSRTC(uint8_t data, uint16_t Address)
{
rtc.data[rtc.index++] = data;
- if (rtc.index == MAX_RTC_INDEX)
+ if (rtc.index == MAX_RTC_INDEX) // We have all the data for the RTC load
{
- // We have all the data for the RTC load
-
- rtc.system_timestamp = time(NULL); // Get local system time
-
- // Get the day of the week
- rtc.data[rtc.index++] = S9xSRTCComputeDayOfWeek();
+ rtc.system_timestamp = time(NULL); // Get local system time
+ rtc.data[rtc.index++] = S9xSRTCComputeDayOfWeek(); // Get the day of the week
// Start RTC counting again
rtc.count_enable = true;
@@ -334,55 +295,32 @@ void S9xSetSRTC(uint8_t data, uint16_t Address)
return;
}
- else
- {
- // Attempting to write too much data
- // error(); // ignore??
- }
}
else if (rtc.mode == MODE_COMMAND)
{
switch (data)
{
case COMMAND_CLEAR_RTC:
- // Disable RTC counter
- rtc.count_enable = false;
-
+ rtc.count_enable = false; // Disable RTC counter
memset(rtc.data, 0, MAX_RTC_INDEX + 1);
rtc.index = -1;
rtc.mode = MODE_COMMAND_DONE;
break;
case COMMAND_LOAD_RTC:
- // Disable RTC counter
- rtc.count_enable = false;
-
+ rtc.count_enable = false; // Disable RTC counter
rtc.index = 0; // Setup for writing
rtc.mode = MODE_LOAD_RTC;
break;
default:
- rtc.mode = MODE_COMMAND_DONE;
- // unrecognized command - need to implement.
+ rtc.mode = MODE_COMMAND_DONE; // unrecognized command - need to implement.
}
return;
}
- else
- {
- if (rtc.mode == MODE_READ)
- {
- // Attempting to write while in read mode. Ignore.
- }
-
- if (rtc.mode == MODE_COMMAND_DONE)
- {
- // Maybe this isn't an error. Maybe we should kick off
- // a new E command. But is this valid?
- }
- }
}
/**********************************************************************************************/
-/* S9xGetSRTC(void) */
+/* S9xGetSRTC() */
/* This function retrieves data from the S-RTC */
/**********************************************************************************************/
uint8_t S9xGetSRTC(uint16_t Address)
@@ -391,20 +329,17 @@ uint8_t S9xGetSRTC(uint16_t Address)
{
if (rtc.index < 0)
{
- S9xUpdateSrtcTime(); // Only update it if the game reads it
+ S9xUpdateSrtcTime(); // Only update it if the game reads it
rtc.index++;
- return (0x0f); // Send start marker.
+ return 0x0f; // Send start marker.
}
else if (rtc.index > MAX_RTC_INDEX)
{
- rtc.index = -1; // Setup for next set of reads
- return (0x0f); // Data done marker.
+ rtc.index = -1; // Setup for next set of reads
+ return 0x0f; // Data done marker.
}
else
- {
- // Feed out the data
- return rtc.data[rtc.index++];
- }
+ return rtc.data[rtc.index++]; // Feed out the data
}
else
return 0x0;
@@ -415,8 +350,8 @@ void S9xSRTCPreSaveState()
if (Settings.SRTC)
{
S9xUpdateSrtcTime();
-
int32_t s = Memory.SRAMSize ? (1 << (Memory.SRAMSize + 3)) * 128 : 0;
+
if (s > 0x20000)
s = 0x20000;
diff --git a/source/srtc.h b/source/srtc.h
index 98fe369..2bd3490 100644
--- a/source/srtc.h
+++ b/source/srtc.h
@@ -36,11 +36,11 @@ Index Description Range (nibble)
typedef struct
{
bool needs_init;
- bool count_enable; // Does RTC mark time or is it frozen
+ bool count_enable; // Does RTC mark time or is it frozen
uint8_t data [MAX_RTC_INDEX + 1];
int8_t index;
uint8_t mode;
- time_t system_timestamp; // Of latest RTC load time
+ time_t system_timestamp; // Of latest RTC load time
} SRTC_DATA;
extern SRTC_DATA rtc;
@@ -52,7 +52,4 @@ void S9xSRTCPreSaveState(void);
void S9xSRTCPostLoadState(void);
void S9xResetSRTC(void);
void S9xHardResetSRTC(void);
-
-#define SRTC_SRAM_PAD (4 + 8 + 1 + MAX_RTC_INDEX)
-
#endif // _srtc_h