1 /*
2  * MIPS disassembler for the MAME project written by smf
3  *
4  */
5 
6 #include <string.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "psx.h"
10 
11 #ifndef STANDALONE
12 #include "memory.h"
13 #endif
14 
make_signed_hex_str_16(UINT32 value)15 static char *make_signed_hex_str_16( UINT32 value )
16 {
17 	static char s_hex[ 20 ];
18 
19 	value &= 0xffff;
20 	if( value & 0x8000 )
21 	{
22 		sprintf( s_hex, "-$%x", ( 0 - value ) & 0x7fff );
23 	}
24 	else
25 	{
26 		sprintf( s_hex, "$%x", value & 0x7fff );
27 	}
28 	return s_hex;
29 }
30 
31 static const char *s_cpugenreg[] =
32 {
33 	"zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
34 	"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
35 	"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
36 	"t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra"
37 };
38 
39 static const char *s_cp0genreg[] =
40 {
41 	"Index", "Random", "EntryLo", "cp0r3", "Context", "cp0r5", "cp0r6", "cp0r7",
42 	"BadVAddr", "cp0r9", "EntryHi", "cp0r11", "SR", "Cause", "EPC", "PRId",
43 	"cp0r16", "cp0r17", "cp0r18", "cp0r19", "cp0r20", "cp0r21", "cp0r22", "cp0r23",
44 	"cp0r24", "cp0r25", "cp0r26", "cp0r27", "cp0r28", "cp0r29", "cp0r30", "cp0r31"
45 };
46 
47 static const char *s_cp1genreg[] =
48 {
49 	"cp1r0", "cp1r1", "cp1r2", "cp1r3", "cp1r4", "cp1r5", "cp1r6", "cp1r7",
50 	"cp1r8", "cp1r9", "cp1r10", "cp1r11", "cp1r12", "cp1r13", "cp1r14", "cp1r15",
51 	"cp1r16", "cp1r17", "cp1r18", "cp1r19", "cp1r20", "cp1r21", "cp1r22", "cp1r22",
52 	"cp1r23", "cp1r24", "cp1r25", "cp1r26", "cp1r27", "cp1r28", "cp1r29", "cp1r30"
53 };
54 
55 static const char *s_cp1ctlreg[] =
56 {
57 	"cp1cr0", "cp1cr1", "cp1cr2", "cp1cr3", "cp1cr4", "cp1cr5", "cp1cr6", "cp1cr7",
58 	"cp1cr8", "cp1cr9", "cp1cr10", "cp1cr11", "cp1cr12", "cp1cr13", "cp1cr14", "cp1cr15",
59 	"cp1cr16", "cp1cr17", "cp1cr18", "cp1cr19", "cp1cr20", "cp1cr21", "cp1cr22", "cp1cr23",
60 	"cp1cr24", "cp1cr25", "cp1cr26", "cp1cr27", "cp1cr28", "cp1cr29", "cp1cr30", "cp1cr31"
61 };
62 
63 static const char *s_cp2genreg[] =
64 {
65 	"vxy0", "vz0", "vxy1", "vz1", "vxy2", "vz2", "rgb", "otz",
66 	"ir0", "ir1", "ir2", "ir3", "sxy0", "sxy1", "sxy2", "sxyp",
67 	"sz0", "sz1", "sz2", "sz3", "rgb0", "rgb1", "rgb2", "cp2cr23",
68 	"mac0", "mac1", "mac2", "mac3", "irgb", "orgb", "lzcs", "lzcr"
69 };
70 
71 static const char *s_cp2ctlreg[] =
72 {
73 	"r11r12", "r13r21", "r22r23", "r31r32", "r33", "trx", "try", "trz",
74 	"l11l12", "l13l21", "l22l23", "l31l32", "l33", "rbk", "gbk", "bbk",
75 	"lr1lr2", "lr3lg1", "lg2lg3", "lb1lb2", "lb3", "rfc", "gfc", "bfc",
76 	"ofx", "ofy", "h", "dqa", "dqb", "zsf3", "zsf4", "flag"
77 };
78 
79 static const char *s_gtesf[] =
80 {
81 	"0", "12"
82 };
83 
84 static const char *s_gtemx[] =
85 {
86 	"rm", "lm", "cm", "0"
87 };
88 
89 static const char *s_gtev[] =
90 {
91 	"v0", "v1", "v2", "ir"
92 };
93 
94 static const char *s_gtecv[] =
95 {
96 	"tr", "bk", "fc", "0"
97 };
98 
99 static const char *s_gtelm[] =
100 {
101 	"0", "1"
102 };
103 
DasmMIPS(char * buffer,UINT32 oldpc)104 unsigned DasmMIPS( char *buffer, UINT32 oldpc )
105 {
106 	UINT32 pc, op;
107 
108 	pc = oldpc;
109 #ifndef STANDALONE
110 	op = cpu_readop32( pc );
111 #else
112 	op = ( filebuf[ pc + order[ 0 ] - offset ] << 24 ) |
113 		( filebuf[ pc + order[ 1 ] - offset ] << 16 ) |
114 		( filebuf[ pc + order[ 2 ] - offset ] << 8 ) |
115 		( filebuf[ pc + order[ 3 ] - offset ] );
116 #endif
117 	pc += 4;
118 
119 	sprintf( buffer, "dw      $%08x", op );
120 
121 	switch( INS_OP( op ) )
122 	{
123 	case OP_SPECIAL:
124 		switch( INS_FUNCT( op ) )
125 		{
126 		case FUNCT_SLL:
127 			if( op == 0 )
128 			{
129 				/* the standard nop is "sll     zero,zero,$0000" */
130 				sprintf( buffer, "nop" );
131 			}
132 			else
133 			{
134 				sprintf( buffer, "sll     %s,%s,$%02x", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RT( op ) ], INS_SHAMT( op ) );
135 			}
136 			break;
137 		case FUNCT_SRL:
138 			sprintf( buffer, "srl     %s,%s,$%02x", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RT( op ) ], INS_SHAMT( op ) );
139 			break;
140 		case FUNCT_SRA:
141 			sprintf( buffer, "sra     %s,%s,$%02x", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RT( op ) ], INS_SHAMT( op ) );
142 			break;
143 		case FUNCT_SLLV:
144 			sprintf( buffer, "sllv    %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ] );
145 			break;
146 		case FUNCT_SRLV:
147 			sprintf( buffer, "srlv    %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ] );
148 			break;
149 		case FUNCT_SRAV:
150 			sprintf( buffer, "srav    %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ] );
151 			break;
152 		case FUNCT_JR:
153 			if( INS_RD( op ) == 0 )
154 			{
155 				sprintf( buffer, "jr      %s", s_cpugenreg[ INS_RS( op ) ] );
156 			}
157 			break;
158 		case FUNCT_JALR:
159 			sprintf( buffer, "jalr    %s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ] );
160 			break;
161 		case FUNCT_SYSCALL:
162 			sprintf( buffer, "syscall $%05x", INS_CODE( op ) );
163 			break;
164 		case FUNCT_BREAK:
165 			sprintf( buffer, "break   $%05x", INS_CODE( op ) );
166 			break;
167 		case FUNCT_MFHI:
168 			sprintf( buffer, "mfhi    %s", s_cpugenreg[ INS_RD( op ) ] );
169 			break;
170 		case FUNCT_MTHI:
171 			if( INS_RD( op ) == 0 )
172 			{
173 				sprintf( buffer, "mthi    %s", s_cpugenreg[ INS_RS( op ) ] );
174 			}
175 			break;
176 		case FUNCT_MFLO:
177 			sprintf( buffer, "mflo    %s", s_cpugenreg[ INS_RD( op ) ] );
178 			break;
179 		case FUNCT_MTLO:
180 			if( INS_RD( op ) == 0 )
181 			{
182 				sprintf( buffer, "mtlo    %s", s_cpugenreg[ INS_RS( op ) ] );
183 			}
184 			break;
185 		case FUNCT_MULT:
186 			if( INS_RD( op ) == 0 )
187 			{
188 				sprintf( buffer, "mult    %s,%s", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] );
189 			}
190 			break;
191 		case FUNCT_MULTU:
192 			if( INS_RD( op ) == 0 )
193 			{
194 				sprintf( buffer, "multu   %s,%s", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] );
195 			}
196 			break;
197 		case FUNCT_DIV:
198 			if( INS_RD( op ) == 0 )
199 			{
200 				sprintf( buffer, "div     %s,%s", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] );
201 			}
202 			break;
203 		case FUNCT_DIVU:
204 			if( INS_RD( op ) == 0 )
205 			{
206 				sprintf( buffer, "divu    %s,%s", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] );
207 			}
208 			break;
209 		case FUNCT_ADD:
210 			sprintf( buffer, "add     %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] );
211 			break;
212 		case FUNCT_ADDU:
213 			sprintf( buffer, "addu    %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] );
214 			break;
215 		case FUNCT_SUB:
216 			sprintf( buffer, "sub     %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] );
217 			break;
218 		case FUNCT_SUBU:
219 			sprintf( buffer, "subu    %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] );
220 			break;
221 		case FUNCT_AND:
222 			sprintf( buffer, "and     %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] );
223 			break;
224 		case FUNCT_OR:
225 			sprintf( buffer, "or      %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] );
226 			break;
227 		case FUNCT_XOR:
228 			sprintf( buffer, "xor     %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] );
229 			break;
230 		case FUNCT_NOR:
231 			sprintf( buffer, "nor     %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] );
232 			break;
233 		case FUNCT_SLT:
234 			sprintf( buffer, "slt     %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] );
235 			break;
236 		case FUNCT_SLTU:
237 			sprintf( buffer, "sltu    %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] );
238 			break;
239 		}
240 		break;
241 	case OP_REGIMM:
242 		switch( INS_RT( op ) )
243 		{
244 		case RT_BLTZ:
245 			sprintf( buffer, "bltz    %s,$%08x", s_cpugenreg[ INS_RS( op ) ], pc + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) );
246 			break;
247 		case RT_BGEZ:
248 			sprintf( buffer, "bgez    %s,$%08x", s_cpugenreg[ INS_RS( op ) ], pc + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) );
249 			break;
250 		case RT_BLTZAL:
251 			sprintf( buffer, "bltzal  %s,$%08x", s_cpugenreg[ INS_RS( op ) ], pc + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) );
252 			break;
253 		case RT_BGEZAL:
254 			sprintf( buffer, "bgezal  %s,$%08x", s_cpugenreg[ INS_RS( op ) ], pc + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) );
255 			break;
256 		}
257 		break;
258 	case OP_J:
259 		sprintf( buffer, "j       $%08x", ( pc & 0xF0000000 ) + ( INS_TARGET( op ) << 2 ) );
260 		break;
261 	case OP_JAL:
262 		sprintf( buffer, "jal     $%08x", ( pc & 0xF0000000 ) + ( INS_TARGET( op ) << 2 ) );
263 		break;
264 	case OP_BEQ:
265 		sprintf( buffer, "beq     %s,%s,$%08x", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ], pc + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) );
266 		break;
267 	case OP_BNE:
268 		sprintf( buffer, "bne     %s,%s,$%08x", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ], pc + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) );
269 		break;
270 	case OP_BLEZ:
271 		if( INS_RT( op ) == 0 )
272 		{
273 			sprintf( buffer, "blez    %s,$%08x", s_cpugenreg[ INS_RS( op ) ], pc + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) );
274 		}
275 		break;
276 	case OP_BGTZ:
277 		if( INS_RT( op ) == 0 )
278 		{
279 			sprintf( buffer, "bgtz    %s,$%08x", s_cpugenreg[ INS_RS( op ) ], pc + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) );
280 		}
281 		break;
282 	case OP_ADDI:
283 		sprintf( buffer, "addi    %s,%s,%s", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ) );
284 		break;
285 	case OP_ADDIU:
286 		sprintf( buffer, "addiu   %s,%s,%s", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ) );
287 		break;
288 	case OP_SLTI:
289 		sprintf( buffer, "slti    %s,%s,%s", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ) );
290 		break;
291 	case OP_SLTIU:
292 		sprintf( buffer, "sltiu   %s,%s,%s", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ) );
293 		break;
294 	case OP_ANDI:
295 		sprintf( buffer, "andi    %s,%s,$%04x", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], INS_IMMEDIATE( op ) );
296 		break;
297 	case OP_ORI:
298 		sprintf( buffer, "ori     %s,%s,$%04x", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], INS_IMMEDIATE( op ) );
299 		break;
300 	case OP_XORI:
301 		sprintf( buffer, "xori    %s,%s,$%04x", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], INS_IMMEDIATE( op ) );
302 		break;
303 	case OP_LUI:
304 		sprintf( buffer, "lui     %s,$%04x", s_cpugenreg[ INS_RT( op ) ], INS_IMMEDIATE( op ) );
305 		break;
306 	case OP_COP0:
307 		switch( INS_RS( op ) )
308 		{
309 		case RS_MFC:
310 			sprintf( buffer, "mfc0    %s,%s",  s_cpugenreg[ INS_RT( op ) ], s_cp0genreg[ INS_RD( op ) ] );
311 			break;
312 		case RS_MTC:
313 			sprintf( buffer, "mtc0    %s,%s",  s_cpugenreg[ INS_RT( op ) ], s_cp0genreg[ INS_RD( op ) ] );
314 			break;
315 		case RS_BC:
316 			switch( INS_RT( op ) )
317 			{
318 			case RT_BCF:
319 				sprintf( buffer, "bc0f    $%08x", pc + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) );
320 				break;
321 			case RT_BCT:
322 				sprintf( buffer, "bc0t    $%08x", pc + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) );
323 				break;
324 			}
325 			break;
326 		default:
327 			switch( INS_CO( op ) )
328 			{
329 			case 1:
330 				sprintf( buffer, "cop0    $%07x", INS_COFUN( op ) );
331 
332 				switch( INS_CF( op ) )
333 				{
334 				case 1:
335 					sprintf( buffer, "tlbr" );
336 					break;
337 				case 4:
338 					sprintf( buffer, "tlbwi" );
339 					break;
340 				case 6:
341 					sprintf( buffer, "tlbwr" );
342 					break;
343 				case 8:
344 					sprintf( buffer, "tlbp" );
345 					break;
346 				case 16:
347 					sprintf( buffer, "rfe" );
348 					break;
349 				}
350 				break;
351 			}
352 			break;
353 		}
354 		break;
355 	case OP_COP1:
356 		switch( INS_RS( op ) )
357 		{
358 		case RS_MFC:
359 			sprintf( buffer, "mfc1    %s,%s",  s_cpugenreg[ INS_RT( op ) ], s_cp1genreg[ INS_RD( op ) ] );
360 			break;
361 		case RS_CFC:
362 			sprintf( buffer, "cfc1    %s,%s",  s_cpugenreg[ INS_RT( op ) ], s_cp1ctlreg[ INS_RD( op ) ] );
363 			break;
364 		case RS_MTC:
365 			sprintf( buffer, "mtc1    %s,%s",  s_cpugenreg[ INS_RT( op ) ], s_cp1genreg[ INS_RD( op ) ] );
366 			break;
367 		case RS_CTC:
368 			sprintf( buffer, "ctc1    %s,%s",  s_cpugenreg[ INS_RT( op ) ], s_cp1ctlreg[ INS_RD( op ) ] );
369 			break;
370 		case RS_BC:
371 			switch( INS_RT( op ) )
372 			{
373 			case RT_BCF:
374 				sprintf( buffer, "bc1f    $%08x", pc + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) );
375 				break;
376 			case RT_BCT:
377 				sprintf( buffer, "bc1t    $%08x", pc + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) );
378 				break;
379 			}
380 			break;
381 		default:
382 			switch( INS_CO( op ) )
383 			{
384 			case 1:
385 				sprintf( buffer, "cop1    $%07x", INS_COFUN( op ) );
386 				break;
387 			}
388 			break;
389 		}
390 		break;
391 	case OP_COP2:
392 		switch( INS_RS( op ) )
393 		{
394 		case RS_MFC:
395 			sprintf( buffer, "mfc2    %s,%s",  s_cpugenreg[ INS_RT( op ) ], s_cp2genreg[ INS_RD( op ) ] );
396 			break;
397 		case RS_CFC:
398 			sprintf( buffer, "cfc2    %s,%s",  s_cpugenreg[ INS_RT( op ) ], s_cp2ctlreg[ INS_RD( op ) ] );
399 			break;
400 		case RS_MTC:
401 			sprintf( buffer, "mtc2    %s,%s",  s_cpugenreg[ INS_RT( op ) ], s_cp2genreg[ INS_RD( op ) ] );
402 			break;
403 		case RS_CTC:
404 			sprintf( buffer, "ctc2    %s,%s",  s_cpugenreg[ INS_RT( op ) ], s_cp2ctlreg[ INS_RD( op ) ] );
405 			break;
406 		case RS_BC:
407 			switch( INS_RT( op ) )
408 			{
409 			case RT_BCF:
410 				sprintf( buffer, "bc2f    $%08x", pc + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) );
411 				break;
412 			case RT_BCT:
413 				sprintf( buffer, "bc2t    $%08x", pc + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) );
414 				break;
415 			}
416 			break;
417 		default:
418 			switch( INS_CO( op ) )
419 			{
420 			case 1:
421 				sprintf( buffer, "cop2    $%07x", INS_COFUN( op ) );
422 
423 				switch( GTE_OP( op ) )
424 				{
425 				case 0x01:
426 					if( INS_CO( op ) == 0x0180001 )
427 					{
428 						sprintf( buffer, "rtps" );
429 					}
430 					break;
431 				case 0x02:
432 					if( INS_CO( op ) == 0x0280030 )
433 					{
434 						sprintf( buffer, "rtpt" );
435 					}
436 					break;
437 				case 0x04:
438 					if( GTE_CT( op ) == 0x012 ||
439 						GTE_CT( op ) == 0x412 )
440 					{
441 						sprintf( buffer, "mvmva%s %s + %s * %s (lm=%s)",
442 							s_gtesf[ GTE_SF( op ) ], s_gtecv[ GTE_CV( op ) ], s_gtemx[ GTE_MX( op ) ],
443 							s_gtev[ GTE_V( op ) ],  s_gtelm[ GTE_LM( op ) ] );
444 					}
445 					break;
446 				case 0x06:
447 					if( INS_CO( op ) == 0x0680029 )
448 					{
449 						sprintf( buffer, "dcpl" );
450 					}
451 					break;
452 				case 0x07:
453 					if( INS_CO( op ) == 0x0780010 )
454 					{
455 						sprintf( buffer, "dpcs" );
456 					}
457 					break;
458 				case 0x09:
459 					if( INS_CO( op ) == 0x0980011 )
460 					{
461 						sprintf( buffer, "intpl" );
462 					}
463 					break;
464 				case 0x0a:
465 					if( GTE_CT( op ) == 0x428 )
466 					{
467 						sprintf( buffer, "sqr%s", s_gtesf[ GTE_SF( op ) ] );
468 					}
469 					break;
470 				case 0x0c:
471 					if( INS_CO( op ) == 0x0c8041e )
472 					{
473 						sprintf( buffer, "ncs" );
474 					}
475 					break;
476 				case 0x0d:
477 					if( INS_CO( op ) == 0x0d80420 )
478 					{
479 						sprintf( buffer, "nct" );
480 					}
481 					break;
482 				case 0x0e:
483 					if( INS_CO( op ) == 0x0e80413 )
484 					{
485 						sprintf( buffer, "ncds" );
486 					}
487 					break;
488 				case 0x0f:
489 					if( INS_CO( op ) == 0x0f8002A )
490 					{
491 						sprintf( buffer, "dpct" );
492 					}
493 					else if( INS_CO( op ) == 0x0f80416 )
494 					{
495 						sprintf( buffer, "ncdt" );
496 					}
497 					break;
498 				case 0x10:
499 					if( INS_CO( op ) == 0x108041b )
500 					{
501 						sprintf( buffer, "nccs" );
502 					}
503 					break;
504 				case 0x11:
505 					if( INS_CO( op ) == 0x118043f )
506 					{
507 						sprintf( buffer, "ncct" );
508 					}
509 					break;
510 				case 0x12:
511 					if( INS_CO( op ) == 0x1280414 )
512 					{
513 						sprintf( buffer, "cdp" );
514 					}
515 					break;
516 				case 0x13:
517 					if( INS_CO( op ) == 0x138041c )
518 					{
519 						sprintf( buffer, "cc" );
520 					}
521 					break;
522 				case 0x14:
523 					if( INS_CO( op ) == 0x1400006 )
524 					{
525 						sprintf( buffer, "nclip" );
526 					}
527 					break;
528 				case 0x15:
529 					if( INS_CO( op ) == 0x158002d )
530 					{
531 						sprintf( buffer, "avsz3" );
532 					}
533 					break;
534 				case 0x16:
535 					if( INS_CO( op ) == 0x168002e )
536 					{
537 						sprintf( buffer, "avsz4" );
538 					}
539 					break;
540 				case 0x17:
541 					if( GTE_CT( op ) == 0x00c )
542 					{
543 						sprintf( buffer, "op%s", s_gtesf[ GTE_SF( op ) ] );
544 					}
545 					break;
546 				case 0x19:
547 					if( GTE_CT( op ) == 0x03d )
548 					{
549 						sprintf( buffer, "gpf%s", s_gtesf[ GTE_SF( op ) ] );
550 					}
551 					break;
552 				case 0x1a:
553 					if( GTE_CT( op ) == 0x03e )
554 					{
555 						sprintf( buffer, "gpl%s", s_gtesf[ GTE_SF( op ) ] );
556 					}
557 					break;
558 				}
559 			}
560 			break;
561 		}
562 		break;
563 	case OP_LB:
564 		sprintf( buffer, "lb      %s,%s(%s)", s_cpugenreg[ INS_RT( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ), s_cpugenreg[ INS_RS( op ) ] );
565 		break;
566 	case OP_LH:
567 		sprintf( buffer, "lh      %s,%s(%s)", s_cpugenreg[ INS_RT( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ), s_cpugenreg[ INS_RS( op ) ] );
568 		break;
569 	case OP_LWL:
570 		sprintf( buffer, "lwl     %s,%s(%s)", s_cpugenreg[ INS_RT( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ), s_cpugenreg[ INS_RS( op ) ] );
571 		break;
572 	case OP_LW:
573 		sprintf( buffer, "lw      %s,%s(%s)", s_cpugenreg[ INS_RT( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ), s_cpugenreg[ INS_RS( op ) ] );
574 		break;
575 	case OP_LBU:
576 		sprintf( buffer, "lbu     %s,%s(%s)", s_cpugenreg[ INS_RT( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ), s_cpugenreg[ INS_RS( op ) ] );
577 		break;
578 	case OP_LHU:
579 		sprintf( buffer, "lhu     %s,%s(%s)", s_cpugenreg[ INS_RT( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ), s_cpugenreg[ INS_RS( op ) ] );
580 		break;
581 	case OP_LWR:
582 		sprintf( buffer, "lwr     %s,%s(%s)", s_cpugenreg[ INS_RT( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ), s_cpugenreg[ INS_RS( op ) ] );
583 		break;
584 	case OP_SB:
585 		sprintf( buffer, "sb      %s,%s(%s)", s_cpugenreg[ INS_RT( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ), s_cpugenreg[ INS_RS( op ) ] );
586 		break;
587 	case OP_SH:
588 		sprintf( buffer, "sh      %s,%s(%s)", s_cpugenreg[ INS_RT( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ), s_cpugenreg[ INS_RS( op ) ] );
589 		break;
590 	case OP_SWL:
591 		sprintf( buffer, "swl     %s,%s(%s)", s_cpugenreg[ INS_RT( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ), s_cpugenreg[ INS_RS( op ) ] );
592 		break;
593 	case OP_SW:
594 		sprintf( buffer, "sw      %s,%s(%s)", s_cpugenreg[ INS_RT( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ), s_cpugenreg[ INS_RS( op ) ] );
595 		break;
596 	case OP_SWR:
597 		sprintf( buffer, "swr     %s,%s(%s)", s_cpugenreg[ INS_RT( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ), s_cpugenreg[ INS_RS( op ) ] );
598 		break;
599 	case OP_LWC1:
600 		sprintf( buffer, "lwc1    %s,%s(%s)", s_cp1genreg[ INS_RT( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ), s_cpugenreg[ INS_RS( op ) ] );
601 		break;
602 	case OP_LWC2:
603 		sprintf( buffer, "lwc2    %s,%s(%s)", s_cp2genreg[ INS_RT( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ), s_cpugenreg[ INS_RS( op ) ] );
604 		break;
605 	case OP_SWC1:
606 		sprintf( buffer, "swc1    %s,%s(%s)", s_cp1genreg[ INS_RT( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ), s_cpugenreg[ INS_RS( op ) ] );
607 		break;
608 	case OP_SWC2:
609 		sprintf( buffer, "swc2    %s,%s(%s)", s_cp2genreg[ INS_RT( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ), s_cpugenreg[ INS_RS( op ) ] );
610 		break;
611 	}
612 	return pc - oldpc;
613 }
614