1 /*
2  * Sony CXD8530AQ/CXD8530BQ/CXD8530CQ/CXD8661R
3  *
4  * PSX CPU emulator for the MAME project written by smf
5  * Thanks to Farfetch'd for information on the delay slot bug
6  *
7  * The PSX CPU is a custom r3000a with a built in
8  * geometry transform engine, no mmu & no data cache.
9  *
10  * There is a stall circuit for load delays, but
11  * it doesn't work if the load occurs in a branch
12  * delay slot.
13  *
14  */
15 
16 #include <stdio.h>
17 #include "cpuintrf.h"
18 #include "memory.h"
19 #include "mamedbg.h"
20 #include "psx.h"
21 #include "state.h"
22 #include "usrintrf.h"
23 
24 #define EXC_INT ( 0 )
25 #define EXC_ADEL ( 4 )
26 #define EXC_ADES ( 5 )
27 #define EXC_SYS ( 8 )
28 #define EXC_BP ( 9 )
29 #define EXC_RI ( 10 )
30 #define EXC_CPU ( 11 )
31 #define EXC_OVF ( 12 )
32 
33 #define CP0_RANDOM ( 1 )
34 #define CP0_BADVADDR ( 8 )
35 #define CP0_SR ( 12 )
36 #define CP0_CAUSE ( 13 )
37 #define CP0_EPC ( 14 )
38 #define CP0_PRID ( 15 )
39 
40 #define SR_IEC ( 1L << 0 )
41 #define SR_KUC ( 1L << 1 )
42 #define SR_ISC ( 1L << 16 )
43 #define SR_SWC ( 1L << 17 )
44 #define SR_TS  ( 1L << 21 )
45 #define SR_BEV ( 1L << 22 )
46 #define SR_RE ( 1L << 25 )
47 #define SR_CU0 ( 1L << 28 )
48 #define SR_CU1 ( 1L << 29 )
49 #define SR_CU2 ( 1L << 30 )
50 #define SR_CU3 ( 1L << 31 )
51 
52 #define CAUSE_EXC ( 31L << 2 )
53 #define CAUSE_IP ( 255L << 8 )
54 #define CAUSE_IP2 ( 1L << 10 )
55 #define CAUSE_IP3 ( 1L << 11 )
56 #define CAUSE_IP4 ( 1L << 12 )
57 #define CAUSE_IP5 ( 1L << 13 )
58 #define CAUSE_IP6 ( 1L << 14 )
59 #define CAUSE_IP7 ( 1L << 15 )
60 #define CAUSE_CE ( 3L << 28 )
61 #define CAUSE_CE0 ( 0L << 28 )
62 #define CAUSE_CE1 ( 1L << 28 )
63 #define CAUSE_CE2 ( 2L << 28 )
64 #define CAUSE_BD ( 1L << 31 )
65 
66 static UINT8 mips_reg_layout[] =
67 {
68 	MIPS_PC, -1,
69 	MIPS_DELAYV, MIPS_DELAYR, -1,
70 	MIPS_HI, MIPS_LO, -1,
71 	-1,
72 	MIPS_R0, MIPS_R1, -1,
73 	MIPS_R2, MIPS_R3, -1,
74 	MIPS_R4, MIPS_R5, -1,
75 	MIPS_R6, MIPS_R7, -1,
76 	MIPS_R8, MIPS_R9, -1,
77 	MIPS_R10, MIPS_R11, -1,
78 	MIPS_R12, MIPS_R13, -1,
79 	MIPS_R14, MIPS_R15, -1,
80 	MIPS_R16, MIPS_R17, -1,
81 	MIPS_R18, MIPS_R19, -1,
82 	MIPS_R20, MIPS_R21, -1,
83 	MIPS_R22, MIPS_R23, -1,
84 	MIPS_R24, MIPS_R25, -1,
85 	MIPS_R26, MIPS_R27, -1,
86 	MIPS_R28, MIPS_R29, -1,
87 	MIPS_R30, MIPS_R31, -1,
88 	-1,
89 	MIPS_CP0R0, MIPS_CP0R1, -1,
90 	MIPS_CP0R2, MIPS_CP0R3, -1,
91 	MIPS_CP0R4, MIPS_CP0R5, -1,
92 	MIPS_CP0R6, MIPS_CP0R7, -1,
93 	MIPS_CP0R8, MIPS_CP0R9, -1,
94 	MIPS_CP0R10, MIPS_CP0R11, -1,
95 	MIPS_CP0R12, MIPS_CP0R13, -1,
96 	MIPS_CP0R14, MIPS_CP0R15, -1,
97 	MIPS_CP0R16, MIPS_CP0R17, -1,
98 	MIPS_CP0R18, MIPS_CP0R19, -1,
99 	MIPS_CP0R20, MIPS_CP0R21, -1,
100 	MIPS_CP0R22, MIPS_CP0R23, -1,
101 	MIPS_CP0R24, MIPS_CP0R25, -1,
102 	MIPS_CP0R26, MIPS_CP0R27, -1,
103 	MIPS_CP0R28, MIPS_CP0R29, -1,
104 	MIPS_CP0R30, MIPS_CP0R31, -1,
105 	-1,
106 	MIPS_CP2DR0, MIPS_CP2DR1, -1,
107 	MIPS_CP2DR2, MIPS_CP2DR3, -1,
108 	MIPS_CP2DR4, MIPS_CP2DR5, -1,
109 	MIPS_CP2DR6, MIPS_CP2DR7, -1,
110 	MIPS_CP2DR8, MIPS_CP2DR9, -1,
111 	MIPS_CP2DR10, MIPS_CP2DR11, -1,
112 	MIPS_CP2DR12, MIPS_CP2DR13, -1,
113 	MIPS_CP2DR14, MIPS_CP2DR15, -1,
114 	MIPS_CP2DR16, MIPS_CP2DR17, -1,
115 	MIPS_CP2DR18, MIPS_CP2DR19, -1,
116 	MIPS_CP2DR20, MIPS_CP2DR21, -1,
117 	MIPS_CP2DR22, MIPS_CP2DR23, -1,
118 	MIPS_CP2DR24, MIPS_CP2DR25, -1,
119 	MIPS_CP2DR26, MIPS_CP2DR27, -1,
120 	MIPS_CP2DR28, MIPS_CP2DR29, -1,
121 	MIPS_CP2DR30, MIPS_CP2DR31, -1,
122 	-1,
123 	MIPS_CP2CR0, MIPS_CP2CR1, -1,
124 	MIPS_CP2CR2, MIPS_CP2CR3, -1,
125 	MIPS_CP2CR4, MIPS_CP2CR5, -1,
126 	MIPS_CP2CR6, MIPS_CP2CR7, -1,
127 	MIPS_CP2CR8, MIPS_CP2CR9, -1,
128 	MIPS_CP2CR10, MIPS_CP2CR11, -1,
129 	MIPS_CP2CR12, MIPS_CP2CR13, -1,
130 	MIPS_CP2CR14, MIPS_CP2CR15, -1,
131 	MIPS_CP2CR16, MIPS_CP2CR17, -1,
132 	MIPS_CP2CR18, MIPS_CP2CR19, -1,
133 	MIPS_CP2CR20, MIPS_CP2CR21, -1,
134 	MIPS_CP2CR22, MIPS_CP2CR23, -1,
135 	MIPS_CP2CR24, MIPS_CP2CR25, -1,
136 #if 0
137 /* the debugger interface is limited to 127 & the kludge no longer works */
138 	MIPS_CP2CR26, MIPS_CP2CR27, -1,
139 	MIPS_CP2CR28, MIPS_CP2CR29, -1,
140 	MIPS_CP2CR30, MIPS_CP2CR31,
141 #endif
142 	0
143 };
144 
145 static UINT8 mips_win_layout[] = {
146 	45, 0,35,13,	/* register window (top right) */
147 	 0, 0,44,13,	/* disassembler window (left, upper) */
148 	 0,14,44, 8,	/* memory #1 window (left, middle) */
149 	45,14,35, 8,	/* memory #2 window (lower) */
150 	 0,23,80, 1 	/* command line window (bottom rows) */
151 };
152 
153 static const char *delayn[] =
154 {
155 	"pc", "at", "v0", "v1", "a0", "a1", "a2", "a3",
156 	"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
157 	"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
158 	"t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra",
159 	"pc"
160 };
161 
162 #define REGPC ( 32 )
163 
164 typedef struct
165 {
166 	UINT32 op;
167 	UINT32 pc;
168 	UINT32 delayv;
169 	UINT32 delayr;
170 	UINT32 hi;
171 	UINT32 lo;
172 	UINT32 r[ 32 ];
173 	UINT32 cp0r[ 32 ];
174 	PAIR cp2cr[ 32 ];
175 	PAIR cp2dr[ 32 ];
176 	int (*irq_callback)(int irqline);
177 } mips_cpu_context;
178 
179 mips_cpu_context mipscpu;
180 
181 int mips_ICount = 0;
182 
183 static UINT32 mips_mtc0_writemask[]=
184 {
185 	0xffffffff, /* INDEX */
186 	0x00000000, /* RANDOM */
187 	0xffffff00, /* ENTRYLO */
188 	0x00000000,
189 	0xffe00000, /* CONTEXT */
190 	0x00000000,
191 	0x00000000,
192 	0x00000000,
193 	0x00000000, /* BADVADDR */
194 	0x00000000,
195 	0xffffffc0, /* ENTRYHI */
196 	0x00000000,
197 	0xf27fff3f, /* SR */
198 	0x00000300, /* CAUSE */
199 	0x00000000, /* EPC */
200 	0x00000000, /* PRID */
201 	0x00000000,
202 	0x00000000,
203 	0x00000000,
204 	0x00000000,
205 	0x00000000,
206 	0x00000000,
207 	0x00000000,
208 	0x00000000,
209 	0x00000000,
210 	0x00000000,
211 	0x00000000,
212 	0x00000000,
213 	0x00000000,
214 	0x00000000,
215 	0x00000000,
216 	0x00000000
217 };
218 
219 static UINT32 getcp2dr( int n_reg );
220 static void setcp2dr( int n_reg, UINT32 n_value );
221 static UINT32 getcp2cr( int n_reg );
222 static void setcp2cr( int n_reg, UINT32 n_value );
223 static void docop2( int gteop );
224 static void mips_exception( int exception );
225 
mips_stop(void)226 void mips_stop( void )
227 {
228 #ifdef MAME_DEBUG
229 	extern int debug_key_pressed;
230 	debug_key_pressed = 1;
231 	CALL_MAME_DEBUG;
232 #endif
233 }
234 
mips_set_cp0r(int reg,UINT32 value)235 static INLINE void mips_set_cp0r( int reg, UINT32 value )
236 {
237 	mipscpu.cp0r[ reg ] = value;
238 	if( reg == CP0_SR || reg == CP0_CAUSE )
239 	{
240 		if( ( mipscpu.cp0r[ CP0_SR ] & SR_IEC ) != 0 && ( mipscpu.cp0r[ CP0_SR ] & mipscpu.cp0r[ CP0_CAUSE ] & CAUSE_IP ) != 0 )
241 		{
242 			mips_exception( EXC_INT );
243 		}
244 		else if( mipscpu.delayr != REGPC && ( mipscpu.pc & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 3 ) ) != 0 )
245 		{
246 			mips_exception( EXC_ADEL );
247 			mips_set_cp0r( CP0_BADVADDR, mipscpu.pc );
248 		}
249 	}
250 }
251 
mips_commit_delayed_load(void)252 static INLINE void mips_commit_delayed_load( void )
253 {
254 	if( mipscpu.delayr != 0 )
255 	{
256 		mipscpu.r[ mipscpu.delayr ] = mipscpu.delayv;
257 		mipscpu.delayr = 0;
258 		mipscpu.delayv = 0;
259 	}
260 }
261 
mips_delayed_branch(UINT32 n_adr)262 static INLINE void mips_delayed_branch( UINT32 n_adr )
263 {
264 	if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 3 ) ) != 0 )
265 	{
266 		mips_exception( EXC_ADEL );
267 		mips_set_cp0r( CP0_BADVADDR, n_adr );
268 	}
269 	else
270 	{
271 		mips_commit_delayed_load();
272 		mipscpu.delayr = REGPC;
273 		mipscpu.delayv = n_adr;
274 		mipscpu.pc += 4;
275 	}
276 }
277 
mips_set_pc(unsigned val)278 static INLINE void mips_set_pc( unsigned val )
279 {
280 	mipscpu.pc = val;
281 	change_pc32ledw( val );
282 	mipscpu.delayr = 0;
283 	mipscpu.delayv = 0;
284 }
285 
mips_advance_pc(void)286 static INLINE void mips_advance_pc( void )
287 {
288 	if( mipscpu.delayr == REGPC )
289 	{
290 		mips_set_pc( mipscpu.delayv );
291 	}
292 	else
293 	{
294 		mips_commit_delayed_load();
295 		mipscpu.pc += 4;
296 	}
297 }
298 
mips_load(UINT32 n_r,UINT32 n_v)299 static INLINE void mips_load( UINT32 n_r, UINT32 n_v )
300 {
301 	mips_advance_pc();
302 	if( n_r != 0 )
303 	{
304 		mipscpu.r[ n_r ] = n_v;
305 	}
306 }
307 
mips_delayed_load(UINT32 n_r,UINT32 n_v)308 static INLINE void mips_delayed_load( UINT32 n_r, UINT32 n_v )
309 {
310 	if( mipscpu.delayr == REGPC )
311 	{
312 		mips_set_pc( mipscpu.delayv );
313 		mipscpu.delayr = n_r;
314 		mipscpu.delayv = n_v;
315 	}
316 	else
317 	{
318 		mips_commit_delayed_load();
319 		mipscpu.pc += 4;
320 		if( n_r != 0 )
321 		{
322 			mipscpu.r[ n_r ] = n_v;
323 		}
324 	}
325 }
326 
mips_exception(int exception)327 static void mips_exception( int exception )
328 {
329 	mips_set_cp0r( CP0_SR, ( mipscpu.cp0r[ CP0_SR ] & ~0x3f ) | ( ( mipscpu.cp0r[ CP0_SR ] << 2 ) & 0x3f ) );
330 	if( mipscpu.delayr == REGPC )
331 	{
332 		mips_set_cp0r( CP0_EPC, mipscpu.pc - 4 );
333 		mips_set_cp0r( CP0_CAUSE, ( mipscpu.cp0r[ CP0_CAUSE ] & ~CAUSE_EXC ) | CAUSE_BD | ( exception << 2 ) );
334 	}
335 	else
336 	{
337 		mips_commit_delayed_load();
338 		mips_set_cp0r( CP0_EPC, mipscpu.pc );
339 		mips_set_cp0r( CP0_CAUSE, ( mipscpu.cp0r[ CP0_CAUSE ] & ~( CAUSE_EXC | CAUSE_BD ) ) | ( exception << 2 ) );
340 	}
341 	if( mipscpu.cp0r[ CP0_SR ] & SR_BEV )
342 	{
343 		mips_set_pc( 0xbfc00180 );
344 	}
345 	else
346 	{
347 		mips_set_pc( 0x80000080 );
348 	}
349 }
350 
mips_init(void)351 void mips_init( void )
352 {
353 	int cpu = cpu_getactivecpu();
354 
355 	state_save_register_UINT32( "psxcpu", cpu, "op", &mipscpu.op, 1 );
356 	state_save_register_UINT32( "psxcpu", cpu, "pc", &mipscpu.pc, 1 );
357 	state_save_register_UINT32( "psxcpu", cpu, "delayv", &mipscpu.delayv, 1 );
358 	state_save_register_UINT32( "psxcpu", cpu, "delayr", &mipscpu.delayr, 1 );
359 	state_save_register_UINT32( "psxcpu", cpu, "hi", &mipscpu.hi, 1 );
360 	state_save_register_UINT32( "psxcpu", cpu, "lo", &mipscpu.lo, 1 );
361 	state_save_register_UINT32( "psxcpu", cpu, "r", &mipscpu.r[ 0 ], 32 );
362 	state_save_register_UINT32( "psxcpu", cpu, "cp0r", &mipscpu.cp0r[ 0 ], 32 );
363 	state_save_register_UINT32( "psxcpu", cpu, "cp2cr", &mipscpu.cp2cr[ 0 ].d, 32 );
364 	state_save_register_UINT32( "psxcpu", cpu, "cp2dr", &mipscpu.cp2dr[ 0 ].d, 32 );
365 }
366 
mips_reset(void * param)367 void mips_reset( void *param )
368 {
369 	mips_set_cp0r( CP0_SR, ( mipscpu.cp0r[ CP0_SR ] & ~( SR_TS | SR_SWC | SR_KUC | SR_IEC ) ) | SR_BEV );
370 	mips_set_cp0r( CP0_RANDOM, 63 ); /* todo: */
371 	mips_set_cp0r( CP0_PRID, 0x00000200 ); /* todo: */
372 	mips_set_pc( 0xbfc00000 );
373 }
374 
mips_exit(void)375 void mips_exit( void )
376 {
377 }
378 
mips_execute(int cycles)379 int mips_execute( int cycles )
380 {
381 	UINT32 n_res;
382 
383 	mips_ICount = cycles;
384 	do
385 	{
386 		CALL_MAME_DEBUG;
387 
388 		mipscpu.op = cpu_readop32( mipscpu.pc );
389 		switch( INS_OP( mipscpu.op ) )
390 		{
391 		case OP_SPECIAL:
392 			switch( INS_FUNCT( mipscpu.op ) )
393 			{
394 			case FUNCT_SLL:
395 				mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RT( mipscpu.op ) ] << INS_SHAMT( mipscpu.op ) );
396 				break;
397 			case FUNCT_SRL:
398 				mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RT( mipscpu.op ) ] >> INS_SHAMT( mipscpu.op ) );
399 				break;
400 			case FUNCT_SRA:
401 				mips_load( INS_RD( mipscpu.op ), (INT32)mipscpu.r[ INS_RT( mipscpu.op ) ] >> INS_SHAMT( mipscpu.op ) );
402 				break;
403 			case FUNCT_SLLV:
404 				mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RT( mipscpu.op ) ] << ( mipscpu.r[ INS_RS( mipscpu.op ) ] & 31 ) );
405 				break;
406 			case FUNCT_SRLV:
407 				mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RT( mipscpu.op ) ] >> ( mipscpu.r[ INS_RS( mipscpu.op ) ] & 31 ) );
408 				break;
409 			case FUNCT_SRAV:
410 				mips_load( INS_RD( mipscpu.op ), (INT32)mipscpu.r[ INS_RT( mipscpu.op ) ] >> ( mipscpu.r[ INS_RS( mipscpu.op ) ] & 31 ) );
411 				break;
412 			case FUNCT_JR:
413 				if( INS_RD( mipscpu.op ) != 0 )
414 				{
415 					mips_exception( EXC_RI );
416 				}
417 				else
418 				{
419 					mips_delayed_branch( mipscpu.r[ INS_RS( mipscpu.op ) ] );
420 				}
421 				break;
422 			case FUNCT_JALR:
423 				n_res = mipscpu.pc + 8;
424 				mips_delayed_branch( mipscpu.r[ INS_RS( mipscpu.op ) ] );
425 				if( INS_RD( mipscpu.op ) != 0 )
426 				{
427 					mipscpu.r[ INS_RD( mipscpu.op ) ] = n_res;
428 				}
429 				break;
430 			case FUNCT_SYSCALL:
431 				mips_exception( EXC_SYS );
432 				break;
433 			case FUNCT_BREAK:
434 				mips_exception( EXC_BP );
435 				break;
436 			case FUNCT_MFHI:
437 				mips_load( INS_RD( mipscpu.op ), mipscpu.hi );
438 				break;
439 			case FUNCT_MTHI:
440 				if( INS_RD( mipscpu.op ) != 0 )
441 				{
442 					mips_exception( EXC_RI );
443 				}
444 				else
445 				{
446 					mips_advance_pc();
447 					mipscpu.hi = mipscpu.r[ INS_RS( mipscpu.op ) ];
448 				}
449 				break;
450 			case FUNCT_MFLO:
451 				mips_load( INS_RD( mipscpu.op ),  mipscpu.lo );
452 				break;
453 			case FUNCT_MTLO:
454 				if( INS_RD( mipscpu.op ) != 0 )
455 				{
456 					mips_exception( EXC_RI );
457 				}
458 				else
459 				{
460 					mips_advance_pc();
461 					mipscpu.lo = mipscpu.r[ INS_RS( mipscpu.op ) ];
462 				}
463 				break;
464 			case FUNCT_MULT:
465 				if( INS_RD( mipscpu.op ) != 0 )
466 				{
467 					mips_exception( EXC_RI );
468 				}
469 				else
470 				{
471 					INT64 n_res64;
472 					n_res64 = MUL_64_32_32( (INT32)mipscpu.r[ INS_RS( mipscpu.op ) ], (INT32)mipscpu.r[ INS_RT( mipscpu.op ) ] );
473 					mips_advance_pc();
474 					mipscpu.lo = LO32_32_64( n_res64 );
475 					mipscpu.hi = HI32_32_64( n_res64 );
476 				}
477 				break;
478 			case FUNCT_MULTU:
479 				if( INS_RD( mipscpu.op ) != 0 )
480 				{
481 					mips_exception( EXC_RI );
482 				}
483 				else
484 				{
485 					UINT64 n_res64;
486 					n_res64 = MUL_U64_U32_U32( mipscpu.r[ INS_RS( mipscpu.op ) ], mipscpu.r[ INS_RT( mipscpu.op ) ] );
487 					mips_advance_pc();
488 					mipscpu.lo = LO32_U32_U64( n_res64 );
489 					mipscpu.hi = HI32_U32_U64( n_res64 );
490 				}
491 				break;
492 			case FUNCT_DIV:
493 				if( INS_RD( mipscpu.op ) != 0 )
494 				{
495 					mips_exception( EXC_RI );
496 				}
497 				else
498 				{
499 					UINT32 n_div;
500 					UINT32 n_mod;
501 					if( mipscpu.r[ INS_RT( mipscpu.op ) ] != 0 )
502 					{
503 						n_div = (INT32)mipscpu.r[ INS_RS( mipscpu.op ) ] / (INT32)mipscpu.r[ INS_RT( mipscpu.op ) ];
504 						n_mod = (INT32)mipscpu.r[ INS_RS( mipscpu.op ) ] % (INT32)mipscpu.r[ INS_RT( mipscpu.op ) ];
505 						mips_advance_pc();
506 						mipscpu.lo = n_div;
507 						mipscpu.hi = n_mod;
508 					}
509 					else
510 					{
511 						mips_advance_pc();
512 					}
513 				}
514 				break;
515 			case FUNCT_DIVU:
516 				if( INS_RD( mipscpu.op ) != 0 )
517 				{
518 					mips_exception( EXC_RI );
519 				}
520 				else
521 				{
522 					UINT32 n_div;
523 					UINT32 n_mod;
524 					if( mipscpu.r[ INS_RT( mipscpu.op ) ] != 0 )
525 					{
526 						n_div = mipscpu.r[ INS_RS( mipscpu.op ) ] / mipscpu.r[ INS_RT( mipscpu.op ) ];
527 						n_mod = mipscpu.r[ INS_RS( mipscpu.op ) ] % mipscpu.r[ INS_RT( mipscpu.op ) ];
528 						mips_advance_pc();
529 						mipscpu.lo = n_div;
530 						mipscpu.hi = n_mod;
531 					}
532 					else
533 					{
534 						mips_advance_pc();
535 					}
536 				}
537 				break;
538 			case FUNCT_ADD:
539 				{
540 					n_res = mipscpu.r[ INS_RS( mipscpu.op ) ] + mipscpu.r[ INS_RT( mipscpu.op ) ];
541 					if( (INT32)( ~( mipscpu.r[ INS_RS( mipscpu.op ) ] ^ mipscpu.r[ INS_RT( mipscpu.op ) ] ) & ( mipscpu.r[ INS_RS( mipscpu.op ) ] ^ n_res ) ) < 0 )
542 					{
543 						mips_exception( EXC_OVF );
544 					}
545 					else
546 					{
547 						mips_load( INS_RD( mipscpu.op ), n_res );
548 					}
549 				}
550 				break;
551 			case FUNCT_ADDU:
552 				mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] + mipscpu.r[ INS_RT( mipscpu.op ) ] );
553 				break;
554 			case FUNCT_SUB:
555 				n_res = mipscpu.r[ INS_RS( mipscpu.op ) ] - mipscpu.r[ INS_RT( mipscpu.op ) ];
556 				if( (INT32)( ( mipscpu.r[ INS_RS( mipscpu.op ) ] ^ mipscpu.r[ INS_RT( mipscpu.op ) ] ) & ( mipscpu.r[ INS_RS( mipscpu.op ) ] ^ n_res ) ) < 0 )
557 				{
558 					mips_exception( EXC_OVF );
559 				}
560 				else
561 				{
562 					mips_load( INS_RD( mipscpu.op ), n_res );
563 				}
564 				break;
565 			case FUNCT_SUBU:
566 				mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] - mipscpu.r[ INS_RT( mipscpu.op ) ] );
567 				break;
568 			case FUNCT_AND:
569 				mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] & mipscpu.r[ INS_RT( mipscpu.op ) ] );
570 				break;
571 			case FUNCT_OR:
572 				mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] | mipscpu.r[ INS_RT( mipscpu.op ) ] );
573 				break;
574 			case FUNCT_XOR:
575 				mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] ^ mipscpu.r[ INS_RT( mipscpu.op ) ] );
576 				break;
577 			case FUNCT_NOR:
578 				mips_load( INS_RD( mipscpu.op ), ~( mipscpu.r[ INS_RS( mipscpu.op ) ] | mipscpu.r[ INS_RT( mipscpu.op ) ] ) );
579 				break;
580 			case FUNCT_SLT:
581 				mips_load( INS_RD( mipscpu.op ), (INT32)mipscpu.r[ INS_RS( mipscpu.op ) ] < (INT32)mipscpu.r[ INS_RT( mipscpu.op ) ] );
582 				break;
583 			case FUNCT_SLTU:
584 				mips_load( INS_RD( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] < mipscpu.r[ INS_RT( mipscpu.op ) ] );
585 				break;
586 			default:
587 				mips_exception( EXC_RI );
588 				break;
589 			}
590 			break;
591 		case OP_REGIMM:
592 			switch( INS_RT( mipscpu.op ) )
593 			{
594 			case RT_BLTZ:
595 				if( (INT32)mipscpu.r[ INS_RS( mipscpu.op ) ] < 0 )
596 				{
597 					mips_delayed_branch( mipscpu.pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) << 2 ) );
598 				}
599 				else
600 				{
601 					mips_advance_pc();
602 				}
603 				break;
604 			case RT_BGEZ:
605 				if( (INT32)mipscpu.r[ INS_RS( mipscpu.op ) ] >= 0 )
606 				{
607 					mips_delayed_branch( mipscpu.pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) << 2 ) );
608 				}
609 				else
610 				{
611 					mips_advance_pc();
612 				}
613 				break;
614 			case RT_BLTZAL:
615 				n_res = mipscpu.pc + 8;
616 				if( (INT32)mipscpu.r[ INS_RS( mipscpu.op ) ] < 0 )
617 				{
618 					mips_delayed_branch( mipscpu.pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) << 2 ) );
619 				}
620 				else
621 				{
622 					mips_advance_pc();
623 				}
624 				mipscpu.r[ 31 ] = n_res;
625 				break;
626 			case RT_BGEZAL:
627 				n_res = mipscpu.pc + 8;
628 				if( (INT32)mipscpu.r[ INS_RS( mipscpu.op ) ] >= 0 )
629 				{
630 					mips_delayed_branch( mipscpu.pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) << 2 ) );
631 				}
632 				else
633 				{
634 					mips_advance_pc();
635 				}
636 				mipscpu.r[ 31 ] = n_res;
637 				break;
638 			}
639 			break;
640 		case OP_J:
641 			mips_delayed_branch( ( ( mipscpu.pc + 4 ) & 0xf0000000 ) + ( INS_TARGET( mipscpu.op ) << 2 ) );
642 			break;
643 		case OP_JAL:
644 			n_res = mipscpu.pc + 8;
645 			mips_delayed_branch( ( ( mipscpu.pc + 4 ) & 0xf0000000 ) + ( INS_TARGET( mipscpu.op ) << 2 ) );
646 			mipscpu.r[ 31 ] = n_res;
647 			break;
648 		case OP_BEQ:
649 			if( mipscpu.r[ INS_RS( mipscpu.op ) ] == mipscpu.r[ INS_RT( mipscpu.op ) ] )
650 			{
651 				mips_delayed_branch( mipscpu.pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) << 2 ) );
652 			}
653 			else
654 			{
655 				mips_advance_pc();
656 			}
657 			break;
658 		case OP_BNE:
659 			if( mipscpu.r[ INS_RS( mipscpu.op ) ] != mipscpu.r[ INS_RT( mipscpu.op ) ] )
660 			{
661 				mips_delayed_branch( mipscpu.pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) << 2 ) );
662 			}
663 			else
664 			{
665 				mips_advance_pc();
666 			}
667 			break;
668 		case OP_BLEZ:
669 			if( INS_RT( mipscpu.op ) != 0 )
670 			{
671 				mips_exception( EXC_RI );
672 			}
673 			else if( (INT32)mipscpu.r[ INS_RS( mipscpu.op ) ] <= 0 )
674 			{
675 				mips_delayed_branch( mipscpu.pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) << 2 ) );
676 			}
677 			else
678 			{
679 				mips_advance_pc();
680 			}
681 			break;
682 		case OP_BGTZ:
683 			if( INS_RT( mipscpu.op ) != 0 )
684 			{
685 				mips_exception( EXC_RI );
686 			}
687 			else if( (INT32)mipscpu.r[ INS_RS( mipscpu.op ) ] > 0 )
688 			{
689 				mips_delayed_branch( mipscpu.pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) << 2 ) );
690 			}
691 			else
692 			{
693 				mips_advance_pc();
694 			}
695 			break;
696 		case OP_ADDI:
697 			{
698 				UINT32 n_imm;
699 				n_imm = MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
700 				n_res = mipscpu.r[ INS_RS( mipscpu.op ) ] + n_imm;
701 				if( (INT32)( ~( mipscpu.r[ INS_RS( mipscpu.op ) ] ^ n_imm ) & ( mipscpu.r[ INS_RS( mipscpu.op ) ] ^ n_res ) ) < 0 )
702 				{
703 					mips_exception( EXC_OVF );
704 				}
705 				else
706 				{
707 					mips_load( INS_RT( mipscpu.op ), n_res );
708 				}
709 			}
710 			break;
711 		case OP_ADDIU:
712 			mips_load( INS_RT( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) );
713 			break;
714 		case OP_SLTI:
715 			mips_load( INS_RT( mipscpu.op ), (INT32)mipscpu.r[ INS_RS( mipscpu.op ) ] < MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) );
716 			break;
717 		case OP_SLTIU:
718 			mips_load( INS_RT( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] < (UINT32)MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) ) );
719 			break;
720 		case OP_ANDI:
721 			mips_load( INS_RT( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] & INS_IMMEDIATE( mipscpu.op ) );
722 			break;
723 		case OP_ORI:
724 			mips_load( INS_RT( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] | INS_IMMEDIATE( mipscpu.op ) );
725 			break;
726 		case OP_XORI:
727 			mips_load( INS_RT( mipscpu.op ), mipscpu.r[ INS_RS( mipscpu.op ) ] ^ INS_IMMEDIATE( mipscpu.op ) );
728 			break;
729 		case OP_LUI:
730 			mips_load( INS_RT( mipscpu.op ), INS_IMMEDIATE( mipscpu.op ) << 16 );
731 			break;
732 		case OP_COP0:
733 			if( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) != 0 && ( mipscpu.cp0r[ CP0_SR ] & SR_CU0 ) == 0 )
734 			{
735 				mips_exception( EXC_CPU );
736 				mips_set_cp0r( CP0_CAUSE, ( mipscpu.cp0r[ CP0_CAUSE ] & ~CAUSE_CE ) | CAUSE_CE0 );
737 			}
738 			else
739 			{
740 				switch( INS_RS( mipscpu.op ) )
741 				{
742 				case RS_MFC:
743 					mips_delayed_load( INS_RT( mipscpu.op ), mipscpu.cp0r[ INS_RD( mipscpu.op ) ] );
744 					break;
745 				case RS_CFC:
746 					/* todo: */
747 					log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: COP0 CFC not supported\n", mipscpu.pc );
748 					mips_stop();
749 					mips_advance_pc();
750 					break;
751 				case RS_MTC:
752 					n_res = ( mipscpu.cp0r[ INS_RD( mipscpu.op ) ] & ~mips_mtc0_writemask[ INS_RD( mipscpu.op ) ] ) |
753 						( mipscpu.r[ INS_RT( mipscpu.op ) ] & mips_mtc0_writemask[ INS_RD( mipscpu.op ) ] );
754 					mips_advance_pc();
755 					mips_set_cp0r( INS_RD( mipscpu.op ), n_res );
756 					break;
757 				case RS_CTC:
758 					/* todo: */
759 					log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: COP0 CTC not supported\n", mipscpu.pc );
760 					mips_stop();
761 					mips_advance_pc();
762 					break;
763 				case RS_BC:
764 					switch( INS_RT( mipscpu.op ) )
765 					{
766 					case RT_BCF:
767 						/* todo: */
768 						log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: COP0 BCF not supported\n", mipscpu.pc );
769 						mips_stop();
770 						mips_advance_pc();
771 						break;
772 					case RT_BCT:
773 						/* todo: */
774 						log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: COP0 BCT not supported\n", mipscpu.pc );
775 						mips_stop();
776 						mips_advance_pc();
777 						break;
778 					default:
779 						/* todo: */
780 						log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: COP0 unknown command %08x\n", mipscpu.pc, mipscpu.op );
781 						mips_stop();
782 						mips_advance_pc();
783 						break;
784 					}
785 					break;
786 				default:
787 					switch( INS_CO( mipscpu.op ) )
788 					{
789 					case 1:
790 						switch( INS_CF( mipscpu.op ) )
791 						{
792 						case CF_RFE:
793 							mips_advance_pc();
794 							mips_set_cp0r( CP0_SR, ( mipscpu.cp0r[ CP0_SR ] & ~0xf ) | ( ( mipscpu.cp0r[ CP0_SR ] >> 2 ) & 0xf ) );
795 							break;
796 						default:
797 							/* todo: */
798 							log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: COP0 unknown command %08x\n", mipscpu.pc, mipscpu.op );
799 							mips_stop();
800 							mips_advance_pc();
801 							break;
802 						}
803 						break;
804 					default:
805 						/* todo: */
806 						log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: COP0 unknown command %08x\n", mipscpu.pc, mipscpu.op );
807 						mips_stop();
808 						mips_advance_pc();
809 						break;
810 					}
811 					break;
812 				}
813 			}
814 			break;
815 		case OP_COP1:
816 			if( ( mipscpu.cp0r[ CP0_SR ] & SR_CU1 ) == 0 )
817 			{
818 				mips_exception( EXC_CPU );
819 				mips_set_cp0r( CP0_CAUSE, ( mipscpu.cp0r[ CP0_CAUSE ] & ~CAUSE_CE ) | CAUSE_CE1 );
820 			}
821 			else
822 			{
823 				switch( INS_RS( mipscpu.op ) )
824 				{
825 				case RS_MFC:
826 					/* todo: */
827 					log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: COP1 BCT not supported\n", mipscpu.pc );
828 					mips_stop();
829 					mips_advance_pc();
830 					break;
831 				case RS_CFC:
832 					/* todo: */
833 					log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: COP1 CFC not supported\n", mipscpu.pc );
834 					mips_stop();
835 					mips_advance_pc();
836 					break;
837 				case RS_MTC:
838 					/* todo: */
839 					log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: COP1 MTC not supported\n", mipscpu.pc );
840 					mips_stop();
841 					mips_advance_pc();
842 					break;
843 				case RS_CTC:
844 					/* todo: */
845 					log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: COP1 CTC not supported\n", mipscpu.pc );
846 					mips_stop();
847 					mips_advance_pc();
848 					break;
849 				case RS_BC:
850 					switch( INS_RT( mipscpu.op ) )
851 					{
852 					case RT_BCF:
853 						/* todo: */
854 						log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: COP1 BCF not supported\n", mipscpu.pc );
855 						mips_stop();
856 						mips_advance_pc();
857 						break;
858 					case RT_BCT:
859 						/* todo: */
860 						log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: COP1 BCT not supported\n", mipscpu.pc );
861 						mips_stop();
862 						mips_advance_pc();
863 						break;
864 					default:
865 						/* todo: */
866 						log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: COP1 unknown command %08x\n", mipscpu.pc, mipscpu.op );
867 						mips_stop();
868 						mips_advance_pc();
869 						break;
870 					}
871 					break;
872 				default:
873 					switch( INS_CO( mipscpu.op ) )
874 					{
875 					case 1:
876 						/* todo: */
877 						log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: COP1 unknown command %08x\n", mipscpu.pc, mipscpu.op );
878 						mips_stop();
879 						mips_advance_pc();
880 						break;
881 					default:
882 						/* todo: */
883 						log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: COP1 unknown command %08x\n", mipscpu.pc, mipscpu.op );
884 						mips_stop();
885 						mips_advance_pc();
886 						break;
887 					}
888 					break;
889 				}
890 			}
891 			break;
892 		case OP_COP2:
893 			if( ( mipscpu.cp0r[ CP0_SR ] & SR_CU2 ) == 0 )
894 			{
895 				mips_exception( EXC_CPU );
896 				mips_set_cp0r( CP0_CAUSE, ( mipscpu.cp0r[ CP0_CAUSE ] & ~CAUSE_CE ) | CAUSE_CE2 );
897 			}
898 			else
899 			{
900 				switch( INS_RS( mipscpu.op ) )
901 				{
902 				case RS_MFC:
903 					mips_delayed_load( INS_RT( mipscpu.op ), getcp2dr( INS_RD( mipscpu.op ) ) );
904 					break;
905 				case RS_CFC:
906 					mips_delayed_load( INS_RT( mipscpu.op ), getcp2cr( INS_RD( mipscpu.op ) ) );
907 					break;
908 				case RS_MTC:
909 					setcp2dr( INS_RD( mipscpu.op ), mipscpu.r[ INS_RT( mipscpu.op ) ] );
910 					mips_advance_pc();
911 					break;
912 				case RS_CTC:
913 					setcp2cr( INS_RD( mipscpu.op ), mipscpu.r[ INS_RT( mipscpu.op ) ] );
914 					mips_advance_pc();
915 					break;
916 				case RS_BC:
917 					switch( INS_RT( mipscpu.op ) )
918 					{
919 					case RT_BCF:
920 						/* todo: */
921 						log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: COP2 BCF not supported\n", mipscpu.pc );
922 						mips_stop();
923 						mips_advance_pc();
924 						break;
925 					case RT_BCT:
926 						/* todo: */
927 						log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: COP2 BCT not supported\n", mipscpu.pc );
928 						mips_stop();
929 						mips_advance_pc();
930 						break;
931 					default:
932 						/* todo: */
933 						log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: COP2 unknown command %08x\n", mipscpu.pc, mipscpu.op );
934 						mips_stop();
935 						mips_advance_pc();
936 						break;
937 					}
938 					break;
939 				default:
940 					switch( INS_CO( mipscpu.op ) )
941 					{
942 					case 1:
943 						docop2( INS_COFUN( mipscpu.op ) );
944 						mips_advance_pc();
945 						break;
946 					default:
947 						/* todo: */
948 						log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: COP2 unknown command %08x\n", mipscpu.pc, mipscpu.op );
949 						mips_stop();
950 						mips_advance_pc();
951 						break;
952 					}
953 					break;
954 				}
955 			}
956 			break;
957 		case OP_LB:
958 			if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
959 			{
960 				/* todo: */
961 				log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: LB SR_ISC not supported\n", mipscpu.pc );
962 				mips_stop();
963 				mips_advance_pc();
964 			}
965 			else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
966 			{
967 				UINT32 n_adr;
968 				n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
969 				if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
970 				{
971 					mips_exception( EXC_ADEL );
972 					mips_set_cp0r( CP0_BADVADDR, n_adr );
973 				}
974 				else
975 				{
976 					mips_delayed_load( INS_RT( mipscpu.op ), MIPS_BYTE_EXTEND( cpu_readmem32ledw( n_adr ^ 3 ) ) );
977 				}
978 			}
979 			else
980 			{
981 				UINT32 n_adr;
982 				n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
983 				if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
984 				{
985 					mips_exception( EXC_ADEL );
986 					mips_set_cp0r( CP0_BADVADDR, n_adr );
987 				}
988 				else
989 				{
990 					mips_delayed_load( INS_RT( mipscpu.op ), MIPS_BYTE_EXTEND( cpu_readmem32ledw( n_adr ) ) );
991 				}
992 			}
993 			break;
994 		case OP_LH:
995 			if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
996 			{
997 				/* todo: */
998 				log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: LH SR_ISC not supported\n", mipscpu.pc );
999 				mips_stop();
1000 				mips_advance_pc();
1001 			}
1002 			else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
1003 			{
1004 				UINT32 n_adr;
1005 				n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
1006 				if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 1 ) ) != 0 )
1007 				{
1008 					mips_exception( EXC_ADEL );
1009 					mips_set_cp0r( CP0_BADVADDR, n_adr );
1010 				}
1011 				else
1012 				{
1013 					mips_delayed_load( INS_RT( mipscpu.op ), MIPS_WORD_EXTEND( cpu_readmem32ledw_word( n_adr ^ 2 ) ) );
1014 				}
1015 			}
1016 			else
1017 			{
1018 				UINT32 n_adr;
1019 				n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
1020 				if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 1 ) ) != 0 )
1021 				{
1022 					mips_exception( EXC_ADEL );
1023 					mips_set_cp0r( CP0_BADVADDR, n_adr );
1024 				}
1025 				else
1026 				{
1027 					mips_delayed_load( INS_RT( mipscpu.op ), MIPS_WORD_EXTEND( cpu_readmem32ledw_word( n_adr ) ) );
1028 				}
1029 			}
1030 			break;
1031 		case OP_LWL:
1032 			if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
1033 			{
1034 				/* todo: */
1035 				log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: LWL SR_ISC not supported\n", mipscpu.pc );
1036 				mips_stop();
1037 				mips_advance_pc();
1038 			}
1039 			else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
1040 			{
1041 				UINT32 n_adr;
1042 				n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
1043 				if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
1044 				{
1045 					mips_exception( EXC_ADEL );
1046 					mips_set_cp0r( CP0_BADVADDR, n_adr );
1047 				}
1048 				else
1049 				{
1050 					switch( n_adr & 3 )
1051 					{
1052 					case 0:
1053 						n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0x00ffffff ) | ( (UINT32)cpu_readmem32ledw( n_adr + 3 ) << 24 );
1054 						break;
1055 					case 1:
1056 						n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0x0000ffff ) | ( (UINT32)cpu_readmem32ledw_word( n_adr + 1 ) << 16 );
1057 						break;
1058 					case 2:
1059 						n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0x000000ff ) | ( (UINT32)cpu_readmem32ledw( n_adr - 1 ) << 8 ) | ( (UINT32)cpu_readmem32ledw_word( n_adr ) << 16 );
1060 						break;
1061 					default:
1062 						n_res = cpu_readmem32ledw_dword( n_adr - 3 );
1063 						break;
1064 					}
1065 					mips_delayed_load( INS_RT( mipscpu.op ), n_res );
1066 				}
1067 			}
1068 			else
1069 			{
1070 				UINT32 n_adr;
1071 				n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
1072 				if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
1073 				{
1074 					mips_exception( EXC_ADEL );
1075 					mips_set_cp0r( CP0_BADVADDR, n_adr );
1076 				}
1077 				else
1078 				{
1079 					switch( n_adr & 3 )
1080 					{
1081 					case 0:
1082 						n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0x00ffffff ) | ( (UINT32)cpu_readmem32ledw( n_adr ) << 24 );
1083 						break;
1084 					case 1:
1085 						n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0x0000ffff ) | ( (UINT32)cpu_readmem32ledw_word( n_adr - 1 ) << 16 );
1086 						break;
1087 					case 2:
1088 						n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0x000000ff ) | ( (UINT32)cpu_readmem32ledw_word( n_adr - 2 ) << 8 ) | ( (UINT32)cpu_readmem32ledw( n_adr ) << 24 );
1089 						break;
1090 					default:
1091 						n_res = cpu_readmem32ledw_dword( n_adr - 3 );
1092 						break;
1093 					}
1094 					mips_delayed_load( INS_RT( mipscpu.op ), n_res );
1095 				}
1096 			}
1097 			break;
1098 		case OP_LW:
1099 			if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
1100 			{
1101 				/* todo: */
1102 				log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: LW SR_ISC not supported\n", mipscpu.pc );
1103 				mips_stop();
1104 				mips_advance_pc();
1105 			}
1106 			else
1107 			{
1108 				UINT32 n_adr;
1109 				n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
1110 				if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 3 ) ) != 0 )
1111 				{
1112 					mips_exception( EXC_ADEL );
1113 					mips_set_cp0r( CP0_BADVADDR, n_adr );
1114 				}
1115 				else
1116 				{
1117 					mips_delayed_load( INS_RT( mipscpu.op ), cpu_readmem32ledw_dword( n_adr ) );
1118 				}
1119 			}
1120 			break;
1121 		case OP_LBU:
1122 			if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
1123 			{
1124 				/* todo: */
1125 				log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: LBU SR_ISC not supported\n", mipscpu.pc );
1126 				mips_stop();
1127 				mips_advance_pc();
1128 			}
1129 			else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
1130 			{
1131 				UINT32 n_adr;
1132 				n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
1133 				if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
1134 				{
1135 					mips_exception( EXC_ADEL );
1136 					mips_set_cp0r( CP0_BADVADDR, n_adr );
1137 				}
1138 				else
1139 				{
1140 					mips_delayed_load( INS_RT( mipscpu.op ), cpu_readmem32ledw( n_adr ^ 3 ) );
1141 				}
1142 			}
1143 			else
1144 			{
1145 				UINT32 n_adr;
1146 				n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
1147 				if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
1148 				{
1149 					mips_exception( EXC_ADEL );
1150 					mips_set_cp0r( CP0_BADVADDR, n_adr );
1151 				}
1152 				else
1153 				{
1154 					mips_delayed_load( INS_RT( mipscpu.op ), cpu_readmem32ledw( n_adr ) );
1155 				}
1156 			}
1157 			break;
1158 		case OP_LHU:
1159 			if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
1160 			{
1161 				/* todo: */
1162 				log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: LHU SR_ISC not supported\n", mipscpu.pc );
1163 				mips_stop();
1164 				mips_advance_pc();
1165 			}
1166 			else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
1167 			{
1168 				UINT32 n_adr;
1169 				n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
1170 				if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 1 ) ) != 0 )
1171 				{
1172 					mips_exception( EXC_ADEL );
1173 					mips_set_cp0r( CP0_BADVADDR, n_adr );
1174 				}
1175 				else
1176 				{
1177 					mips_delayed_load( INS_RT( mipscpu.op ), cpu_readmem32ledw_word( n_adr ^ 2 ) );
1178 				}
1179 			}
1180 			else
1181 			{
1182 				UINT32 n_adr;
1183 				n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
1184 				if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 1 ) ) != 0 )
1185 				{
1186 					mips_exception( EXC_ADEL );
1187 					mips_set_cp0r( CP0_BADVADDR, n_adr );
1188 				}
1189 				else
1190 				{
1191 					mips_delayed_load( INS_RT( mipscpu.op ), cpu_readmem32ledw_word( n_adr ) );
1192 				}
1193 			}
1194 			break;
1195 		case OP_LWR:
1196 			if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
1197 			{
1198 				/* todo: */
1199 				log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: LWR SR_ISC not supported\n", mipscpu.pc );
1200 				mips_stop();
1201 				mips_advance_pc();
1202 			}
1203 			else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
1204 			{
1205 				UINT32 n_adr;
1206 				n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
1207 				if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
1208 				{
1209 					mips_exception( EXC_ADEL );
1210 					mips_set_cp0r( CP0_BADVADDR, n_adr );
1211 				}
1212 				else
1213 				{
1214 					switch( n_adr & 3 )
1215 					{
1216 					case 3:
1217 						n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0xffffff00 ) | cpu_readmem32ledw( n_adr - 3 );
1218 						break;
1219 					case 2:
1220 						n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0xffff0000 ) | cpu_readmem32ledw_word( n_adr - 2 );
1221 						break;
1222 					case 1:
1223 						n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0xff000000 ) | cpu_readmem32ledw_word( n_adr - 1 ) | ( (UINT32)cpu_readmem32ledw( n_adr + 1 ) << 16 );
1224 						break;
1225 					default:
1226 						n_res = cpu_readmem32ledw_dword( n_adr );
1227 						break;
1228 					}
1229 					mips_delayed_load( INS_RT( mipscpu.op ), n_res );
1230 				}
1231 			}
1232 			else
1233 			{
1234 				UINT32 n_adr;
1235 				n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
1236 				if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
1237 				{
1238 					mips_exception( EXC_ADEL );
1239 					mips_set_cp0r( CP0_BADVADDR, n_adr );
1240 				}
1241 				else
1242 				{
1243 					switch( n_adr & 3 )
1244 					{
1245 					case 3:
1246 						n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0xffffff00 ) | cpu_readmem32ledw( n_adr );
1247 						break;
1248 					case 2:
1249 						n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0xffff0000 ) | cpu_readmem32ledw_word( n_adr );
1250 						break;
1251 					case 1:
1252 						n_res = ( mipscpu.r[ INS_RT( mipscpu.op ) ] & 0xff000000 ) | cpu_readmem32ledw( n_adr ) | ( (UINT32)cpu_readmem32ledw_word( n_adr + 1 ) << 8 );
1253 						break;
1254 					default:
1255 						n_res = cpu_readmem32ledw_dword( n_adr );
1256 						break;
1257 					}
1258 					mips_delayed_load( INS_RT( mipscpu.op ), n_res );
1259 				}
1260 			}
1261 			break;
1262 		case OP_SB:
1263 			if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
1264 			{
1265 				/* todo: */
1266 				log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: SB SR_ISC not supported\n", mipscpu.pc );
1267 				mips_stop();
1268 				mips_advance_pc();
1269 			}
1270 			else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
1271 			{
1272 				UINT32 n_adr;
1273 				n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
1274 				if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
1275 				{
1276 					mips_exception( EXC_ADES );
1277 					mips_set_cp0r( CP0_BADVADDR, n_adr );
1278 				}
1279 				else
1280 				{
1281 					cpu_writemem32ledw( n_adr ^ 3, mipscpu.r[ INS_RT( mipscpu.op ) ] );
1282 					mips_advance_pc();
1283 				}
1284 			}
1285 			else
1286 			{
1287 				UINT32 n_adr;
1288 				n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
1289 				if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
1290 				{
1291 					mips_exception( EXC_ADES );
1292 					mips_set_cp0r( CP0_BADVADDR, n_adr );
1293 				}
1294 				else
1295 				{
1296 					cpu_writemem32ledw( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] );
1297 					mips_advance_pc();
1298 				}
1299 			}
1300 			break;
1301 		case OP_SH:
1302 			if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
1303 			{
1304 				/* todo: */
1305 				log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: SH SR_ISC not supported\n", mipscpu.pc );
1306 				mips_stop();
1307 				mips_advance_pc();
1308 			}
1309 			else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
1310 			{
1311 				UINT32 n_adr;
1312 				n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
1313 				if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 1 ) ) != 0 )
1314 				{
1315 					mips_exception( EXC_ADES );
1316 					mips_set_cp0r( CP0_BADVADDR, n_adr );
1317 				}
1318 				else
1319 				{
1320 					cpu_writemem32ledw_word( n_adr ^ 2, mipscpu.r[ INS_RT( mipscpu.op ) ] );
1321 					mips_advance_pc();
1322 				}
1323 			}
1324 			else
1325 			{
1326 				UINT32 n_adr;
1327 				n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
1328 				if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 1 ) ) != 0 )
1329 				{
1330 					mips_exception( EXC_ADES );
1331 					mips_set_cp0r( CP0_BADVADDR, n_adr );
1332 				}
1333 				else
1334 				{
1335 					cpu_writemem32ledw_word( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] );
1336 					mips_advance_pc();
1337 				}
1338 			}
1339 			break;
1340 		case OP_SWL:
1341 			if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
1342 			{
1343 				/* todo: */
1344 				log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: SWL SR_ISC not supported\n", mipscpu.pc );
1345 				mips_stop();
1346 				mips_advance_pc();
1347 			}
1348 			else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
1349 			{
1350 				UINT32 n_adr;
1351 				n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
1352 				if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
1353 				{
1354 					mips_exception( EXC_ADES );
1355 					mips_set_cp0r( CP0_BADVADDR, n_adr );
1356 				}
1357 				else
1358 				{
1359 					switch( n_adr & 3 )
1360 					{
1361 					case 0:
1362 						cpu_writemem32ledw( n_adr + 3, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 24 );
1363 						break;
1364 					case 1:
1365 						cpu_writemem32ledw_word( n_adr + 1, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 16 );
1366 						break;
1367 					case 2:
1368 						cpu_writemem32ledw( n_adr - 1, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 8 );
1369 						cpu_writemem32ledw_word( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 16 );
1370 						break;
1371 					case 3:
1372 						cpu_writemem32ledw_dword( n_adr - 3, mipscpu.r[ INS_RT( mipscpu.op ) ] );
1373 						break;
1374 					}
1375 					mips_advance_pc();
1376 				}
1377 			}
1378 			else
1379 			{
1380 				UINT32 n_adr;
1381 				n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
1382 				if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
1383 				{
1384 					mips_exception( EXC_ADES );
1385 					mips_set_cp0r( CP0_BADVADDR, n_adr );
1386 				}
1387 				else
1388 				{
1389 					switch( n_adr & 3 )
1390 					{
1391 					case 0:
1392 						cpu_writemem32ledw( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 24 );
1393 						break;
1394 					case 1:
1395 						cpu_writemem32ledw_word( n_adr - 1, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 16 );
1396 						break;
1397 					case 2:
1398 						cpu_writemem32ledw_word( n_adr - 2, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 8 );
1399 						cpu_writemem32ledw( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 24 );
1400 						break;
1401 					case 3:
1402 						cpu_writemem32ledw_dword( n_adr - 3, mipscpu.r[ INS_RT( mipscpu.op ) ] );
1403 						break;
1404 					}
1405 					mips_advance_pc();
1406 				}
1407 			}
1408 			break;
1409 		case OP_SW:
1410 			if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
1411 			{
1412 				/* todo: */
1413 /* used by bootstrap
1414 				log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: SW SR_ISC not supported\n", mipscpu.pc );
1415 				mips_stop();
1416 */
1417 				mips_advance_pc();
1418 			}
1419 			else
1420 			{
1421 				UINT32 n_adr;
1422 				n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
1423 				if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 3 ) ) != 0 )
1424 				{
1425 					mips_exception( EXC_ADES );
1426 					mips_set_cp0r( CP0_BADVADDR, n_adr );
1427 				}
1428 				else
1429 				{
1430 					cpu_writemem32ledw_dword( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] );
1431 					mips_advance_pc();
1432 				}
1433 			}
1434 			break;
1435 		case OP_SWR:
1436 			if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
1437 			{
1438 				/* todo: */
1439 				log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: SWR SR_ISC not supported\n", mipscpu.pc );
1440 				mips_stop();
1441 				mips_advance_pc();
1442 			}
1443 			else if( ( mipscpu.cp0r[ CP0_SR ] & ( SR_RE | SR_KUC ) ) == ( SR_RE | SR_KUC ) )
1444 			{
1445 				UINT32 n_adr;
1446 				n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
1447 				if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
1448 				{
1449 					mips_exception( EXC_ADES );
1450 					mips_set_cp0r( CP0_BADVADDR, n_adr );
1451 				}
1452 				else
1453 				{
1454 					switch( n_adr & 3 )
1455 					{
1456 					case 0:
1457 						cpu_writemem32ledw_dword( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] );
1458 						break;
1459 					case 1:
1460 						cpu_writemem32ledw_word( n_adr - 1, mipscpu.r[ INS_RT( mipscpu.op ) ] );
1461 						cpu_writemem32ledw( n_adr + 1, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 16 );
1462 						break;
1463 					case 2:
1464 						cpu_writemem32ledw_word( n_adr - 2, mipscpu.r[ INS_RT( mipscpu.op ) ] );
1465 						break;
1466 					case 3:
1467 						cpu_writemem32ledw( n_adr - 3, mipscpu.r[ INS_RT( mipscpu.op ) ] );
1468 						break;
1469 					}
1470 					mips_advance_pc();
1471 				}
1472 			}
1473 			else
1474 			{
1475 				UINT32 n_adr;
1476 				n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
1477 				if( ( n_adr & ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) ) != 0 )
1478 				{
1479 					mips_exception( EXC_ADES );
1480 					mips_set_cp0r( CP0_BADVADDR, n_adr );
1481 				}
1482 				else
1483 				{
1484 					switch( n_adr & 3 )
1485 					{
1486 					case 0:
1487 						cpu_writemem32ledw_dword( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] );
1488 						break;
1489 					case 1:
1490 						cpu_writemem32ledw( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] );
1491 						cpu_writemem32ledw_word( n_adr + 1, mipscpu.r[ INS_RT( mipscpu.op ) ] >> 8 );
1492 						break;
1493 					case 2:
1494 						cpu_writemem32ledw_word( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] );
1495 						break;
1496 					case 3:
1497 						cpu_writemem32ledw( n_adr, mipscpu.r[ INS_RT( mipscpu.op ) ] );
1498 						break;
1499 					}
1500 					mips_advance_pc();
1501 				}
1502 			}
1503 			break;
1504 		case OP_LWC1:
1505 			/* todo: */
1506 			log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: COP1 LWC not supported\n", mipscpu.pc );
1507 			mips_stop();
1508 			mips_advance_pc();
1509 			break;
1510 		case OP_LWC2:
1511 			if( ( mipscpu.cp0r[ CP0_SR ] & SR_CU2 ) == 0 )
1512 			{
1513 				mips_exception( EXC_CPU );
1514 				mips_set_cp0r( CP0_CAUSE, ( mipscpu.cp0r[ CP0_CAUSE ] & ~CAUSE_CE ) | CAUSE_CE2 );
1515 			}
1516 			else if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
1517 			{
1518 				/* todo: */
1519 				log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: LWC2 SR_ISC not supported\n", mipscpu.pc );
1520 				mips_stop();
1521 				mips_advance_pc();
1522 			}
1523 			else
1524 			{
1525 				UINT32 n_adr;
1526 				n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
1527 				if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 3 ) ) != 0 )
1528 				{
1529 					mips_exception( EXC_ADEL );
1530 					mips_set_cp0r( CP0_BADVADDR, n_adr );
1531 				}
1532 				else
1533 				{
1534 					/* todo: delay? */
1535 					setcp2dr( INS_RT( mipscpu.op ), cpu_readmem32ledw_dword( n_adr ) );
1536 					mips_advance_pc();
1537 				}
1538 			}
1539 			break;
1540 		case OP_SWC1:
1541 			/* todo: */
1542 			log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: COP1 SWC not supported\n", mipscpu.pc );
1543 			mips_stop();
1544 			mips_advance_pc();
1545 			break;
1546 		case OP_SWC2:
1547 			if( ( mipscpu.cp0r[ CP0_SR ] & SR_CU2 ) == 0 )
1548 			{
1549 				mips_exception( EXC_CPU );
1550 				mips_set_cp0r( CP0_CAUSE, ( mipscpu.cp0r[ CP0_CAUSE ] & ~CAUSE_CE ) | CAUSE_CE2 );
1551 			}
1552 			else if( ( mipscpu.cp0r[ CP0_SR ] & SR_ISC ) != 0 )
1553 			{
1554 				/* todo: */
1555 				log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: SWC2 SR_ISC not supported\n", mipscpu.pc );
1556 				mips_stop();
1557 				mips_advance_pc();
1558 			}
1559 			else
1560 			{
1561 				UINT32 n_adr;
1562 				n_adr = mipscpu.r[ INS_RS( mipscpu.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mipscpu.op ) );
1563 				if( ( n_adr & ( ( ( mipscpu.cp0r[ CP0_SR ] & SR_KUC ) << 30 ) | 3 ) ) != 0 )
1564 				{
1565 					mips_exception( EXC_ADES );
1566 					mips_set_cp0r( CP0_BADVADDR, n_adr );
1567 				}
1568 				else
1569 				{
1570 					cpu_writemem32ledw_dword( n_adr, getcp2dr( INS_RT( mipscpu.op ) ) );
1571 					mips_advance_pc();
1572 				}
1573 			}
1574 			break;
1575 		default:
1576 			log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: unknown opcode %08x\n", mipscpu.pc, mipscpu.op );
1577 			mips_stop();
1578 			mips_exception( EXC_RI );
1579 			break;
1580 		}
1581 		mips_ICount--;
1582 	} while( mips_ICount > 0 );
1583 
1584 	return cycles - mips_ICount;
1585 }
1586 
mips_get_context(void * dst)1587 unsigned mips_get_context( void *dst )
1588 {
1589 	if( dst )
1590 	{
1591 		*(mips_cpu_context *)dst = mipscpu;
1592 	}
1593 	return sizeof( mips_cpu_context );
1594 }
1595 
mips_set_context(void * src)1596 void mips_set_context( void *src )
1597 {
1598 	if( src )
1599 	{
1600 		mipscpu = *(mips_cpu_context *)src;
1601 		change_pc32ledw( mipscpu.pc );
1602 	}
1603 }
1604 
mips_get_reg(int regnum)1605 unsigned mips_get_reg( int regnum )
1606 {
1607 	switch( regnum )
1608 	{
1609 	case REG_PC:		return mipscpu.pc;
1610 	case MIPS_PC:		return mipscpu.pc;
1611 	case REG_SP:
1612 		/* because there is no hardware stack and the pipeline causes the cpu to execute the
1613 		instruction after a subroutine call before the subroutine is executed there is little
1614 		chance of cmd_step_over() in mamedbg.c working. */
1615 						return 0;
1616 	case MIPS_DELAYV:	return mipscpu.delayv;
1617 	case MIPS_DELAYR:	return mipscpu.delayr;
1618 	case MIPS_HI:		return mipscpu.hi;
1619 	case MIPS_LO:		return mipscpu.lo;
1620 	case MIPS_R0:		return mipscpu.r[ 0 ];
1621 	case MIPS_R1:		return mipscpu.r[ 1 ];
1622 	case MIPS_R2:		return mipscpu.r[ 2 ];
1623 	case MIPS_R3:		return mipscpu.r[ 3 ];
1624 	case MIPS_R4:		return mipscpu.r[ 4 ];
1625 	case MIPS_R5:		return mipscpu.r[ 5 ];
1626 	case MIPS_R6:		return mipscpu.r[ 6 ];
1627 	case MIPS_R7:		return mipscpu.r[ 7 ];
1628 	case MIPS_R8:		return mipscpu.r[ 8 ];
1629 	case MIPS_R9:		return mipscpu.r[ 9 ];
1630 	case MIPS_R10:		return mipscpu.r[ 10 ];
1631 	case MIPS_R11:		return mipscpu.r[ 11 ];
1632 	case MIPS_R12:		return mipscpu.r[ 12 ];
1633 	case MIPS_R13:		return mipscpu.r[ 13 ];
1634 	case MIPS_R14:		return mipscpu.r[ 14 ];
1635 	case MIPS_R15:		return mipscpu.r[ 15 ];
1636 	case MIPS_R16:		return mipscpu.r[ 16 ];
1637 	case MIPS_R17:		return mipscpu.r[ 17 ];
1638 	case MIPS_R18:		return mipscpu.r[ 18 ];
1639 	case MIPS_R19:		return mipscpu.r[ 19 ];
1640 	case MIPS_R20:		return mipscpu.r[ 20 ];
1641 	case MIPS_R21:		return mipscpu.r[ 21 ];
1642 	case MIPS_R22:		return mipscpu.r[ 22 ];
1643 	case MIPS_R23:		return mipscpu.r[ 23 ];
1644 	case MIPS_R24:		return mipscpu.r[ 24 ];
1645 	case MIPS_R25:		return mipscpu.r[ 25 ];
1646 	case MIPS_R26:		return mipscpu.r[ 26 ];
1647 	case MIPS_R27:		return mipscpu.r[ 27 ];
1648 	case MIPS_R28:		return mipscpu.r[ 28 ];
1649 	case MIPS_R29:		return mipscpu.r[ 29 ];
1650 	case MIPS_R30:		return mipscpu.r[ 30 ];
1651 	case MIPS_R31:		return mipscpu.r[ 31 ];
1652 	case MIPS_CP0R0:	return mipscpu.cp0r[ 0 ];
1653 	case MIPS_CP0R1:	return mipscpu.cp0r[ 1 ];
1654 	case MIPS_CP0R2:	return mipscpu.cp0r[ 2 ];
1655 	case MIPS_CP0R3:	return mipscpu.cp0r[ 3 ];
1656 	case MIPS_CP0R4:	return mipscpu.cp0r[ 4 ];
1657 	case MIPS_CP0R5:	return mipscpu.cp0r[ 5 ];
1658 	case MIPS_CP0R6:	return mipscpu.cp0r[ 6 ];
1659 	case MIPS_CP0R7:	return mipscpu.cp0r[ 7 ];
1660 	case MIPS_CP0R8:	return mipscpu.cp0r[ 8 ];
1661 	case MIPS_CP0R9:	return mipscpu.cp0r[ 9 ];
1662 	case MIPS_CP0R10:	return mipscpu.cp0r[ 10 ];
1663 	case MIPS_CP0R11:	return mipscpu.cp0r[ 11 ];
1664 	case MIPS_CP0R12:	return mipscpu.cp0r[ 12 ];
1665 	case MIPS_CP0R13:	return mipscpu.cp0r[ 13 ];
1666 	case MIPS_CP0R14:	return mipscpu.cp0r[ 14 ];
1667 	case MIPS_CP0R15:	return mipscpu.cp0r[ 15 ];
1668 	case MIPS_CP0R16:	return mipscpu.cp0r[ 16 ];
1669 	case MIPS_CP0R17:	return mipscpu.cp0r[ 17 ];
1670 	case MIPS_CP0R18:	return mipscpu.cp0r[ 18 ];
1671 	case MIPS_CP0R19:	return mipscpu.cp0r[ 19 ];
1672 	case MIPS_CP0R20:	return mipscpu.cp0r[ 20 ];
1673 	case MIPS_CP0R21:	return mipscpu.cp0r[ 21 ];
1674 	case MIPS_CP0R22:	return mipscpu.cp0r[ 22 ];
1675 	case MIPS_CP0R23:	return mipscpu.cp0r[ 23 ];
1676 	case MIPS_CP0R24:	return mipscpu.cp0r[ 24 ];
1677 	case MIPS_CP0R25:	return mipscpu.cp0r[ 25 ];
1678 	case MIPS_CP0R26:	return mipscpu.cp0r[ 26 ];
1679 	case MIPS_CP0R27:	return mipscpu.cp0r[ 27 ];
1680 	case MIPS_CP0R28:	return mipscpu.cp0r[ 28 ];
1681 	case MIPS_CP0R29:	return mipscpu.cp0r[ 29 ];
1682 	case MIPS_CP0R30:	return mipscpu.cp0r[ 30 ];
1683 	case MIPS_CP0R31:	return mipscpu.cp0r[ 31 ];
1684 	case MIPS_CP2DR0:	return mipscpu.cp2dr[ 0 ].d;
1685 	case MIPS_CP2DR1:	return mipscpu.cp2dr[ 1 ].d;
1686 	case MIPS_CP2DR2:	return mipscpu.cp2dr[ 2 ].d;
1687 	case MIPS_CP2DR3:	return mipscpu.cp2dr[ 3 ].d;
1688 	case MIPS_CP2DR4:	return mipscpu.cp2dr[ 4 ].d;
1689 	case MIPS_CP2DR5:	return mipscpu.cp2dr[ 5 ].d;
1690 	case MIPS_CP2DR6:	return mipscpu.cp2dr[ 6 ].d;
1691 	case MIPS_CP2DR7:	return mipscpu.cp2dr[ 7 ].d;
1692 	case MIPS_CP2DR8:	return mipscpu.cp2dr[ 8 ].d;
1693 	case MIPS_CP2DR9:	return mipscpu.cp2dr[ 9 ].d;
1694 	case MIPS_CP2DR10:	return mipscpu.cp2dr[ 10 ].d;
1695 	case MIPS_CP2DR11:	return mipscpu.cp2dr[ 11 ].d;
1696 	case MIPS_CP2DR12:	return mipscpu.cp2dr[ 12 ].d;
1697 	case MIPS_CP2DR13:	return mipscpu.cp2dr[ 13 ].d;
1698 	case MIPS_CP2DR14:	return mipscpu.cp2dr[ 14 ].d;
1699 	case MIPS_CP2DR15:	return mipscpu.cp2dr[ 15 ].d;
1700 	case MIPS_CP2DR16:	return mipscpu.cp2dr[ 16 ].d;
1701 	case MIPS_CP2DR17:	return mipscpu.cp2dr[ 17 ].d;
1702 	case MIPS_CP2DR18:	return mipscpu.cp2dr[ 18 ].d;
1703 	case MIPS_CP2DR19:	return mipscpu.cp2dr[ 19 ].d;
1704 	case MIPS_CP2DR20:	return mipscpu.cp2dr[ 20 ].d;
1705 	case MIPS_CP2DR21:	return mipscpu.cp2dr[ 21 ].d;
1706 	case MIPS_CP2DR22:	return mipscpu.cp2dr[ 22 ].d;
1707 	case MIPS_CP2DR23:	return mipscpu.cp2dr[ 23 ].d;
1708 	case MIPS_CP2DR24:	return mipscpu.cp2dr[ 24 ].d;
1709 	case MIPS_CP2DR25:	return mipscpu.cp2dr[ 25 ].d;
1710 	case MIPS_CP2DR26:	return mipscpu.cp2dr[ 26 ].d;
1711 	case MIPS_CP2DR27:	return mipscpu.cp2dr[ 27 ].d;
1712 	case MIPS_CP2DR28:	return mipscpu.cp2dr[ 28 ].d;
1713 	case MIPS_CP2DR29:	return mipscpu.cp2dr[ 29 ].d;
1714 	case MIPS_CP2DR30:	return mipscpu.cp2dr[ 30 ].d;
1715 	case MIPS_CP2DR31:	return mipscpu.cp2dr[ 31 ].d;
1716 	case MIPS_CP2CR0:	return mipscpu.cp2cr[ 0 ].d;
1717 	case MIPS_CP2CR1:	return mipscpu.cp2cr[ 1 ].d;
1718 	case MIPS_CP2CR2:	return mipscpu.cp2cr[ 2 ].d;
1719 	case MIPS_CP2CR3:	return mipscpu.cp2cr[ 3 ].d;
1720 	case MIPS_CP2CR4:	return mipscpu.cp2cr[ 4 ].d;
1721 	case MIPS_CP2CR5:	return mipscpu.cp2cr[ 5 ].d;
1722 	case MIPS_CP2CR6:	return mipscpu.cp2cr[ 6 ].d;
1723 	case MIPS_CP2CR7:	return mipscpu.cp2cr[ 7 ].d;
1724 	case MIPS_CP2CR8:	return mipscpu.cp2cr[ 8 ].d;
1725 	case MIPS_CP2CR9:	return mipscpu.cp2cr[ 9 ].d;
1726 	case MIPS_CP2CR10:	return mipscpu.cp2cr[ 10 ].d;
1727 	case MIPS_CP2CR11:	return mipscpu.cp2cr[ 11 ].d;
1728 	case MIPS_CP2CR12:	return mipscpu.cp2cr[ 12 ].d;
1729 	case MIPS_CP2CR13:	return mipscpu.cp2cr[ 13 ].d;
1730 	case MIPS_CP2CR14:	return mipscpu.cp2cr[ 14 ].d;
1731 	case MIPS_CP2CR15:	return mipscpu.cp2cr[ 15 ].d;
1732 	case MIPS_CP2CR16:	return mipscpu.cp2cr[ 16 ].d;
1733 	case MIPS_CP2CR17:	return mipscpu.cp2cr[ 17 ].d;
1734 	case MIPS_CP2CR18:	return mipscpu.cp2cr[ 18 ].d;
1735 	case MIPS_CP2CR19:	return mipscpu.cp2cr[ 19 ].d;
1736 	case MIPS_CP2CR20:	return mipscpu.cp2cr[ 20 ].d;
1737 	case MIPS_CP2CR21:	return mipscpu.cp2cr[ 21 ].d;
1738 	case MIPS_CP2CR22:	return mipscpu.cp2cr[ 22 ].d;
1739 	case MIPS_CP2CR23:	return mipscpu.cp2cr[ 23 ].d;
1740 	case MIPS_CP2CR24:	return mipscpu.cp2cr[ 24 ].d;
1741 	case MIPS_CP2CR25:	return mipscpu.cp2cr[ 25 ].d;
1742 	case MIPS_CP2CR26:	return mipscpu.cp2cr[ 26 ].d;
1743 	case MIPS_CP2CR27:	return mipscpu.cp2cr[ 27 ].d;
1744 	case MIPS_CP2CR28:	return mipscpu.cp2cr[ 28 ].d;
1745 	case MIPS_CP2CR29:	return mipscpu.cp2cr[ 29 ].d;
1746 	case MIPS_CP2CR30:	return mipscpu.cp2cr[ 30 ].d;
1747 	case MIPS_CP2CR31:	return mipscpu.cp2cr[ 31 ].d;
1748 	}
1749 	return 0;
1750 }
1751 
mips_set_reg(int regnum,unsigned val)1752 void mips_set_reg( int regnum, unsigned val )
1753 {
1754 	switch( regnum )
1755 	{
1756 	case REG_PC:		mips_set_pc( val );				break;
1757 	case MIPS_PC:		mips_set_pc( val );				break;
1758 	case REG_SP:		/* no stack */					break;
1759 	case MIPS_DELAYV:	mipscpu.delayv = val;			break;
1760 	case MIPS_DELAYR:	if( val <= REGPC ) mipscpu.delayr = val; break;
1761 	case MIPS_HI:		mipscpu.hi = val;				break;
1762 	case MIPS_LO:		mipscpu.lo = val;				break;
1763 	case MIPS_R0:		mipscpu.r[ 0 ] = val;			break;
1764 	case MIPS_R1:		mipscpu.r[ 1 ] = val;			break;
1765 	case MIPS_R2:		mipscpu.r[ 2 ] = val;			break;
1766 	case MIPS_R3:		mipscpu.r[ 3 ] = val;			break;
1767 	case MIPS_R4:		mipscpu.r[ 4 ] = val;			break;
1768 	case MIPS_R5:		mipscpu.r[ 5 ] = val;			break;
1769 	case MIPS_R6:		mipscpu.r[ 6 ] = val;			break;
1770 	case MIPS_R7:		mipscpu.r[ 7 ] = val;			break;
1771 	case MIPS_R8:		mipscpu.r[ 8 ] = val;			break;
1772 	case MIPS_R9:		mipscpu.r[ 9 ] = val;			break;
1773 	case MIPS_R10:		mipscpu.r[ 10 ] = val;			break;
1774 	case MIPS_R11:		mipscpu.r[ 11 ] = val;			break;
1775 	case MIPS_R12:		mipscpu.r[ 12 ] = val;			break;
1776 	case MIPS_R13:		mipscpu.r[ 13 ] = val;			break;
1777 	case MIPS_R14:		mipscpu.r[ 14 ] = val;			break;
1778 	case MIPS_R15:		mipscpu.r[ 15 ] = val;			break;
1779 	case MIPS_R16:		mipscpu.r[ 16 ] = val;			break;
1780 	case MIPS_R17:		mipscpu.r[ 17 ] = val;			break;
1781 	case MIPS_R18:		mipscpu.r[ 18 ] = val;			break;
1782 	case MIPS_R19:		mipscpu.r[ 19 ] = val;			break;
1783 	case MIPS_R20:		mipscpu.r[ 20 ] = val;			break;
1784 	case MIPS_R21:		mipscpu.r[ 21 ] = val;			break;
1785 	case MIPS_R22:		mipscpu.r[ 22 ] = val;			break;
1786 	case MIPS_R23:		mipscpu.r[ 23 ] = val;			break;
1787 	case MIPS_R24:		mipscpu.r[ 24 ] = val;			break;
1788 	case MIPS_R25:		mipscpu.r[ 25 ] = val;			break;
1789 	case MIPS_R26:		mipscpu.r[ 26 ] = val;			break;
1790 	case MIPS_R27:		mipscpu.r[ 27 ] = val;			break;
1791 	case MIPS_R28:		mipscpu.r[ 28 ] = val;			break;
1792 	case MIPS_R29:		mipscpu.r[ 29 ] = val;			break;
1793 	case MIPS_R30:		mipscpu.r[ 30 ] = val;			break;
1794 	case MIPS_R31:		mipscpu.r[ 31 ] = val;			break;
1795 	case MIPS_CP0R0:	mips_set_cp0r( 0, val );		break;
1796 	case MIPS_CP0R1:	mips_set_cp0r( 1, val );		break;
1797 	case MIPS_CP0R2:	mips_set_cp0r( 2, val );		break;
1798 	case MIPS_CP0R3:	mips_set_cp0r( 3, val );		break;
1799 	case MIPS_CP0R4:	mips_set_cp0r( 4, val );		break;
1800 	case MIPS_CP0R5:	mips_set_cp0r( 5, val );		break;
1801 	case MIPS_CP0R6:	mips_set_cp0r( 6, val );		break;
1802 	case MIPS_CP0R7:	mips_set_cp0r( 7, val );		break;
1803 	case MIPS_CP0R8:	mips_set_cp0r( 8, val );		break;
1804 	case MIPS_CP0R9:	mips_set_cp0r( 9, val );		break;
1805 	case MIPS_CP0R10:	mips_set_cp0r( 10, val );		break;
1806 	case MIPS_CP0R11:	mips_set_cp0r( 11, val );		break;
1807 	case MIPS_CP0R12:	mips_set_cp0r( 12, val );		break;
1808 	case MIPS_CP0R13:	mips_set_cp0r( 13, val );		break;
1809 	case MIPS_CP0R14:	mips_set_cp0r( 14, val );		break;
1810 	case MIPS_CP0R15:	mips_set_cp0r( 15, val );		break;
1811 	case MIPS_CP0R16:	mips_set_cp0r( 16, val );		break;
1812 	case MIPS_CP0R17:	mips_set_cp0r( 17, val );		break;
1813 	case MIPS_CP0R18:	mips_set_cp0r( 18, val );		break;
1814 	case MIPS_CP0R19:	mips_set_cp0r( 19, val );		break;
1815 	case MIPS_CP0R20:	mips_set_cp0r( 20, val );		break;
1816 	case MIPS_CP0R21:	mips_set_cp0r( 21, val );		break;
1817 	case MIPS_CP0R22:	mips_set_cp0r( 22, val );		break;
1818 	case MIPS_CP0R23:	mips_set_cp0r( 23, val );		break;
1819 	case MIPS_CP0R24:	mips_set_cp0r( 24, val );		break;
1820 	case MIPS_CP0R25:	mips_set_cp0r( 25, val );		break;
1821 	case MIPS_CP0R26:	mips_set_cp0r( 26, val );		break;
1822 	case MIPS_CP0R27:	mips_set_cp0r( 27, val );		break;
1823 	case MIPS_CP0R28:	mips_set_cp0r( 28, val );		break;
1824 	case MIPS_CP0R29:	mips_set_cp0r( 29, val );		break;
1825 	case MIPS_CP0R30:	mips_set_cp0r( 30, val );		break;
1826 	case MIPS_CP0R31:	mips_set_cp0r( 31, val );		break;
1827 	case MIPS_CP2DR0:	mipscpu.cp2dr[ 0 ].d = val;		break;
1828 	case MIPS_CP2DR1:	mipscpu.cp2dr[ 1 ].d = val;		break;
1829 	case MIPS_CP2DR2:	mipscpu.cp2dr[ 2 ].d = val;		break;
1830 	case MIPS_CP2DR3:	mipscpu.cp2dr[ 3 ].d = val;		break;
1831 	case MIPS_CP2DR4:	mipscpu.cp2dr[ 4 ].d = val;		break;
1832 	case MIPS_CP2DR5:	mipscpu.cp2dr[ 5 ].d = val;		break;
1833 	case MIPS_CP2DR6:	mipscpu.cp2dr[ 6 ].d = val;		break;
1834 	case MIPS_CP2DR7:	mipscpu.cp2dr[ 7 ].d = val;		break;
1835 	case MIPS_CP2DR8:	mipscpu.cp2dr[ 8 ].d = val;		break;
1836 	case MIPS_CP2DR9:	mipscpu.cp2dr[ 9 ].d = val;		break;
1837 	case MIPS_CP2DR10:	mipscpu.cp2dr[ 10 ].d = val;	break;
1838 	case MIPS_CP2DR11:	mipscpu.cp2dr[ 11 ].d = val;	break;
1839 	case MIPS_CP2DR12:	mipscpu.cp2dr[ 12 ].d = val;	break;
1840 	case MIPS_CP2DR13:	mipscpu.cp2dr[ 13 ].d = val;	break;
1841 	case MIPS_CP2DR14:	mipscpu.cp2dr[ 14 ].d = val;	break;
1842 	case MIPS_CP2DR15:	mipscpu.cp2dr[ 15 ].d = val;	break;
1843 	case MIPS_CP2DR16:	mipscpu.cp2dr[ 16 ].d = val;	break;
1844 	case MIPS_CP2DR17:	mipscpu.cp2dr[ 17 ].d = val;	break;
1845 	case MIPS_CP2DR18:	mipscpu.cp2dr[ 18 ].d = val;	break;
1846 	case MIPS_CP2DR19:	mipscpu.cp2dr[ 19 ].d = val;	break;
1847 	case MIPS_CP2DR20:	mipscpu.cp2dr[ 20 ].d = val;	break;
1848 	case MIPS_CP2DR21:	mipscpu.cp2dr[ 21 ].d = val;	break;
1849 	case MIPS_CP2DR22:	mipscpu.cp2dr[ 22 ].d = val;	break;
1850 	case MIPS_CP2DR23:	mipscpu.cp2dr[ 23 ].d = val;	break;
1851 	case MIPS_CP2DR24:	mipscpu.cp2dr[ 24 ].d = val;	break;
1852 	case MIPS_CP2DR25:	mipscpu.cp2dr[ 25 ].d = val;	break;
1853 	case MIPS_CP2DR26:	mipscpu.cp2dr[ 26 ].d = val;	break;
1854 	case MIPS_CP2DR27:	mipscpu.cp2dr[ 27 ].d = val;	break;
1855 	case MIPS_CP2DR28:	mipscpu.cp2dr[ 28 ].d = val;	break;
1856 	case MIPS_CP2DR29:	mipscpu.cp2dr[ 29 ].d = val;	break;
1857 	case MIPS_CP2DR30:	mipscpu.cp2dr[ 30 ].d = val;	break;
1858 	case MIPS_CP2DR31:	mipscpu.cp2dr[ 31 ].d = val;	break;
1859 	case MIPS_CP2CR0:	mipscpu.cp2cr[ 0 ].d = val;		break;
1860 	case MIPS_CP2CR1:	mipscpu.cp2cr[ 1 ].d = val;		break;
1861 	case MIPS_CP2CR2:	mipscpu.cp2cr[ 2 ].d = val;		break;
1862 	case MIPS_CP2CR3:	mipscpu.cp2cr[ 3 ].d = val;		break;
1863 	case MIPS_CP2CR4:	mipscpu.cp2cr[ 4 ].d = val;		break;
1864 	case MIPS_CP2CR5:	mipscpu.cp2cr[ 5 ].d = val;		break;
1865 	case MIPS_CP2CR6:	mipscpu.cp2cr[ 6 ].d = val;		break;
1866 	case MIPS_CP2CR7:	mipscpu.cp2cr[ 7 ].d = val;		break;
1867 	case MIPS_CP2CR8:	mipscpu.cp2cr[ 8 ].d = val;		break;
1868 	case MIPS_CP2CR9:	mipscpu.cp2cr[ 9 ].d = val;		break;
1869 	case MIPS_CP2CR10:	mipscpu.cp2cr[ 10 ].d = val;	break;
1870 	case MIPS_CP2CR11:	mipscpu.cp2cr[ 11 ].d = val;	break;
1871 	case MIPS_CP2CR12:	mipscpu.cp2cr[ 12 ].d = val;	break;
1872 	case MIPS_CP2CR13:	mipscpu.cp2cr[ 13 ].d = val;	break;
1873 	case MIPS_CP2CR14:	mipscpu.cp2cr[ 14 ].d = val;	break;
1874 	case MIPS_CP2CR15:	mipscpu.cp2cr[ 15 ].d = val;	break;
1875 	case MIPS_CP2CR16:	mipscpu.cp2cr[ 16 ].d = val;	break;
1876 	case MIPS_CP2CR17:	mipscpu.cp2cr[ 17 ].d = val;	break;
1877 	case MIPS_CP2CR18:	mipscpu.cp2cr[ 18 ].d = val;	break;
1878 	case MIPS_CP2CR19:	mipscpu.cp2cr[ 19 ].d = val;	break;
1879 	case MIPS_CP2CR20:	mipscpu.cp2cr[ 20 ].d = val;	break;
1880 	case MIPS_CP2CR21:	mipscpu.cp2cr[ 21 ].d = val;	break;
1881 	case MIPS_CP2CR22:	mipscpu.cp2cr[ 22 ].d = val;	break;
1882 	case MIPS_CP2CR23:	mipscpu.cp2cr[ 23 ].d = val;	break;
1883 	case MIPS_CP2CR24:	mipscpu.cp2cr[ 24 ].d = val;	break;
1884 	case MIPS_CP2CR25:	mipscpu.cp2cr[ 25 ].d = val;	break;
1885 	case MIPS_CP2CR26:	mipscpu.cp2cr[ 26 ].d = val;	break;
1886 	case MIPS_CP2CR27:	mipscpu.cp2cr[ 27 ].d = val;	break;
1887 	case MIPS_CP2CR28:	mipscpu.cp2cr[ 28 ].d = val;	break;
1888 	case MIPS_CP2CR29:	mipscpu.cp2cr[ 29 ].d = val;	break;
1889 	case MIPS_CP2CR30:	mipscpu.cp2cr[ 30 ].d = val;	break;
1890 	case MIPS_CP2CR31:	mipscpu.cp2cr[ 31 ].d = val;	break;
1891 	}
1892 }
1893 
mips_set_nmi_line(int state)1894 void mips_set_nmi_line( int state )
1895 {
1896 	/* no nmi */
1897 }
1898 
mips_set_irq_line(int irqline,int state)1899 void mips_set_irq_line( int irqline, int state )
1900 {
1901 	UINT32 ip;
1902 
1903 	switch( irqline )
1904 	{
1905 	case 0:
1906 		ip = CAUSE_IP2;
1907 		break;
1908 	case 1:
1909 		ip = CAUSE_IP3;
1910 		break;
1911 	case 2:
1912 		ip = CAUSE_IP4;
1913 		break;
1914 	case 3:
1915 		ip = CAUSE_IP5;
1916 		break;
1917 	case 4:
1918 		ip = CAUSE_IP6;
1919 		break;
1920 	case 5:
1921 		ip = CAUSE_IP7;
1922 		break;
1923 	default:
1924 		return;
1925 	}
1926 
1927 	switch( state )
1928 	{
1929 	case CLEAR_LINE:
1930 		mips_set_cp0r( CP0_CAUSE, mipscpu.cp0r[ CP0_CAUSE ] & ~ip );
1931 		break;
1932 	case ASSERT_LINE:
1933 		mips_set_cp0r( CP0_CAUSE, mipscpu.cp0r[ CP0_CAUSE ] |= ip );
1934 		if( mipscpu.irq_callback )
1935 		{
1936 			/* HOLD_LINE interrupts are not supported by the architecture.
1937 			By acknowledging the interupt here they are treated like PULSE_LINE
1938 			interrupts, so if the interrupt isn't enabled it will be ignored.
1939 			There is also a problem with PULSE_LINE interrupts as the interrupt
1940 			pending bits aren't latched the emulated code won't know what caused
1941 			the interrupt. */
1942 			(*mipscpu.irq_callback)( irqline );
1943 		}
1944 		break;
1945 	}
1946 }
1947 
mips_set_irq_callback(int (* callback)(int irqline))1948 void mips_set_irq_callback( int (*callback)(int irqline) )
1949 {
1950 	mipscpu.irq_callback = callback;
1951 }
1952 
1953 /****************************************************************************
1954  * Return a formatted string for a register
1955  ****************************************************************************/
1956 
mips_info(void * context,int regnum)1957 const char *mips_info( void *context, int regnum )
1958 {
1959 	static char buffer[ 64 ][ 47 + 1 ];
1960 	static int which = 0;
1961 	mips_cpu_context *r = context;
1962 
1963 	which++;
1964 	which %= 64;
1965 	buffer[ which ][ 0 ] = '\0';
1966 	if( !context )
1967 	{
1968 		static mips_cpu_context tmp;
1969 		mips_get_context( &tmp );
1970 		r = &tmp;
1971 	}
1972 
1973 	switch( regnum )
1974 	{
1975 	case CPU_INFO_REG + MIPS_PC:		sprintf( buffer[ which ], "pc      :%08x", r->pc );		break;
1976 	case CPU_INFO_REG + MIPS_DELAYV:	sprintf( buffer[ which ], "delay   :%08x", r->delayv );			break;
1977 	case CPU_INFO_REG + MIPS_DELAYR:	sprintf( buffer[ which ], "delay %s:%02x", delayn[ r->delayr ], r->delayr ); break;
1978 	case CPU_INFO_REG + MIPS_HI:		sprintf( buffer[ which ], "hi      :%08x", r->hi );		break;
1979 	case CPU_INFO_REG + MIPS_LO:		sprintf( buffer[ which ], "lo      :%08x", r->lo );		break;
1980 	case CPU_INFO_REG + MIPS_R0:		sprintf( buffer[ which ], "zero    :%08x", r->r[ 0 ] );			break;
1981 	case CPU_INFO_REG + MIPS_R1:		sprintf( buffer[ which ], "at      :%08x", r->r[ 1 ] );			break;
1982 	case CPU_INFO_REG + MIPS_R2:		sprintf( buffer[ which ], "v0      :%08x", r->r[ 2 ] );			break;
1983 	case CPU_INFO_REG + MIPS_R3:		sprintf( buffer[ which ], "v1      :%08x", r->r[ 3 ] );			break;
1984 	case CPU_INFO_REG + MIPS_R4:		sprintf( buffer[ which ], "a0      :%08x", r->r[ 4 ] );			break;
1985 	case CPU_INFO_REG + MIPS_R5:		sprintf( buffer[ which ], "a1      :%08x", r->r[ 5 ] );			break;
1986 	case CPU_INFO_REG + MIPS_R6:		sprintf( buffer[ which ], "a2      :%08x", r->r[ 6 ] );			break;
1987 	case CPU_INFO_REG + MIPS_R7:		sprintf( buffer[ which ], "a3      :%08x", r->r[ 7 ] );			break;
1988 	case CPU_INFO_REG + MIPS_R8:		sprintf( buffer[ which ], "t0      :%08x", r->r[ 8 ] );			break;
1989 	case CPU_INFO_REG + MIPS_R9:		sprintf( buffer[ which ], "t1      :%08x", r->r[ 9 ] );			break;
1990 	case CPU_INFO_REG + MIPS_R10:		sprintf( buffer[ which ], "t2      :%08x", r->r[ 10 ] );		break;
1991 	case CPU_INFO_REG + MIPS_R11:		sprintf( buffer[ which ], "t3      :%08x", r->r[ 11 ] );		break;
1992 	case CPU_INFO_REG + MIPS_R12:		sprintf( buffer[ which ], "t4      :%08x", r->r[ 12 ] );		break;
1993 	case CPU_INFO_REG + MIPS_R13:		sprintf( buffer[ which ], "t5      :%08x", r->r[ 13 ] );		break;
1994 	case CPU_INFO_REG + MIPS_R14:		sprintf( buffer[ which ], "t6      :%08x", r->r[ 14 ] );		break;
1995 	case CPU_INFO_REG + MIPS_R15:		sprintf( buffer[ which ], "t7      :%08x", r->r[ 15 ] );		break;
1996 	case CPU_INFO_REG + MIPS_R16:		sprintf( buffer[ which ], "s0      :%08x", r->r[ 16 ] );		break;
1997 	case CPU_INFO_REG + MIPS_R17:		sprintf( buffer[ which ], "s1      :%08x", r->r[ 17 ] );		break;
1998 	case CPU_INFO_REG + MIPS_R18:		sprintf( buffer[ which ], "s2      :%08x", r->r[ 18 ] );		break;
1999 	case CPU_INFO_REG + MIPS_R19:		sprintf( buffer[ which ], "s3      :%08x", r->r[ 19 ] );		break;
2000 	case CPU_INFO_REG + MIPS_R20:		sprintf( buffer[ which ], "s4      :%08x", r->r[ 20 ] );		break;
2001 	case CPU_INFO_REG + MIPS_R21:		sprintf( buffer[ which ], "s5      :%08x", r->r[ 21 ] );		break;
2002 	case CPU_INFO_REG + MIPS_R22:		sprintf( buffer[ which ], "s6      :%08x", r->r[ 22 ] );		break;
2003 	case CPU_INFO_REG + MIPS_R23:		sprintf( buffer[ which ], "s7      :%08x", r->r[ 23 ] );		break;
2004 	case CPU_INFO_REG + MIPS_R24:		sprintf( buffer[ which ], "t8      :%08x", r->r[ 24 ] );		break;
2005 	case CPU_INFO_REG + MIPS_R25:		sprintf( buffer[ which ], "t9      :%08x", r->r[ 25 ] );		break;
2006 	case CPU_INFO_REG + MIPS_R26:		sprintf( buffer[ which ], "k0      :%08x", r->r[ 26 ] );		break;
2007 	case CPU_INFO_REG + MIPS_R27:		sprintf( buffer[ which ], "k1      :%08x", r->r[ 27 ] );		break;
2008 	case CPU_INFO_REG + MIPS_R28:		sprintf( buffer[ which ], "gp      :%08x", r->r[ 28 ] );		break;
2009 	case CPU_INFO_REG + MIPS_R29:		sprintf( buffer[ which ], "sp      :%08x", r->r[ 29 ] );		break;
2010 	case CPU_INFO_REG + MIPS_R30:		sprintf( buffer[ which ], "fp      :%08x", r->r[ 30 ] );		break;
2011 	case CPU_INFO_REG + MIPS_R31:		sprintf( buffer[ which ], "ra      :%08x", r->r[ 31 ] );		break;
2012 	case CPU_INFO_REG + MIPS_CP0R0:		sprintf( buffer[ which ], "Index   :%08x", r->cp0r[ 0 ] );		break;
2013 	case CPU_INFO_REG + MIPS_CP0R1:		sprintf( buffer[ which ], "Random  :%08x", r->cp0r[ 1 ] );		break;
2014 	case CPU_INFO_REG + MIPS_CP0R2:		sprintf( buffer[ which ], "EntryLo :%08x", r->cp0r[ 2 ] );		break;
2015 	case CPU_INFO_REG + MIPS_CP0R3:		sprintf( buffer[ which ], "cp0r3   :%08x", r->cp0r[ 3 ] );		break;
2016 	case CPU_INFO_REG + MIPS_CP0R4:		sprintf( buffer[ which ], "Context :%08x", r->cp0r[ 4 ] );		break;
2017 	case CPU_INFO_REG + MIPS_CP0R5:		sprintf( buffer[ which ], "cp0r5   :%08x", r->cp0r[ 5 ] );		break;
2018 	case CPU_INFO_REG + MIPS_CP0R6:		sprintf( buffer[ which ], "cp0r6   :%08x", r->cp0r[ 6 ] );		break;
2019 	case CPU_INFO_REG + MIPS_CP0R7:		sprintf( buffer[ which ], "cp0r7   :%08x", r->cp0r[ 7 ] );		break;
2020 	case CPU_INFO_REG + MIPS_CP0R8:		sprintf( buffer[ which ], "BadVAddr:%08x", r->cp0r[ 8 ] );		break;
2021 	case CPU_INFO_REG + MIPS_CP0R9:		sprintf( buffer[ which ], "cp0r9   :%08x", r->cp0r[ 9 ] );		break;
2022 	case CPU_INFO_REG + MIPS_CP0R10:	sprintf( buffer[ which ], "EntryHi :%08x", r->cp0r[ 10 ] );		break;
2023 	case CPU_INFO_REG + MIPS_CP0R11:	sprintf( buffer[ which ], "cp0r11  :%08x", r->cp0r[ 11 ] );		break;
2024 	case CPU_INFO_REG + MIPS_CP0R12:	sprintf( buffer[ which ], "SR      :%08x", r->cp0r[ 12 ] );		break;
2025 	case CPU_INFO_REG + MIPS_CP0R13:	sprintf( buffer[ which ], "Cause   :%08x", r->cp0r[ 13 ] );		break;
2026 	case CPU_INFO_REG + MIPS_CP0R14:	sprintf( buffer[ which ], "EPC     :%08x", r->cp0r[ 14 ] );		break;
2027 	case CPU_INFO_REG + MIPS_CP0R15:	sprintf( buffer[ which ], "PRId    :%08x", r->cp0r[ 15 ] );		break;
2028 	case CPU_INFO_REG + MIPS_CP0R16:	sprintf( buffer[ which ], "cp0r16  :%08x", r->cp0r[ 16 ] );		break;
2029 	case CPU_INFO_REG + MIPS_CP0R17:	sprintf( buffer[ which ], "cp0r17  :%08x", r->cp0r[ 17 ] );		break;
2030 	case CPU_INFO_REG + MIPS_CP0R18:	sprintf( buffer[ which ], "cp0r18  :%08x", r->cp0r[ 18 ] );		break;
2031 	case CPU_INFO_REG + MIPS_CP0R19:	sprintf( buffer[ which ], "cp0r19  :%08x", r->cp0r[ 19 ] );		break;
2032 	case CPU_INFO_REG + MIPS_CP0R20:	sprintf( buffer[ which ], "cp0r20  :%08x", r->cp0r[ 20 ] );		break;
2033 	case CPU_INFO_REG + MIPS_CP0R21:	sprintf( buffer[ which ], "cp0r21  :%08x", r->cp0r[ 21 ] );		break;
2034 	case CPU_INFO_REG + MIPS_CP0R22:	sprintf( buffer[ which ], "cp0r22  :%08x", r->cp0r[ 22 ] );		break;
2035 	case CPU_INFO_REG + MIPS_CP0R23:	sprintf( buffer[ which ], "cp0r23  :%08x", r->cp0r[ 23 ] );		break;
2036 	case CPU_INFO_REG + MIPS_CP0R24:	sprintf( buffer[ which ], "cp0r24  :%08x", r->cp0r[ 24 ] );		break;
2037 	case CPU_INFO_REG + MIPS_CP0R25:	sprintf( buffer[ which ], "cp0r25  :%08x", r->cp0r[ 25 ] );		break;
2038 	case CPU_INFO_REG + MIPS_CP0R26:	sprintf( buffer[ which ], "cp0r26  :%08x", r->cp0r[ 26 ] );		break;
2039 	case CPU_INFO_REG + MIPS_CP0R27:	sprintf( buffer[ which ], "cp0r27  :%08x", r->cp0r[ 27 ] );		break;
2040 	case CPU_INFO_REG + MIPS_CP0R28:	sprintf( buffer[ which ], "cp0r28  :%08x", r->cp0r[ 28 ] );		break;
2041 	case CPU_INFO_REG + MIPS_CP0R29:	sprintf( buffer[ which ], "cp0r29  :%08x", r->cp0r[ 29 ] );		break;
2042 	case CPU_INFO_REG + MIPS_CP0R30:	sprintf( buffer[ which ], "cp0r30  :%08x", r->cp0r[ 30 ] );		break;
2043 	case CPU_INFO_REG + MIPS_CP0R31:	sprintf( buffer[ which ], "cp0r31  :%08x", r->cp0r[ 31 ] );		break;
2044 	case CPU_INFO_REG + MIPS_CP2DR0:	sprintf( buffer[ which ], "vxy0    :%08x", r->cp2dr[ 0 ].d );	break;
2045 	case CPU_INFO_REG + MIPS_CP2DR1:	sprintf( buffer[ which ], "vz0     :%08x", r->cp2dr[ 1 ].d );	break;
2046 	case CPU_INFO_REG + MIPS_CP2DR2:	sprintf( buffer[ which ], "vxy1    :%08x", r->cp2dr[ 2 ].d );	break;
2047 	case CPU_INFO_REG + MIPS_CP2DR3:	sprintf( buffer[ which ], "vz1     :%08x", r->cp2dr[ 3 ].d );	break;
2048 	case CPU_INFO_REG + MIPS_CP2DR4:	sprintf( buffer[ which ], "vxy2    :%08x", r->cp2dr[ 4 ].d );	break;
2049 	case CPU_INFO_REG + MIPS_CP2DR5:	sprintf( buffer[ which ], "vz2     :%08x", r->cp2dr[ 5 ].d );	break;
2050 	case CPU_INFO_REG + MIPS_CP2DR6:	sprintf( buffer[ which ], "rgb     :%08x", r->cp2dr[ 6 ].d );	break;
2051 	case CPU_INFO_REG + MIPS_CP2DR7:	sprintf( buffer[ which ], "otz     :%08x", r->cp2dr[ 7 ].d );	break;
2052 	case CPU_INFO_REG + MIPS_CP2DR8:	sprintf( buffer[ which ], "ir0     :%08x", r->cp2dr[ 8 ].d );	break;
2053 	case CPU_INFO_REG + MIPS_CP2DR9:	sprintf( buffer[ which ], "ir1     :%08x", r->cp2dr[ 9 ].d );	break;
2054 	case CPU_INFO_REG + MIPS_CP2DR10:	sprintf( buffer[ which ], "ir2     :%08x", r->cp2dr[ 10 ].d );	break;
2055 	case CPU_INFO_REG + MIPS_CP2DR11:	sprintf( buffer[ which ], "ir3     :%08x", r->cp2dr[ 11 ].d );	break;
2056 	case CPU_INFO_REG + MIPS_CP2DR12:	sprintf( buffer[ which ], "sxy0    :%08x", r->cp2dr[ 12 ].d );	break;
2057 	case CPU_INFO_REG + MIPS_CP2DR13:	sprintf( buffer[ which ], "sxy1    :%08x", r->cp2dr[ 13 ].d );	break;
2058 	case CPU_INFO_REG + MIPS_CP2DR14:	sprintf( buffer[ which ], "sxy2    :%08x", r->cp2dr[ 14 ].d );	break;
2059 	case CPU_INFO_REG + MIPS_CP2DR15:	sprintf( buffer[ which ], "sxyp    :%08x", r->cp2dr[ 15 ].d );	break;
2060 	case CPU_INFO_REG + MIPS_CP2DR16:	sprintf( buffer[ which ], "sz0     :%08x", r->cp2dr[ 16 ].d );	break;
2061 	case CPU_INFO_REG + MIPS_CP2DR17:	sprintf( buffer[ which ], "sz1     :%08x", r->cp2dr[ 17 ].d );	break;
2062 	case CPU_INFO_REG + MIPS_CP2DR18:	sprintf( buffer[ which ], "sz2     :%08x", r->cp2dr[ 18 ].d );	break;
2063 	case CPU_INFO_REG + MIPS_CP2DR19:	sprintf( buffer[ which ], "sz3     :%08x", r->cp2dr[ 19 ].d );	break;
2064 	case CPU_INFO_REG + MIPS_CP2DR20:	sprintf( buffer[ which ], "rgb0    :%08x", r->cp2dr[ 20 ].d );	break;
2065 	case CPU_INFO_REG + MIPS_CP2DR21:	sprintf( buffer[ which ], "rgb1    :%08x", r->cp2dr[ 21 ].d );	break;
2066 	case CPU_INFO_REG + MIPS_CP2DR22:	sprintf( buffer[ which ], "rgb2    :%08x", r->cp2dr[ 22 ].d );	break;
2067 	case CPU_INFO_REG + MIPS_CP2DR23:	sprintf( buffer[ which ], "res1    :%08x", r->cp2dr[ 23 ].d );	break;
2068 	case CPU_INFO_REG + MIPS_CP2DR24:	sprintf( buffer[ which ], "mac0    :%08x", r->cp2dr[ 24 ].d );	break;
2069 	case CPU_INFO_REG + MIPS_CP2DR25:	sprintf( buffer[ which ], "mac1    :%08x", r->cp2dr[ 25 ].d );	break;
2070 	case CPU_INFO_REG + MIPS_CP2DR26:	sprintf( buffer[ which ], "mac2    :%08x", r->cp2dr[ 26 ].d );	break;
2071 	case CPU_INFO_REG + MIPS_CP2DR27:	sprintf( buffer[ which ], "mac3    :%08x", r->cp2dr[ 27 ].d );	break;
2072 	case CPU_INFO_REG + MIPS_CP2DR28:	sprintf( buffer[ which ], "irgb    :%08x", r->cp2dr[ 28 ].d );	break;
2073 	case CPU_INFO_REG + MIPS_CP2DR29:	sprintf( buffer[ which ], "orgb    :%08x", r->cp2dr[ 29 ].d );	break;
2074 	case CPU_INFO_REG + MIPS_CP2DR30:	sprintf( buffer[ which ], "lzcs    :%08x", r->cp2dr[ 30 ].d );	break;
2075 	case CPU_INFO_REG + MIPS_CP2DR31:	sprintf( buffer[ which ], "lzcr    :%08x", r->cp2dr[ 31 ].d );	break;
2076 	case CPU_INFO_REG + MIPS_CP2CR0:	sprintf( buffer[ which ], "r11r12  :%08x", r->cp2cr[ 0 ].d );	break;
2077 	case CPU_INFO_REG + MIPS_CP2CR1:	sprintf( buffer[ which ], "r13r21  :%08x", r->cp2cr[ 1 ].d );	break;
2078 	case CPU_INFO_REG + MIPS_CP2CR2:	sprintf( buffer[ which ], "r22r23  :%08x", r->cp2cr[ 2 ].d );	break;
2079 	case CPU_INFO_REG + MIPS_CP2CR3:	sprintf( buffer[ which ], "r31r32  :%08x", r->cp2cr[ 3 ].d );	break;
2080 	case CPU_INFO_REG + MIPS_CP2CR4:	sprintf( buffer[ which ], "r33     :%08x", r->cp2cr[ 4 ].d );	break;
2081 	case CPU_INFO_REG + MIPS_CP2CR5:	sprintf( buffer[ which ], "trx     :%08x", r->cp2cr[ 5 ].d );	break;
2082 	case CPU_INFO_REG + MIPS_CP2CR6:	sprintf( buffer[ which ], "try     :%08x", r->cp2cr[ 6 ].d );	break;
2083 	case CPU_INFO_REG + MIPS_CP2CR7:	sprintf( buffer[ which ], "trz     :%08x", r->cp2cr[ 7 ].d );	break;
2084 	case CPU_INFO_REG + MIPS_CP2CR8:	sprintf( buffer[ which ], "l11l12  :%08x", r->cp2cr[ 8 ].d );	break;
2085 	case CPU_INFO_REG + MIPS_CP2CR9:	sprintf( buffer[ which ], "l13l21  :%08x", r->cp2cr[ 9 ].d );	break;
2086 	case CPU_INFO_REG + MIPS_CP2CR10:	sprintf( buffer[ which ], "l22l23  :%08x", r->cp2cr[ 10 ].d );	break;
2087 	case CPU_INFO_REG + MIPS_CP2CR11:	sprintf( buffer[ which ], "l31l32  :%08x", r->cp2cr[ 11 ].d );	break;
2088 	case CPU_INFO_REG + MIPS_CP2CR12:	sprintf( buffer[ which ], "l33     :%08x", r->cp2cr[ 12 ].d );	break;
2089 	case CPU_INFO_REG + MIPS_CP2CR13:	sprintf( buffer[ which ], "rbk     :%08x", r->cp2cr[ 13 ].d );	break;
2090 	case CPU_INFO_REG + MIPS_CP2CR14:	sprintf( buffer[ which ], "gbk     :%08x", r->cp2cr[ 14 ].d );	break;
2091 	case CPU_INFO_REG + MIPS_CP2CR15:	sprintf( buffer[ which ], "bbk     :%08x", r->cp2cr[ 15 ].d );	break;
2092 	case CPU_INFO_REG + MIPS_CP2CR16:	sprintf( buffer[ which ], "lr1lr2  :%08x", r->cp2cr[ 16 ].d );	break;
2093 	case CPU_INFO_REG + MIPS_CP2CR17:	sprintf( buffer[ which ], "lr31g1  :%08x", r->cp2cr[ 17 ].d );	break;
2094 	case CPU_INFO_REG + MIPS_CP2CR18:	sprintf( buffer[ which ], "lg2lg3  :%08x", r->cp2cr[ 18 ].d );	break;
2095 	case CPU_INFO_REG + MIPS_CP2CR19:	sprintf( buffer[ which ], "lb1lb2  :%08x", r->cp2cr[ 19 ].d );	break;
2096 	case CPU_INFO_REG + MIPS_CP2CR20:	sprintf( buffer[ which ], "lb3     :%08x", r->cp2cr[ 20 ].d );	break;
2097 	case CPU_INFO_REG + MIPS_CP2CR21:	sprintf( buffer[ which ], "rfc     :%08x", r->cp2cr[ 21 ].d );	break;
2098 	case CPU_INFO_REG + MIPS_CP2CR22:	sprintf( buffer[ which ], "gfc     :%08x", r->cp2cr[ 22 ].d );	break;
2099 	case CPU_INFO_REG + MIPS_CP2CR23:	sprintf( buffer[ which ], "bfc     :%08x", r->cp2cr[ 23 ].d );	break;
2100 	case CPU_INFO_REG + MIPS_CP2CR24:	sprintf( buffer[ which ], "ofx     :%08x", r->cp2cr[ 24 ].d );	break;
2101 	case CPU_INFO_REG + MIPS_CP2CR25:	sprintf( buffer[ which ], "ofy     :%08x", r->cp2cr[ 25 ].d );	break;
2102 	case CPU_INFO_REG + MIPS_CP2CR26:	sprintf( buffer[ which ], "h       :%08x", r->cp2cr[ 26 ].d );	break;
2103 	case CPU_INFO_REG + MIPS_CP2CR27:	sprintf( buffer[ which ], "dqa     :%08x", r->cp2cr[ 27 ].d );	break;
2104 	case CPU_INFO_REG + MIPS_CP2CR28:	sprintf( buffer[ which ], "dqb     :%08x", r->cp2cr[ 28 ].d );	break;
2105 	case CPU_INFO_REG + MIPS_CP2CR29:	sprintf( buffer[ which ], "zsf3    :%08x", r->cp2cr[ 29 ].d );	break;
2106 	case CPU_INFO_REG + MIPS_CP2CR30:	sprintf( buffer[ which ], "zsf4    :%08x", r->cp2cr[ 30 ].d );	break;
2107 	case CPU_INFO_REG + MIPS_CP2CR31:	sprintf( buffer[ which ], "flag    :%08x", r->cp2cr[ 31 ].d );	break;
2108 	case CPU_INFO_FLAGS:		return "";
2109 	case CPU_INFO_NAME:			return "PSX CPU";
2110 	case CPU_INFO_FAMILY:		return "mipscpu";
2111 	case CPU_INFO_VERSION:		return "1.4";
2112 	case CPU_INFO_FILE:			return __FILE__;
2113 	case CPU_INFO_CREDITS:		return "Copyright 2003 smf";
2114 	case CPU_INFO_REG_LAYOUT:	return (const char*)mips_reg_layout;
2115 	case CPU_INFO_WIN_LAYOUT:	return (const char*)mips_win_layout;
2116 	}
2117 	return buffer[ which ];
2118 }
2119 
mips_dasm(char * buffer,UINT32 pc)2120 unsigned mips_dasm( char *buffer, UINT32 pc )
2121 {
2122 	unsigned ret;
2123 	change_pc32ledw( pc );
2124 #ifdef MAME_DEBUG
2125 	ret = DasmMIPS( buffer, pc );
2126 #else
2127 	sprintf( buffer, "$%08x", cpu_readop32( pc ) );
2128 	ret = 4;
2129 #endif
2130 	change_pc32ledw( mipscpu.pc );
2131 	return ret;
2132 }
2133 
2134 /* preliminary gte code */
2135 
2136 #define VXY0 ( mipscpu.cp2dr[ 0 ].d )
2137 #define VX0  ( mipscpu.cp2dr[ 0 ].w.l )
2138 #define VY0  ( mipscpu.cp2dr[ 0 ].w.h )
2139 #define VZ0  ( mipscpu.cp2dr[ 1 ].w.l )
2140 #define VXY1 ( mipscpu.cp2dr[ 2 ].d )
2141 #define VX1  ( mipscpu.cp2dr[ 2 ].w.l )
2142 #define VY1  ( mipscpu.cp2dr[ 2 ].w.h )
2143 #define VZ1  ( mipscpu.cp2dr[ 3 ].w.l )
2144 #define VXY2 ( mipscpu.cp2dr[ 4 ].d )
2145 #define VX2  ( mipscpu.cp2dr[ 4 ].w.l )
2146 #define VY2  ( mipscpu.cp2dr[ 4 ].w.h )
2147 #define VZ2  ( mipscpu.cp2dr[ 5 ].w.l )
2148 #define RGB  ( mipscpu.cp2dr[ 6 ].d )
2149 #define R    ( mipscpu.cp2dr[ 6 ].b.l )
2150 #define G    ( mipscpu.cp2dr[ 6 ].b.h )
2151 #define B    ( mipscpu.cp2dr[ 6 ].b.h2 )
2152 #define CODE ( mipscpu.cp2dr[ 6 ].b.h3 )
2153 #define OTZ  ( mipscpu.cp2dr[ 7 ].w.l )
2154 #define IR0  ( mipscpu.cp2dr[ 8 ].d )
2155 #define IR1  ( mipscpu.cp2dr[ 9 ].d )
2156 #define IR2  ( mipscpu.cp2dr[ 10 ].d )
2157 #define IR3  ( mipscpu.cp2dr[ 11 ].d )
2158 #define SXY0 ( mipscpu.cp2dr[ 12 ].d )
2159 #define SX0  ( mipscpu.cp2dr[ 12 ].w.l )
2160 #define SY0  ( mipscpu.cp2dr[ 12 ].w.h )
2161 #define SXY1 ( mipscpu.cp2dr[ 13 ].d )
2162 #define SX1  ( mipscpu.cp2dr[ 13 ].w.l )
2163 #define SY1  ( mipscpu.cp2dr[ 13 ].w.h )
2164 #define SXY2 ( mipscpu.cp2dr[ 14 ].d )
2165 #define SX2  ( mipscpu.cp2dr[ 14 ].w.l )
2166 #define SY2  ( mipscpu.cp2dr[ 14 ].w.h )
2167 #define SXYP ( mipscpu.cp2dr[ 15 ].d )
2168 #define SXP  ( mipscpu.cp2dr[ 15 ].w.l )
2169 #define SYP  ( mipscpu.cp2dr[ 15 ].w.h )
2170 #define SZ0  ( mipscpu.cp2dr[ 16 ].w.l )
2171 #define SZ1  ( mipscpu.cp2dr[ 17 ].w.l )
2172 #define SZ2  ( mipscpu.cp2dr[ 18 ].w.l )
2173 #define SZ3  ( mipscpu.cp2dr[ 19 ].w.l )
2174 #define RGB0 ( mipscpu.cp2dr[ 20 ].d )
2175 #define R0   ( mipscpu.cp2dr[ 20 ].b.l )
2176 #define G0   ( mipscpu.cp2dr[ 20 ].b.h )
2177 #define B0   ( mipscpu.cp2dr[ 20 ].b.h2 )
2178 #define CD0  ( mipscpu.cp2dr[ 20 ].b.h3 )
2179 #define RGB1 ( mipscpu.cp2dr[ 21 ].d )
2180 #define R1   ( mipscpu.cp2dr[ 21 ].b.l )
2181 #define G1   ( mipscpu.cp2dr[ 21 ].b.h )
2182 #define B1   ( mipscpu.cp2dr[ 21 ].b.h2 )
2183 #define CD1  ( mipscpu.cp2dr[ 21 ].b.h3 )
2184 #define RGB2 ( mipscpu.cp2dr[ 22 ].d )
2185 #define R2   ( mipscpu.cp2dr[ 22 ].b.l )
2186 #define G2   ( mipscpu.cp2dr[ 22 ].b.h )
2187 #define B2   ( mipscpu.cp2dr[ 22 ].b.h2 )
2188 #define CD2  ( mipscpu.cp2dr[ 22 ].b.h3 )
2189 #define RES1 ( mipscpu.cp2dr[ 23 ].d )
2190 #define MAC0 ( mipscpu.cp2dr[ 24 ].d )
2191 #define MAC1 ( mipscpu.cp2dr[ 25 ].d )
2192 #define MAC2 ( mipscpu.cp2dr[ 26 ].d )
2193 #define MAC3 ( mipscpu.cp2dr[ 27 ].d )
2194 #define IRGB ( mipscpu.cp2dr[ 28 ].d )
2195 #define ORGB ( mipscpu.cp2dr[ 29 ].d )
2196 #define LZCS ( mipscpu.cp2dr[ 30 ].d )
2197 #define LZCR ( mipscpu.cp2dr[ 31 ].d )
2198 
2199 #define D1  ( mipscpu.cp2cr[ 0 ].d )
2200 #define R11 ( mipscpu.cp2cr[ 0 ].w.l )
2201 #define R12 ( mipscpu.cp2cr[ 0 ].w.h )
2202 #define R13 ( mipscpu.cp2cr[ 1 ].w.l )
2203 #define R21 ( mipscpu.cp2cr[ 1 ].w.h )
2204 #define D2  ( mipscpu.cp2cr[ 2 ].d )
2205 #define R22 ( mipscpu.cp2cr[ 2 ].w.l )
2206 #define R23 ( mipscpu.cp2cr[ 2 ].w.h )
2207 #define R31 ( mipscpu.cp2cr[ 3 ].w.l )
2208 #define R32 ( mipscpu.cp2cr[ 3 ].w.h )
2209 #define D3  ( mipscpu.cp2cr[ 4 ].d )
2210 #define R33 ( mipscpu.cp2cr[ 4 ].w.l )
2211 #define TRX ( mipscpu.cp2cr[ 5 ].d )
2212 #define TRY ( mipscpu.cp2cr[ 6 ].d )
2213 #define TRZ ( mipscpu.cp2cr[ 7 ].d )
2214 #define L11 ( mipscpu.cp2cr[ 8 ].w.l )
2215 #define L12 ( mipscpu.cp2cr[ 8 ].w.h )
2216 #define L13 ( mipscpu.cp2cr[ 9 ].w.l )
2217 #define L21 ( mipscpu.cp2cr[ 9 ].w.h )
2218 #define L22 ( mipscpu.cp2cr[ 10 ].w.l )
2219 #define L23 ( mipscpu.cp2cr[ 10 ].w.h )
2220 #define L31 ( mipscpu.cp2cr[ 11 ].w.l )
2221 #define L32 ( mipscpu.cp2cr[ 11 ].w.h )
2222 #define L33 ( mipscpu.cp2cr[ 12 ].w.l )
2223 #define RBK ( mipscpu.cp2cr[ 13 ].d )
2224 #define GBK ( mipscpu.cp2cr[ 14 ].d )
2225 #define BBK ( mipscpu.cp2cr[ 15 ].d )
2226 #define LR1 ( mipscpu.cp2cr[ 16 ].w.l )
2227 #define LR2 ( mipscpu.cp2cr[ 16 ].w.h )
2228 #define LR3 ( mipscpu.cp2cr[ 17 ].w.l )
2229 #define LG1 ( mipscpu.cp2cr[ 17 ].w.h )
2230 #define LG2 ( mipscpu.cp2cr[ 18 ].w.l )
2231 #define LG3 ( mipscpu.cp2cr[ 18 ].w.h )
2232 #define LB1 ( mipscpu.cp2cr[ 19 ].w.l )
2233 #define LB2 ( mipscpu.cp2cr[ 19 ].w.h )
2234 #define LB3 ( mipscpu.cp2cr[ 20 ].w.l )
2235 #define RFC ( mipscpu.cp2cr[ 21 ].d )
2236 #define GFC ( mipscpu.cp2cr[ 22 ].d )
2237 #define BFC ( mipscpu.cp2cr[ 23 ].d )
2238 #define OFX ( mipscpu.cp2cr[ 24 ].d )
2239 #define OFY ( mipscpu.cp2cr[ 25 ].d )
2240 #define H   ( mipscpu.cp2cr[ 26 ].w.l )
2241 #define DQA ( mipscpu.cp2cr[ 27 ].w.l )
2242 #define DQB ( mipscpu.cp2cr[ 28 ].d )
2243 #define ZSF3 ( mipscpu.cp2cr[ 29 ].w.l )
2244 #define ZSF4 ( mipscpu.cp2cr[ 30 ].w.l )
2245 #define FLAG ( mipscpu.cp2cr[ 31 ].d )
2246 
getcp2dr(int n_reg)2247 static UINT32 getcp2dr( int n_reg )
2248 {
2249 	if( n_reg == 1 || n_reg == 3 || n_reg == 5 || n_reg == 8 || n_reg == 9 || n_reg == 10 || n_reg == 11 )
2250 	{
2251 		mipscpu.cp2dr[ n_reg ].d = (INT32)(INT16)mipscpu.cp2dr[ n_reg ].d;
2252 	}
2253 	else if( n_reg == 17 || n_reg == 18 || n_reg == 19 )
2254 	{
2255 		mipscpu.cp2dr[ n_reg ].d = (UINT32)(UINT16)mipscpu.cp2dr[ n_reg ].d;
2256 	}
2257 	else if( n_reg == 29 )
2258 	{
2259 		ORGB = ( ( IR1 >> 7 ) & 0x1f ) | ( ( IR2 >> 2 ) & 0x3e0 ) | ( ( IR3 << 3 ) & 0x7c00 );
2260 	}
2261 	log_cb(RETRO_LOG_DEBUG, LOGPRE "get CP2DR%u=%08x", n_reg, mipscpu.cp2dr[ n_reg ].d );
2262 	return mipscpu.cp2dr[ n_reg ].d;
2263 }
2264 
setcp2dr(int n_reg,UINT32 n_value)2265 static void setcp2dr( int n_reg, UINT32 n_value )
2266 {
2267 	log_cb(RETRO_LOG_DEBUG, LOGPRE "set CP2DR%u=%08x", n_reg, n_value );
2268 	mipscpu.cp2dr[ n_reg ].d = n_value;
2269 
2270 	if( n_reg == 15 )
2271 	{
2272 		SXY0 = SXY1;
2273 		SXY1 = SXY2;
2274 		SXY2 = SXYP;
2275 	}
2276 	else if( n_reg == 28 )
2277 	{
2278 		IR1 = ( IRGB & 0x1f ) << 4;
2279 		IR2 = ( IRGB & 0x3e0 ) >> 1;
2280 		IR3 = ( IRGB & 0x7c00 ) >> 6;
2281 	}
2282 	else if( n_reg == 30 )
2283 	{
2284 		UINT32 n_lzcs = LZCS;
2285 		UINT32 n_lzcr = 0;
2286 
2287 		if( ( n_lzcs & 0x80000000 ) == 0 )
2288 		{
2289 			n_lzcs = ~n_lzcs;
2290 		}
2291 		while( ( n_lzcs & 0x80000000 ) != 0 )
2292 		{
2293 			n_lzcr++;
2294 			n_lzcs <<= 1;
2295 		}
2296 		LZCR = n_lzcr;
2297 	}
2298 }
2299 
getcp2cr(int n_reg)2300 static UINT32 getcp2cr( int n_reg )
2301 {
2302 	log_cb(RETRO_LOG_DEBUG, LOGPRE "get CP2CR%u=%08x", n_reg, mipscpu.cp2cr[ n_reg ].d );
2303 	return mipscpu.cp2cr[ n_reg ].d;
2304 }
2305 
setcp2cr(int n_reg,UINT32 n_value)2306 static void setcp2cr( int n_reg, UINT32 n_value )
2307 {
2308 	log_cb(RETRO_LOG_DEBUG, LOGPRE "set CP2CR%u=%08x", n_reg, n_value );
2309 	mipscpu.cp2cr[ n_reg ].d = n_value;
2310 }
2311 
LIM(INT32 n_value,INT32 n_max,INT32 n_min,UINT32 n_flag)2312 static INLINE INT32 LIM( INT32 n_value, INT32 n_max, INT32 n_min, UINT32 n_flag )
2313 {
2314 	if( n_value > n_max )
2315 	{
2316 		FLAG |= n_flag;
2317 		return n_max;
2318 	}
2319 	else if( n_value < n_min )
2320 	{
2321 		FLAG |= n_flag;
2322 		return n_min;
2323 	}
2324 	return n_value;
2325 }
2326 
BOUNDS(INT64 n_value,INT64 n_max,int n_maxflag,INT64 n_min,int n_minflag)2327 static INLINE INT64 BOUNDS( INT64 n_value, INT64 n_max, int n_maxflag, INT64 n_min, int n_minflag )
2328 {
2329 	if( n_value > n_max )
2330 	{
2331 		FLAG |= n_maxflag;
2332 	}
2333 	else if( n_value < n_min )
2334 	{
2335 		FLAG |= n_minflag;
2336 	}
2337 	return n_value;
2338 }
2339 
2340 #define A1( a ) BOUNDS( ( a ), 0x7fffffff, 30, -(INT64)0x80000000, ( 1 << 27 ) )
2341 #define A2( a ) BOUNDS( ( a ), 0x7fffffff, 29, -(INT64)0x80000000, ( 1 << 26 ) )
2342 #define A3( a ) BOUNDS( ( a ), 0x7fffffff, 28, -(INT64)0x80000000, ( 1 << 25 ) )
2343 #define Lm_B1( a, l ) LIM( ( a ), 0x7fff, -0x8000 * !l, ( 1 << 31 ) | ( 1 << 24 ) )
2344 #define Lm_B2( a, l ) LIM( ( a ), 0x7fff, -0x8000 * !l, ( 1 << 31 ) | ( 1 << 23 ) )
2345 #define Lm_B3( a, l ) LIM( ( a ), 0x7fff, -0x8000 * !l, ( 1 << 22 ) )
2346 #define Lm_C1( a ) LIM( ( a ), 0x00ff, 0x0000, ( 1 << 21 ) )
2347 #define Lm_C2( a ) LIM( ( a ), 0x00ff, 0x0000, ( 1 << 20 ) )
2348 #define Lm_C3( a ) LIM( ( a ), 0x00ff, 0x0000, ( 1 << 19 ) )
2349 #define Lm_D( a ) LIM( ( a ), 0xffff, 0x0000, ( 1 << 31 ) | ( 1 << 18 ) )
2350 
Lm_E(UINT32 n_z)2351 static INLINE UINT32 Lm_E( UINT32 n_z )
2352 {
2353 	if( n_z <= H / 2 )
2354 	{
2355 		n_z = H / 2;
2356 		FLAG |= ( 1 << 31 ) | ( 1 << 17 );
2357 	}
2358 	if( n_z == 0 )
2359 	{
2360 		n_z = 1;
2361 	}
2362 	return n_z;
2363 }
2364 
2365 #define F( a ) BOUNDS( ( a ), 0x7fffffff, ( 1 << 31 ) | ( 1 << 16 ), -(INT64)0x80000000, ( 1 << 31 ) | ( 1 << 15 ) )
2366 #define Lm_G1( a ) LIM( ( a ), 0x3ff, -0x400, ( 1 << 31 ) | ( 1 << 14 ) )
2367 #define Lm_G2( a ) LIM( ( a ), 0x3ff, -0x400, ( 1 << 31 ) | ( 1 << 13 ) )
2368 #define Lm_H( a ) LIM( ( a ), 0xfff, 0x000, ( 1 << 12 ) )
2369 
docop2(int gteop)2370 static void docop2( int gteop )
2371 {
2372 	int n_sf;
2373 	int n_v;
2374 	int n_lm;
2375 	int n_pass;
2376 	UINT16 n_v1;
2377 	UINT16 n_v2;
2378 	UINT16 n_v3;
2379 	const UINT16 **p_n_mx;
2380 	const UINT32 **p_n_cv;
2381 	static const UINT16 n_zm = 0;
2382 	static const UINT32 n_zc = 0;
2383 	static const UINT16 *p_n_vx[] = { &VX0, &VX1, &VX2 };
2384 	static const UINT16 *p_n_vy[] = { &VY0, &VY1, &VY2 };
2385 	static const UINT16 *p_n_vz[] = { &VZ0, &VZ1, &VZ2 };
2386 	static const UINT16 *p_n_rm[] = { &R11, &R12, &R13, &R21, &R22, &R23, &R31, &R32, &R33 };
2387 	static const UINT16 *p_n_lm[] = { &L11, &L12, &L13, &L21, &L22, &L23, &L31, &L32, &L33 };
2388 	static const UINT16 *p_n_cm[] = { &LR1, &LR2, &LR3, &LG1, &LG2, &LG3, &LB1, &LB2, &LB3 };
2389 	static const UINT16 *p_n_zm[] = { &n_zm, &n_zm, &n_zm, &n_zm, &n_zm, &n_zm, &n_zm, &n_zm, &n_zm };
2390 	static const UINT16 **p_p_n_mx[] = { p_n_rm, p_n_lm, p_n_cm, p_n_zm };
2391 	static const UINT32 *p_n_tr[] = { &TRX, &TRY, &TRZ };
2392 	static const UINT32 *p_n_bk[] = { &RBK, &GBK, &BBK };
2393 	static const UINT32 *p_n_fc[] = { &RFC, &GFC, &BFC };
2394 	static const UINT32 *p_n_zc[] = { &n_zc, &n_zc, &n_zc };
2395 	static const UINT32 **p_p_n_cv[] = { p_n_tr, p_n_bk, p_n_fc, p_n_zc };
2396 
2397 	switch( GTE_OP( gteop ) )
2398 	{
2399 	case 0x01:
2400 		if( gteop == 0x0180001 )
2401 		{
2402 			log_cb(RETRO_LOG_DEBUG, LOGPRE "RTPS" );
2403 			FLAG = 0;
2404 
2405 			MAC1 = A1( ( ( (INT64)(INT32)TRX << 12 ) + ( (INT16)R11 * (INT16)VX0 ) + ( (INT16)R12 * (INT16)VY0 ) + ( (INT16)R13 * (INT16)VZ0 ) ) >> 12 );
2406 			MAC2 = A2( ( ( (INT64)(INT32)TRY << 12 ) + ( (INT16)R21 * (INT16)VX0 ) + ( (INT16)R22 * (INT16)VY0 ) + ( (INT16)R23 * (INT16)VZ0 ) ) >> 12 );
2407 			MAC3 = A3( ( ( (INT64)(INT32)TRZ << 12 ) + ( (INT16)R31 * (INT16)VX0 ) + ( (INT16)R32 * (INT16)VY0 ) + ( (INT16)R33 * (INT16)VZ0 ) ) >> 12 );
2408 			IR1 = Lm_B1( (INT32)MAC1, 0 );
2409 			IR2 = Lm_B2( (INT32)MAC2, 0 );
2410 			IR3 = Lm_B3( (INT32)MAC3, 0 );
2411 			SZ0 = SZ1;
2412 			SZ1 = SZ2;
2413 			SZ2 = SZ3;
2414 			SZ3 = Lm_D( (INT32)MAC3 );
2415 			SXY0 = SXY1;
2416 			SXY1 = SXY2;
2417 			SX2 = Lm_G1( F( (INT64)(INT32)OFX + ( (INT64)(INT16)IR1 * ( ( (UINT32)H << 16 ) / Lm_E( SZ3 ) ) ) ) >> 16 );
2418 			SY2 = Lm_G2( F( (INT64)(INT32)OFY + ( (INT64)(INT16)IR2 * ( ( (UINT32)H << 16 ) / Lm_E( SZ3 ) ) ) ) >> 16 );
2419 			MAC0 = F( (INT64)(INT32)DQB + ( (INT64)(INT16)DQA * ( ( (UINT32)H << 16 ) / Lm_E( SZ3 ) ) ) );
2420 			IR0 = Lm_H( (INT32)MAC0 >> 12 );
2421 			return;
2422 		}
2423 		break;
2424 	case 0x02:
2425 		if( gteop == 0x0280030 )
2426 		{
2427 			log_cb(RETRO_LOG_DEBUG, LOGPRE "RTPT" );
2428 			FLAG = 0;
2429 
2430 			for( n_v = 0; n_v < 3; n_v++ )
2431 			{
2432 				MAC1 = A1( ( ( (INT64)(INT32)TRX << 12 ) + ( (INT16)R11 * (INT16)*p_n_vx[ n_v ] ) + ( (INT16)R12 * (INT16)*p_n_vy[ n_v ] ) + ( (INT16)R13 * (INT16)*p_n_vz[ n_v ] ) ) >> 12 );
2433 				MAC2 = A2( ( ( (INT64)(INT32)TRY << 12 ) + ( (INT16)R21 * (INT16)*p_n_vx[ n_v ] ) + ( (INT16)R22 * (INT16)*p_n_vy[ n_v ] ) + ( (INT16)R23 * (INT16)*p_n_vz[ n_v ] ) ) >> 12 );
2434 				MAC3 = A3( ( ( (INT64)(INT32)TRZ << 12 ) + ( (INT16)R31 * (INT16)*p_n_vx[ n_v ] ) + ( (INT16)R32 * (INT16)*p_n_vy[ n_v ] ) + ( (INT16)R33 * (INT16)*p_n_vz[ n_v ] ) ) >> 12 );
2435 				IR1 = Lm_B1( (INT32)MAC1, 0 );
2436 				IR2 = Lm_B2( (INT32)MAC2, 0 );
2437 				IR3 = Lm_B3( (INT32)MAC3, 0 );
2438 				SZ0 = SZ1;
2439 				SZ1 = SZ2;
2440 				SZ2 = SZ3;
2441 				SZ3 = Lm_D( (INT32)MAC3 );
2442 				SXY0 = SXY1;
2443 				SXY1 = SXY2;
2444 				SX2 = Lm_G1( F( ( (INT64)(INT32)OFX + ( (INT64)(INT16)IR1 * ( ( (UINT32)H << 16 ) / Lm_E( SZ3 ) ) ) ) >> 16 ) );
2445 				SY2 = Lm_G2( F( ( (INT64)(INT32)OFY + ( (INT64)(INT16)IR2 * ( ( (UINT32)H << 16 ) / Lm_E( SZ3 ) ) ) ) >> 16 ) );
2446 				MAC0 = F( (INT64)(INT32)DQB + ( (INT64)(INT16)DQA * ( ( (UINT32)H << 16 ) / Lm_E( SZ3 ) ) ) );
2447 				IR0 = Lm_H( (INT32)MAC0 >> 12 );
2448 			}
2449 			return;
2450 		}
2451 		break;
2452 	case 0x04:
2453 		if( GTE_CT( gteop ) == 0x012 ||
2454 			GTE_CT( gteop ) == 0x412 )
2455 		{
2456 			log_cb(RETRO_LOG_DEBUG, LOGPRE "MVMVA" );
2457 			n_sf = 12 * GTE_SF( gteop );
2458 			p_n_mx = p_p_n_mx[ GTE_MX( gteop ) ];
2459 			n_v = GTE_V( gteop );
2460 			if( n_v < 3 )
2461 			{
2462 				n_v1 = *p_n_vx[ n_v ];
2463 				n_v2 = *p_n_vy[ n_v ];
2464 				n_v3 = *p_n_vz[ n_v ];
2465 			}
2466 			else
2467 			{
2468 				n_v1 = IR1;
2469 				n_v2 = IR2;
2470 				n_v3 = IR3;
2471 			}
2472 			p_n_cv = p_p_n_cv[ GTE_CV( gteop ) ];
2473 			n_lm = GTE_LM( gteop );
2474 			FLAG = 0;
2475 
2476 			MAC1 = A1( ( ( (INT64)(INT32)*p_n_cv[ 0 ] << 12 ) + ( (INT16)*p_n_mx[ 0 ] * (INT16)n_v1 ) + ( (INT16)*p_n_mx[ 1 ] * (INT16)n_v2 ) + ( (INT16)*p_n_mx[ 2 ] * (INT16)n_v3 ) ) >> n_sf );
2477 			MAC2 = A2( ( ( (INT64)(INT32)*p_n_cv[ 1 ] << 12 ) + ( (INT16)*p_n_mx[ 3 ] * (INT16)n_v1 ) + ( (INT16)*p_n_mx[ 4 ] * (INT16)n_v2 ) + ( (INT16)*p_n_mx[ 5 ] * (INT16)n_v3 ) ) >> n_sf );
2478 			MAC3 = A3( ( ( (INT64)(INT32)*p_n_cv[ 2 ] << 12 ) + ( (INT16)*p_n_mx[ 6 ] * (INT16)n_v1 ) + ( (INT16)*p_n_mx[ 7 ] * (INT16)n_v2 ) + ( (INT16)*p_n_mx[ 8 ] * (INT16)n_v3 ) ) >> n_sf );
2479 
2480 			IR1 = Lm_B1( (INT32)MAC1, n_lm );
2481 			IR2 = Lm_B2( (INT32)MAC2, n_lm );
2482 			IR3 = Lm_B3( (INT32)MAC3, n_lm );
2483 			return;
2484 		}
2485 		break;
2486 	case 0x07:
2487 		if( gteop == 0x0780010 )
2488 		{
2489 			log_cb(RETRO_LOG_DEBUG, LOGPRE "DPCS" );
2490 			FLAG = 0;
2491 
2492 			MAC1 = A1( ( ( (INT64)R << 16 ) + ( (INT64)(INT16)IR0 * ( Lm_B1( (INT32)RFC - ( R << 4 ), 0 ) ) ) ) >> 12 );
2493 			MAC2 = A2( ( ( (INT64)G << 16 ) + ( (INT64)(INT16)IR0 * ( Lm_B1( (INT32)GFC - ( G << 4 ), 0 ) ) ) ) >> 12 );
2494 			MAC3 = A3( ( ( (INT64)B << 16 ) + ( (INT64)(INT16)IR0 * ( Lm_B1( (INT32)BFC - ( B << 4 ), 0 ) ) ) ) >> 12 );
2495 			IR1 = Lm_B1( (INT32)MAC1, 0 );
2496 			IR2 = Lm_B2( (INT32)MAC2, 0 );
2497 			IR3 = Lm_B3( (INT32)MAC3, 0 );
2498 			CD0 = CD1;
2499 			CD1 = CD2;
2500 			CD2 = CODE;
2501 			R0 = R1;
2502 			R1 = R2;
2503 			R2 = Lm_C1( (INT32)MAC1 >> 4 );
2504 			G0 = G1;
2505 			G1 = G2;
2506 			G2 = Lm_C2( (INT32)MAC2 >> 4 );
2507 			B0 = B1;
2508 			B1 = B2;
2509 			B2 = Lm_C3( (INT32)MAC3 >> 4 );
2510 			return;
2511 		}
2512 		break;
2513 	case 0x09:
2514 		if( gteop == 0x0980011 )
2515 		{
2516 			log_cb(RETRO_LOG_DEBUG, LOGPRE "INTPL" );
2517 			FLAG = 0;
2518 
2519 			MAC1 = A1( ( ( (INT64)(INT16)IR1 << 12 ) + ( (INT64)(INT16)IR0 * ( Lm_B1( (INT32)RFC - (INT16)IR1, 0 ) ) ) ) >> 12 );
2520 			MAC2 = A2( ( ( (INT64)(INT16)IR2 << 12 ) + ( (INT64)(INT16)IR0 * ( Lm_B1( (INT32)GFC - (INT16)IR2, 0 ) ) ) ) >> 12 );
2521 			MAC3 = A3( ( ( (INT64)(INT16)IR3 << 12 ) + ( (INT64)(INT16)IR0 * ( Lm_B1( (INT32)BFC - (INT16)IR3, 0 ) ) ) ) >> 12 );
2522 			IR1 = Lm_B1( (INT32)MAC1, 0 );
2523 			IR2 = Lm_B2( (INT32)MAC2, 0 );
2524 			IR3 = Lm_B3( (INT32)MAC3, 0 );
2525 			CD0 = CD1;
2526 			CD1 = CD2;
2527 			CD2 = CODE;
2528 			R0 = R1;
2529 			R1 = R2;
2530 			R2 = Lm_C1( (INT32)MAC1 );
2531 			G0 = G1;
2532 			G1 = G2;
2533 			G2 = Lm_C2( (INT32)MAC2 );
2534 			B0 = B1;
2535 			B1 = B2;
2536 			B2 = Lm_C3( (INT32)MAC3 );
2537 			return;
2538 		}
2539 		break;
2540 	case 0x0a:
2541 		if( GTE_CT( gteop ) == 0x428 )
2542 		{
2543 			log_cb(RETRO_LOG_DEBUG, LOGPRE "SQR" );
2544 			n_sf = 12 * GTE_SF( gteop );
2545 			FLAG = 0;
2546 
2547 			MAC1 = A1( ( (INT64)(INT16)IR1 * (INT16)IR1 ) >> n_sf );
2548 			MAC2 = A2( ( (INT64)(INT16)IR2 * (INT16)IR2 ) >> n_sf );
2549 			MAC3 = A3( ( (INT64)(INT16)IR3 * (INT16)IR3 ) >> n_sf );
2550 			IR1 = Lm_B1( MAC1, 1 );
2551 			IR2 = Lm_B2( MAC2, 1 );
2552 			IR3 = Lm_B3( MAC3, 1 );
2553 			return;
2554 		}
2555 		break;
2556 	case 0x0c:
2557 		if( gteop == 0x0c8041e )
2558 		{
2559 			log_cb(RETRO_LOG_DEBUG, LOGPRE "NCS" );
2560 			FLAG = 0;
2561 
2562 			MAC1 = A1( ( ( (INT64)(INT16)L11 * (INT16)VX0 ) + ( (INT16)L12 * (INT16)VY0 ) + ( (INT16)L13 * (INT16)VZ0 ) ) >> 12 );
2563 			MAC2 = A2( ( ( (INT64)(INT16)L21 * (INT16)VX0 ) + ( (INT16)L22 * (INT16)VY0 ) + ( (INT16)L23 * (INT16)VZ0 ) ) >> 12 );
2564 			MAC3 = A3( ( ( (INT64)(INT16)L31 * (INT16)VX0 ) + ( (INT16)L32 * (INT16)VY0 ) + ( (INT16)L33 * (INT16)VZ0 ) ) >> 12 );
2565 			IR1 = Lm_B1( (INT32)MAC1, 1 );
2566 			IR2 = Lm_B2( (INT32)MAC2, 1 );
2567 			IR3 = Lm_B3( (INT32)MAC3, 1 );
2568 			MAC1 = A1( ( ( (INT64)RBK << 12 ) + ( (INT16)LR1 * (INT16)IR1 ) + ( (INT16)LR2 * (INT16)IR2 ) + ( (INT16)LR3 * (INT16)IR3 ) ) >> 12 );
2569 			MAC2 = A2( ( ( (INT64)GBK << 12 ) + ( (INT16)LG1 * (INT16)IR1 ) + ( (INT16)LG2 * (INT16)IR2 ) + ( (INT16)LG3 * (INT16)IR3 ) ) >> 12 );
2570 			MAC3 = A3( ( ( (INT64)BBK << 12 ) + ( (INT16)LB1 * (INT16)IR1 ) + ( (INT16)LB2 * (INT16)IR2 ) + ( (INT16)LB3 * (INT16)IR3 ) ) >> 12 );
2571 			IR1 = Lm_B1( (INT32)MAC1, 1 );
2572 			IR2 = Lm_B2( (INT32)MAC2, 1 );
2573 			IR3 = Lm_B3( (INT32)MAC3, 1 );
2574 			CD0 = CD1;
2575 			CD1 = CD2;
2576 			CD2 = CODE;
2577 			R0 = R1;
2578 			R1 = R2;
2579 			R2 = Lm_C1( (INT32)MAC1 >> 4 );
2580 			G0 = G1;
2581 			G1 = G2;
2582 			G2 = Lm_C2( (INT32)MAC2 >> 4 );
2583 			B0 = B1;
2584 			B1 = B2;
2585 			B2 = Lm_C3( (INT32)MAC3 >> 4 );
2586 			return;
2587 		}
2588 		break;
2589 	case 0x0d:
2590 		if( gteop == 0x0d80420 )
2591 		{
2592 			log_cb(RETRO_LOG_DEBUG, LOGPRE "NCT" );
2593 			FLAG = 0;
2594 
2595 			for( n_v = 0; n_v < 3; n_v++ )
2596 			{
2597 				MAC1 = A1( ( ( (INT64)(INT16)L11 * (INT16)*p_n_vx[ n_v ] ) + ( (INT16)L12 * (INT16)*p_n_vy[ n_v ] ) + ( (INT16)L13 * (INT16)*p_n_vz[ n_v ] ) ) >> 12 );
2598 				MAC2 = A2( ( ( (INT64)(INT16)L21 * (INT16)*p_n_vx[ n_v ] ) + ( (INT16)L22 * (INT16)*p_n_vy[ n_v ] ) + ( (INT16)L23 * (INT16)*p_n_vz[ n_v ] ) ) >> 12 );
2599 				MAC3 = A3( ( ( (INT64)(INT16)L31 * (INT16)*p_n_vx[ n_v ] ) + ( (INT16)L32 * (INT16)*p_n_vy[ n_v ] ) + ( (INT16)L33 * (INT16)*p_n_vz[ n_v ] ) ) >> 12 );
2600 				IR1 = Lm_B1( (INT32)MAC1, 1 );
2601 				IR2 = Lm_B2( (INT32)MAC2, 1 );
2602 				IR3 = Lm_B3( (INT32)MAC3, 1 );
2603 				MAC1 = A1( ( ( (INT64)RBK << 12 ) + ( (INT16)LR1 * (INT16)IR1 ) + ( (INT16)LR2 * (INT16)IR2 ) + ( (INT16)LR3 * (INT16)IR3 ) ) >> 12 );
2604 				MAC2 = A2( ( ( (INT64)GBK << 12 ) + ( (INT16)LG1 * (INT16)IR1 ) + ( (INT16)LG2 * (INT16)IR2 ) + ( (INT16)LG3 * (INT16)IR3 ) ) >> 12 );
2605 				MAC3 = A3( ( ( (INT64)BBK << 12 ) + ( (INT16)LB1 * (INT16)IR1 ) + ( (INT16)LB2 * (INT16)IR2 ) + ( (INT16)LB3 * (INT16)IR3 ) ) >> 12 );
2606 				IR1 = Lm_B1( (INT32)MAC1, 1 );
2607 				IR2 = Lm_B2( (INT32)MAC2, 1 );
2608 				IR3 = Lm_B3( (INT32)MAC3, 1 );
2609 				CD0 = CD1;
2610 				CD1 = CD2;
2611 				CD2 = CODE;
2612 				R0 = R1;
2613 				R1 = R2;
2614 				R2 = Lm_C1( (INT32)MAC1 >> 4 );
2615 				G0 = G1;
2616 				G1 = G2;
2617 				G2 = Lm_C2( (INT32)MAC2 >> 4 );
2618 				B0 = B1;
2619 				B1 = B2;
2620 				B2 = Lm_C3( (INT32)MAC3 >> 4 );
2621 			}
2622 			return;
2623 		}
2624 		break;
2625 	case 0x0e:
2626 		if( gteop == 0x0e80413 )
2627 		{
2628 			log_cb(RETRO_LOG_DEBUG, LOGPRE "NCDS" );
2629 			FLAG = 0;
2630 
2631 			MAC1 = A1( ( ( (INT64)(INT16)L11 * (INT16)VX0 ) + ( (INT16)L12 * (INT16)VY0 ) + ( (INT16)L13 * (INT16)VZ0 ) ) >> 12 );
2632 			MAC2 = A2( ( ( (INT64)(INT16)L21 * (INT16)VX0 ) + ( (INT16)L22 * (INT16)VY0 ) + ( (INT16)L23 * (INT16)VZ0 ) ) >> 12 );
2633 			MAC3 = A3( ( ( (INT64)(INT16)L31 * (INT16)VX0 ) + ( (INT16)L32 * (INT16)VY0 ) + ( (INT16)L33 * (INT16)VZ0 ) ) >> 12 );
2634 			IR1 = Lm_B1( (INT32)MAC1, 1 );
2635 			IR2 = Lm_B2( (INT32)MAC2, 1 );
2636 			IR3 = Lm_B3( (INT32)MAC3, 1 );
2637 			MAC1 = A1( ( ( (INT64)RBK << 12 ) + ( (INT16)LR1 * (INT16)IR1 ) + ( (INT16)LR2 * (INT16)IR2 ) + ( (INT16)LR3 * (INT16)IR3 ) ) >> 12 );
2638 			MAC2 = A2( ( ( (INT64)GBK << 12 ) + ( (INT16)LG1 * (INT16)IR1 ) + ( (INT16)LG2 * (INT16)IR2 ) + ( (INT16)LG3 * (INT16)IR3 ) ) >> 12 );
2639 			MAC3 = A3( ( ( (INT64)BBK << 12 ) + ( (INT16)LB1 * (INT16)IR1 ) + ( (INT16)LB2 * (INT16)IR2 ) + ( (INT16)LB3 * (INT16)IR3 ) ) >> 12 );
2640 			IR1 = Lm_B1( (INT32)MAC1, 1 );
2641 			IR2 = Lm_B2( (INT32)MAC2, 1 );
2642 			IR3 = Lm_B3( (INT32)MAC3, 1 );
2643 			MAC1 = A1( ( ( ( (INT64)R << 4 ) * (INT16)IR1 ) + ( (INT16)IR0 * Lm_B1( (INT32)RFC - ( ( R * (INT16)IR1 ) >> 8 ), 0 ) ) ) >> 12 );
2644 			MAC2 = A2( ( ( ( (INT64)G << 4 ) * (INT16)IR2 ) + ( (INT16)IR0 * Lm_B2( (INT32)GFC - ( ( G * (INT16)IR2 ) >> 8 ), 0 ) ) ) >> 12 );
2645 			MAC3 = A3( ( ( ( (INT64)B << 4 ) * (INT16)IR3 ) + ( (INT16)IR0 * Lm_B3( (INT32)BFC - ( ( B * (INT16)IR3 ) >> 8 ), 0 ) ) ) >> 12 );
2646 			IR1 = Lm_B1( (INT32)MAC1, 1 );
2647 			IR2 = Lm_B2( (INT32)MAC2, 1 );
2648 			IR3 = Lm_B3( (INT32)MAC3, 1 );
2649 			CD0 = CD1;
2650 			CD1 = CD2;
2651 			CD2 = CODE;
2652 			R0 = R1;
2653 			R1 = R2;
2654 			R2 = Lm_C1( (INT32)MAC1 >> 4 );
2655 			G0 = G1;
2656 			G1 = G2;
2657 			G2 = Lm_C2( (INT32)MAC2 >> 4 );
2658 			B0 = B1;
2659 			B1 = B2;
2660 			B2 = Lm_C3( (INT32)MAC3 >> 4 );
2661 			return;
2662 		}
2663 		break;
2664 	case 0x0f:
2665 		if( gteop == 0x0f8002a )
2666 		{
2667 			log_cb(RETRO_LOG_DEBUG, LOGPRE "DPCT" );
2668 			FLAG = 0;
2669 
2670 			for( n_pass = 0; n_pass < 3; n_pass++ )
2671 			{
2672 				MAC1 = A1( ( ( (INT64)R0 << 16 ) + ( (INT64)(INT16)IR0 * ( Lm_B1( (INT32)RFC - ( R0 << 4 ), 0 ) ) ) ) >> 12 );
2673 				MAC2 = A2( ( ( (INT64)G0 << 16 ) + ( (INT64)(INT16)IR0 * ( Lm_B1( (INT32)GFC - ( G0 << 4 ), 0 ) ) ) ) >> 12 );
2674 				MAC3 = A3( ( ( (INT64)B0 << 16 ) + ( (INT64)(INT16)IR0 * ( Lm_B1( (INT32)BFC - ( B0 << 4 ), 0 ) ) ) ) >> 12 );
2675 				IR1 = Lm_B1( (INT32)MAC1, 0 );
2676 				IR2 = Lm_B2( (INT32)MAC2, 0 );
2677 				IR3 = Lm_B3( (INT32)MAC3, 0 );
2678 				CD0 = CD1;
2679 				CD1 = CD2;
2680 				CD2 = CODE;
2681 				R0 = R1;
2682 				R1 = R2;
2683 				R2 = Lm_C1( (INT32)MAC1 >> 4 );
2684 				G0 = G1;
2685 				G1 = G2;
2686 				G2 = Lm_C2( (INT32)MAC2 >> 4 );
2687 				B0 = B1;
2688 				B1 = B2;
2689 				B2 = Lm_C3( (INT32)MAC3 >> 4 );
2690 			}
2691 			return;
2692 		}
2693 		else if( gteop == 0x0f80416 )
2694 		{
2695 			log_cb(RETRO_LOG_DEBUG, LOGPRE "NCDT" );
2696 			FLAG = 0;
2697 
2698 			for( n_v = 0; n_v < 3; n_v++ )
2699 			{
2700 				MAC1 = A1( ( ( (INT64)(INT16)L11 * (INT16)*p_n_vx[ n_v ] ) + ( (INT16)L12 * (INT16)*p_n_vy[ n_v ] ) + ( (INT16)L13 * (INT16)*p_n_vz[ n_v ] ) ) >> 12 );
2701 				MAC2 = A2( ( ( (INT64)(INT16)L21 * (INT16)*p_n_vx[ n_v ] ) + ( (INT16)L22 * (INT16)*p_n_vy[ n_v ] ) + ( (INT16)L23 * (INT16)*p_n_vz[ n_v ] ) ) >> 12 );
2702 				MAC3 = A3( ( ( (INT64)(INT16)L31 * (INT16)*p_n_vx[ n_v ] ) + ( (INT16)L32 * (INT16)*p_n_vy[ n_v ] ) + ( (INT16)L33 * (INT16)*p_n_vz[ n_v ] ) ) >> 12 );
2703 				IR1 = Lm_B1( (INT32)MAC1, 1 );
2704 				IR2 = Lm_B2( (INT32)MAC2, 1 );
2705 				IR3 = Lm_B3( (INT32)MAC3, 1 );
2706 				MAC1 = A1( ( ( (INT64)RBK << 12 ) + ( (INT16)LR1 * (INT16)IR1 ) + ( (INT16)LR2 * (INT16)IR2 ) + ( (INT16)LR3 * (INT16)IR3 ) ) >> 12 );
2707 				MAC2 = A2( ( ( (INT64)GBK << 12 ) + ( (INT16)LG1 * (INT16)IR1 ) + ( (INT16)LG2 * (INT16)IR2 ) + ( (INT16)LG3 * (INT16)IR3 ) ) >> 12 );
2708 				MAC3 = A3( ( ( (INT64)BBK << 12 ) + ( (INT16)LB1 * (INT16)IR1 ) + ( (INT16)LB2 * (INT16)IR2 ) + ( (INT16)LB3 * (INT16)IR3 ) ) >> 12 );
2709 				IR1 = Lm_B1( (INT32)MAC1, 1 );
2710 				IR2 = Lm_B2( (INT32)MAC2, 1 );
2711 				IR3 = Lm_B3( (INT32)MAC3, 1 );
2712 				MAC1 = A1( ( ( ( (INT64)R << 4 ) * (INT16)IR1 ) + ( (INT16)IR0 * Lm_B1( (INT32)RFC - ( ( R * (INT16)IR1 ) >> 8 ), 0 ) ) ) >> 12 );
2713 				MAC2 = A2( ( ( ( (INT64)G << 4 ) * (INT16)IR2 ) + ( (INT16)IR0 * Lm_B2( (INT32)GFC - ( ( G * (INT16)IR2 ) >> 8 ), 0 ) ) ) >> 12 );
2714 				MAC3 = A3( ( ( ( (INT64)B << 4 ) * (INT16)IR3 ) + ( (INT16)IR0 * Lm_B3( (INT32)BFC - ( ( B * (INT16)IR3 ) >> 8 ), 0 ) ) ) >> 12 );
2715 				IR1 = Lm_B1( (INT32)MAC1, 1 );
2716 				IR2 = Lm_B2( (INT32)MAC2, 1 );
2717 				IR3 = Lm_B3( (INT32)MAC3, 1 );
2718 				CD0 = CD1;
2719 				CD1 = CD2;
2720 				CD2 = CODE;
2721 				R0 = R1;
2722 				R1 = R2;
2723 				R2 = Lm_C1( (INT32)MAC1 >> 4 );
2724 				G0 = G1;
2725 				G1 = G2;
2726 				G2 = Lm_C2( (INT32)MAC2 >> 4 );
2727 				B0 = B1;
2728 				B1 = B2;
2729 				B2 = Lm_C3( (INT32)MAC3 >> 4 );
2730 			}
2731 			return;
2732 		}
2733 		break;
2734 	case 0x10:
2735 		if( gteop == 0x108041b )
2736 		{
2737 			log_cb(RETRO_LOG_DEBUG, LOGPRE "NCCS" );
2738 			FLAG = 0;
2739 
2740 			MAC1 = A1( ( ( (INT64)(INT16)L11 * (INT16)VX0 ) + ( (INT16)L12 * (INT16)VY0 ) + ( (INT16)L13 * (INT16)VZ0 ) ) >> 12 );
2741 			MAC2 = A2( ( ( (INT64)(INT16)L21 * (INT16)VX0 ) + ( (INT16)L22 * (INT16)VY0 ) + ( (INT16)L23 * (INT16)VZ0 ) ) >> 12 );
2742 			MAC3 = A3( ( ( (INT64)(INT16)L31 * (INT16)VX0 ) + ( (INT16)L32 * (INT16)VY0 ) + ( (INT16)L33 * (INT16)VZ0 ) ) >> 12 );
2743 			IR1 = Lm_B1( (INT32)MAC1, 1 );
2744 			IR2 = Lm_B2( (INT32)MAC2, 1 );
2745 			IR3 = Lm_B3( (INT32)MAC3, 1 );
2746 			MAC1 = A1( ( ( (INT64)RBK << 12 ) + ( (INT16)LR1 * (INT16)IR1 ) + ( (INT16)LR2 * (INT16)IR2 ) + ( (INT16)LR3 * (INT16)IR3 ) ) >> 12 );
2747 			MAC2 = A2( ( ( (INT64)GBK << 12 ) + ( (INT16)LG1 * (INT16)IR1 ) + ( (INT16)LG2 * (INT16)IR2 ) + ( (INT16)LG3 * (INT16)IR3 ) ) >> 12 );
2748 			MAC3 = A3( ( ( (INT64)BBK << 12 ) + ( (INT16)LB1 * (INT16)IR1 ) + ( (INT16)LB2 * (INT16)IR2 ) + ( (INT16)LB3 * (INT16)IR3 ) ) >> 12 );
2749 			IR1 = Lm_B1( (INT32)MAC1, 1 );
2750 			IR2 = Lm_B2( (INT32)MAC2, 1 );
2751 			IR3 = Lm_B3( (INT32)MAC3, 1 );
2752 			MAC1 = A1( ( (INT64)R * (INT16)IR1 ) >> 8 );
2753 			MAC2 = A2( ( (INT64)G * (INT16)IR2 ) >> 8 );
2754 			MAC3 = A3( ( (INT64)B * (INT16)IR3 ) >> 8 );
2755 			IR1 = Lm_B1( (INT32)MAC1, 1 );
2756 			IR2 = Lm_B2( (INT32)MAC2, 1 );
2757 			IR3 = Lm_B3( (INT32)MAC3, 1 );
2758 			CD0 = CD1;
2759 			CD1 = CD2;
2760 			CD2 = CODE;
2761 			R0 = R1;
2762 			R1 = R2;
2763 			R2 = Lm_C1( (INT32)MAC1 >> 4 );
2764 			G0 = G1;
2765 			G1 = G2;
2766 			G2 = Lm_C2( (INT32)MAC2 >> 4 );
2767 			B0 = B1;
2768 			B1 = B2;
2769 			B2 = Lm_C3( (INT32)MAC3 >> 4 );
2770 			return;
2771 		}
2772 		break;
2773 	case 0x11:
2774 		if( gteop == 0x118043f )
2775 		{
2776 			log_cb(RETRO_LOG_DEBUG, LOGPRE "NCCT" );
2777 			FLAG = 0;
2778 
2779 			for( n_v = 0; n_v < 3; n_v++ )
2780 			{
2781 				MAC1 = A1( ( ( (INT64)(INT16)L11 * (INT16)*p_n_vx[ n_v ] ) + ( (INT16)L12 * (INT16)*p_n_vy[ n_v ] ) + ( (INT16)L13 * (INT16)*p_n_vz[ n_v ] ) ) >> 12 );
2782 				MAC2 = A2( ( ( (INT64)(INT16)L21 * (INT16)*p_n_vx[ n_v ] ) + ( (INT16)L22 * (INT16)*p_n_vy[ n_v ] ) + ( (INT16)L23 * (INT16)*p_n_vz[ n_v ] ) ) >> 12 );
2783 				MAC3 = A3( ( ( (INT64)(INT16)L31 * (INT16)*p_n_vx[ n_v ] ) + ( (INT16)L32 * (INT16)*p_n_vy[ n_v ] ) + ( (INT16)L33 * (INT16)*p_n_vz[ n_v ] ) ) >> 12 );
2784 				IR1 = Lm_B1( (INT32)MAC1, 1 );
2785 				IR2 = Lm_B2( (INT32)MAC2, 1 );
2786 				IR3 = Lm_B3( (INT32)MAC3, 1 );
2787 				MAC1 = A1( ( ( (INT64)RBK << 12 ) + ( (INT16)LR1 * (INT16)IR1 ) + ( (INT16)LR2 * (INT16)IR2 ) + ( (INT16)LR3 * (INT16)IR3 ) ) >> 12 );
2788 				MAC2 = A2( ( ( (INT64)GBK << 12 ) + ( (INT16)LG1 * (INT16)IR1 ) + ( (INT16)LG2 * (INT16)IR2 ) + ( (INT16)LG3 * (INT16)IR3 ) ) >> 12 );
2789 				MAC3 = A3( ( ( (INT64)BBK << 12 ) + ( (INT16)LB1 * (INT16)IR1 ) + ( (INT16)LB2 * (INT16)IR2 ) + ( (INT16)LB3 * (INT16)IR3 ) ) >> 12 );
2790 				IR1 = Lm_B1( (INT32)MAC1, 1 );
2791 				IR2 = Lm_B2( (INT32)MAC2, 1 );
2792 				IR3 = Lm_B3( (INT32)MAC3, 1 );
2793 				MAC1 = A1( ( (INT64)R * (INT16)IR1 ) >> 8 );
2794 				MAC2 = A2( ( (INT64)G * (INT16)IR2 ) >> 8 );
2795 				MAC3 = A3( ( (INT64)B * (INT16)IR3 ) >> 8 );
2796 				IR1 = Lm_B1( (INT32)MAC1, 1 );
2797 				IR2 = Lm_B2( (INT32)MAC2, 1 );
2798 				IR3 = Lm_B3( (INT32)MAC3, 1 );
2799 				CD0 = CD1;
2800 				CD1 = CD2;
2801 				CD2 = CODE;
2802 				R0 = R1;
2803 				R1 = R2;
2804 				R2 = Lm_C1( (INT32)MAC1 >> 4 );
2805 				G0 = G1;
2806 				G1 = G2;
2807 				G2 = Lm_C2( (INT32)MAC2 >> 4 );
2808 				B0 = B1;
2809 				B1 = B2;
2810 				B2 = Lm_C3( (INT32)MAC3 >> 4 );
2811 			}
2812 			return;
2813 		}
2814 		break;
2815 	case 0x13:
2816 		if( gteop == 0x138041c )
2817 		{
2818 			log_cb(RETRO_LOG_DEBUG, LOGPRE "CC" );
2819 			FLAG = 0;
2820 
2821 			MAC1 = A1( ( ( (INT64)RBK << 12 ) + ( (INT16)LR1 * (INT16)IR1 ) + ( (INT16)LR2 * (INT16)IR2 ) + ( (INT16)LR3 * (INT16)IR3 ) ) >> 12 );
2822 			MAC2 = A2( ( ( (INT64)GBK << 12 ) + ( (INT16)LG1 * (INT16)IR1 ) + ( (INT16)LG2 * (INT16)IR2 ) + ( (INT16)LG3 * (INT16)IR3 ) ) >> 12 );
2823 			MAC3 = A3( ( ( (INT64)BBK << 12 ) + ( (INT16)LB1 * (INT16)IR1 ) + ( (INT16)LB2 * (INT16)IR2 ) + ( (INT16)LB3 * (INT16)IR3 ) ) >> 12 );
2824 			IR1 = Lm_B1( MAC1, 1 );
2825 			IR2 = Lm_B2( MAC2, 1 );
2826 			IR3 = Lm_B3( MAC3, 1 );
2827 			MAC1 = A1( ( (INT64)R * (INT16)IR1 ) >> 8 );
2828 			MAC2 = A2( ( (INT64)G * (INT16)IR2 ) >> 8 );
2829 			MAC3 = A3( ( (INT64)B * (INT16)IR3 ) >> 8 );
2830 			IR1 = Lm_B1( MAC1, 1 );
2831 			IR2 = Lm_B2( MAC2, 1 );
2832 			IR3 = Lm_B3( MAC3, 1 );
2833 			CD0 = CD1;
2834 			CD1 = CD2;
2835 			CD2 = CODE;
2836 			R0 = R1;
2837 			R1 = R2;
2838 			R2 = Lm_C1( (INT32)MAC1 >> 4 );
2839 			G0 = G1;
2840 			G1 = G2;
2841 			G2 = Lm_C2( (INT32)MAC2 >> 4 );
2842 			B0 = B1;
2843 			B1 = B2;
2844 			B2 = Lm_C3( (INT32)MAC3 >> 4 );
2845 			return;
2846 		}
2847 		break;
2848 	case 0x14:
2849 		if( gteop == 0x1400006 )
2850 		{
2851 			log_cb(RETRO_LOG_DEBUG, LOGPRE "NCLIP" );
2852 			FLAG = 0;
2853 
2854 			MAC0 = F( ( (INT64)(INT16)SX0 * (INT16)SY1 ) + ( (INT16)SX1 * (INT16)SY2 ) + ( (INT16)SX2 * (INT16)SY0 ) - ( (INT16)SX0 * (INT16)SY2 ) - ( (INT16)SX1 * (INT16)SY0 ) - ( (INT16)SX2 * (INT16)SY1 ) );
2855 			return;
2856 		}
2857 		break;
2858 	case 0x15:
2859 		if( gteop == 0x158002d )
2860 		{
2861 			log_cb(RETRO_LOG_DEBUG, LOGPRE "AVSZ3" );
2862 			FLAG = 0;
2863 
2864 			MAC0 = F( ( (INT64)(INT16)ZSF3 * SZ1 ) + ( (INT16)ZSF3 * SZ2 ) + ( (INT16)ZSF3 * SZ3 ) );
2865 			OTZ = Lm_D( (INT32)MAC0 >> 12 );
2866 			return;
2867 		}
2868 		break;
2869 	case 0x16:
2870 		if( gteop == 0x168002e )
2871 		{
2872 			log_cb(RETRO_LOG_DEBUG, LOGPRE "AVSZ4" );
2873 			FLAG = 0;
2874 
2875 			MAC0 = F( ( (INT64)(INT16)ZSF4 * SZ0 ) + ( (INT16)ZSF4 * SZ1 ) + ( (INT16)ZSF4 * SZ2 ) + ( (INT16)ZSF4 * SZ3 ) );
2876 			OTZ = Lm_D( (INT32)MAC0 >> 12 );
2877 			return;
2878 		}
2879 		break;
2880 	case 0x17:
2881 		if( GTE_CT( gteop ) == 0x00c )
2882 		{
2883 			log_cb(RETRO_LOG_DEBUG, LOGPRE "OP" );
2884 			n_sf = 12 * GTE_SF( gteop );
2885 			FLAG = 0;
2886 
2887 			MAC1 = A1( ( ( (INT64)(INT32)D2 * (INT16)IR3 ) - ( (INT64)(INT32)D3 * (INT16)IR2 ) ) >> n_sf );
2888 			MAC2 = A2( ( ( (INT64)(INT32)D3 * (INT16)IR1 ) - ( (INT64)(INT32)D1 * (INT16)IR3 ) ) >> n_sf );
2889 			MAC3 = A3( ( ( (INT64)(INT32)D1 * (INT16)IR2 ) - ( (INT64)(INT32)D2 * (INT16)IR1 ) ) >> n_sf );
2890 			IR1 = Lm_B1( (INT32)MAC1, 0 );
2891 			IR2 = Lm_B2( (INT32)MAC2, 0 );
2892 			IR3 = Lm_B3( (INT32)MAC3, 0 );
2893 			return;
2894 		}
2895 		break;
2896 	case 0x19:
2897 		if( GTE_CT( gteop ) == 0x03d )
2898 		{
2899 			log_cb(RETRO_LOG_DEBUG, LOGPRE "GPF" );
2900 			n_sf = 12 * GTE_SF( gteop );
2901 			FLAG = 0;
2902 
2903 			MAC1 = A1( ( (INT64)(INT16)IR0 * (INT16)IR1 ) >> n_sf );
2904 			MAC2 = A2( ( (INT64)(INT16)IR0 * (INT16)IR2 ) >> n_sf );
2905 			MAC3 = A3( ( (INT64)(INT16)IR0 * (INT16)IR3 ) >> n_sf );
2906 			IR1 = Lm_B1( (INT32)MAC1, 0 );
2907 			IR2 = Lm_B2( (INT32)MAC2, 0 );
2908 			IR3 = Lm_B3( (INT32)MAC3, 0 );
2909 			CD0 = CD1;
2910 			CD1 = CD2;
2911 			CD2 = CODE;
2912 			R0 = R1;
2913 			R1 = R2;
2914 			R2 = Lm_C1( (INT32)MAC1 >> 4 );
2915 			G0 = G1;
2916 			G1 = G2;
2917 			G2 = Lm_C2( (INT32)MAC2 >> 4 );
2918 			B0 = B1;
2919 			B1 = B2;
2920 			B2 = Lm_C3( (INT32)MAC3 >> 4 );
2921 			return;
2922 		}
2923 		break;
2924 	case 0x1a:
2925 		if( GTE_CT( gteop ) == 0x03e )
2926 		{
2927 			log_cb(RETRO_LOG_DEBUG, LOGPRE "GPL" );
2928 			n_sf = 12 * GTE_SF( gteop );
2929 			FLAG = 0;
2930 
2931 			MAC1 = A1( ( ( (INT64)(INT32)MAC1 << 12 ) + ( (INT16)IR0 * (INT16)IR1 ) ) >> n_sf );
2932 			MAC2 = A2( ( ( (INT64)(INT32)MAC2 << 12 ) + ( (INT16)IR0 * (INT16)IR2 ) ) >> n_sf );
2933 			MAC3 = A3( ( ( (INT64)(INT32)MAC3 << 12 ) + ( (INT16)IR0 * (INT16)IR3 ) ) >> n_sf );
2934 			IR1 = Lm_B1( (INT32)MAC1, 0 );
2935 			IR2 = Lm_B2( (INT32)MAC2, 0 );
2936 			IR3 = Lm_B3( (INT32)MAC3, 0 );
2937 			CD0 = CD1;
2938 			CD1 = CD2;
2939 			CD2 = CODE;
2940 			R0 = R1;
2941 			R1 = R2;
2942 			R2 = Lm_C1( (INT32)MAC1 >> 4 );
2943 			G0 = G1;
2944 			G1 = G2;
2945 			G2 = Lm_C2( (INT32)MAC2 >> 4 );
2946 			B0 = B1;
2947 			B1 = B2;
2948 			B2 = Lm_C3( (INT32)MAC3 >> 4 );
2949 			return;
2950 		}
2951 		break;
2952 	}
2953 	usrintf_showmessage_secs( 1, "unknown GTE op %08x", gteop );
2954 	log_cb(RETRO_LOG_DEBUG, LOGPRE  "%08x: unknown GTE op %08x\n", mipscpu.pc, gteop );
2955 	mips_stop();
2956 }
2957