📄 dsp1.cpp
字号:
{ 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 + -