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