aboutsummaryrefslogtreecommitdiff
path: root/source/spc7110.cpp
diff options
context:
space:
mode:
authoraliaspider2014-10-29 05:36:07 +0100
committeraliaspider2014-10-29 05:36:07 +0100
commita6dc7abc9b8cc3986eda5a84141da7dc9e4e8f1a (patch)
tree6f82417b0ab41f3887dd025ee3b85254e28143da /source/spc7110.cpp
parent1d98e1c317fa19687ae6bc3cb8e550ef7531bf02 (diff)
downloadsnes9x2005-a6dc7abc9b8cc3986eda5a84141da7dc9e4e8f1a.tar.gz
snes9x2005-a6dc7abc9b8cc3986eda5a84141da7dc9e4e8f1a.tar.bz2
snes9x2005-a6dc7abc9b8cc3986eda5a84141da7dc9e4e8f1a.zip
start moving everything to C
Diffstat (limited to 'source/spc7110.cpp')
-rw-r--r--source/spc7110.cpp2285
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);
-}
-