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

📄 dsp1.cpp

📁 SFC游戏模拟器 snes9x 1.43 的原代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		{			DSP1.command = byte;			DSP1.in_index = 0;			DSP1.waiting4command = FALSE;//			DSP1.first_parameter = TRUE;//			printf("Op%02X\n",byte);			switch (byte)			{			case 0x01:DSP1.in_count=32;break;			case 0x03:DSP1.in_count=1;break;			case 0x05:DSP1.in_count=1;break;			case 0x09:DSP1.in_count=4;break;			case 0x06:DSP1.in_count=1;break;			case 0x0D:DSP1.in_count=2;break;			default:				printf("Op%02X\n",byte);			case 0x0f:DSP1.in_count=0;break;			}		}		else		{			DSP1.parameters [DSP1.in_index] = byte;//			DSP1.first_parameter = FALSE;			DSP1.in_index++;		}				if (DSP1.in_count==DSP1.in_index)		{			//DSP1.parameters [DSP1.in_index] |= (byte << 8);			// Actually execute the command			DSP1.waiting4command = TRUE;			DSP1.out_index = 0;			switch (DSP1.command)			{			case 0x0D:				if(DSP2Op0DHasLen)				{					DSP2Op0DHasLen=false;					DSP1.out_count=DSP2Op0DOutLen;					//execute Op5					DSP2_Op0D();				}				else				{					DSP2Op0DInLen=DSP1.parameters[0];					DSP2Op0DOutLen=DSP1.parameters[1];					DSP1.in_index=0;					DSP1.in_count=(DSP2Op0DInLen+1)>>1;					DSP2Op0DHasLen=true;					if(byte)						DSP1.waiting4command=false;				}				break;			case 0x06:				if(DSP2Op06HasLen)				{					DSP2Op06HasLen=false;					DSP1.out_count=DSP2Op06Len;					//execute Op5					DSP2_Op06();				}				else				{					DSP2Op06Len=DSP1.parameters[0];					DSP1.in_index=0;					DSP1.in_count=DSP2Op06Len;					DSP2Op06HasLen=true;					if(byte)						DSP1.waiting4command=false;				}				break;			case 0x01:				DSP1.out_count=32;				DSP2_Op01();				break;			case 0x09:				// Multiply - don't yet know if this is signed or unsigned				DSP2Op09Word1 = DSP1.parameters[0] | (DSP1.parameters[1]<<8);                DSP2Op09Word2 = DSP1.parameters[2] | (DSP1.parameters[3]<<8);				DSP1.out_count=4;#ifdef FAST_LSB_WORD_ACCESS                *(uint32 *)DSP1.output = DSP2Op09Word1 * DSP2Op09Word2;#else				uint32 temp;				temp=DSP2Op09Word1 * DSP2Op09Word2;				DSP1.output[0]=temp&0xFF;				DSP1.output[1]=(temp>>8)&0xFF;				DSP1.output[2]=(temp>>16)&0xFF;				DSP1.output[3]=(temp>>24)&0xFF;#endif				break;			case 0x05:				if(DSP2Op05HasLen)				{					DSP2Op05HasLen=false;					DSP1.out_count=DSP2Op05Len;					//execute Op5					DSP2_Op05();				}				else				{					DSP2Op05Len=DSP1.parameters[0];					DSP1.in_index=0;					DSP1.in_count=2*DSP2Op05Len;					DSP2Op05HasLen=true;					if(byte)						DSP1.waiting4command=false;				}				break;			case 0x03:				DSP2Op05Transparent= DSP1.parameters[0];				//DSP2Op03();				break;			case 0x0f:				default:					break;			}		}	}}uint8 DSP2GetByte(uint16 address){	uint8 t;    if ((address & 0xf000) == 0x6000 ||		(address >= 0x8000 && address < 0xc000))    {		if (DSP1.out_count)		{			t = (uint8) DSP1.output [DSP1.out_index];			DSP1.out_index++;			if(DSP1.out_count==DSP1.out_index)				DSP1.out_count=0;		}		else		{			t = 0xff;		}    }    else t = 0x80;	return t;}struct SDSP4 {    bool8 waiting4command;    bool8 half_command;    uint16 command;    uint32 in_count;    uint32 in_index;    uint32 out_count;    uint32 out_index;    uint8 parameters [512];    uint8 output [512];};SDSP4 DSP4;#include "dsp4emu.cpp"bool DSP4_init=FALSE;void DSP4SetByte(uint8 byte, uint16 address){	if(!DSP4_init)	{		// bootup		DSP4.waiting4command=1;		DSP4_init=TRUE;	}	if ((address & 0xf000) == 0x6000 ||			(address >= 0x8000 && address < 0xc000))	{		if(DSP4.out_index<DSP4.out_count)		{			DSP4.out_index++;			return;		}		if (DSP4.waiting4command)		{			if(DSP4.half_command)			{				DSP4.command |= (byte<<8);				DSP4.in_index = 0;				DSP4.waiting4command = FALSE;	//			DSP4.first_parameter = TRUE;				DSP4.half_command=0;				DSP4.out_count=0;				DSP4.out_index=0;				DSP4_Logic=0;				switch (DSP4.command)				{				case 0x0000:DSP4.in_count=4;break;				case 0x0001:DSP4.in_count=36;break;				case 0x0003:DSP4.in_count=0;break;				case 0x0005:DSP4.in_count=0;break;				case 0x0006:DSP4.in_count=0;break;				case 0x0007:DSP4.in_count=22;break;				case 0x0008:DSP4.in_count=72;break;				case 0x0009:DSP4.in_count=14;break;				case 0x000A:DSP4.in_count=6;break;				case 0x000B:DSP4.in_count=6;break;				case 0x000D:DSP4.in_count=34;break;				case 0x000E:DSP4.in_count=0;break;				case 0x0011:DSP4.in_count=8;break;				default:					DSP4.waiting4command=TRUE;					//printf("(line %d) Unknown Op%02X\n",line,DSP4.command);					break;				}			}			else			{				DSP4.command=byte;				DSP4.half_command=1;			}		}		else		{			DSP4.parameters [DSP4.in_index] = byte;//			DSP4.first_parameter = FALSE;			DSP4.in_index++;		}				if (!DSP4.waiting4command && DSP4.in_count==DSP4.in_index)
		{
			//DSP4.parameters [DSP4.in_index] |= (byte << 8);
			// Actually execute the command
			DSP4.waiting4command = TRUE;
			DSP4.out_index = 0;
			DSP4.in_index=0;
			switch (DSP4.command)
			{
			// 16-bit multiplication
			case 0x0000:
				{
					int16 multiplier, multiplicand;
					int product;
					
					multiplier = DSP4_READ_WORD(0);
					multiplicand = DSP4_READ_WORD(2);

					DSP4_Multiply(multiplicand,multiplier,product);

					DSP4.out_count = 4;
					DSP4_WRITE_WORD(0,product);
					DSP4_WRITE_WORD(2,product>>16);
				}
				break;

			// unknown: horizontal mapping command
			case 0x0011:
				{
					int16 a,b,c,d,m;

					a = DSP4_READ_WORD(6);
					b = DSP4_READ_WORD(4);
					c = DSP4_READ_WORD(2);
					d = DSP4_READ_WORD(0);

					DSP4_UnknownOP11(a,b,c,d,m);

					DSP4.out_count = 2;
					DSP4_WRITE_WORD(0,m);
					break;
				}

			// track projection
			case 0x0001: DSP4_Op01(); break;

			// track projection (pass 2)
			case 0x0007: DSP4_Op07(); break;

			// zone projections (fuel/repair/lap/teleport/...)
			case 0x0008: DSP4_Op08(); break;

			// sprite transformation
			case 0x0009: DSP4_Op09(); break;

			// fast track projection
			case 0x000D: DSP4_Op0D(); break;

			// single-player selection
			case 0x0003: DSP4_Op03(); break;

			// clear OAM
			case 0x0005:
				{
					op06_index = 0;
					op06_offset = 0;
					for( int lcv=0; lcv<32; lcv++ )
						op06_OAM[lcv] = 0;
					break;
				}

			// multi-player selection
			case 0x000E: DSP4_Op0E(); break;

#undef PRINT

			// transfer OAM
			case 0x0006:
				{
					DSP4.out_count = 32;
					for( int lcv=0; lcv<32; lcv++ )
						DSP4.output[lcv] = op06_OAM[lcv];
				}
				break;

			// unknown
			case 0x000A:
				{
					int16 in1a = DSP4_READ_WORD(0);
					int16 in2a = DSP4_READ_WORD(2);
					int16 in3a = DSP4_READ_WORD(4);
					int16 out1a,out2a,out3a,out4a;

					// NOTE: Snes9x only!
					// For some odd reason, the input nybbles are reversed

					DSP4_Op0A(in2a,out1a,out2a,out3a,out4a);

					DSP4.out_count=8;

					// Hack: Reverse the outputs for now to compensate
					//       Otherwise the AI gets really flaky
					DSP4_WRITE_WORD(0,out2a);
					DSP4_WRITE_WORD(2,out1a);
					DSP4_WRITE_WORD(4,out4a);
					DSP4_WRITE_WORD(6,out3a);
				}
				break;

			// set OAM
			case 0x000B:
				{
					int16 sp_x = DSP4_READ_WORD(0);
					int16 sp_y = DSP4_READ_WORD(2);
					int16 oam = DSP4_READ_WORD(4);

					if ((sp_y < 0) || ((sp_y & 0x01ff) < 0x00eb))
					{
						short Row = (sp_y >> 3) & 0x1f;

						if (RowCount[Row] < MaxTilesPerRow)
						{
							RowCount[Row]++;

							// yield OAM output
							DSP4.out_count = 6;
							DSP4_WRITE_WORD(0,1);

							// pack OAM data: x,y,name,attr
							DSP4.output[2] = sp_x & 0xff;
							DSP4.output[3] = sp_y & 0xff;
							DSP4_WRITE_WORD(4,oam);

							// OAM: size,msb data
							DSP4_Op06(0,0);
						}
					}
				}
				break;
			
			default: break;
			}		}	}}uint8 DSP4GetByte(uint16 address){	uint8 t;	if ((address & 0xf000) == 0x6000 ||			(address >= 0x8000 && address < 0xc000))	{		if (DSP4.out_count)		{			t = (uint8) DSP4.output [DSP4.out_index];			DSP4.out_index++;			if(DSP4.out_count==DSP4.out_index)				DSP4.out_count=0;		}		else			t = 0xff;	}	else	{		t = 0x80;	}	return t;}

⌨️ 快捷键说明

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