1 #include <stdio.h>
2 # include <stdlib.h>
3 # include <string.h>
4 #ifdef _MSC_VER
5 #include <direct.h>
6 #else
7 #include <unistd.h>
8 #endif
9 
10 #include <encodings/crc32.h>
11 
12 #include "gles2N64.h"
13 #include "GBI.h"
14 #include "RDP.h"
15 #include "RSP.h"
16 #include "F3D.h"
17 #include "F3DEX.h"
18 #include "F3DEX2.h"
19 #include "L3D.h"
20 #include "L3DEX.h"
21 #include "L3DEX2.h"
22 #include "S2DEX.h"
23 #include "S2DEX2.h"
24 #include "F3DDKR.h"
25 #include "F3DSWSE.h"
26 #include "F3DWRUS.h"
27 #include "F3DPD.h"
28 #include "F3DEX2CBFD.h"
29 #include "ZSort.h"
30 # include "convert.h"
31 #include "Common.h"
32 
33 #include "CRC.h"
34 #include "Debug.h"
35 
36 #define uc_crc gln64uc_crc
37 
38 uint32_t uc_crc, uc_dcrc;
39 char uc_str[256];
40 
41 SpecialMicrocodeInfo specialMicrocodes[] =
42 {
43 	{ F3D,		false,	0xe62a706d, "Fast3D" },
44 	{ F3D,		false,	0x7d372819, "Fast3D" },
45 	{ F3D,		false,	0x2edee7be, "Fast3D" },
46 	{ F3D,		false,	0xe01e14be, "Fast3D" },
47    { F3D,		false,	0x4AED6B3B, "Fast3D" }, /* Vivid Dolls [ALECK64] */
48 
49 	{ F3DWRUS,	false,	0xd17906e2, "RSP SW Version: 2.0D, 04-01-96" },
50 	{ F3DSWSE,	false,	0x94c4c833, "RSP SW Version: 2.0D, 04-01-96" },
51 	{ F3DEX,	true,	0x637b4b58, "RSP SW Version: 2.0D, 04-01-96" },
52 	{ F3D,		true,	0x54c558ba, "RSP SW Version: 2.0D, 04-01-96" }, // Pilot Wings
53    { F3D,		true,	0x302bca09, "RSP SW Version: 2.0G, 09-30-96" }, // GoldenEye
54 
55 	{ S2DEX,	false,	0x9df31081, "RSP Gfx ucode S2DEX  1.06 Yoshitaka Yasumoto Nintendo." },
56 
57 	{ F3DDKR,	false,	0x8d91244f, "Diddy Kong Racing" },
58 	{ F3DDKR,	false,	0x6e6fc893, "Diddy Kong Racing" },
59 	{ F3DJFG,	false,	0xbde9d1fb, "Jet Force Gemini" },
60 	{ F3DPD,	true,	0x1c4f7869, "Perfect Dark" },
61 	{ Turbo3D,	false,	0x2bdcfc8a, "Turbo3D" },
62 	{ F3DEX2CBFD, true, 0x1b4ace88, "Conker's Bad Fur Day" }
63 };
64 
65 uint32_t G_RDPHALF_1, G_RDPHALF_2, G_RDPHALF_CONT;
66 uint32_t G_SPNOOP;
67 uint32_t G_SETOTHERMODE_H, G_SETOTHERMODE_L;
68 uint32_t G_DL, G_ENDDL, G_CULLDL, G_BRANCH_Z;
69 uint32_t G_LOAD_UCODE;
70 uint32_t G_MOVEMEM, G_MOVEWORD;
71 uint32_t G_MTX, G_POPMTX;
72 uint32_t G_GEOMETRYMODE, G_SETGEOMETRYMODE, G_CLEARGEOMETRYMODE;
73 uint32_t G_TEXTURE;
74 uint32_t G_DMA_IO, G_DMA_DL, G_DMA_TRI, G_DMA_MTX, G_DMA_VTX, G_DMA_TEX_OFFSET, G_DMA_OFFSETS;
75 uint32_t G_SPECIAL_1, G_SPECIAL_2, G_SPECIAL_3;
76 uint32_t G_VTX, G_MODIFYVTX, G_VTXCOLORBASE;
77 uint32_t G_TRI1, G_TRI2, G_TRI4;
78 uint32_t G_QUAD, G_LINE3D;
79 uint32_t G_RESERVED0, G_RESERVED1, G_RESERVED2, G_RESERVED3;
80 uint32_t G_SPRITE2D_BASE;
81 uint32_t G_BG_1CYC, G_BG_COPY;
82 uint32_t G_OBJ_RECTANGLE, G_OBJ_SPRITE, G_OBJ_MOVEMEM;
83 uint32_t G_SELECT_DL, G_OBJ_RENDERMODE, G_OBJ_RECTANGLE_R;
84 uint32_t G_OBJ_LOADTXTR, G_OBJ_LDTX_SPRITE, G_OBJ_LDTX_RECT, G_OBJ_LDTX_RECT_R;
85 uint32_t G_RDPHALF_0;
86 
87 /* TODO/FIXME - remove? */
88 uint32_t G_TRI_UNKNOWN;
89 
90 uint32_t G_MTX_STACKSIZE;
91 uint32_t G_MTX_MODELVIEW;
92 uint32_t G_MTX_PROJECTION;
93 uint32_t G_MTX_MUL;
94 uint32_t G_MTX_LOAD;
95 uint32_t G_MTX_NOPUSH;
96 uint32_t G_MTX_PUSH;
97 
98 uint32_t G_TEXTURE_ENABLE;
99 uint32_t G_SHADING_SMOOTH;
100 uint32_t G_CULL_FRONT;
101 uint32_t G_CULL_BACK;
102 uint32_t G_CULL_BOTH;
103 uint32_t G_CLIPPING;
104 
105 uint32_t G_MV_VIEWPORT;
106 
107 uint32_t G_MWO_aLIGHT_1, G_MWO_bLIGHT_1;
108 uint32_t G_MWO_aLIGHT_2, G_MWO_bLIGHT_2;
109 uint32_t G_MWO_aLIGHT_3, G_MWO_bLIGHT_3;
110 uint32_t G_MWO_aLIGHT_4, G_MWO_bLIGHT_4;
111 uint32_t G_MWO_aLIGHT_5, G_MWO_bLIGHT_5;
112 uint32_t G_MWO_aLIGHT_6, G_MWO_bLIGHT_6;
113 uint32_t G_MWO_aLIGHT_7, G_MWO_bLIGHT_7;
114 uint32_t G_MWO_aLIGHT_8, G_MWO_bLIGHT_8;
115 
116 GBIInfo GBI;
117 
118 static uint32_t current_type;
119 
GBI_GetCurrentMicrocodeType(void)120 uint32_t GBI_GetCurrentMicrocodeType(void)
121 {
122    return current_type;
123 }
124 
GBI_Unknown(uint32_t w0,uint32_t w1)125 void GBI_Unknown( uint32_t w0, uint32_t w1 )
126 {
127 #ifdef DEBUG
128 	if (Debug.level == DEBUG_LOW)
129 		DebugMsg( DEBUG_LOW | DEBUG_UNKNOWN, "UNKNOWN GBI COMMAND 0x%02X", _SHIFTR( w0, 24, 8 ) );
130 	if (Debug.level == DEBUG_MEDIUM)
131 		DebugMsg( DEBUG_MEDIUM | DEBUG_UNKNOWN, "Unknown GBI Command 0x%02X", _SHIFTR( w0, 24, 8 ) );
132 	else if (Debug.level == DEBUG_HIGH)
133 		DebugMsg( DEBUG_HIGH | DEBUG_UNKNOWN, "// Unknown GBI Command 0x%02X", _SHIFTR( w0, 24, 8 ) );
134 #endif
135 }
136 
MicrocodeDialog(void)137 static int MicrocodeDialog(void)
138 {
139     return 0;
140 }
141 
GBI_AddMicrocode(void)142 MicrocodeInfo *GBI_AddMicrocode(void)
143 {
144     MicrocodeInfo *newtop = (MicrocodeInfo*)malloc( sizeof( MicrocodeInfo ) );
145 
146     newtop->lower = GBI.top;
147     newtop->higher = NULL;
148 
149     if (GBI.top)
150         GBI.top->higher = newtop;
151 
152     if (!GBI.bottom)
153         GBI.bottom = newtop;
154 
155     GBI.top = newtop;
156 
157     GBI.numMicrocodes++;
158 
159 
160     return newtop;
161 }
162 
GBI_Init(void)163 void GBI_Init(void)
164 {
165    uint32_t i;
166    GBI.top = NULL;
167    GBI.bottom = NULL;
168    GBI.current = NULL;
169    GBI.numMicrocodes = 0;
170 
171    for (i = 0; i <= 0xFF; i++)
172       GBI.cmd[i] = GBI_Unknown;
173 }
174 
GBI_Destroy(void)175 void GBI_Destroy(void)
176 {
177    while (GBI.bottom)
178    {
179       MicrocodeInfo *newBottom = GBI.bottom->higher;
180 
181       if (GBI.bottom == GBI.top)
182          GBI.top = NULL;
183 
184       free( GBI.bottom );
185 
186       GBI.bottom = newBottom;
187 
188       if (GBI.bottom)
189          GBI.bottom->lower = NULL;
190 
191       GBI.numMicrocodes--;
192    }
193 }
194 
_isDigit(char _c)195 static INLINE bool _isDigit(char _c)
196 {
197 	return _c >= '0' && _c <= '9';
198 }
199 
GBI_DetectMicrocode(uint32_t uc_start,uint32_t uc_dstart,uint16_t uc_dsize)200 MicrocodeInfo *GBI_DetectMicrocode( uint32_t uc_start, uint32_t uc_dstart, uint16_t uc_dsize )
201 {
202    unsigned i;
203    char uc_data[2048];
204    MicrocodeInfo *current;
205 
206    for (i = 0; i < GBI.numMicrocodes; i++)
207    {
208       current = GBI.top;
209 
210       while (current)
211       {
212          if ((current->address == uc_start) && (current->dataAddress == uc_dstart) && (current->dataSize == uc_dsize))
213             return current;
214 
215          current = current->lower;
216       }
217    }
218 
219    current = GBI_AddMicrocode();
220 
221    current->address = uc_start;
222    current->dataAddress = uc_dstart;
223    current->dataSize = uc_dsize;
224    current->NoN = false;
225    current->type = NONE;
226 
227    // See if we can identify it by CRC
228    uc_crc = encoding_crc32(0xffffffff, &gfx_info.RDRAM[uc_start & 0x1FFFFFFF], 4096);
229    LOG(LOG_MINIMAL, "UCODE CRC=0x%x\n", uc_crc);
230 
231    for (i = 0; i < sizeof( specialMicrocodes ) / sizeof( SpecialMicrocodeInfo ); i++)
232    {
233       if (uc_crc == specialMicrocodes[i].crc)
234       {
235          current->type = specialMicrocodes[i].type;
236          current_type  = current->type;
237          return current;
238       }
239    }
240 
241    // See if we can identify it by text
242    UnswapCopyWrap(gfx_info.RDRAM, uc_dstart & 0x1FFFFFFF, (uint8_t*)uc_data, 0, 0x7FF, 2048);
243    strcpy( uc_str, "Not Found" );
244 
245    for (i = 0; i < 2048; i++)
246    {
247       if ((uc_data[i] == 'R') && (uc_data[i+1] == 'S') && (uc_data[i+2] == 'P'))
248       {
249          uint32_t j = 0;
250          int type = NONE;
251 
252          while (uc_data[i+j] > 0x0A)
253          {
254             uc_str[j] = uc_data[i+j];
255             j++;
256          }
257 
258          uc_str[j] = 0x00;
259 
260          if (strncmp( &uc_str[4], "SW", 2 ) == 0)
261             type = F3D;
262          else if (strncmp( &uc_str[4], "Gfx", 3 ) == 0)
263          {
264             current->NoN = (strncmp( &uc_str[20], ".NoN", 4 ) == 0);
265 
266             if (strncmp( &uc_str[14], "F3D", 3 ) == 0)
267             {
268 					if (uc_str[28] == '1' || strncmp(&uc_str[28], "0.95", 4) == 0 || strncmp(&uc_str[28], "0.96", 4) == 0)
269 						type = F3DEX;
270 					else if (uc_str[31] == '2')
271 						type = F3DEX2;
272             }
273             else if (strncmp( &uc_str[14], "L3D", 3 ) == 0)
274             {
275 					uint32_t t = 22;
276 					while (!_isDigit(uc_str[t]) && t++ < j);
277 					if (uc_str[t] == '1')
278 						type = L3DEX;
279 					else if (uc_str[t] == '2')
280 						type = L3DEX2;
281             }
282             else if (strncmp( &uc_str[14], "S2D", 3 ) == 0)
283             {
284 					uint32_t t = 20;
285 					while (!_isDigit(uc_str[t]) && t++ < j);
286 					if (uc_str[t] == '1')
287 						type = S2DEX;
288 					else if (uc_str[t] == '2')
289 						type = S2DEX2;
290             }
291 				else if (strncmp(&uc_str[14], "ZSortp", 6) == 0)
292 					type = ZSortp;
293          }
294 
295          LOG(LOG_VERBOSE, "UCODE STRING=%s\n", uc_str);
296 
297          if (type != NONE)
298          {
299             current->type = type;
300             current_type = type;
301             return current;
302          }
303 
304          break;
305       }
306    }
307 
308 
309    for (i = 0; i < sizeof( specialMicrocodes ) / sizeof( SpecialMicrocodeInfo ); i++)
310    {
311       if (strcmp( uc_str, specialMicrocodes[i].text ) == 0)
312       {
313          current->type = specialMicrocodes[i].type;
314          current_type = current->type;
315          return current;
316       }
317    }
318 
319    // Let the user choose the microcode
320    LOG(LOG_ERROR, "[gles2n64]: Warning - unknown ucode!!!\n");
321    if(last_good_ucode != (uint32_t)-1)
322       current->type=last_good_ucode;
323    else
324       current->type = MicrocodeDialog();
325    current_type = current->type;
326    return current;
327 }
328 
GBI_MakeCurrent(MicrocodeInfo * current)329 void GBI_MakeCurrent( MicrocodeInfo *current )
330 {
331    int i;
332    if (current != GBI.top)
333    {
334       if (current == GBI.bottom)
335       {
336          GBI.bottom = current->higher;
337          GBI.bottom->lower = NULL;
338       }
339       else
340       {
341          current->higher->lower = current->lower;
342          current->lower->higher = current->higher;
343       }
344 
345       current->higher = NULL;
346       current->lower = GBI.top;
347       GBI.top->higher = current;
348       GBI.top = current;
349    }
350 
351    if (!GBI.current || (GBI.current->type != current->type))
352    {
353 
354       for (i = 0; i <= 0xFF; i++)
355          GBI.cmd[i] = GBI_Unknown;
356 
357       RDP_Init();
358       switch (current->type)
359       {
360          case F3D:       F3D_Init();     break;
361          case F3DEX:     F3DEX_Init();   break;
362          case F3DEX2:    F3DEX2_Init();  break;
363          case L3D:       L3D_Init();     break;
364          case L3DEX:     L3DEX_Init();   break;
365          case L3DEX2:    L3DEX2_Init();  break;
366          case S2DEX:     S2DEX_Init();   break;
367          case S2DEX2:    S2DEX2_Init();  break;
368          case F3DDKR:    F3DDKR_Init();  break;
369 			case F3DJFG:	 F3DJFG_Init();	break;
370 			case F3DSWSE:	 F3DSWSE_Init();	break;
371          case F3DWRUS:   F3DWRUS_Init(); break;
372          case F3DPD:     F3DPD_Init();   break;
373 			case Turbo3D:	F3D_Init();		break;
374 			case ZSortp:	ZSort_Init();	break;
375 			case F3DEX2CBFD:F3DEX2CBFD_Init(); break;
376       }
377 
378 #ifdef NEW
379 		if (current->NoN)
380       {
381          // Disable near and far plane clipping
382          glEnable(GL_DEPTH_CLAMP);
383          // Enable Far clipping plane in vertex shader
384          glEnable(GL_CLIP_DISTANCE0);
385       } else {
386 			glDisable(GL_DEPTH_CLAMP);
387 			glDisable(GL_CLIP_DISTANCE0);
388 		}
389 #endif
390    }
391 #ifdef NEW
392    else if (current->NoN != current->NoN)
393    {
394 		if (current->NoN) {
395 			// Disable near and far plane clipping
396 			glEnable(GL_DEPTH_CLAMP);
397 			// Enable Far clipping plane in vertex shader
398 			glEnable(GL_CLIP_DISTANCE0);
399 		}
400 		else {
401 			glDisable(GL_DEPTH_CLAMP);
402 			glDisable(GL_CLIP_DISTANCE0);
403 		}
404 	}
405 #endif
406 
407    GBI.current = current;
408 }
409