diff options
author | aliaspider | 2014-10-29 05:36:07 +0100 |
---|---|---|
committer | aliaspider | 2014-10-29 05:36:07 +0100 |
commit | a6dc7abc9b8cc3986eda5a84141da7dc9e4e8f1a (patch) | |
tree | 6f82417b0ab41f3887dd025ee3b85254e28143da /source/spc7110.cpp | |
parent | 1d98e1c317fa19687ae6bc3cb8e550ef7531bf02 (diff) | |
download | snesemu-a6dc7abc9b8cc3986eda5a84141da7dc9e4e8f1a.tar.gz snesemu-a6dc7abc9b8cc3986eda5a84141da7dc9e4e8f1a.tar.bz2 snesemu-a6dc7abc9b8cc3986eda5a84141da7dc9e4e8f1a.zip |
start moving everything to C
Diffstat (limited to 'source/spc7110.cpp')
-rw-r--r-- | source/spc7110.cpp | 2285 |
1 files changed, 0 insertions, 2285 deletions
diff --git a/source/spc7110.cpp b/source/spc7110.cpp deleted file mode 100644 index 3ae0cfd..0000000 --- a/source/spc7110.cpp +++ /dev/null @@ -1,2285 +0,0 @@ -/******************************************************************************* - Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - - (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and - Jerremy Koot (jkoot@snes9x.com) - - (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net) - - (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net), - funkyass (funkyass@spam.shaw.ca), - Joel Yliluoma (http://iki.fi/bisqwit/) - Kris Bleakley (codeviolation@hotmail.com), - Matthew Kendora, - Nach (n-a-c-h@users.sourceforge.net), - Peter Bortas (peter@bortas.org) and - zones (kasumitokoduck@yahoo.com) - - C4 x86 assembler and some C emulation code - (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), - _Demo_ (_demo_@zsnes.com), and Nach - - C4 C++ code - (c) Copyright 2003 Brad Jorsch - - DSP-1 emulator code - (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, - John Weidman, neviksti (neviksti@hotmail.com), - Kris Bleakley, Andreas Naive - - DSP-2 emulator code - (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and - Lord Nightmare (lord_nightmare@users.sourceforge.net - - OBC1 emulator code - (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and - Kris Bleakley - Ported from x86 assembler to C by sanmaiwashi - - SPC7110 and RTC C++ emulator code - (c) Copyright 2002 Matthew Kendora with research by - zsKnight, John Weidman, and Dark Force - - 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 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) - - - 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. -*******************************************************************************/ - -#include "spc7110.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 -#define FREEZEFOLDER GUI.FreezeFileDir -//zinx suggested this, for *nix compatibility -#define PATH_MAX MAX_PATH -#else // Unix -#include "display.h" -#include <limits.h> -#include <unistd.h> -#define FREEZEFOLDER S9xGetSnapshotDirectory () -#endif - -extern "C" const char *S9xGetFilename (const char *); -extern "C" 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 - -//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 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 SPC7110DecompressionLocationStruct -{ - 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]; -} 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; -} 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 - -//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); -} - - -//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(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"); -#else - 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); - } -} - - -//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() -{ - 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(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(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); - } - } -} - -extern "C"{ -//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=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=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) -{ - 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(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: - Memory.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 - } -} -extern "C"{ -//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; - return 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 */ -/**********************************************************************************************/ -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; -} - - -#define DAYTICKS (60*60*24) -#define HOURTICKS (60*60) -#define MINUTETICKS 60 - - -/**********************************************************************************************/ -/* S9xUpdateRTC() */ -/* Advance the RTC time */ -/**********************************************************************************************/ - -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; - } - } -} -extern "C"{ - -//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; - return &ROM[i]; -} -//end extern -} - -//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 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; - - decompack=new Pack7110; - -#ifndef _XBOX - getcwd(temp_path,PATH_MAX); -#endif - - ZeroMemory(decompack, sizeof(Pack7110)); - -#ifndef _XBOX - if(-1==chdir(dirname)) - { - S9xMessage(0,0,"Graphics Pack not found!"); - } -#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]=new uint8[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; -#ifdef __WIN32__ - #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; - - decompack=new Pack7110; - -#ifndef _XBOX - getcwd(temp_path,PATH_MAX); -#endif - - ZeroMemory(decompack, sizeof(Pack7110)); - -#ifndef _XBOX - if(-1==chdir(dirname)) - { - S9xMessage(0,0,"Graphics Pack not found!"); - } -#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(); - -#ifndef _XBOX - chdir(temp_path); -#endif - - Copy7110=&ReadPackData; - CleanUp7110=&Close7110Gfx; - -#ifdef __WIN32__ - #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; - - decompack=new Pack7110; - -#ifndef _XBOX - getcwd(temp_path,PATH_MAX); -#endif - - int32 buffer_size=1024*1024*cacheMegs;//*some setting - - ZeroMemory(decompack, sizeof(Pack7110)); -#ifndef _XBOX - - if(-1==chdir(dirname)) - { - S9xMessage(0,0,"Graphics Pack not found!"); - } -#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]=new uint8[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); -#endif - - Copy7110=&GetPackData; - CleanUp7110=&Drop7110Gfx; - - -#ifdef __WIN32__ - #ifndef _XBOX - EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_ENABLED); - #endif -#endif -} - -//Cache 1 clean up function -void Del7110Gfx() -{ - int i; - if(Settings.SPC7110) - { -#ifdef __WIN32__ - #ifndef _XBOX - EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_GRAYED); - #endif -#endif - Do7110Logging(); - } - for(i=0;i<MAX_TABLES;i++) - { - if(decompack->binfiles[i]!=NULL) - { - delete []decompack->binfiles[i]; - decompack->binfiles[i]=NULL; - } - } - Settings.SPC7110=false; - Settings.SPC7110RTC=false; - if(NULL!=decompack) - delete decompack; - decompack=NULL; - CleanUp7110=NULL; - Copy7110=NULL; -} - -//Cache2 cleanup function -void Close7110Gfx() -{ - int i; - if(Settings.SPC7110) - { -#ifdef __WIN32__ - #ifndef _XBOX - EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_GRAYED); - #endif -#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) - delete decompack; - decompack=NULL; - CleanUp7110=NULL; - Copy7110=NULL; -} - -//cache 3's clean-up code -void Drop7110Gfx() -{ - int i; - if(Settings.SPC7110) - { -#ifdef __WIN32__ - #ifndef _XBOX - EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_GRAYED); - #endif -#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 - { - delete []decompack->binfiles[i]; - decompack->binfiles[i]=NULL; - } - } - } - Settings.SPC7110=false; - Settings.SPC7110RTC=false; - if(NULL!=decompack) - delete decompack; - 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); -} - - -//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() -{ - 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"); -#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 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"); -#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) - { - int j=0; - int temp=0; - for(j=0;j<MAX_TABLES;j++) - { - for(int 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++) - { - for(int 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) -{ - 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) -{ - FILE* fp; - - if((fp=fopen(S9xGetFilename(".rtc"), "rb"))==NULL) - return (FALSE); - for (int 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); -} - |