GLES2N64: Added WIP fix for CBFD from mupen64plus-ae
[mupen64plus-pandora.git] / source / gles2n64 / src / GBI.cpp
CommitLineData
34cf4058 1#include <stdio.h>
2#include <unistd.h>
3#include <stdlib.h>
4#include "gles2N64.h"
5#include "GBI.h"
6#include "RDP.h"
7#include "RSP.h"
8#include "F3D.h"
9#include "F3DEX.h"
10#include "F3DEX2.h"
11#include "L3D.h"
12#include "L3DEX.h"
13#include "L3DEX2.h"
14#include "S2DEX.h"
15#include "S2DEX2.h"
16#include "F3DDKR.h"
17#include "F3DWRUS.h"
18#include "F3DPD.h"
19#include "F3DCBFD.h"
20#include "Types.h"
21# include <string.h>
22# include <unistd.h>
23# include <stdlib.h>
24# include "convert.h"
25#include "Common.h"
26#include "ticks.h"
27
28#include "CRC.h"
29#include "Debug.h"
30
31u32 uc_crc, uc_dcrc;
32char uc_str[256];
33
34SpecialMicrocodeInfo specialMicrocodes[] =
35{
36 {F3DWRUS, FALSE, 0xd17906e2, "RSP SW Version: 2.0D, 04-01-96"},
37 {F3DWRUS, FALSE, 0x94c4c833, "RSP SW Version: 2.0D, 04-01-96"},
38 {S2DEX, FALSE, 0x9df31081, "RSP Gfx ucode S2DEX 1.06 Yoshitaka Yasumoto Nintendo."},
39 {F3DDKR, FALSE, 0x8d91244f, "Diddy Kong Racing"},
40 {F3DDKR, FALSE, 0x6e6fc893, "Diddy Kong Racing"},
41 {F3DDKR, FALSE, 0xbde9d1fb, "Jet Force Gemini"},
42 {F3DPD, FALSE, 0x1c4f7869, "Perfect Dark"},
43 {F3DEX, FALSE, 0x0ace4c3f, "Mario Kart"},
44 //{F3DEX, FALSE, 0xda51ccdb, "Rogue Squadron"},
1f4ee9e9 45 {F3DCBFD, FALSE, 0x1b4ace88, "RSP Gfx ucode F3DEXBG.NoN fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo."},
34cf4058 46};
47
48u32 G_RDPHALF_1, G_RDPHALF_2, G_RDPHALF_CONT;
49u32 G_SPNOOP;
50u32 G_SETOTHERMODE_H, G_SETOTHERMODE_L;
51u32 G_DL, G_ENDDL, G_CULLDL, G_BRANCH_Z;
52u32 G_LOAD_UCODE;
53u32 G_MOVEMEM, G_MOVEWORD;
54u32 G_MTX, G_POPMTX;
55u32 G_GEOMETRYMODE, G_SETGEOMETRYMODE, G_CLEARGEOMETRYMODE;
56u32 G_TEXTURE;
57u32 G_DMA_IO, G_DMA_DL, G_DMA_TRI, G_DMA_MTX, G_DMA_VTX, G_DMA_OFFSETS;
58u32 G_SPECIAL_1, G_SPECIAL_2, G_SPECIAL_3;
59u32 G_VTX, G_MODIFYVTX, G_VTXCOLORBASE;
60u32 G_TRI1, G_TRI2, G_TRI4;
61u32 G_QUAD, G_LINE3D;
62u32 G_RESERVED0, G_RESERVED1, G_RESERVED2, G_RESERVED3;
63u32 G_SPRITE2D_BASE;
64u32 G_BG_1CYC, G_BG_COPY;
65u32 G_OBJ_RECTANGLE, G_OBJ_SPRITE, G_OBJ_MOVEMEM;
66u32 G_SELECT_DL, G_OBJ_RENDERMODE, G_OBJ_RECTANGLE_R;
67u32 G_OBJ_LOADTXTR, G_OBJ_LDTX_SPRITE, G_OBJ_LDTX_RECT, G_OBJ_LDTX_RECT_R;
68u32 G_RDPHALF_0, G_TRI_UNKNOWN;
69
70u32 G_MTX_STACKSIZE;
71u32 G_MTX_MODELVIEW;
72u32 G_MTX_PROJECTION;
73u32 G_MTX_MUL;
74u32 G_MTX_LOAD;
75u32 G_MTX_NOPUSH;
76u32 G_MTX_PUSH;
77
78u32 G_TEXTURE_ENABLE;
79u32 G_SHADING_SMOOTH;
80u32 G_CULL_FRONT;
81u32 G_CULL_BACK;
82u32 G_CULL_BOTH;
83u32 G_CLIPPING;
84
85u32 G_MV_VIEWPORT;
86
87u32 G_MWO_aLIGHT_1, G_MWO_bLIGHT_1;
88u32 G_MWO_aLIGHT_2, G_MWO_bLIGHT_2;
89u32 G_MWO_aLIGHT_3, G_MWO_bLIGHT_3;
90u32 G_MWO_aLIGHT_4, G_MWO_bLIGHT_4;
91u32 G_MWO_aLIGHT_5, G_MWO_bLIGHT_5;
92u32 G_MWO_aLIGHT_6, G_MWO_bLIGHT_6;
93u32 G_MWO_aLIGHT_7, G_MWO_bLIGHT_7;
94u32 G_MWO_aLIGHT_8, G_MWO_bLIGHT_8;
95
96//GBIFunc GBICmd[256];
97GBIInfo GBI;
98
99void GBI_Unknown( u32 w0, u32 w1 )
100{
101}
102
103#if 0
104INT_PTR CALLBACK MicrocodeDlgProc( HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
105{
106 switch (uMsg)
107 {
108 case WM_INITDIALOG:
109 for (int i = 0; i < numMicrocodeTypes; i++)
110 {
111 SendDlgItemMessage( hWndDlg, IDC_MICROCODE, CB_ADDSTRING, 0, (LPARAM)MicrocodeTypes[i] );
112 }
113 SendDlgItemMessage( hWndDlg, IDC_MICROCODE, CB_SETCURSEL, 0, 0 );
114
115 char text[1024];
116 sprintf( text, "Microcode CRC:\t\t0x%08x\r\nMicrocode Data CRC:\t0x%08x\r\nMicrocode Text:\t\t%s", uc_crc, uc_dcrc, uc_str );
117 SendDlgItemMessage( hWndDlg, IDC_TEXTBOX, WM_SETTEXT, NULL, (LPARAM)text );
118 return TRUE;
119
120 case WM_COMMAND:
121 switch (LOWORD(wParam))
122 {
123 case IDOK:
124 EndDialog( hWndDlg, SendDlgItemMessage( hWndDlg, IDC_MICROCODE, CB_GETCURSEL, 0, 0 ) );
125 return TRUE;
126
127 case IDCANCEL:
128 EndDialog( hWndDlg, NONE );
129 return TRUE;
130 }
131 break;
132 }
133
134 return FALSE;
135}
136#elif defined(USE_GTK)
137static int selectedMicrocode = -1;
138static GtkWidget *microcodeWindow = 0;
139static GtkWidget *microcodeList = 0;
140
141static void okButton_clicked( GtkWidget *widget, void *data )
142{
143 gtk_widget_hide( microcodeWindow );
144 if (GTK_LIST(microcodeList)->selection != 0)
145 {
146 char *text = 0;
147 GtkListItem *item = GTK_LIST_ITEM(GTK_LIST(microcodeList)->selection->data);
148 GtkLabel *label = GTK_LABEL(GTK_BIN(item)->child);
149 gtk_label_get( label, &text );
150 if (text != 0)
151 for (int i = 0; i < numMicrocodeTypes; i++)
152 if (!strcmp( text, MicrocodeTypes[i] ))
153 {
154 selectedMicrocode = i;
155 return;
156 }
157 }
158
159 selectedMicrocode = NONE;
160}
161
162static void stopButton_clicked( GtkWidget *widget, void *data )
163{
164 gtk_widget_hide( microcodeWindow );
165 selectedMicrocode = NONE;
166}
167
168static gint
169delete_question_event(GtkWidget *widget, GdkEvent *event, gpointer data)
170{
171 return TRUE; // undeleteable
172}
173
174static int MicrocodeDialog()
175{
176 GtkWidget *infoLabel;
177 GtkWidget *infoFrame, *infoTable;
178 GtkWidget *crcInfoLabel, *crcDataInfoLabel, *textInfoLabel;
179 GtkWidget *crcLabel = NULL, *crcDataLabel = NULL, *textLabel = NULL;
180 GtkWidget *selectUcodeLabel;
181 //GtkWidget *microcodeLabel;
182 GtkWidget *okButton, *stopButton;
183 GList *ucodeList = 0;
184 char buf[1024];
185
186 if (!g_thread_supported())
187 g_thread_init( NULL );
188 gdk_threads_enter();
189
190 // create dialog
191 if (microcodeWindow == 0)
192 {
193 microcodeWindow = gtk_dialog_new();
194 gtk_signal_connect( GTK_OBJECT(microcodeWindow), "delete_event",
195 GTK_SIGNAL_FUNC(delete_question_event), (gpointer)NULL );
196 sprintf( buf, "%s - unknown microcode", pluginName );
197 gtk_window_set_title( GTK_WINDOW(microcodeWindow), buf );
198 gtk_container_set_border_width( GTK_CONTAINER(GTK_DIALOG(microcodeWindow)->vbox), 11 );
199
200 // ok button
201 okButton = gtk_button_new_with_label( "Ok" );
202 gtk_signal_connect_object( GTK_OBJECT(okButton), "clicked",
203 GTK_SIGNAL_FUNC(okButton_clicked), NULL );
204 gtk_container_add( GTK_CONTAINER(GTK_DIALOG(microcodeWindow)->action_area), okButton );
205
206 // stop button
207 stopButton = gtk_button_new_with_label( "Stop" );
208 gtk_signal_connect_object( GTK_OBJECT(stopButton), "clicked",
209 GTK_SIGNAL_FUNC(stopButton_clicked), NULL );
210 gtk_container_add( GTK_CONTAINER(GTK_DIALOG(microcodeWindow)->action_area), stopButton );
211
212 // info label
213 infoLabel = gtk_label_new( "Unknown microcode. Please notify Orkin, including the following information:" );
214 gtk_box_pack_start_defaults( GTK_BOX(GTK_DIALOG(microcodeWindow)->vbox), infoLabel );
215
216 // info frame
217 infoFrame = gtk_frame_new( "Microcode info" );
218 gtk_container_set_border_width( GTK_CONTAINER(infoFrame), 7 );
219 gtk_box_pack_start_defaults( GTK_BOX(GTK_DIALOG(microcodeWindow)->vbox), infoFrame );
220
221 infoTable = gtk_table_new( 3, 2, FALSE );
222 gtk_container_set_border_width( GTK_CONTAINER(infoTable), 7 );
223 gtk_table_set_col_spacings( GTK_TABLE(infoTable), 3 );
224 gtk_table_set_row_spacings( GTK_TABLE(infoTable), 3 );
225 gtk_container_add( GTK_CONTAINER(infoFrame), infoTable );
226
227 crcInfoLabel = gtk_label_new( "Microcode CRC:" );
228 crcDataInfoLabel = gtk_label_new( "Microcode Data CRC:" );
229 textInfoLabel = gtk_label_new( "Microcode Text:" );
230
231 crcLabel = gtk_label_new( "" );
232 crcDataLabel = gtk_label_new( "" );
233 textLabel = gtk_label_new( "" );
234
235 gtk_table_attach_defaults( GTK_TABLE(infoTable), crcInfoLabel, 0, 1, 0, 1 );
236 gtk_table_attach_defaults( GTK_TABLE(infoTable), crcLabel, 1, 2, 0, 1 );
237 gtk_table_attach_defaults( GTK_TABLE(infoTable), crcDataInfoLabel, 0, 1, 1, 2 );
238 gtk_table_attach_defaults( GTK_TABLE(infoTable), crcDataLabel, 1, 2, 1, 2 );
239 gtk_table_attach_defaults( GTK_TABLE(infoTable), textInfoLabel, 0, 1, 2, 3 );
240 gtk_table_attach_defaults( GTK_TABLE(infoTable), textLabel, 1, 2, 2, 3 );
241
242 selectUcodeLabel = gtk_label_new( "You can manually select the closest matching microcode." );
243 for (int i = 0; i < numMicrocodeTypes; i++)
244 ucodeList = g_list_append( ucodeList, gtk_list_item_new_with_label( MicrocodeTypes[i] ) );
245 microcodeList = gtk_list_new();
246 gtk_list_set_selection_mode( GTK_LIST(microcodeList), GTK_SELECTION_SINGLE );
247 gtk_list_append_items( GTK_LIST(microcodeList), ucodeList );
248
249 gtk_box_pack_start_defaults( GTK_BOX(GTK_DIALOG(microcodeWindow)->vbox), selectUcodeLabel );
250 gtk_box_pack_start_defaults( GTK_BOX(GTK_DIALOG(microcodeWindow)->vbox), microcodeList );
251 }
252
253 snprintf( buf, 1024, "0x%8.8X", (unsigned int)uc_crc );
254 if(crcLabel) gtk_label_set_text( GTK_LABEL(crcLabel), buf );
255 snprintf( buf, 1024, "0x%8.8X", (unsigned int)uc_dcrc );
256 if(crcDataLabel) gtk_label_set_text( GTK_LABEL(crcDataLabel), buf );
257 if(textLabel) gtk_label_set_text( GTK_LABEL(textLabel), uc_str );
258
259 selectedMicrocode = -1;
260 gtk_widget_show_all( microcodeWindow );
261
262 while (selectedMicrocode == -1)
263 {
264 if( gtk_main_iteration() )
265 break;
266 usleep( 10000 );
267 }
268 gdk_threads_leave();
269
270 return selectedMicrocode;
271}
272#else
273static int MicrocodeDialog()
274{
275 // FIXME
276 return 0;
277}
278#endif
279
280MicrocodeInfo *GBI_AddMicrocode()
281{
282 MicrocodeInfo *newtop = (MicrocodeInfo*)malloc( sizeof( MicrocodeInfo ) );
283
284 newtop->lower = GBI.top;
285 newtop->higher = NULL;
286
287 if (GBI.top)
288 GBI.top->higher = newtop;
289
290 if (!GBI.bottom)
291 GBI.bottom = newtop;
292
293 GBI.top = newtop;
294
295 GBI.numMicrocodes++;
296
297
298 return newtop;
299}
300
301void GBI_Init()
302{
303 GBI.top = NULL;
304 GBI.bottom = NULL;
305 GBI.current = NULL;
306 GBI.numMicrocodes = 0;
307
308 for (u32 i = 0; i <= 0xFF; i++)
309 GBI.cmd[i] = GBI_Unknown;
310
311#ifdef PROFILE_GBI
312 GBI_ProfileInit();
313#endif
314}
315
316void GBI_Destroy()
317{
318 while (GBI.bottom)
319 {
320 MicrocodeInfo *newBottom = GBI.bottom->higher;
321
322 if (GBI.bottom == GBI.top)
323 GBI.top = NULL;
324
325 free( GBI.bottom );
326
327 GBI.bottom = newBottom;
328
329 if (GBI.bottom)
330 GBI.bottom->lower = NULL;
331
332 GBI.numMicrocodes--;
333 }
334}
335
336#ifdef PROFILE_GBI
337void GBI_ProfileInit()
338{
339 GBI_ProfileReset();
340}
341
342void GBI_ProfileBegin(u32 cmd)
343{
344 GBI.profileTmp = ticksGetTicks();
345}
346
347void GBI_ProfileEnd(u32 cmd)
348{
349 unsigned int i = 256*GBI.current->type + cmd;
350 GBI.profileNum[i]++;
351 GBI.profileTimer[i] += ticksGetTicks() - GBI.profileTmp;
352}
353
354void
355GBI_ProfileReset()
356{
357 memset(GBI.profileTimer, 0, 12 * 256 * sizeof(int));
358 memset(GBI.profileNum, 0, 12 * 256 * sizeof(int));
359}
360
361u32
362GBI_GetFuncTime(u32 ucode, u32 cmd)
363{
364 return GBI.profileTimer[ucode*256+cmd];
365}
366
367u32
368GBI_GetFuncNum(u32 ucode, u32 cmd)
369{
370 return GBI.profileNum[ucode*256+cmd];
371}
372
373u32
374GBI_ProfilePrint(FILE *file)
375{
376 int uc, cmd, total=0;
377
378 for(uc=0;uc<12;uc++)
379 {
380 for(cmd=0;cmd<256;cmd++)
381 {
382 total += GBI_GetFuncTime(uc, cmd);
383 }
384 }
385
386
387 for(uc=0;uc<12;uc++)
388 {
389 for(cmd=0;cmd<256;cmd++)
390 {
391 unsigned int t = GBI_GetFuncTime(uc, cmd);
392 if (t != 0)
393 {
394 fprintf(file, "%s x %i = %u ms (%.2f%%)\n", GBI_GetFuncName(uc,cmd), GBI_GetFuncNum(uc, cmd), t, 100.0f * (float)t / total);
395 }
396 }
397 }
398 return total;
399}
400
401const char*
402GBI_GetUcodeName(u32 ucode)
403{
404 switch(ucode)
405 {
406 case F3D: return "F3D";
407 case F3DEX: return "F3DEX";
408 case F3DEX2: return "F3DEX2";
409 case L3D: return "L3D";
410 case L3DEX: return "L3DEX";
411 case L3DEX2: return "L3DEX2";
412 case S2DEX: return "S2DEX";
413 case S2DEX2: return "S2DEX2";
414 case F3DPD: return "F3DPD";
415 case F3DDKR: return "F3DDKR";
416 case F3DWRUS: return "F3DWRUS";
417 case NONE: return "NONE";
418 default: return "UNKNOWN UCODE";
419 }
420}
421
422const char*
423GBI_GetFuncName(unsigned int ucode, unsigned int cmd)
424{
425 switch(cmd)
426 {
427 //common
428 case G_SETCIMG: return "G_SETCIMG";
429 case G_SETZIMG: return "G_SETZIMG";
430 case G_SETTIMG: return "G_SETTIMG";
431 case G_SETCOMBINE: return "G_SETCOMBINE";
432 case G_SETENVCOLOR: return "G_SETENVCOLOR";
433 case G_SETPRIMCOLOR: return "G_SETPRIMCOLOR";
434 case G_SETBLENDCOLOR: return "G_SETBLENDCOLOR";
435 case G_SETFOGCOLOR: return "G_SETFOGCOLOR";
436 case G_SETFILLCOLOR: return "G_SETFILLCOLOR";
437 case G_FILLRECT: return "G_FILLRECT";
438 case G_SETTILE: return "G_SETTILE";
439 case G_LOADTILE: return "G_LOADTILE";
440 case G_LOADBLOCK: return "G_LOADBLOCK";
441 case G_SETTILESIZE: return "G_SETTILESIZE";
442 case G_LOADTLUT: return "G_LOADTLUT";
443 case G_RDPSETOTHERMODE: return "G_RDPSETOTHERMODE";
444 case G_SETPRIMDEPTH: return "G_SETPRIMDEPTH";
445 case G_SETSCISSOR: return "G_SETSCISSOR";
446 case G_SETCONVERT: return "G_SETCONVERT";
447 case G_SETKEYR: return "G_SETKEYR";
448 case G_SETKEYGB: return "G_SETKEYGB";
449 case G_RDPFULLSYNC: return "G_RDPFULLSYNC";
450 case G_RDPTILESYNC: return "G_RDPTILESYNC";
451 case G_RDPPIPESYNC: return "G_RDPPIPESYNC";
452 case G_RDPLOADSYNC: return "G_RDPLOADSYNC";
453 case G_TEXRECTFLIP: return "G_TEXRECTFLIP";
454
455 //ucode
456 case 0x00: return "SPNOOP";
457
458/*
459 F3D_MTX: 0x01
460 F3DEX2_VTX 0x01
461 F3DDKR_DMA_MTX 0x01
462 S2DEX_BG_1CYC 0x01
463 S2DEX2_OBJ_RECTANGLE 0x01
464*/
465 case 0x01:
466 {
467 switch(ucode)
468 {
469 case F3DEX2: return "F3DEX2_VTX";
470 case F3DDKR: return "F3DDKR_DMA_MTX";
471 case S2DEX: return "S2DEX_BG_1CYC";
472 case S2DEX2: return "S2DEX2_OBJ_RECTANGLE";
473 default: return "F3D_MTX";
474 }
475 }
476/*
477 F3D_RESERVED0: 0x02
478 F3DEX2_MODIFYVTX 0x02
479 S2DEX_BG_COPY 0x02
480 S2DEX2_OBJ_SPRITE 0x02
481*/
482 case 0x02:
483 {
484 switch(ucode)
485 {
486 case F3DEX2: return "F3DEX2_MODIFYVTX";
487 case S2DEX: return "S2DEX_BG_COPY";
488 case S2DEX2: return "S2DEX2_OBJ_SPRITE";
489 default: return "F3D_RESERVED0";
490 }
491 }
492/*
493 F3D_MOVEMEM: 0x03
494 F3DEX2_CULLDL 0x03
495 S2DEX_OBJ_RECTANGLE 0x03
496*/
497 case 0x03:
498 {
499 switch(ucode)
500 {
501 case F3DEX2: return "F3DEX2_CULLDL";
502 case S2DEX: return "S2DEX_OBJ_RECTANGLE";
503 default: return "F3D_MOVEMEM";
504 }
505 }
506/*
507 F3D_VTX: 0x04
508 F3DEX2_BRANCH_Z 0x04
509 F3DDKR_DMA_VTX 0x04
510 S2DEX_OBJ_SPRITE 0x04
511 S2DEX2_SELECT_DL 0x04
512*/
513 case 0x04:
514 {
515 switch(ucode)
516 {
517 case F3DEX2: return "F3DEX2_BRANCH_Z";
518 case F3DDKR: return "F3DDKR_DMA_VTX";
519 case S2DEX: return "S2DEX_OBJ_SPRITE";
520 case S2DEX2: return "S2DEX2_SELECT_DL";
521 default: return "F3D_VTX";
522 }
523 }
524
525/*
526 F3D_RESERVED1: 0x05
527 F3DEX2_TRI1 0x05
528 F3DDKR_DMA_TRI 0x05
529 S2DEX_OBJ_MOVEMEM 0x05
530 S2DEX2_OBJ_LOADTXTR 0x05
531*/
532 case 0x05:
533 {
534 switch(ucode)
535 {
536 case F3DEX2: return "F3DEX2_TR1";
537 case F3DDKR: return "F3DDKR_DMA_TRI";
538 case S2DEX: return "S2DEX_OBJ_MOVEMEM";
539 case S2DEX2: return "S2DEX2_OBJ_LOADTXTR";
540 default: return "F3D_RESERVED1";
541 }
542 }
543/*
544 F3D_DL: 0x06
545 F3DEX2_TRI2 0x06
546 S2DEX2_OBJ_LDTX_SPRITE 0x06
547*/
548 case 0x06:
549 {
550 switch(ucode)
551 {
552 case F3DEX2: return "F3DEX2_TR2";
553 case S2DEX2: return "S2DEX2_OBJ_LDTX_SPRITE";
554 default: return "F3D_DL";
555 }
556 }
557
558/*
559 F3D_RESERVED2: 0x07
560 F3DEX2_QUAD 0x07
561 F3DPD_VTXCOLORBASE 0x07
562 F3DDKR_DMA_DL 0x07
563 S2DEX2_OBJ_LDTX_RECT 0x07
564*/
565 case 0x07:
566 {
567 switch(ucode)
568 {
569 case F3DEX2: return "F3DEX2_QUAD";
570 case F3DPD: return "F3DPD_VTXCOLORBASE";
571 case F3DDKR: return "F3DDKR_DMA_DL";
572 case S2DEX2: return "S2DEX2_OBJ_LDTX_RECT";
573 default: return "F3D_RESERVED2";
574 }
575 }
576/*
577 F3D_RESERVED3: 0x08
578 L3DEX2_LINE3D 0x08
579 S2DEX2_OBJ_LDTX_RECT_R 0x08
580*/
581 case 0x08:
582 {
583 switch(ucode)
584 {
585 case L3DEX2: return "L3DEX2_LINE3D";
586 case S2DEX2: return "S2DEX2_OBJ_LDTX_RECT_R";
587 default: return "F3D_RESERVED3";
588 }
589 }
590
591/*
592 F3D_SPRITE2D_BASE: 0x09
593 S2DEX2_BG_1CYC 0x09
594*/
595 case 0x09:
596 {
597 switch(ucode)
598 {
599 case S2DEX2: return "S2DEX2_BG_1CYC";
600 default: return "F3D_SPRITE2D_BASE";
601 }
602 }
603
604// S2DEX2_BG_COPY 0x0A
605 case 0x0A: return "S2DEX2_BG_COPY";
606// S2DEX2_OBJ_RENDERMODE 0x0B
607 case 0x0B: return "S2DEX2_OBJ_RENDERMODE";
608// F3DEX2_RDPHALF_2 0xF1
609 case 0xF1: return "F3DEX2_RDPHALF_2";
610/*
611 S2DEX_RDPHALF_0 0xE4
612 S2DEX2_RDPHALF_0 0xE4
613*/
614 case 0xE4:
615 {
616 switch(ucode)
617 {
618 case S2DEX: return "S2DEX_RDPHALF_0";
619 case S2DEX2: return "S2DEX2_RDPHALF_0";
620 default: return "G_TEXRECT";
621 }
622 }
623// F3DEX2_SETOTHERMODE_H 0xE3
624 case 0xE3: return "F3DEX2_SETOTHERMODE_H";
625// F3DEX2_SETOTHERMODE_L 0xE2
626 case 0xE2: return "F3DEX2_SETOTHERMODE_L";
627// F3DEX2_RDPHALF_1 0xE1
628 case 0xE1: return "F3DEX2_RDPHALF_1";
629// F3DEX2_SPNOOP 0xE0
630 case 0xE0: return "F3DEX2_SPNOOP";
631// F3DEX2_ENDDL 0xDF
632 case 0xDF: return "F3DEX2_ENDDL";
633// F3DEX2_DL 0xDE
634 case 0xDE: return "F3DEX2_DL";
635// F3DEX2_LOAD_UCODE 0xDD
636 case 0xDD: return "F3DEX2_LOAD_UCODE";
637/*
638 F3DEX2_MOVEMEM 0xDC
639 S2DEX2_OBJ_MOVEMEM 0xDC
640*/
641 case 0xDC:
642 {
643 switch(ucode)
644 {
645 case S2DEX2: return "S2DEX2_OBJ_MOVEMEM";
646 default: return "F3DEX2_MOVEMEM";
647 }
648 }
649// F3DEX2_MOVEWORD 0xDB
650 case 0xDB: return "F3DEX2_MOVEWORD";
651/*
652 F3DEX2_MTX 0xDA
653 S2DEX2_OBJ_RECTANGLE_R 0xDA
654*/
655 case 0xDA:
656 {
657 switch(ucode)
658 {
659 case S2DEX2: return "S2DEX2_OBJ_RECTANGLE_R";
660 default: return "F3DEX2_MTX";
661 }
662 }
663// F3DEX2_GEOMETRYMODE 0xD9
664 case 0xD9: return "F3DEX2_GEOMETRYMODE";
665// F3DEX2_POPMTX 0xD8
666 case 0xD8: return "F3DEX2_POPMTX";
667// F3DEX2_TEXTURE 0xD7
668 case 0xD7: return "F3DEX2_TEXTURE";
669// F3DEX2_DMA_IO 0xD6
670 case 0xD6: return "F3DEX2_DMA_IO";
671// F3DEX2_SPECIAL_1 0xD5
672 case 0xD5: return "F3DEX2_SPECIAL_1";
673// F3DEX2_SPECIAL_2 0xD4
674 case 0xD4: return "F3DEX2_SPECIAL_2";
675// F3DEX2_SPECIAL_3 0xD3
676 case 0xD3: return "F3DEX2_SPECIAL_3";
677
678// S2DEX_OBJ_LOADTXTR 0xC1
679 case 0xC1: return "S2DEX_OBJ_LOADTXTR";
680// S2DEX_OBJ_LDTX_SPRITE 0xC2
681 case 0xC2: return "S2DEX_OBJ_LDTX_SPRITE";
682// S2DEX_OBJ_LDTX_RECT 0xC3
683 case 0xC3: return "S2DEX_OBJ_LDTX_RECT";
684// S2DEX_OBJ_LDTX_RECT_R 0xC4
685 case 0xC4: return "S2DEX_OBJ_LDTX_RECT_R";
686/*
687 F3D_TRI1: 0xBF
688 F3DDKR_DMA_OFFSETS 0xBF
689*/
690 case 0xBF:
691 {
692 switch(ucode)
693 {
694 case F3DDKR: return "F3DDKR_DMA_OFFSETS";
695 default: return "F3D_TRI1";
696 }
697 }
698
699// F3D_CULLDL: 0xBE
700 case 0xBE: return "F3D_CULLDL";
701// F3D_POPMTX: 0xBD
702 case 0xBD: return "F3D_POPMTX";
703// F3D_MOVEWORD: 0xBC
704 case 0xBC: return "F3D_MOVEWORD";
705// F3D_TEXTURE: 0xBB
706 case 0xBB: return "F3D_TEXTURE";
707// F3D_SETOTHERMODE_H: 0xBA
708 case 0xBA: return "F3D_SETOTHERMODE_H";
709// F3D_SETOTHERMODE_L: 0xB9
710 case 0xB9: return "F3D_SETOTHERMODE_L";
711// F3D_ENDDL: 0xB8
712 case 0xB8: return "F3D_ENDDL";
713// F3D_SETGEOMETRYMODE: 0xB7
714 case 0xB7: return "F3D_SETGEOMETRYMODE";
715// F3D_CLEARGEOMETRYMODE: 0xB6
716 case 0xB6: return "F3D_CLEARGEOMETRYMODE";
717/*
718 F3D_QUAD: 0xB5
719 L3D_LINE3D 0xB5
720*/
721 case 0xB5:
722 {
723 switch(ucode)
724 {
725 case L3D: return "L3D_LINE3D";
726 default: return "F3D_QUAD";
727 }
728 }
729
730// F3D_RDPHALF_1: 0xB4
731 case 0xB4: return "F3D_RDPHALF_1";
732// F3D_RDPHALF_2: 0xB3
733 case 0xB3: return "F3D_RDPHALF_2";
734/*
735 F3D_RDPHALF_CONT: 0xB2
736 F3DEX_MODIFYVTX 0xB2
737 S2DEX_OBJ_RECTANGLE_R 0xB2
738*/
739 case 0xB2:
740 {
741 switch(ucode)
742 {
743 case F3DEX: return "F3DEX_MODIFYVTX";
744 case S2DEX: return "S2DEX_OBJ_RECTANGLE_R";
745 default: return "F3D_RDPHALF_CONT";
746 }
747 }
748/*
749 F3D_TRI4: 0xB1
750 F3DEX_TRI2 0xB1
751 F3DWRUS_TRI2 0xB1
752 S2DEX_OBJ_RENDERMODE 0xB1
753*/
754 case 0xB1:
755 {
756 switch(ucode)
757 {
758 case F3DEX: return "F3DEX_TRI2";
759 case F3DWRUS: return "F3DWRUS_TRI2";
760 case S2DEX: return "S2DEX_OBJ_RENDERMODE";
761 default: return "F3D_TRI4";
762 }
763 }
764/*
765 F3DEX_BRANCH_Z 0xB0
766 S2DEX_SELECT_DL 0xB0
767*/
768 case 0xB0:
769 {
770 switch(ucode)
771 {
772 case S2DEX: return "S2DEX_SELECT_DL";
773 default: return "F3DEX_BRANCH_Z";
774 }
775 }
776/*
777 F3DEX_LOAD_UCODE 0xAF
778 S2DEX_LOAD_UCODE 0xAF
779*/
780 case 0xAF:
781 {
782 switch(ucode)
783 {
784 case S2DEX: return "S2DEX_LOAD_UCODE";
785 default: return "F3DEX_LOAD_UCODE";
786 }
787 }
788
789 default:
790 {
791 if (ucode == F3DCBFD)
792 {
793 if (cmd >= 0x10 && cmd <= 0x1f)
794 return "F3DCBFD_TRI4";
795
796 }
797 return "UNKNOWN CMD";
798 }
799 }
800}
801#endif
802
803MicrocodeInfo *GBI_DetectMicrocode( u32 uc_start, u32 uc_dstart, u16 uc_dsize )
804{
805 MicrocodeInfo *current;
806
807 for (unsigned int i = 0; i < GBI.numMicrocodes; i++)
808 {
809 current = GBI.top;
810
811 while (current)
812 {
813 if ((current->address == uc_start) && (current->dataAddress == uc_dstart) && (current->dataSize == uc_dsize))
814 return current;
815
816 current = current->lower;
817 }
818 }
819
820 current = GBI_AddMicrocode();
821
822 current->address = uc_start;
823 current->dataAddress = uc_dstart;
824 current->dataSize = uc_dsize;
825 current->NoN = FALSE;
826 current->type = NONE;
827
828 // See if we can identify it by CRC
829 uc_crc = CRC_Calculate( 0xFFFFFFFF, &RDRAM[uc_start & 0x1FFFFFFF], 4096);
830 LOG(LOG_MINIMAL, "UCODE CRC=0x%x\n", uc_crc);
831
832 for (u32 i = 0; i < sizeof( specialMicrocodes ) / sizeof( SpecialMicrocodeInfo ); i++)
833 {
834 if (uc_crc == specialMicrocodes[i].crc)
835 {
836 current->type = specialMicrocodes[i].type;
837 return current;
838 }
839 }
840
841 // See if we can identify it by text
842 char uc_data[2048];
843 UnswapCopy( &RDRAM[uc_dstart & 0x1FFFFFFF], uc_data, 2048 );
844 strcpy( uc_str, "Not Found" );
845
846 for (u32 i = 0; i < 2048; i++)
847 {
848 if ((uc_data[i] == 'R') && (uc_data[i+1] == 'S') && (uc_data[i+2] == 'P'))
849 {
850 u32 j = 0;
851 while (uc_data[i+j] > 0x0A)
852 {
853 uc_str[j] = uc_data[i+j];
854 j++;
855 }
856
857 uc_str[j] = 0x00;
858
859 int type = NONE;
860
861 if (strncmp( &uc_str[4], "SW", 2 ) == 0)
862 {
863 type = F3D;
864 }
865 else if (strncmp( &uc_str[4], "Gfx", 3 ) == 0)
866 {
867 current->NoN = (strncmp( &uc_str[20], ".NoN", 4 ) == 0);
868
869 if (strncmp( &uc_str[14], "F3D", 3 ) == 0)
870 {
871 if (uc_str[28] == '1')
872 type = F3DEX;
873 else if (uc_str[31] == '2')
874 type = F3DEX2;
875 }
876 else if (strncmp( &uc_str[14], "L3D", 3 ) == 0)
877 {
878 if (uc_str[28] == '1')
879 type = L3DEX;
880 else if (uc_str[31] == '2')
881 type = L3DEX2;
882 }
883 else if (strncmp( &uc_str[14], "S2D", 3 ) == 0)
884 {
885 if (uc_str[28] == '1')
886 type = S2DEX;
887 else if (uc_str[31] == '2')
888 type = S2DEX2;
889 }
890 }
891
892 LOG(LOG_VERBOSE, "UCODE STRING=%s\n", uc_str);
893
894 if (type != NONE)
895 {
896 current->type = type;
897 return current;
898 }
899
900 break;
901 }
902 }
903
904
905 for (u32 i = 0; i < sizeof( specialMicrocodes ) / sizeof( SpecialMicrocodeInfo ); i++)
906 {
907 if (strcmp( uc_str, specialMicrocodes[i].text ) == 0)
908 {
909 current->type = specialMicrocodes[i].type;
910 return current;
911 }
912 }
913
914 // Let the user choose the microcode
915 LOG(LOG_ERROR, "[gles2n64]: Warning - unknown ucode!!!\n");
916 if(last_good_ucode != (u32)-1)
917 {
918 current->type=last_good_ucode;
919 }
920 else
921 {
922 current->type = MicrocodeDialog();
923 }
924 return current;
925}
926
927void GBI_MakeCurrent( MicrocodeInfo *current )
928{
929 if (current != GBI.top)
930 {
931 if (current == GBI.bottom)
932 {
933 GBI.bottom = current->higher;
934 GBI.bottom->lower = NULL;
935 }
936 else
937 {
938 current->higher->lower = current->lower;
939 current->lower->higher = current->higher;
940 }
941
942 current->higher = NULL;
943 current->lower = GBI.top;
944 GBI.top->higher = current;
945 GBI.top = current;
946 }
947
948 if (!GBI.current || (GBI.current->type != current->type))
949 {
950
951 for (int i = 0; i <= 0xFF; i++)
952 GBI.cmd[i] = GBI_Unknown;
953
954 RDP_Init();
955 switch (current->type)
956 {
957 case F3D: F3D_Init(); break;
958 case F3DEX: F3DEX_Init(); break;
959 case F3DEX2: F3DEX2_Init(); break;
960 case L3D: L3D_Init(); break;
961 case L3DEX: L3DEX_Init(); break;
962 case L3DEX2: L3DEX2_Init(); break;
963 case S2DEX: S2DEX_Init(); break;
964 case S2DEX2: S2DEX2_Init(); break;
965 case F3DDKR: F3DDKR_Init(); break;
966 case F3DWRUS: F3DWRUS_Init(); break;
967 case F3DPD: F3DPD_Init(); break;
968 case F3DCBFD: F3DCBFD_Init(); break;
969 }
970 }
971
972
973 GBI.current = current;
974}
975