From 804169dd621a3ad3eec1a32ce30350de667fee80 Mon Sep 17 00:00:00 2001 From: aliaspider Date: Thu, 30 Oct 2014 00:23:30 +0100 Subject: apply a facelift --- source/spc7110.c | 3886 +++++++++++++++++++++++++++--------------------------- 1 file changed, 1955 insertions(+), 1931 deletions(-) (limited to 'source/spc7110.c') diff --git a/source/spc7110.c b/source/spc7110.c index b9fa722..fdd625c 100644 --- a/source/spc7110.c +++ b/source/spc7110.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -94,14 +94,14 @@ //Windows includes #ifdef __WIN32__ -#ifndef _XBOX // chdir and getcwd not supported on Xbox hardware +#ifndef _XBOX // chdir and getcwd not supported on Xbox hardware #include #define chdir _chdir #define getcwd _getcwd #endif -#define FREEZEFOLDER GUI.FreezeFileDir +#define FREEZEFOLDER GUI.FreezeFileDir //zinx suggested this, for *nix compatibility -#define PATH_MAX MAX_PATH +#define PATH_MAX MAX_PATH #else // Unix #include "display.h" #include @@ -109,8 +109,8 @@ #define FREEZEFOLDER S9xGetSnapshotDirectory () #endif -const char *S9xGetFilename (const char *); -char *osd_GetPackDir(); +const char* S9xGetFilename(const char*); +char* osd_GetPackDir(); //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 @@ -119,189 +119,192 @@ char *osd_GetPackDir(); #define MAX_TABLES 48 //default to using 5 megs of RAM for method 3 caching. -uint16 cacheMegs=5; +uint16 cacheMegs = 5; //using function pointers to initialize cache management -void (*CleanUp7110)(void)=NULL; -void (*LoadUp7110)(char*)=&SPC7110Load; -void (*Copy7110)(void)=NULL; +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 SPC7110DecompressionLocationStruct { - uint32 offset; - uint32 size; - uint16 used_offset; - uint16 used_len; + uint32 offset; + uint32 size; + uint16 used_offset; + uint16 used_len; } Data7110; //this maps an index.bin table to the decompression pack typedef struct SPC7110DecompressionIndexStruct { - int table; - bool is_file; - Data7110 location[256]; + int table; + bool is_file; + Data7110 location[256]; } Index7110; //this contains all the data for the decompression pack. typedef struct SPC7110DecompressionPackStructure { - uint8* binfiles[MAX_TABLES]; - Index7110 tableEnts[MAX_TABLES]; - int last_table; - int idx; - uint8 last_idx; - uint16 last_offset; + uint8* binfiles[MAX_TABLES]; + Index7110 tableEnts[MAX_TABLES]; + int last_table; + int idx; + uint8 last_idx; + uint16 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 (); //S-RTC function hacked to work with the RTC +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(); //S-RTC function hacked to work with the RTC //Emulate power on state void S9xSpc7110Init() { - s7r.DataRomOffset=0x00100000;//handy constant! - s7r.DataRomSize=Memory.CalculatedSize-s7r.DataRomOffset; - s7r.reg4800=0; - s7r.reg4801=0; - s7r.reg4802=0; - s7r.reg4803=0; - s7r.reg4804=0; - s7r.reg4805=0; - s7r.reg4806=0; - s7r.reg4807=0; - s7r.reg4808=0; - s7r.reg4809=0; - s7r.reg480A=0; - s7r.reg480B=0; - s7r.reg480C=0; - s7r.reg4811=0; - s7r.reg4812=0; - s7r.reg4813=0; - s7r.reg4814=0; - s7r.reg4815=0; - s7r.reg4816=0; - s7r.reg4817=0; - s7r.reg4818=0; - s7r.reg4820=0; - s7r.reg4821=0; - s7r.reg4822=0; - s7r.reg4823=0; - s7r.reg4824=0; - s7r.reg4825=0; - s7r.reg4826=0; - s7r.reg4827=0; - s7r.reg4828=0; - s7r.reg4829=0; - s7r.reg482A=0; - s7r.reg482B=0; - s7r.reg482C=0; - s7r.reg482D=0; - s7r.reg482E=0; - s7r.reg482F=0; - s7r.reg4830=0; - s7r.reg4831=0; - s7r.reg4832=1; - s7r.reg4833=2; - s7r.reg4834=0; - s7r.reg4840=0; - s7r.reg4841=0; - s7r.reg4842=0; - s7r.written=0; - s7r.offset_add=0; - s7r.AlignBy=1; - - (*LoadUp7110)(osd_GetPackDir()); - - s7r.bank50Internal=0; - memset(s7r.bank50,0x00,DECOMP_BUFFER_SIZE); + s7r.DataRomOffset = 0x00100000; //handy constant! + s7r.DataRomSize = Memory.CalculatedSize - s7r.DataRomOffset; + s7r.reg4800 = 0; + s7r.reg4801 = 0; + s7r.reg4802 = 0; + s7r.reg4803 = 0; + s7r.reg4804 = 0; + s7r.reg4805 = 0; + s7r.reg4806 = 0; + s7r.reg4807 = 0; + s7r.reg4808 = 0; + s7r.reg4809 = 0; + s7r.reg480A = 0; + s7r.reg480B = 0; + s7r.reg480C = 0; + s7r.reg4811 = 0; + s7r.reg4812 = 0; + s7r.reg4813 = 0; + s7r.reg4814 = 0; + s7r.reg4815 = 0; + s7r.reg4816 = 0; + s7r.reg4817 = 0; + s7r.reg4818 = 0; + s7r.reg4820 = 0; + s7r.reg4821 = 0; + s7r.reg4822 = 0; + s7r.reg4823 = 0; + s7r.reg4824 = 0; + s7r.reg4825 = 0; + s7r.reg4826 = 0; + s7r.reg4827 = 0; + s7r.reg4828 = 0; + s7r.reg4829 = 0; + s7r.reg482A = 0; + s7r.reg482B = 0; + s7r.reg482C = 0; + s7r.reg482D = 0; + s7r.reg482E = 0; + s7r.reg482F = 0; + s7r.reg4830 = 0; + s7r.reg4831 = 0; + s7r.reg4832 = 1; + s7r.reg4833 = 2; + s7r.reg4834 = 0; + s7r.reg4840 = 0; + s7r.reg4841 = 0; + s7r.reg4842 = 0; + 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() { - //log the last entry - Data7110* log=&(decompack->tableEnts[decompack->idx].location[decompack->last_idx]); - if((log->used_len+log->used_offset)<(decompack->last_offset+(unsigned short)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 - int table=(s7r.reg4803<<16)|(s7r.reg4802<<8)|s7r.reg4801; - - //the table is a offset multiplier byte and a big-endian pointer - int 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) - { - int i=0; - while(itableEnts[i].table!=table) - i++; - if(i==MAX_TABLES) - { + //log the last entry + Data7110* log = & + (decompack->tableEnts[decompack->idx].location[decompack->last_idx]); + if ((log->used_len + log->used_offset) < (decompack->last_offset + + (unsigned short)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 + int table = (s7r.reg4803 << 16) | (s7r.reg4802 << 8) | s7r.reg4801; + + //the table is a offset multiplier byte and a big-endian pointer + int 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) + { + int 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"); + FILE* fp = fopen("T:\\sp7err.out", "a"); #else - FILE* fp=fopen("sp7err.out","a"); + FILE* fp = fopen("sp7err.out", "a"); #endif -// fprintf(fp, "Table Entry %06X:%02X not found\n", table, s7r.reg4804); - 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); - } + // fprintf(fp, "Table Entry %06X:%02X not found\n", table, s7r.reg4804); + 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); + } } @@ -309,1149 +312,1185 @@ void MovePackData() // and reads the data directly. Method 2 void ReadPackData() { - static int table_age_2; - static int table_age_3; - static int table_age_4; - static int table_age_5; - - int 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+(unsigned short)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; - - int 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) - { - int i=0; - while(itableEnts[i].table!=table) - i++; - if(i==MAX_TABLES) - { - FILE* fp=fopen("sp7err.out","a"); -// fprintf(fp, "Table Entry %06X:%02X not found\n", table, s7r.reg4804); - 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]; - if (strlen (FREEZEFOLDER)) - { - //splitpath (Memory.ROMFilename, drive, dir, fname, ext); - strcpy (name, FREEZEFOLDER); - strcat (name, "/"); - } - else - { - splitpath (Memory.ROMFilename, drive, dir, fname, ext); - strcpy(name, drive); - //strcat(filename, "\\"); - strcat(name, dir); - } - strcat(name, pfold); - char bfname[11]; - sprintf(bfname, "%06X.bin", table); - strcat(name, "/"); - strcat(name, bfname); - decompack->binfiles[i]=(uint8*)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])); - } + static int table_age_2; + static int table_age_3; + static int table_age_4; + static int table_age_5; + + int 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 + + (unsigned short)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; + + int 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) + { + int i = 0; + while (i < MAX_TABLES && decompack->tableEnts[i].table != table) + i++; + if (i == MAX_TABLES) + { + FILE* fp = fopen("sp7err.out", "a"); + // fprintf(fp, "Table Entry %06X:%02X not found\n", table, s7r.reg4804); + 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]; + if (strlen(FREEZEFOLDER)) + { + //splitpath (Memory.ROMFilename, drive, dir, fname, ext); + strcpy(name, FREEZEFOLDER); + strcat(name, "/"); + } + else + { + splitpath(Memory.ROMFilename, drive, dir, fname, ext); + strcpy(name, drive); + //strcat(filename, "\\"); + strcat(name, dir); + } + strcat(name, pfold); + char bfname[11]; + sprintf(bfname, "%06X.bin", table); + strcat(name, "/"); + strcat(name, bfname); + decompack->binfiles[i] = (uint8*)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() { - Data7110* log=&(decompack->tableEnts[decompack->idx].location[decompack->last_idx]); - if((log->used_len+log->used_offset)<(decompack->last_offset+(unsigned short)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; - int table=(s7r.reg4803<<16)|(s7r.reg4802<<8)|s7r.reg4801; - - int 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) - { - int i=0; - while(itableEnts[i].table!=table) - i++; - if(i==MAX_TABLES) - { - FILE* fp=fopen("sp7err.out","a"); -// fprintf(fp, "Table Entry %06X:%02X not found\n", table, s7r.reg4804); - 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); - } - } + Data7110* log = & + (decompack->tableEnts[decompack->idx].location[decompack->last_idx]); + if ((log->used_len + log->used_offset) < (decompack->last_offset + + (unsigned short)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; + int table = (s7r.reg4803 << 16) | (s7r.reg4802 << 8) | s7r.reg4801; + + int 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) + { + int i = 0; + while (i < MAX_TABLES && decompack->tableEnts[i].table != table) + i++; + if (i == MAX_TABLES) + { + FILE* fp = fopen("sp7err.out", "a"); + // fprintf(fp, "Table Entry %06X:%02X not found\n", table, s7r.reg4804); + 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 S9xGetSPC7110(uint16 Address) { - switch (Address) - { - //decompressed data read port. decrements 4809-A (with wrap) - //4805-6 is the offset into the bank - //AlignBy is set (afaik) at decompression time, and is the offset multiplier - //bank50internal is an internal pointer to the actual byte to read. - //so you read from offset*multiplier + bank50internal - //the offset registers cannot be incremented due to the offset multiplier. - case 0x4800: - { - unsigned short count=s7r.reg4809|(s7r.reg480A<<8); - uint32 i, j; - j=(s7r.reg4805|(s7r.reg4806<<8)); - j*=s7r.AlignBy; - i=j; - if(count >0) - count--; - 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; - } - return s7r.reg4800; - //table register low - case 0x4801: return s7r.reg4801; - //table register middle - case 0x4802: return s7r.reg4802; - //table register high - case 0x4803: return s7r.reg4803; - //index of pointer in table (each entry is 4 bytes) - case 0x4804: return s7r.reg4804; - //offset register low - case 0x4805: return s7r.reg4805; - //offset register high - case 0x4806: return s7r.reg4806; - //DMA channel (not that I see this usually set, - //regardless of what channel DMA is on) - case 0x4807: return s7r.reg4807; - //C r/w option, unknown, defval:00 is what Dark Force says - //afaict, Snes9x doesn't use this at all. - case 0x4808: return s7r.reg4808; - //C-Length low - //counts down the number of bytes left to read from the decompression buffer. - //this is set by the ROM, and wraps on bounds. - case 0x4809: return s7r.reg4809; - //C Length high - case 0x480A: 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: - s7r.reg480C^=0x80; - return s7r.reg480C^0x80; - - //Data access port - //reads from the data ROM (anywhere over the first 8 mbits - //behavior is complex, will document later, - //possibly missing cases, because of the number of switches in play - case 0x4810: - if(s7r.written==0) - return 0; - if((s7r.written&0x07)==0x07) - { - uint32 i=(s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811; - i%=s7r.DataRomSize; - if(s7r.reg4818&0x02) - { - if(s7r.reg4818&0x08) - { - signed short r4814; - r4814=(s7r.reg4815<<8)|s7r.reg4814; - i+=r4814; - r4814++; - s7r.reg4815=(uint8)(r4814>>8); - s7r.reg4814=(uint8)(r4814&0x00FF); - } - else - { - unsigned short r4814; - r4814=(s7r.reg4815<<8)|s7r.reg4814; - i+=r4814; - if(r4814!=0xFFFF) - r4814++; - else r4814=0; - s7r.reg4815=(uint8)(r4814>>8); - s7r.reg4814=(uint8)(r4814&0x00FF); - - } - } - i+=s7r.DataRomOffset; - uint8 tmp=Memory.ROM[i]; - i=(s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811; - - if(s7r.reg4818&0x02) - { - } - else if(s7r.reg4818&0x01) - { - if(s7r.reg4818&0x04) - { - signed short inc; - inc=(s7r.reg4817<<8)|s7r.reg4816; - - if(!(s7r.reg4818&0x10)) - i+=inc; - else - { - if(s7r.reg4818&0x08) - { - signed short r4814; - r4814=(s7r.reg4815<<8)|s7r.reg4814; - r4814+=inc; - s7r.reg4815=(r4814&0xFF00)>>8; - s7r.reg4814=r4814&0xFF; - } - else - { - unsigned short r4814; - r4814=(s7r.reg4815<<8)|s7r.reg4814; - r4814+=inc; - s7r.reg4815=(r4814&0xFF00)>>8; - s7r.reg4814=r4814&0xFF; - - } - } - //is signed - } - else - { - uint16 inc; - inc=(s7r.reg4817<<8)|s7r.reg4816; - if(!(s7r.reg4818&0x10)) - i+=inc; - else - { - if(s7r.reg4818&0x08) - { - signed short r4814; - r4814=(s7r.reg4815<<8)|s7r.reg4814; - r4814+=inc; - s7r.reg4815=(r4814&0xFF00)>>8; - s7r.reg4814=r4814&0xFF; - } - else - { - unsigned short r4814; - r4814=(s7r.reg4815<<8)|s7r.reg4814; - r4814+=inc; - s7r.reg4815=(r4814&0xFF00)>>8; - s7r.reg4814=r4814&0xFF; - - } - } - } - } - else - { - if(!(s7r.reg4818&0x10)) - i+=1; - else - { - if(s7r.reg4818&0x08) - { - signed short r4814; - r4814=(s7r.reg4815<<8)|s7r.reg4814; - r4814+=1; - s7r.reg4815=(r4814&0xFF00)>>8; - s7r.reg4814=r4814&0xFF; - } - else - { - unsigned short r4814; - r4814=(s7r.reg4815<<8)|s7r.reg4814; - r4814+=1; - s7r.reg4815=(r4814&0xFF00)>>8; - s7r.reg4814=r4814&0xFF; - - } - } - } - - i%=s7r.DataRomSize; - s7r.reg4811=i&0x00FF; - s7r.reg4812=(i&0x00FF00)>>8; - s7r.reg4813=((i&0xFF0000)>>16); - return tmp; - } - else return 0; - //direct read address low - case 0x4811: return s7r.reg4811; - //direct read address middle - case 0x4812: return s7r.reg4812; - //direct read access high - case 0x4813: return s7r.reg4813; - //read adjust low - case 0x4814: return s7r.reg4814; - //read adjust high - case 0x4815: return s7r.reg4815; - //read increment low - case 0x4816: return s7r.reg4816; - //read increment high - case 0x4817: return s7r.reg4817; - //Data ROM command mode - //essentially, this controls the insane code of $4810 and $481A - case 0x4818: return s7r.reg4818; - //read after adjust port - //what this does, besides more nasty stuff like 4810, - //I don't know. Just assume it is a different implementation of $4810, - //if it helps your sanity - case 0x481A: - if(s7r.written==0x1F) - { - uint32 i=((s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811); - if(s7r.reg4818&0x08) - { - short adj; - adj=((short)(s7r.reg4815<<8))|s7r.reg4814; - i+=adj; - } - else - { - uint16 adj; - adj=(s7r.reg4815<<8)|s7r.reg4814; - i+=adj; - } - - i%=s7r.DataRomSize; - i+=s7r.DataRomOffset; - uint8 tmp=Memory.ROM[i]; - i=((s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811); - if(0x60==(s7r.reg4818&0x60)) - { - i=((s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811); - - if(!(s7r.reg4818&0x10)) - { - if(s7r.reg4818&0x08) - { - short adj; - adj=((short)(s7r.reg4815<<8))|s7r.reg4814; - i+=adj; - } - else - { - uint16 adj; - adj=(s7r.reg4815<<8)|s7r.reg4814; - i+=adj; - } - i%=s7r.DataRomSize; - s7r.reg4811=i&0x00FF; - s7r.reg4812=(i&0x00FF00)>>8; - s7r.reg4813=((i&0xFF0000)>>16); - } - else - { - if(s7r.reg4818&0x08) - { - short adj; - adj=((short)(s7r.reg4815<<8))|s7r.reg4814; - adj+=adj; - s7r.reg4815=(adj&0xFF00)>>8; - s7r.reg4814=adj&0xFF; - } - else - { - uint16 adj; - adj=(s7r.reg4815<<8)|s7r.reg4814; - adj+=adj; - s7r.reg4815=(adj&0xFF00)>>8; - s7r.reg4814=adj&0xFF; - } - } - } - return tmp; - } - else return 0; - - //multiplicand low or dividend lowest - case 0x4820: return s7r.reg4820; - //multiplicand high or divdend lower - case 0x4821: return s7r.reg4821; - //dividend higher - case 0x4822: return s7r.reg4822; - //dividend highest - case 0x4823: return s7r.reg4823; - //multiplier low - case 0x4824: return s7r.reg4824; - //multiplier high - case 0x4825: return s7r.reg4825; - //divisor low - case 0x4826: return s7r.reg4826; - //divisor high - case 0x4827: return s7r.reg4827; - - //result lowest - case 0x4828: - return s7r.reg4828; - //result lower - case 0x4829: - return s7r.reg4829; - //result higher - case 0x482A: - return s7r.reg482A; - //result highest - case 0x482B: - return s7r.reg482B; - //remainder (division) low - case 0x482C: return s7r.reg482C; - //remainder (division) high - case 0x482D: return s7r.reg482D; - //signed/unsigned - case 0x482E: return s7r.reg482E; - //finished flag, emulated as an on-read toggle. - case 0x482F: - if(s7r.reg482F) - { - s7r.reg482F=0; - return 0x80; - } - return 0; - break; - - //SRAM toggle - case 0x4830: - return s7r.reg4830; - //DX bank mapping - case 0x4831: - return s7r.reg4831; - //EX bank mapping - case 0x4832: - return s7r.reg4832; - //FX bank mapping - case 0x4833: - return s7r.reg4833; - //SRAM mapping? We have no clue! - case 0x4834: - return s7r.reg4834; -//RTC enable - case 0x4840: - if(!Settings.SPC7110RTC) - return Address>>8; - return s7r.reg4840; -//command/index/value of RTC (essentially, zero unless we're in read mode - case 0x4841: - if(!Settings.SPC7110RTC) - return Address>>8; - if(rtc_f9.init) - { - S9xUpdateRTC(); - uint8 tmp=rtc_f9.reg[rtc_f9.index]; - rtc_f9.index++; - rtc_f9.index%=0x10; - return tmp; - } - else return 0; -//RTC done flag - case 0x4842: - if(!Settings.SPC7110RTC) - return Address>>8; - s7r.reg4842^=0x80; - return s7r.reg4842^0x80; - default: - return 0x00; - } + switch (Address) + { + //decompressed data read port. decrements 4809-A (with wrap) + //4805-6 is the offset into the bank + //AlignBy is set (afaik) at decompression time, and is the offset multiplier + //bank50internal is an internal pointer to the actual byte to read. + //so you read from offset*multiplier + bank50internal + //the offset registers cannot be incremented due to the offset multiplier. + case 0x4800: + { + unsigned short count = s7r.reg4809 | (s7r.reg480A << 8); + uint32 i, j; + j = (s7r.reg4805 | (s7r.reg4806 << 8)); + j *= s7r.AlignBy; + i = j; + if (count > 0) + count--; + 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; + } + return s7r.reg4800; + //table register low + case 0x4801: + return s7r.reg4801; + //table register middle + case 0x4802: + return s7r.reg4802; + //table register high + case 0x4803: + return s7r.reg4803; + //index of pointer in table (each entry is 4 bytes) + case 0x4804: + return s7r.reg4804; + //offset register low + case 0x4805: + return s7r.reg4805; + //offset register high + case 0x4806: + return s7r.reg4806; + //DMA channel (not that I see this usually set, + //regardless of what channel DMA is on) + case 0x4807: + return s7r.reg4807; + //C r/w option, unknown, defval:00 is what Dark Force says + //afaict, Snes9x doesn't use this at all. + case 0x4808: + return s7r.reg4808; + //C-Length low + //counts down the number of bytes left to read from the decompression buffer. + //this is set by the ROM, and wraps on bounds. + case 0x4809: + return s7r.reg4809; + //C Length high + case 0x480A: + 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: + s7r.reg480C ^= 0x80; + return s7r.reg480C ^ 0x80; + + //Data access port + //reads from the data ROM (anywhere over the first 8 mbits + //behavior is complex, will document later, + //possibly missing cases, because of the number of switches in play + case 0x4810: + if (s7r.written == 0) + return 0; + if ((s7r.written & 0x07) == 0x07) + { + uint32 i = (s7r.reg4813 << 16) | (s7r.reg4812 << 8) | s7r.reg4811; + i %= s7r.DataRomSize; + if (s7r.reg4818 & 0x02) + { + if (s7r.reg4818 & 0x08) + { + signed short r4814; + r4814 = (s7r.reg4815 << 8) | s7r.reg4814; + i += r4814; + r4814++; + s7r.reg4815 = (uint8)(r4814 >> 8); + s7r.reg4814 = (uint8)(r4814 & 0x00FF); + } + else + { + unsigned short r4814; + r4814 = (s7r.reg4815 << 8) | s7r.reg4814; + i += r4814; + if (r4814 != 0xFFFF) + r4814++; + else r4814 = 0; + s7r.reg4815 = (uint8)(r4814 >> 8); + s7r.reg4814 = (uint8)(r4814 & 0x00FF); + + } + } + i += s7r.DataRomOffset; + uint8 tmp = Memory.ROM[i]; + i = (s7r.reg4813 << 16) | (s7r.reg4812 << 8) | s7r.reg4811; + + if (s7r.reg4818 & 0x02) + { + } + else if (s7r.reg4818 & 0x01) + { + if (s7r.reg4818 & 0x04) + { + signed short inc; + inc = (s7r.reg4817 << 8) | s7r.reg4816; + + if (!(s7r.reg4818 & 0x10)) + i += inc; + else + { + if (s7r.reg4818 & 0x08) + { + signed short r4814; + r4814 = (s7r.reg4815 << 8) | s7r.reg4814; + r4814 += inc; + s7r.reg4815 = (r4814 & 0xFF00) >> 8; + s7r.reg4814 = r4814 & 0xFF; + } + else + { + unsigned short r4814; + r4814 = (s7r.reg4815 << 8) | s7r.reg4814; + r4814 += inc; + s7r.reg4815 = (r4814 & 0xFF00) >> 8; + s7r.reg4814 = r4814 & 0xFF; + + } + } + //is signed + } + else + { + uint16 inc; + inc = (s7r.reg4817 << 8) | s7r.reg4816; + if (!(s7r.reg4818 & 0x10)) + i += inc; + else + { + if (s7r.reg4818 & 0x08) + { + signed short r4814; + r4814 = (s7r.reg4815 << 8) | s7r.reg4814; + r4814 += inc; + s7r.reg4815 = (r4814 & 0xFF00) >> 8; + s7r.reg4814 = r4814 & 0xFF; + } + else + { + unsigned short r4814; + r4814 = (s7r.reg4815 << 8) | s7r.reg4814; + r4814 += inc; + s7r.reg4815 = (r4814 & 0xFF00) >> 8; + s7r.reg4814 = r4814 & 0xFF; + + } + } + } + } + else + { + if (!(s7r.reg4818 & 0x10)) + i += 1; + else + { + if (s7r.reg4818 & 0x08) + { + signed short r4814; + r4814 = (s7r.reg4815 << 8) | s7r.reg4814; + r4814 += 1; + s7r.reg4815 = (r4814 & 0xFF00) >> 8; + s7r.reg4814 = r4814 & 0xFF; + } + else + { + unsigned short r4814; + r4814 = (s7r.reg4815 << 8) | s7r.reg4814; + r4814 += 1; + s7r.reg4815 = (r4814 & 0xFF00) >> 8; + s7r.reg4814 = r4814 & 0xFF; + + } + } + } + + i %= s7r.DataRomSize; + s7r.reg4811 = i & 0x00FF; + s7r.reg4812 = (i & 0x00FF00) >> 8; + s7r.reg4813 = ((i & 0xFF0000) >> 16); + return tmp; + } + else return 0; + //direct read address low + case 0x4811: + return s7r.reg4811; + //direct read address middle + case 0x4812: + return s7r.reg4812; + //direct read access high + case 0x4813: + return s7r.reg4813; + //read adjust low + case 0x4814: + return s7r.reg4814; + //read adjust high + case 0x4815: + return s7r.reg4815; + //read increment low + case 0x4816: + return s7r.reg4816; + //read increment high + case 0x4817: + return s7r.reg4817; + //Data ROM command mode + //essentially, this controls the insane code of $4810 and $481A + case 0x4818: + return s7r.reg4818; + //read after adjust port + //what this does, besides more nasty stuff like 4810, + //I don't know. Just assume it is a different implementation of $4810, + //if it helps your sanity + case 0x481A: + if (s7r.written == 0x1F) + { + uint32 i = ((s7r.reg4813 << 16) | (s7r.reg4812 << 8) | s7r.reg4811); + if (s7r.reg4818 & 0x08) + { + short adj; + adj = ((short)(s7r.reg4815 << 8)) | s7r.reg4814; + i += adj; + } + else + { + uint16 adj; + adj = (s7r.reg4815 << 8) | s7r.reg4814; + i += adj; + } + + i %= s7r.DataRomSize; + i += s7r.DataRomOffset; + uint8 tmp = Memory.ROM[i]; + i = ((s7r.reg4813 << 16) | (s7r.reg4812 << 8) | s7r.reg4811); + if (0x60 == (s7r.reg4818 & 0x60)) + { + i = ((s7r.reg4813 << 16) | (s7r.reg4812 << 8) | s7r.reg4811); + + if (!(s7r.reg4818 & 0x10)) + { + if (s7r.reg4818 & 0x08) + { + short adj; + adj = ((short)(s7r.reg4815 << 8)) | s7r.reg4814; + i += adj; + } + else + { + uint16 adj; + adj = (s7r.reg4815 << 8) | s7r.reg4814; + i += adj; + } + i %= s7r.DataRomSize; + s7r.reg4811 = i & 0x00FF; + s7r.reg4812 = (i & 0x00FF00) >> 8; + s7r.reg4813 = ((i & 0xFF0000) >> 16); + } + else + { + if (s7r.reg4818 & 0x08) + { + short adj; + adj = ((short)(s7r.reg4815 << 8)) | s7r.reg4814; + adj += adj; + s7r.reg4815 = (adj & 0xFF00) >> 8; + s7r.reg4814 = adj & 0xFF; + } + else + { + uint16 adj; + adj = (s7r.reg4815 << 8) | s7r.reg4814; + adj += adj; + s7r.reg4815 = (adj & 0xFF00) >> 8; + s7r.reg4814 = adj & 0xFF; + } + } + } + return tmp; + } + else return 0; + + //multiplicand low or dividend lowest + case 0x4820: + return s7r.reg4820; + //multiplicand high or divdend lower + case 0x4821: + return s7r.reg4821; + //dividend higher + case 0x4822: + return s7r.reg4822; + //dividend highest + case 0x4823: + return s7r.reg4823; + //multiplier low + case 0x4824: + return s7r.reg4824; + //multiplier high + case 0x4825: + return s7r.reg4825; + //divisor low + case 0x4826: + return s7r.reg4826; + //divisor high + case 0x4827: + return s7r.reg4827; + + //result lowest + case 0x4828: + return s7r.reg4828; + //result lower + case 0x4829: + return s7r.reg4829; + //result higher + case 0x482A: + return s7r.reg482A; + //result highest + case 0x482B: + return s7r.reg482B; + //remainder (division) low + case 0x482C: + return s7r.reg482C; + //remainder (division) high + case 0x482D: + return s7r.reg482D; + //signed/unsigned + case 0x482E: + return s7r.reg482E; + //finished flag, emulated as an on-read toggle. + case 0x482F: + if (s7r.reg482F) + { + s7r.reg482F = 0; + return 0x80; + } + return 0; + break; + + //SRAM toggle + case 0x4830: + return s7r.reg4830; + //DX bank mapping + case 0x4831: + return s7r.reg4831; + //EX bank mapping + case 0x4832: + return s7r.reg4832; + //FX bank mapping + case 0x4833: + return s7r.reg4833; + //SRAM mapping? We have no clue! + case 0x4834: + return s7r.reg4834; + //RTC enable + case 0x4840: + if (!Settings.SPC7110RTC) + return Address >> 8; + return s7r.reg4840; + //command/index/value of RTC (essentially, zero unless we're in read mode + case 0x4841: + if (!Settings.SPC7110RTC) + return Address >> 8; + if (rtc_f9.init) + { + S9xUpdateRTC(); + uint8 tmp = rtc_f9.reg[rtc_f9.index]; + rtc_f9.index++; + rtc_f9.index %= 0x10; + return tmp; + } + else return 0; + //RTC done flag + case 0x4842: + if (!Settings.SPC7110RTC) + return Address >> 8; + s7r.reg4842 ^= 0x80; + return s7r.reg4842 ^ 0x80; + default: + return 0x00; + } } -void S9xSetSPC7110 (uint8 data, uint16 Address) +void S9xSetSPC7110(uint8 data, uint16 Address) { - switch(Address) - { -//Writes to $4800 are undefined. - - //table low, middle, and high. - case 0x4801: - s7r.reg4801=data; - break; - case 0x4802: - s7r.reg4802=data; - break; - case 0x4803: - s7r.reg4803=data; - break; - - //table index (4 byte entries, bigendian with a multiplier byte) - case 0x4804: - s7r.reg4804=data; - break; - - //offset low - case 0x4805: - s7r.reg4805=data; - break; - - //offset high, starts decompression - case 0x4806: - s7r.reg4806=data; - (*Copy7110)(); - s7r.bank50Internal=0; - s7r.reg480C&=0x7F; - break; - - //DMA channel register (Is it used??) - case 0x4807: - 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: - s7r.reg4809=data; - break; - //C-Length high - case 0x480A: - s7r.reg480A=data; - break; - - //Offset enable - case 0x480B: - { - s7r.reg480B=data; - int table=(s7r.reg4803<<16)|(s7r.reg4802<<8)|s7r.reg4801; - - int 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; - } - } -// s7r.decomp_set=true; - } - break; -//$4810 is probably read only. - - //Data port address low - case 0x4811: - s7r.reg4811=data; - s7r.written|=0x01; - break; - - //data port address middle - case 0x4812: - s7r.reg4812=data; - s7r.written|=0x02; - break; - - //data port address high - case 0x4813: - s7r.reg4813=data; - s7r.written|=0x04; - break; - - //data port adjust low (has a funky immediate increment mode) - case 0x4814: - s7r.reg4814=data; - if(s7r.reg4818&0x02) - { - if((s7r.reg4818&0x20)&&!(s7r.reg4818&0x40)) - { - s7r.offset_add|=0x01; - if(s7r.offset_add==3) - { - if(s7r.reg4818&0x10) - { - } - else - { - uint32 i=(s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811; - if(s7r.reg4818&0x08) - { - i+=(signed char)s7r.reg4814; - } - else - { - i+=s7r.reg4814; - } - i%=s7r.DataRomSize; - s7r.reg4811=i&0x00FF; - s7r.reg4812=(i&0x00FF00)>>8; - s7r.reg4813=((i&0xFF0000)>>16); - } - } - } - else if((s7r.reg4818&0x40)&&!(s7r.reg4818&0x20)) - { - s7r.offset_add|=0x01; - if(s7r.offset_add==3) - { - if(s7r.reg4818&0x10) - { - } - else - { - uint32 i=(s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811; - if(s7r.reg4818&0x08) - { - short adj; - adj=((short)(s7r.reg4815<<8))|s7r.reg4814; - i+=adj; - } - else - { - uint16 adj; - adj=(s7r.reg4815<<8)|s7r.reg4814; - i+=adj; - } - 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: - s7r.reg4815=data; - if(s7r.reg4818&0x02) - { - if(s7r.reg4818&0x20&&!(s7r.reg4818&0x40)) - { - s7r.offset_add|=0x02; - if(s7r.offset_add==3) - { - if(s7r.reg4818&0x10) - { - } - else - { - uint32 i=(s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811; - - if(s7r.reg4818&0x08) - { - i+=(signed char)s7r.reg4814; - } - else - { - i+=s7r.reg4814; - } - i%=s7r.DataRomSize; - s7r.reg4811=i&0x00FF; - s7r.reg4812=(i&0x00FF00)>>8; - s7r.reg4813=((i&0xFF0000)>>16); - } - } - } - else if(s7r.reg4818&0x40&&!(s7r.reg4818&0x20)) - { - s7r.offset_add|=0x02; - if(s7r.offset_add==3) - { - if(s7r.reg4818&0x10) - { - } - else - { - uint32 i=(s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811; - if(s7r.reg4818&0x08) - { - short adj; - adj=((short)(s7r.reg4815<<8))|s7r.reg4814; - i+=adj; - } - else - { - uint16 adj; - adj=(s7r.reg4815<<8)|s7r.reg4814; - i+=adj; - } - i%=s7r.DataRomSize; - s7r.reg4811=i&0x00FF; - s7r.reg4812=(i&0x00FF00)>>8; - s7r.reg4813=((i&0xFF0000)>>16); - } - } - } - } - s7r.written|=0x10; - break; - //data port increment low - case 0x4816: - s7r.reg4816=data; - break; - //data port increment high - case 0x4817: - s7r.reg4817=data; - break; - - //data port mode switches - //note that it starts inactive. - case 0x4818: - if((s7r.written&0x18)!=0x18) - break; - s7r.offset_add=0; - s7r.reg4818=data; - break; - - //multiplicand low or dividend lowest - case 0x4820: - s7r.reg4820=data; - break; - //multiplicand high or dividend lower - case 0x4821: - s7r.reg4821=data; - break; - //dividend higher - case 0x4822: - s7r.reg4822=data; - break; - //dividend highest - case 0x4823: - s7r.reg4823=data; - break; - //multiplier low - case 0x4824: - s7r.reg4824=data; - break; - //multiplier high (triggers operation) - case 0x4825: - s7r.reg4825=data; - if(s7r.reg482E&0x01) - { - int mul; - short m1=(short)((s7r.reg4824)|(s7r.reg4825<<8)); - short m2=(short)((s7r.reg4820)|(s7r.reg4821<<8)); - - mul=m1*m2; - s7r.reg4828=(uint8)(mul&0x000000FF); - s7r.reg4829=(uint8)((mul&0x0000FF00)>>8); - s7r.reg482A=(uint8)((mul&0x00FF0000)>>16); - s7r.reg482B=(uint8)((mul&0xFF000000)>>24); - } - else - { - uint32 mul; - uint16 m1=(uint16)((s7r.reg4824)|(s7r.reg4825<<8)); - uint16 m2=(uint16)((s7r.reg4820)|(s7r.reg4821<<8)); - - mul=m1*m2; - s7r.reg4828=(uint8)(mul&0x000000FF); - s7r.reg4829=(uint8)((mul&0x0000FF00)>>8); - s7r.reg482A=(uint8)((mul&0x00FF0000)>>16); - s7r.reg482B=(uint8)((mul&0xFF000000)>>24); - } - s7r.reg482F=0x80; - break; - //divisor low - case 0x4826: - s7r.reg4826=data; - break; - //divisor high (triggers operation) - case 0x4827: - s7r.reg4827=data; - if(s7r.reg482E&0x01) - { - int quotient; - short remainder; - int dividend=(int)(s7r.reg4820|(s7r.reg4821<<8)|(s7r.reg4822<<16)|(s7r.reg4823<<24)); - short divisor=(short)(s7r.reg4826|(s7r.reg4827<<8)); - if(divisor != 0) - { - quotient=(int)(dividend/divisor); - remainder=(short)(dividend%divisor); - } - else - { - quotient=0; - remainder=dividend&0x0000FFFF; - } - s7r.reg4828=(uint8)(quotient&0x000000FF); - s7r.reg4829=(uint8)((quotient&0x0000FF00)>>8); - s7r.reg482A=(uint8)((quotient&0x00FF0000)>>16); - s7r.reg482B=(uint8)((quotient&0xFF000000)>>24); - s7r.reg482C=(uint8)remainder&0x00FF; - s7r.reg482D=(uint8)((remainder&0xFF00)>>8); - } - else - { - uint32 quotient; - uint16 remainder; - uint32 dividend=(uint32)(s7r.reg4820|(s7r.reg4821<<8)|(s7r.reg4822<<16)|(s7r.reg4823<<24)); - uint16 divisor=(uint16)(s7r.reg4826|(s7r.reg4827<<8)); - if(divisor != 0) - { - quotient=(uint32)(dividend/divisor); - remainder=(uint16)(dividend%divisor); - } - else - { - quotient=0; - remainder=dividend&0x0000FFFF; - } - s7r.reg4828=(uint8)(quotient&0x000000FF); - s7r.reg4829=(uint8)((quotient&0x0000FF00)>>8); - s7r.reg482A=(uint8)((quotient&0x00FF0000)>>16); - s7r.reg482B=(uint8)((quotient&0xFF000000)>>24); - s7r.reg482C=(uint8)remainder&0x00FF; - s7r.reg482D=(uint8)((remainder&0xFF00)>>8); - } - s7r.reg482F=0x80; - break; - //result registers are possibly read-only - - //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.reg482E=data; - break; - - //math status register possibly read only - - //SRAM toggle - case 0x4830: + switch (Address) + { + //Writes to $4800 are undefined. + + //table low, middle, and high. + case 0x4801: + s7r.reg4801 = data; + break; + case 0x4802: + s7r.reg4802 = data; + break; + case 0x4803: + s7r.reg4803 = data; + break; + + //table index (4 byte entries, bigendian with a multiplier byte) + case 0x4804: + s7r.reg4804 = data; + break; + + //offset low + case 0x4805: + s7r.reg4805 = data; + break; + + //offset high, starts decompression + case 0x4806: + s7r.reg4806 = data; + (*Copy7110)(); + s7r.bank50Internal = 0; + s7r.reg480C &= 0x7F; + break; + + //DMA channel register (Is it used??) + case 0x4807: + 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: + s7r.reg4809 = data; + break; + //C-Length high + case 0x480A: + s7r.reg480A = data; + break; + + //Offset enable + case 0x480B: + { + s7r.reg480B = data; + int table = (s7r.reg4803 << 16) | (s7r.reg4802 << 8) | s7r.reg4801; + + int 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; + } + } + // s7r.decomp_set=true; + } + break; + //$4810 is probably read only. + + //Data port address low + case 0x4811: + s7r.reg4811 = data; + s7r.written |= 0x01; + break; + + //data port address middle + case 0x4812: + s7r.reg4812 = data; + s7r.written |= 0x02; + break; + + //data port address high + case 0x4813: + s7r.reg4813 = data; + s7r.written |= 0x04; + break; + + //data port adjust low (has a funky immediate increment mode) + case 0x4814: + s7r.reg4814 = data; + if (s7r.reg4818 & 0x02) + { + if ((s7r.reg4818 & 0x20) && !(s7r.reg4818 & 0x40)) + { + s7r.offset_add |= 0x01; + if (s7r.offset_add == 3) + { + if (s7r.reg4818 & 0x10) + { + } + else + { + uint32 i = (s7r.reg4813 << 16) | (s7r.reg4812 << 8) | s7r.reg4811; + if (s7r.reg4818 & 0x08) + i += (signed char)s7r.reg4814; + else + i += s7r.reg4814; + i %= s7r.DataRomSize; + s7r.reg4811 = i & 0x00FF; + s7r.reg4812 = (i & 0x00FF00) >> 8; + s7r.reg4813 = ((i & 0xFF0000) >> 16); + } + } + } + else if ((s7r.reg4818 & 0x40) && !(s7r.reg4818 & 0x20)) + { + s7r.offset_add |= 0x01; + if (s7r.offset_add == 3) + { + if (s7r.reg4818 & 0x10) + { + } + else + { + uint32 i = (s7r.reg4813 << 16) | (s7r.reg4812 << 8) | s7r.reg4811; + if (s7r.reg4818 & 0x08) + { + short adj; + adj = ((short)(s7r.reg4815 << 8)) | s7r.reg4814; + i += adj; + } + else + { + uint16 adj; + adj = (s7r.reg4815 << 8) | s7r.reg4814; + i += adj; + } + 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: + s7r.reg4815 = data; + if (s7r.reg4818 & 0x02) + { + if (s7r.reg4818 & 0x20 && !(s7r.reg4818 & 0x40)) + { + s7r.offset_add |= 0x02; + if (s7r.offset_add == 3) + { + if (s7r.reg4818 & 0x10) + { + } + else + { + uint32 i = (s7r.reg4813 << 16) | (s7r.reg4812 << 8) | s7r.reg4811; + + if (s7r.reg4818 & 0x08) + i += (signed char)s7r.reg4814; + else + i += s7r.reg4814; + i %= s7r.DataRomSize; + s7r.reg4811 = i & 0x00FF; + s7r.reg4812 = (i & 0x00FF00) >> 8; + s7r.reg4813 = ((i & 0xFF0000) >> 16); + } + } + } + else if (s7r.reg4818 & 0x40 && !(s7r.reg4818 & 0x20)) + { + s7r.offset_add |= 0x02; + if (s7r.offset_add == 3) + { + if (s7r.reg4818 & 0x10) + { + } + else + { + uint32 i = (s7r.reg4813 << 16) | (s7r.reg4812 << 8) | s7r.reg4811; + if (s7r.reg4818 & 0x08) + { + short adj; + adj = ((short)(s7r.reg4815 << 8)) | s7r.reg4814; + i += adj; + } + else + { + uint16 adj; + adj = (s7r.reg4815 << 8) | s7r.reg4814; + i += adj; + } + i %= s7r.DataRomSize; + s7r.reg4811 = i & 0x00FF; + s7r.reg4812 = (i & 0x00FF00) >> 8; + s7r.reg4813 = ((i & 0xFF0000) >> 16); + } + } + } + } + s7r.written |= 0x10; + break; + //data port increment low + case 0x4816: + s7r.reg4816 = data; + break; + //data port increment high + case 0x4817: + s7r.reg4817 = data; + break; + + //data port mode switches + //note that it starts inactive. + case 0x4818: + if ((s7r.written & 0x18) != 0x18) + break; + s7r.offset_add = 0; + s7r.reg4818 = data; + break; + + //multiplicand low or dividend lowest + case 0x4820: + s7r.reg4820 = data; + break; + //multiplicand high or dividend lower + case 0x4821: + s7r.reg4821 = data; + break; + //dividend higher + case 0x4822: + s7r.reg4822 = data; + break; + //dividend highest + case 0x4823: + s7r.reg4823 = data; + break; + //multiplier low + case 0x4824: + s7r.reg4824 = data; + break; + //multiplier high (triggers operation) + case 0x4825: + s7r.reg4825 = data; + if (s7r.reg482E & 0x01) + { + int mul; + short m1 = (short)((s7r.reg4824) | (s7r.reg4825 << 8)); + short m2 = (short)((s7r.reg4820) | (s7r.reg4821 << 8)); + + mul = m1 * m2; + s7r.reg4828 = (uint8)(mul & 0x000000FF); + s7r.reg4829 = (uint8)((mul & 0x0000FF00) >> 8); + s7r.reg482A = (uint8)((mul & 0x00FF0000) >> 16); + s7r.reg482B = (uint8)((mul & 0xFF000000) >> 24); + } + else + { + uint32 mul; + uint16 m1 = (uint16)((s7r.reg4824) | (s7r.reg4825 << 8)); + uint16 m2 = (uint16)((s7r.reg4820) | (s7r.reg4821 << 8)); + + mul = m1 * m2; + s7r.reg4828 = (uint8)(mul & 0x000000FF); + s7r.reg4829 = (uint8)((mul & 0x0000FF00) >> 8); + s7r.reg482A = (uint8)((mul & 0x00FF0000) >> 16); + s7r.reg482B = (uint8)((mul & 0xFF000000) >> 24); + } + s7r.reg482F = 0x80; + break; + //divisor low + case 0x4826: + s7r.reg4826 = data; + break; + //divisor high (triggers operation) + case 0x4827: + s7r.reg4827 = data; + if (s7r.reg482E & 0x01) + { + int quotient; + short remainder; + int dividend = (int)(s7r.reg4820 | (s7r.reg4821 << 8) | (s7r.reg4822 << 16) | + (s7r.reg4823 << 24)); + short divisor = (short)(s7r.reg4826 | (s7r.reg4827 << 8)); + if (divisor != 0) + { + quotient = (int)(dividend / divisor); + remainder = (short)(dividend % divisor); + } + else + { + quotient = 0; + remainder = dividend & 0x0000FFFF; + } + s7r.reg4828 = (uint8)(quotient & 0x000000FF); + s7r.reg4829 = (uint8)((quotient & 0x0000FF00) >> 8); + s7r.reg482A = (uint8)((quotient & 0x00FF0000) >> 16); + s7r.reg482B = (uint8)((quotient & 0xFF000000) >> 24); + s7r.reg482C = (uint8)remainder & 0x00FF; + s7r.reg482D = (uint8)((remainder & 0xFF00) >> 8); + } + else + { + uint32 quotient; + uint16 remainder; + uint32 dividend = (uint32)(s7r.reg4820 | (s7r.reg4821 << 8) | + (s7r.reg4822 << 16) | (s7r.reg4823 << 24)); + uint16 divisor = (uint16)(s7r.reg4826 | (s7r.reg4827 << 8)); + if (divisor != 0) + { + quotient = (uint32)(dividend / divisor); + remainder = (uint16)(dividend % divisor); + } + else + { + quotient = 0; + remainder = dividend & 0x0000FFFF; + } + s7r.reg4828 = (uint8)(quotient & 0x000000FF); + s7r.reg4829 = (uint8)((quotient & 0x0000FF00) >> 8); + s7r.reg482A = (uint8)((quotient & 0x00FF0000) >> 16); + s7r.reg482B = (uint8)((quotient & 0xFF000000) >> 24); + s7r.reg482C = (uint8)remainder & 0x00FF; + s7r.reg482D = (uint8)((remainder & 0xFF00) >> 8); + } + s7r.reg482F = 0x80; + break; + //result registers are possibly read-only + + //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.reg482E = data; + break; + + //math status register possibly read only + + //SRAM toggle + case 0x4830: SPC7110Sram(data); - s7r.reg4830=data; - break; - //Bank DX mapping - case 0x4831: - s7r.reg4831=data; - break; - //Bank EX mapping - case 0x4832: - s7r.reg4832=data; - break; - //Bank FX mapping - case 0x4833: - s7r.reg4833=data; - break; - //S-RAM mapping? who knows? - case 0x4834: - s7r.reg4834=data; - break; - //RTC Toggle - case 0x4840: - if(0==data) - { - S9xUpdateRTC(); - // rtc_f9.init=false; - // rtc_f9.index=-1; - } - if(data&0x01) - { - s7r.reg4842=0x80; - //rtc_f9.last_used=time(NULL);//???? - rtc_f9.init=false; - rtc_f9.index=-1; - } - s7r.reg4840=data; - break; - //RTC init/command/index register - case 0x4841: - if(rtc_f9.init) - { - if(-1==rtc_f9.index) - { - rtc_f9.index=data&0x0F; - break; - } - if(rtc_f9.control==0x0C) - { - rtc_f9.index=data&0x0F; - s7r.reg4842=0x80; - rtc_f9.last_used=time(NULL); - } - else - { - - if(0x0D==rtc_f9.index) - { - if(data&0x08) - { - if(rtc_f9.reg[1]<3) - { - S9xUpdateRTC(); - rtc_f9.reg[0]=0; - rtc_f9.reg[1]=0; - rtc_f9.last_used=time(NULL); - } - else - { - S9xUpdateRTC(); - rtc_f9.reg[0]=0; - rtc_f9.reg[1]=0; - rtc_f9.last_used=time(NULL)-60; - S9xUpdateRTC(); - rtc_f9.last_used=time(NULL); - } - data&=0x07; - } - if(rtc_f9.reg[0x0D]&0x01) - { - if(!(data%2)) - { - rtc_f9.reg[rtc_f9.index&0x0F]=data; - rtc_f9.last_used=time(NULL)-1; - S9xUpdateRTC(); - rtc_f9.last_used=time(NULL); - } - } - } - if(0x0F==rtc_f9.index) - { - if(data&0x01&&!(rtc_f9.reg[0x0F]&0x01)) - { - S9xUpdateRTC(); - rtc_f9.reg[0]=0; - rtc_f9.reg[1]=0; - rtc_f9.last_used=time(NULL); - } - if(data&0x02&&!(rtc_f9.reg[0x0F]&0x02)) - { - S9xUpdateRTC(); - rtc_f9.last_used=time(NULL); - } - } - rtc_f9.reg[rtc_f9.index&0x0F]=data; - s7r.reg4842=0x80; - rtc_f9.index=(rtc_f9.index+1)%0x10; - } - } - else - { - if(data==0x03||data==0x0C) - { - rtc_f9.init=true; - rtc_f9.control=data; - rtc_f9.index=-1; - } - } - break; - //writes to RTC status register aren't expected to be meaningful - default: - Address-=0x4800; - break; - //16 BIT MULTIPLIER: ($FF00) high byte, defval:00 - } + s7r.reg4830 = data; + break; + //Bank DX mapping + case 0x4831: + s7r.reg4831 = data; + break; + //Bank EX mapping + case 0x4832: + s7r.reg4832 = data; + break; + //Bank FX mapping + case 0x4833: + s7r.reg4833 = data; + break; + //S-RAM mapping? who knows? + case 0x4834: + s7r.reg4834 = data; + break; + //RTC Toggle + case 0x4840: + if (0 == data) + { + S9xUpdateRTC(); + // rtc_f9.init=false; + // rtc_f9.index=-1; + } + if (data & 0x01) + { + s7r.reg4842 = 0x80; + //rtc_f9.last_used=time(NULL);//???? + rtc_f9.init = false; + rtc_f9.index = -1; + } + s7r.reg4840 = data; + break; + //RTC init/command/index register + case 0x4841: + if (rtc_f9.init) + { + if (-1 == rtc_f9.index) + { + rtc_f9.index = data & 0x0F; + break; + } + if (rtc_f9.control == 0x0C) + { + rtc_f9.index = data & 0x0F; + s7r.reg4842 = 0x80; + rtc_f9.last_used = time(NULL); + } + else + { + + if (0x0D == rtc_f9.index) + { + if (data & 0x08) + { + if (rtc_f9.reg[1] < 3) + { + S9xUpdateRTC(); + rtc_f9.reg[0] = 0; + rtc_f9.reg[1] = 0; + rtc_f9.last_used = time(NULL); + } + else + { + S9xUpdateRTC(); + rtc_f9.reg[0] = 0; + rtc_f9.reg[1] = 0; + rtc_f9.last_used = time(NULL) - 60; + S9xUpdateRTC(); + rtc_f9.last_used = time(NULL); + } + data &= 0x07; + } + if (rtc_f9.reg[0x0D] & 0x01) + { + if (!(data % 2)) + { + rtc_f9.reg[rtc_f9.index & 0x0F] = data; + rtc_f9.last_used = time(NULL) - 1; + S9xUpdateRTC(); + rtc_f9.last_used = time(NULL); + } + } + } + if (0x0F == rtc_f9.index) + { + if (data & 0x01 && !(rtc_f9.reg[0x0F] & 0x01)) + { + S9xUpdateRTC(); + rtc_f9.reg[0] = 0; + rtc_f9.reg[1] = 0; + rtc_f9.last_used = time(NULL); + } + if (data & 0x02 && !(rtc_f9.reg[0x0F] & 0x02)) + { + S9xUpdateRTC(); + rtc_f9.last_used = time(NULL); + } + } + rtc_f9.reg[rtc_f9.index & 0x0F] = data; + s7r.reg4842 = 0x80; + rtc_f9.index = (rtc_f9.index + 1) % 0x10; + } + } + else + { + if (data == 0x03 || data == 0x0C) + { + rtc_f9.init = true; + rtc_f9.control = data; + rtc_f9.index = -1; + } + } + break; + //writes to RTC status register aren't expected to be meaningful + default: + Address -= 0x4800; + break; + //16 BIT MULTIPLIER: ($FF00) high byte, defval:00 + } } //emulate the SPC7110's ability to remap banks Dx, Ex, and Fx. uint8 S9xGetSPC7110Byte(uint32 Address) { - uint32 i; - switch((Address&0x00F00000)>>16) - { - case 0xD0: - i=s7r.reg4831*0x00100000; - break; - case 0xE0: - i=s7r.reg4832*0x00100000; - break; - case 0xF0: - i=s7r.reg4833*0x00100000; - break; - default:i=0; - } - i+=Address&0x000FFFFF; - i+=s7r.DataRomOffset; + uint32 i; + switch ((Address & 0x00F00000) >> 16) + { + case 0xD0: + i = s7r.reg4831 * 0x00100000; + break; + case 0xE0: + i = s7r.reg4832 * 0x00100000; + break; + case 0xF0: + i = s7r.reg4833 * 0x00100000; + break; + default: + i = 0; + } + i += Address & 0x000FFFFF; + i += s7r.DataRomOffset; return Memory.ROM[i]; } /**********************************************************************************************/ /* S9xSRTCDaysInMonth() */ /* Return the number of days in a specific month for a certain year */ -/* copied directly for RTC functionality, separated in case of incompatibilities */ +/* copied directly for RTC functionality, separated in case of incompatibilities */ /**********************************************************************************************/ -int S9xRTCDaysInMonth( int month, int year ) +int S9xRTCDaysInMonth(int month, int year) { - int mdays; - - 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; - } - - return mdays; + int mdays; + + 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; + } + + return mdays; } @@ -1461,166 +1500,158 @@ int S9xRTCDaysInMonth( int month, int year ) /**********************************************************************************************/ -/* S9xUpdateRTC() */ -/* Advance the RTC time */ +/* S9xUpdateRTC() */ +/* Advance the RTC time */ /**********************************************************************************************/ -void S9xUpdateRTC () +void S9xUpdateRTC() { - time_t cur_systime; - long time_diff; - - // Keep track of game time by computing the number of seconds that pass on the system - // clock and adding the same number of seconds to the RTC clock structure. - - if (rtc_f9.init && 0==(rtc_f9.reg[0x0D]&0x01) && 0==(rtc_f9.reg[0x0F]&0x03)) - { - 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 = (long) (cur_systime - rtc_f9.last_used); - rtc_f9.last_used = cur_systime; - - if ( time_diff > 0 ) - { - int seconds; - int minutes; - int hours; - int days; - int month; - int year; - int temp_days; - - int year_hundreds; - int year_tens; - int year_ones; - - - if ( time_diff > DAYTICKS ) - { - days = time_diff / DAYTICKS; - time_diff = time_diff - days * DAYTICKS; - } - else - { - days = 0; - } - - if ( time_diff > HOURTICKS ) - { - hours = time_diff / HOURTICKS; - time_diff = time_diff - hours * HOURTICKS; - } - else - { - hours = 0; - } - - if ( time_diff > MINUTETICKS ) - { - minutes = time_diff / MINUTETICKS; - time_diff = time_diff - minutes * MINUTETICKS; - } - else - { - minutes = 0; - } - - if ( time_diff > 0 ) - { - seconds = time_diff; - } - else - { - seconds = 0; - } - - - seconds += (rtc_f9.reg[1]*10 + rtc_f9.reg[0]); - if ( seconds >= 60 ) - { - seconds -= 60; - minutes += 1; - } - - minutes += (rtc_f9.reg[3]*10 + rtc_f9.reg[2]); - if ( minutes >= 60 ) - { - minutes -= 60; - hours += 1; - } - - hours += (rtc_f9.reg[5]*10 + rtc_f9.reg[4]); - if ( hours >= 24 ) - { - hours -= 24; - days += 1; - } - - year = rtc_f9.reg[11]*10 + rtc_f9.reg[10]; - year += ( 1900 ); - month = rtc_f9.reg[8]+10*rtc_f9.reg[9]; - rtc_f9.reg[12]+=days; - days += (rtc_f9.reg[7]*10 + rtc_f9.reg[6]); - if ( days > 0 ) - { - while ( days > (temp_days = S9xRTCDaysInMonth( month, year )) ) - { - days -= temp_days; - month += 1; - if ( month > 12 ) - { - year += 1; - month = 1; - } - } - } - - year_tens = year % 100; - year_ones = year_tens % 10; - year_tens /= 10; - year_hundreds = (year - 1000) / 100; - - rtc_f9.reg[0] = seconds % 10; - rtc_f9.reg[1] = seconds / 10; - rtc_f9.reg[2] = minutes % 10; - rtc_f9.reg[3] = minutes / 10; - rtc_f9.reg[4] = hours % 10; - rtc_f9.reg[5] = hours / 10; - rtc_f9.reg[6] = days % 10; - rtc_f9.reg[7] = days / 10; - rtc_f9.reg[8] = month%10; - rtc_f9.reg[9] = month /10; - rtc_f9.reg[10] = year_ones; - rtc_f9.reg[11] = year_tens; - rtc_f9.reg[12] %= 7; - return; - } - } + time_t cur_systime; + long time_diff; + + // Keep track of game time by computing the number of seconds that pass on the system + // clock and adding the same number of seconds to the RTC clock structure. + + if (rtc_f9.init && 0 == (rtc_f9.reg[0x0D] & 0x01) + && 0 == (rtc_f9.reg[0x0F] & 0x03)) + { + 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 = (long)(cur_systime - rtc_f9.last_used); + rtc_f9.last_used = cur_systime; + + if (time_diff > 0) + { + int seconds; + int minutes; + int hours; + int days; + int month; + int year; + int temp_days; + + int year_hundreds; + int year_tens; + int year_ones; + + + if (time_diff > DAYTICKS) + { + days = time_diff / DAYTICKS; + time_diff = time_diff - days * DAYTICKS; + } + else + days = 0; + + if (time_diff > HOURTICKS) + { + hours = time_diff / HOURTICKS; + time_diff = time_diff - hours * HOURTICKS; + } + else + hours = 0; + + if (time_diff > MINUTETICKS) + { + minutes = time_diff / MINUTETICKS; + time_diff = time_diff - minutes * MINUTETICKS; + } + else + minutes = 0; + + if (time_diff > 0) + seconds = time_diff; + else + seconds = 0; + + + seconds += (rtc_f9.reg[1] * 10 + rtc_f9.reg[0]); + if (seconds >= 60) + { + seconds -= 60; + minutes += 1; + } + + minutes += (rtc_f9.reg[3] * 10 + rtc_f9.reg[2]); + if (minutes >= 60) + { + minutes -= 60; + hours += 1; + } + + hours += (rtc_f9.reg[5] * 10 + rtc_f9.reg[4]); + if (hours >= 24) + { + hours -= 24; + days += 1; + } + + year = rtc_f9.reg[11] * 10 + rtc_f9.reg[10]; + year += (1900); + month = rtc_f9.reg[8] + 10 * rtc_f9.reg[9]; + rtc_f9.reg[12] += days; + days += (rtc_f9.reg[7] * 10 + rtc_f9.reg[6]); + if (days > 0) + { + while (days > (temp_days = S9xRTCDaysInMonth(month, year))) + { + days -= temp_days; + month += 1; + if (month > 12) + { + year += 1; + month = 1; + } + } + } + + year_tens = year % 100; + year_ones = year_tens % 10; + year_tens /= 10; + year_hundreds = (year - 1000) / 100; + + rtc_f9.reg[0] = seconds % 10; + rtc_f9.reg[1] = seconds / 10; + rtc_f9.reg[2] = minutes % 10; + rtc_f9.reg[3] = minutes / 10; + rtc_f9.reg[4] = hours % 10; + rtc_f9.reg[5] = hours / 10; + rtc_f9.reg[6] = days % 10; + rtc_f9.reg[7] = days / 10; + rtc_f9.reg[8] = month % 10; + rtc_f9.reg[9] = month / 10; + rtc_f9.reg[10] = year_ones; + rtc_f9.reg[11] = year_tens; + rtc_f9.reg[12] %= 7; + return; + } + } } //allows DMA from the ROM (is this even possible on the SPC7110? uint8* Get7110BasePtr(uint32 Address) { - uint32 i; - switch((Address&0x00F00000)>>16) - { - case 0xD0: - i=s7r.reg4831*0x100000; - break; - case 0xE0: - i=s7r.reg4832*0x100000; - break; - case 0xF0: - i=s7r.reg4833*0x100000; - break; - default:i=0; - } - i+=Address&0x000F0000; + uint32 i; + switch ((Address & 0x00F00000) >> 16) + { + case 0xD0: + i = s7r.reg4831 * 0x100000; + break; + case 0xE0: + i = s7r.reg4832 * 0x100000; + break; + case 0xF0: + i = s7r.reg4833 * 0x100000; + break; + default: + i = 0; + } + i += Address & 0x000F0000; return &Memory.ROM[i]; } @@ -1629,391 +1660,386 @@ uint8* Get7110BasePtr(uint32 Address) //format index (1)-table(3)-file offset(4)-length(4) bool Load7110Index(char* filename) { - FILE* fp; - uint8 buffer[12]; - int table=0; - uint8 index=0; - uint32 offset=0; - uint32 size=0; - int i=0; - fp=fopen(filename, "rb"); - if(NULL==fp) - return false; - - int f_len; - //do - 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(itableEnts[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; - - } - //while(!feof(fp)); - fclose(fp); - return true; + FILE* fp; + uint8 buffer[12]; + int table = 0; + uint8 index = 0; + uint32 offset = 0; + uint32 size = 0; + int i = 0; + fp = fopen(filename, "rb"); + if (NULL == fp) + return false; + + int f_len; + //do + 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; + + } + //while(!feof(fp)); + fclose(fp); + return true; } //Cache 1 load function void SPC7110Load(char* dirname) { - char temp_path[PATH_MAX]; - int i=0; + char temp_path[PATH_MAX]; + int i = 0; - decompack=(Pack7110*)malloc(sizeof(Pack7110)); + decompack = (Pack7110*)malloc(sizeof(Pack7110)); #ifndef _XBOX - getcwd(temp_path,PATH_MAX); + getcwd(temp_path, PATH_MAX); #endif - ZeroMemory(decompack, sizeof(Pack7110)); - + ZeroMemory(decompack, sizeof(Pack7110)); + #ifndef _XBOX - if(-1==chdir(dirname)) - { - S9xMessage(0,0,"Graphics Pack not found!"); - } + if (-1 == chdir(dirname)) + S9xMessage(0, 0, "Graphics Pack not found!"); #endif #ifndef _XBOX - Load7110Index("index.bin"); + Load7110Index("index.bin"); #else - // D:\\ is always app.path in Xbox - Load7110Index("d:\\index.bin"); + // D:\\ is always app.path in Xbox + Load7110Index("d:\\index.bin"); #endif - for(i=0;itableEnts[i].table!=0) - { - char binname[PATH_MAX]; + 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); + sprintf(binname, "%06X.bin", decompack->tableEnts[i].table); #else - sprintf(binname,"%s%06X.bin",filename,decompack->tableEnts[i].table); + sprintf(binname, "%s%06X.bin", filename, decompack->tableEnts[i].table); #endif - struct stat buf; - if(-1!=stat(binname, &buf)) - decompack->binfiles[i]=(uint8*)malloc(buf.st_size); - FILE* fp=fopen(binname, "rb"); - if(fp) - { - fread(decompack->binfiles[i],buf.st_size,1,fp); - fclose(fp); - } - } - } - -#ifndef _XBOX - chdir(temp_path); + struct stat buf; + if (-1 != stat(binname, &buf)) + decompack->binfiles[i] = (uint8*)malloc(buf.st_size); + FILE* fp = fopen(binname, "rb"); + if (fp) + { + fread(decompack->binfiles[i], buf.st_size, 1, fp); + fclose(fp); + } + } + } + +#ifndef _XBOX + chdir(temp_path); #endif - Copy7110=&MovePackData; - CleanUp7110=&Del7110Gfx; + Copy7110 = &MovePackData; + CleanUp7110 = &Del7110Gfx; #ifdef __WIN32__ - #ifndef _XBOX - EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_ENABLED); - #endif +#ifndef _XBOX + EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_ENABLED); +#endif #endif } //Cache 2 load function void SPC7110Open(char* dirname) { - char temp_path[PATH_MAX]; - int i=0; + char temp_path[PATH_MAX]; + int i = 0; - decompack=(Pack7110*)malloc(sizeof(Pack7110)); + decompack = (Pack7110*)malloc(sizeof(Pack7110)); #ifndef _XBOX - getcwd(temp_path,PATH_MAX); + getcwd(temp_path, PATH_MAX); #endif - ZeroMemory(decompack, sizeof(Pack7110)); - + ZeroMemory(decompack, sizeof(Pack7110)); + #ifndef _XBOX - if(-1==chdir(dirname)) - { - S9xMessage(0,0,"Graphics Pack not found!"); - } + if (-1 == chdir(dirname)) + S9xMessage(0, 0, "Graphics Pack not found!"); #endif #ifndef _XBOX - Load7110Index("index.bin"); + Load7110Index("index.bin"); #else - // D:\\ is always app.path in Xbox - Load7110Index("d:\\index.bin"); + // D:\\ is always app.path in Xbox + Load7110Index("d:\\index.bin"); #endif - for (i=0; ibinfiles[i]=NULL; + for (i = 0; i < MAX_TABLES; i++) + decompack->binfiles[i] = NULL; - ReadPackData(); + ReadPackData(); #ifndef _XBOX - chdir(temp_path); + chdir(temp_path); #endif - Copy7110=&ReadPackData; - CleanUp7110=&Close7110Gfx; + Copy7110 = &ReadPackData; + CleanUp7110 = &Close7110Gfx; #ifdef __WIN32__ - #ifndef _XBOX - EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_ENABLED); - #endif +#ifndef _XBOX + EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_ENABLED); +#endif #endif } //Cache 3's load function void SPC7110Grab(char* dirname) { - char temp_path[PATH_MAX]; - int i=0; + char temp_path[PATH_MAX]; + int i = 0; - decompack=(Pack7110*)malloc(sizeof(Pack7110)); + decompack = (Pack7110*)malloc(sizeof(Pack7110)); #ifndef _XBOX - getcwd(temp_path,PATH_MAX); + getcwd(temp_path, PATH_MAX); #endif - int32 buffer_size=1024*1024*cacheMegs;//*some setting + int32 buffer_size = 1024 * 1024 * cacheMegs; //*some setting - ZeroMemory(decompack, sizeof(Pack7110)); + ZeroMemory(decompack, sizeof(Pack7110)); #ifndef _XBOX - - if(-1==chdir(dirname)) - { - S9xMessage(0,0,"Graphics Pack not found!"); - } + + if (-1 == chdir(dirname)) + S9xMessage(0, 0, "Graphics Pack not found!"); #endif #ifndef _XBOX - Load7110Index("index.bin"); + Load7110Index("index.bin"); #else - // D:\\ is always app.path in Xbox - Load7110Index("d:\\index.bin"); + // D:\\ is always app.path in Xbox + Load7110Index("d:\\index.bin"); #endif - for(i=0;itableEnts[i].table!=0) - { - char binname[PATH_MAX]; + 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); + sprintf(binname, "%06X.bin", decompack->tableEnts[i].table); #else - sprintf(binname,"%s%06X.bin",filename,decompack->tableEnts[i].table); + 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_sizebinfiles[i]=(uint8*)malloc(buf.st_size); - FILE* fp=fopen(binname, "rb"); - //use them here - if(fp) - { - if(buf.st_sizebinfiles[i],buf.st_size,1,fp); - fclose(fp); - buffer_size-=buf.st_size; - decompack->tableEnts[i].is_file=false; - } - else - { - decompack->binfiles[i]=(uint8*)fp; - decompack->tableEnts[i].is_file=true; - } - } - } - } - } + struct stat buf; + //add load/no load calculations here + if (-1 != stat(binname, &buf)) + { + if (buf.st_size < buffer_size) + decompack->binfiles[i] = (uint8*)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*)fp; + decompack->tableEnts[i].is_file = true; + } + } + } + } + } #ifndef _XBOX - chdir(temp_path); + chdir(temp_path); #endif - Copy7110=&GetPackData; - CleanUp7110=&Drop7110Gfx; + Copy7110 = &GetPackData; + CleanUp7110 = &Drop7110Gfx; #ifdef __WIN32__ - #ifndef _XBOX - EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_ENABLED); - #endif +#ifndef _XBOX + EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_ENABLED); +#endif #endif } //Cache 1 clean up function void Del7110Gfx() { - int i; - if(Settings.SPC7110) - { + int i; + if (Settings.SPC7110) + { #ifdef __WIN32__ - #ifndef _XBOX - EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_GRAYED); - #endif +#ifndef _XBOX + EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_GRAYED); #endif - Do7110Logging(); - } - for(i=0;ibinfiles[i]!=NULL) - { +#endif + Do7110Logging(); + } + for (i = 0; i < MAX_TABLES; i++) + { + if (decompack->binfiles[i] != NULL) + { free(decompack->binfiles[i]); - decompack->binfiles[i]=NULL; - } - } - Settings.SPC7110=false; - Settings.SPC7110RTC=false; - if(NULL!=decompack) + decompack->binfiles[i] = NULL; + } + } + Settings.SPC7110 = false; + Settings.SPC7110RTC = false; + if (NULL != decompack) free(decompack); - decompack=NULL; - CleanUp7110=NULL; - Copy7110=NULL; + decompack = NULL; + CleanUp7110 = NULL; + Copy7110 = NULL; } //Cache2 cleanup function void Close7110Gfx() { - int i; - if(Settings.SPC7110) - { + int i; + if (Settings.SPC7110) + { #ifdef __WIN32__ - #ifndef _XBOX - EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_GRAYED); - #endif +#ifndef _XBOX + EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_GRAYED); #endif - Do7110Logging(); - } - for(i=0;ibinfiles[i]!=NULL) - { - fclose((FILE*)decompack->binfiles[i]); - decompack->binfiles[i]=NULL; - } - } - Settings.SPC7110=false; - Settings.SPC7110RTC=false; - if(NULL!=decompack) +#endif + 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; + decompack = NULL; + CleanUp7110 = NULL; + Copy7110 = NULL; } //cache 3's clean-up code void Drop7110Gfx() { - int i; - if(Settings.SPC7110) - { + int i; + if (Settings.SPC7110) + { #ifdef __WIN32__ - #ifndef _XBOX - EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_GRAYED); - #endif +#ifndef _XBOX + EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_GRAYED); #endif - Do7110Logging(); - } - for(i=0;ibinfiles[i]!=NULL) - { - if(decompack->tableEnts[i].is_file) - { - fclose((FILE*)decompack->binfiles[i]); - decompack->binfiles[i]=NULL; - } - else - { +#endif + 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) + decompack->binfiles[i] = NULL; + } + } + } + Settings.SPC7110 = false; + Settings.SPC7110RTC = false; + if (NULL != decompack) free(decompack); - decompack=NULL; - CleanUp7110=NULL; - Copy7110=NULL; + decompack = NULL; + CleanUp7110 = NULL; + Copy7110 = NULL; } //emulate a reset. void S9xSpc7110Reset() { - s7r.reg4800=0; - s7r.reg4801=0; - s7r.reg4802=0; - s7r.reg4803=0; - s7r.reg4804=0; - s7r.reg4805=0; - s7r.reg4806=0; - s7r.reg4807=0; - s7r.reg4808=0; - s7r.reg4809=0; - s7r.reg480A=0; - s7r.reg480B=0; - s7r.reg480C=0; - s7r.reg4811=0; - s7r.reg4812=0; - s7r.reg4813=0; - s7r.reg4814=0; - s7r.reg4815=0; - s7r.reg4816=0; - s7r.reg4817=0; - s7r.reg4818=0; - s7r.reg4820=0; - s7r.reg4821=0; - s7r.reg4822=0; - s7r.reg4823=0; - s7r.reg4824=0; - s7r.reg4825=0; - s7r.reg4826=0; - s7r.reg4827=0; - s7r.reg4828=0; - s7r.reg4829=0; - s7r.reg482A=0; - s7r.reg482B=0; - s7r.reg482C=0; - s7r.reg482D=0; - s7r.reg482E=0; - s7r.reg482F=0; - s7r.reg4830=0; - s7r.reg4831=0; - s7r.reg4832=1; - s7r.reg4833=2; - s7r.reg4834=0; - s7r.reg4840=0; - s7r.reg4841=0; - s7r.reg4842=0; - s7r.written=0; - s7r.offset_add=0; - s7r.AlignBy=1; - s7r.bank50Internal=0; - memset(s7r.bank50,0x00,DECOMP_BUFFER_SIZE); + s7r.reg4800 = 0; + s7r.reg4801 = 0; + s7r.reg4802 = 0; + s7r.reg4803 = 0; + s7r.reg4804 = 0; + s7r.reg4805 = 0; + s7r.reg4806 = 0; + s7r.reg4807 = 0; + s7r.reg4808 = 0; + s7r.reg4809 = 0; + s7r.reg480A = 0; + s7r.reg480B = 0; + s7r.reg480C = 0; + s7r.reg4811 = 0; + s7r.reg4812 = 0; + s7r.reg4813 = 0; + s7r.reg4814 = 0; + s7r.reg4815 = 0; + s7r.reg4816 = 0; + s7r.reg4817 = 0; + s7r.reg4818 = 0; + s7r.reg4820 = 0; + s7r.reg4821 = 0; + s7r.reg4822 = 0; + s7r.reg4823 = 0; + s7r.reg4824 = 0; + s7r.reg4825 = 0; + s7r.reg4826 = 0; + s7r.reg4827 = 0; + s7r.reg4828 = 0; + s7r.reg4829 = 0; + s7r.reg482A = 0; + s7r.reg482B = 0; + s7r.reg482C = 0; + s7r.reg482D = 0; + s7r.reg482E = 0; + s7r.reg482F = 0; + s7r.reg4830 = 0; + s7r.reg4831 = 0; + s7r.reg4832 = 1; + s7r.reg4833 = 2; + s7r.reg4834 = 0; + s7r.reg4840 = 0; + s7r.reg4841 = 0; + s7r.reg4842 = 0; + s7r.written = 0; + s7r.offset_add = 0; + s7r.AlignBy = 1; + s7r.bank50Internal = 0; + memset(s7r.bank50, 0x00, DECOMP_BUFFER_SIZE); } @@ -2023,262 +2049,260 @@ void S9xSpc7110Reset() //note the logs are explicitly little-endian, not host byte order. void Do7110Logging() { - uint8 ent_temp; - FILE* flog; - int entries=0; - - if(Settings.SPC7110) - { - //flush last read into logging - (*Copy7110)(); - - if(!strncmp((char*)&Memory.ROM [0xffc0], "SUPER POWER LEAG 4 ", 21)) - { + uint8 ent_temp; + FILE* flog; + int 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"); + flog = fopen("T:\\spl4-sp7.dat", "rb"); #else - flog=fopen("spl4-sp7.dat","rb"); + flog = fopen("spl4-sp7.dat", "rb"); #endif - } - else if(!strncmp((char*)&Memory.ROM [0xffc0], "MOMOTETSU HAPPY ",21)) - { + } + else if (!strncmp((char*)&Memory.ROM [0xffc0], "MOMOTETSU HAPPY ", 21)) + { #ifdef _XBOX - flog=fopen("T:\\smht-sp7.dat","rb"); + flog = fopen("T:\\smht-sp7.dat", "rb"); #else - flog=fopen("smht-sp7.dat","rb"); + flog = fopen("smht-sp7.dat", "rb"); #endif - } - else if(!strncmp((char*)&Memory.ROM [0xffc0], "HU TENGAI MAKYO ZERO ", 21)) - { + } + else if (!strncmp((char*)&Memory.ROM [0xffc0], "HU TENGAI MAKYO ZERO ", 21)) + { #ifdef _XBOX - flog=fopen("T:\\feoezsp7.dat","rb"); + flog = fopen("T:\\feoezsp7.dat", "rb"); #else - flog=fopen("feoezsp7.dat","rb"); + flog = fopen("feoezsp7.dat", "rb"); #endif - } - else if(!strncmp((char*)&Memory.ROM [0xffc0], "JUMP TENGAIMAKYO ZERO",21)) - { + } + else if (!strncmp((char*)&Memory.ROM [0xffc0], "JUMP TENGAIMAKYO ZERO", 21)) + { #ifdef _XBOX - flog=fopen("T:\\sjumpsp7.dat","rb"); + flog = fopen("T:\\sjumpsp7.dat", "rb"); #else - flog=fopen("sjumpsp7.dat","rb"); + flog = fopen("sjumpsp7.dat", "rb"); #endif - } - else - { + } + else + { #ifdef _XBOX - flog=fopen("T:\\misc-sp7.dat","rb"); + flog = fopen("T:\\misc-sp7.dat", "rb"); #else - flog=fopen("misc-sp7.dat","rb"); + flog = fopen("misc-sp7.dat", "rb"); #endif - } - - if(flog) - { - uint8 buffer[8]; - int table=0; - uint16 offset=0; - uint16 length=0; - fseek(flog, 35,0); - - int f_len; - //do - while(1) - { - int 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(itableEnts[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++; - } - } - //while(!feof(flog)); - 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"); + } + + if (flog) + { + uint8 buffer[8]; + int table = 0; + uint16 offset = 0; + uint16 length = 0; + fseek(flog, 35, 0); + + int f_len; + //do + while (1) + { + int 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++; + } + } + //while(!feof(flog)); + 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"); + flog = fopen("spl4-sp7.dat", "wb"); #endif - } - else if(!strncmp((char*)&Memory.ROM [0xffc0], "MOMOTETSU HAPPY ",21)) - { + } + else if (!strncmp((char*)&Memory.ROM [0xffc0], "MOMOTETSU HAPPY ", 21)) + { #ifdef _XBOX - flog=fopen("T:\\smht-sp7.dat","wb"); + flog = fopen("T:\\smht-sp7.dat", "wb"); #else - flog=fopen("smht-sp7.dat","wb"); + flog = fopen("smht-sp7.dat", "wb"); #endif - } - else if(!strncmp((char*)&Memory.ROM [0xffc0], "HU TENGAI MAKYO ZERO ", 21)) - { + } + else if (!strncmp((char*)&Memory.ROM [0xffc0], "HU TENGAI MAKYO ZERO ", 21)) + { #ifdef _XBOX - flog=fopen("T:\\feoezsp7.dat","wb"); + flog = fopen("T:\\feoezsp7.dat", "wb"); #else - flog=fopen("feoezsp7.dat","wb"); + flog = fopen("feoezsp7.dat", "wb"); #endif - } - else if(!strncmp((char*)&Memory.ROM [0xffc0], "JUMP TENGAIMAKYO ZERO",21)) - { + } + else if (!strncmp((char*)&Memory.ROM [0xffc0], "JUMP TENGAIMAKYO ZERO", 21)) + { #ifdef _XBOX - flog=fopen("T:\\sjumpsp7.dat","wb"); + flog = fopen("T:\\sjumpsp7.dat", "wb"); #else - flog=fopen("sjumpsp7.dat","wb"); + flog = fopen("sjumpsp7.dat", "wb"); #endif - } - else - { + } + else + { #ifdef _XBOX - flog=fopen("T:\\misc-sp7.dat","wb"); + flog = fopen("T:\\misc-sp7.dat", "wb"); #else - flog=fopen("misc-sp7.dat","wb"); + flog = fopen("misc-sp7.dat", "wb"); #endif - } - //count entries - if(flog) - { - int j=0; - int temp=0; - for(j=0;jtableEnts[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;jtableEnts[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++) + { int 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); - } - } + 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); + } + } } -bool8 S9xSaveSPC7110RTC (S7RTC *rtc_f9) +bool8 S9xSaveSPC7110RTC(S7RTC* rtc_f9) { - FILE* fp; - - if((fp=fopen(S9xGetFilename(".rtc"), "wb"))==NULL) - return (FALSE); - int i=0; - uint8 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)rtc_f9->control; - fwrite(&temp,1,1,fp); - temp=(uint8)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); + FILE* fp; + + if ((fp = fopen(S9xGetFilename(".rtc"), "wb")) == NULL) + return (FALSE); + int i = 0; + uint8 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)rtc_f9->control; + fwrite(&temp, 1, 1, fp); + temp = (uint8)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); } -bool8 S9xLoadSPC7110RTC (S7RTC *rtc_f9) +bool8 S9xLoadSPC7110RTC(S7RTC* rtc_f9) { - FILE* fp; - - if((fp=fopen(S9xGetFilename(".rtc"), "rb"))==NULL) - return (FALSE); - int i; - for (i=0; i<16;i++) - { - fread(&(rtc_f9->reg[i]),1,1,fp); - } - uint8 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); + FILE* fp; + + if ((fp = fopen(S9xGetFilename(".rtc"), "rb")) == NULL) + return (FALSE); + int i; + for (i = 0; i < 16; i++) + fread(&(rtc_f9->reg[i]), 1, 1, fp); + uint8 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); } -- cgit v1.2.3