⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spc7110.cpp

📁 SFC游戏模拟器 snes9x 1.43 的原代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
						{							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;	do	{		i=0;		fread(buffer, 1, 12,fp);		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 functionvoid 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)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -