1 /*****************************************************************************
2  *
3  *	 sh2.c
4  *	 Portable Hitachi SH-2 (SH7600 family) emulator
5  *
6  *	 Copyright (c) 2000 Juergen Buchmueller <pullmoll@t-online.de>,
7  *	 all rights reserved.
8  *
9  *	 - This source code is released as freeware for non-commercial purposes.
10  *	 - You are free to use and redistribute this code in modified or
11  *	   unmodified form, provided you list me in the credits.
12  *	 - If you modify this source code, you must add a notice to each modified
13  *	   source file that it has been changed.  If you're a nice person, you
14  *	   will clearly mark each change too.  :)
15  *	 - If you wish to use this for commercial purposes, please contact me at
16  *	   pullmoll@t-online.de
17  *	 - The author of this copywritten work reserves the right to change the
18  *	   terms of its usage and license at any time, including retroactively
19  *	 - This entire notice must remain in the source code.
20  *
21  *	This work is based on <tiraniddo@hotmail.com> C/C++ implementation of
22  *	the SH-2 CPU core and was adapted to the MAME CPU core requirements.
23  *	Thanks also go to Chuck Mason <chukjr@sundail.net> and Olivier Galibert
24  *	<galibert@pobox.com> for letting me peek into their SEMU code :-)
25  *
26  *****************************************************************************/
27 
28 /*****************************************************************************
29 	Changes
30 	20031015 O. Galibert
31 	- dma fixes, thanks to sthief
32 
33 	20031013 O. Galibert, A. Giles
34 	- timer fixes
35 	- multi-cpu simplifications
36 
37     20030915 O. Galibert
38     - fix DMA1 irq vector
39     - ignore writes to DRCRx
40     - fix cpu number issues
41     - fix slave/master recognition
42     - fix wrong-cpu-in-context problem with the timers
43 
44     20021020 O. Galibert
45     - DMA implementation, lightly tested
46     - change_pc() crap fixed
47     - delay slot in debugger fixed
48     - add divide box mirrors
49     - Nicola-ify the indentation
50     - Uncrapify sh2_internal_*
51     - Put back nmi support that had been lost somehow
52 
53 	20020914 R. Belmont
54 	- Initial SH2 internal timers implementation, based on code by O. Galibert.
55 	  Makes music work in galspanic4/s/s2, panic street, cyvern, other SKNS games.
56 	- Fix to external division, thanks to "spice" on the E2J board.
57 	  Corrects behavior of s1945ii turret boss.
58 
59 	20020302 Olivier Galibert (galibert@mame.net)
60 	- Fixed interrupt in delay slot
61 	- Fixed rotcr
62 	- Fixed div1
63 	- Fixed mulu
64 	- Fixed negc
65 
66 	20020301 R. Belmont
67 	- Fixed external division
68 
69 	20020225 Olivier Galibert (galibert@mame.net)
70 	- Fixed interrupt handling
71 
72 	20010207 Sylvain Glaize (mokona@puupuu.org)
73 
74 	- Bug fix in INLINE void MOVBM(UINT32 m, UINT32 n) (see comment)
75 	- Support of full 32 bit addressing (RB, RW, RL and WB, WW, WL functions)
76 		reason : when the two high bits of the address are set, access is
77 		done directly in the cache data array. The SUPER KANEKO NOVA SYSTEM
78 		sets the stack pointer here, using these addresses as usual RAM access.
79 
80 		No real cache support has been added.
81 	- Read/Write memory format correction (_bew to _bedw) (see also SH2
82 		definition in cpuintrf.c and DasmSH2(..) in sh2dasm.c )
83 
84 	20010623 James Forshaw (TyRaNiD@totalise.net)
85 
86     - Modified operation of sh2_exception. Done cause mame irq system is stupid, and
87       doesnt really seem designed for any more than 8 interrupt lines.
88 
89     20010701 James Forshaw (TyRaNiD@totalise.net)
90 
91     - Fixed DIV1 operation. Q bit now correctly generated
92 
93 	20020218 Added save states (mokona@puupuu.org)
94 
95  *****************************************************************************/
96 
97 #include <stdio.h>
98 #include "driver.h"
99 #include "state.h"
100 #include "mamedbg.h"
101 #include "sh2.h"
102 #include "memory.h"
103 
104 /* speed up delay loops, bail out of tight loops */
105 #define BUSY_LOOP_HACKS 	1
106 
107 typedef struct
108 {
109 	int irq_vector;
110 	int irq_priority;
111 } irq_entry;
112 
113 typedef struct
114 {
115 	UINT32	ppc;
116 	UINT32	pc;
117 	UINT32	pr;
118 	UINT32	sr;
119 	UINT32	gbr, vbr;
120 	UINT32	mach, macl;
121 	UINT32	r[16];
122 	UINT32	ea;
123 	UINT32	delay;
124 	UINT32	cpu_off;
125 	UINT32	dvsr, dvdnth, dvdntl, dvcr;
126 	UINT32	pending_irq;
127 	UINT32    test_irq;
128 	irq_entry     irq_queue[16];
129 
130 	INT8	irq_line_state[16];
131 	int 	(*irq_callback)(int irqline);
132 	UINT32	*m;
133 	INT8  nmi_line_state;
134 
135 	UINT16 	frc;
136 	UINT16 	ocra, ocrb, icr;
137 	UINT32 	frc_base;
138 
139 	int		frt_input;
140 	int 	internal_irq_level;
141 	int 	internal_irq_vector;
142 
143 	void 	*timer;
144 	void    *dma_timer[2];
145 	int     dma_timer_active[2];
146 
147 	int     is_slave, cpu_number;
148 } SH2;
149 
150 int sh2_icount;
151 static SH2 sh2;
152 
153 /* Atrocious hack that makes the soldivid music correct*/
154 
155 /*static const int div_tab[4] = { 3, 5, 7, 0 };*/
156 static const int div_tab[4] = { 3, 5, 3, 0 };
157 
158 enum {
159 	ICF  = 0x00800000,
160 	OCFA = 0x00080000,
161 	OCFB = 0x00040000,
162 	OVF  = 0x00020000
163 };
164 
165 static void sh2_timer_callback(int data);
166 
167 #define T	0x00000001
168 #define S	0x00000002
169 #define I	0x000000f0
170 #define Q	0x00000100
171 #define M	0x00000200
172 
173 #define AM	0x07ffffff
174 
175 #define FLAGS	(M|Q|I|S|T)
176 
177 #define Rn	((opcode>>8)&15)
178 #define Rm	((opcode>>4)&15)
179 
RB(offs_t A)180 static INLINE data8_t RB(offs_t A)
181 {
182 	if (A >= 0xe0000000)
183 		return sh2_internal_r((A & 0x1fc)>>2, ~(0xff << (((~A) & 3)*8))) >> (((~A) & 3)*8);
184 
185 	if (A >= 0xc0000000)
186 		return cpu_readmem32bedw(A);
187 
188 	if (A >= 0x40000000)
189 		return 0xa5;
190 
191 	return cpu_readmem32bedw(A & AM);
192 }
193 
RW(offs_t A)194 static INLINE data16_t RW(offs_t A)
195 {
196 	if (A >= 0xe0000000)
197 		return sh2_internal_r((A & 0x1fc)>>2, ~(0xffff << (((~A) & 2)*8))) >> (((~A) & 2)*8);
198 
199 	if (A >= 0xc0000000)
200 		return cpu_readmem32bedw_word(A);
201 
202 	if (A >= 0x40000000)
203 		return 0xa5a5;
204 
205 	return cpu_readmem32bedw_word(A & AM);
206 }
207 
RL(offs_t A)208 static INLINE data32_t RL(offs_t A)
209 {
210 	if (A >= 0xe0000000)
211 		return sh2_internal_r((A & 0x1fc)>>2, 0);
212 
213 	if (A >= 0xc0000000)
214 		return cpu_readmem32bedw_dword(A);
215 
216 	if (A >= 0x40000000)
217 		return 0xa5a5a5a5;
218 
219   return cpu_readmem32bedw_dword(A & AM);
220 }
221 
WB(offs_t A,data8_t V)222 static INLINE void WB(offs_t A, data8_t V)
223 {
224 
225 	if (A >= 0xe0000000)
226 	{
227 		sh2_internal_w((A & 0x1fc)>>2, V << (((~A) & 3)*8), ~(0xff << (((~A) & 3)*8)));
228 		return;
229 	}
230 
231 	if (A >= 0xc0000000)
232 	{
233 		cpu_writemem32bedw(A,V);
234 		return;
235 	}
236 
237 	if (A >= 0x40000000)
238 		return;
239 
240 	cpu_writemem32bedw(A & AM,V);
241 }
242 
WW(offs_t A,data16_t V)243 static INLINE void WW(offs_t A, data16_t V)
244 {
245 	if (A >= 0xe0000000)
246 	{
247 		sh2_internal_w((A & 0x1fc)>>2, V << (((~A) & 2)*8), ~(0xffff << (((~A) & 2)*8)));
248 		return;
249 	}
250 
251 	if (A >= 0xc0000000)
252 	{
253 		cpu_writemem32bedw_word(A,V);
254 		return;
255 	}
256 
257 	if (A >= 0x40000000)
258 		return;
259 
260 	cpu_writemem32bedw_word(A & AM,V);
261 }
262 
WL(offs_t A,data32_t V)263 static INLINE void WL(offs_t A, data32_t V)
264 {
265 	if (A >= 0xe0000000)
266 	{
267 		sh2_internal_w((A & 0x1fc)>>2, V, 0);
268 		return;
269 	}
270 
271 	if (A >= 0xc0000000)
272 	{
273 		cpu_writemem32bedw_dword(A,V);
274 		return;
275 	}
276 
277 	if (A >= 0x40000000)
278 		return;
279 
280 	cpu_writemem32bedw_dword(A & AM,V);
281 }
282 
sh2_exception(const char * message,int irqline)283 static INLINE void sh2_exception(const char *message, int irqline)
284 {
285 	int vector;
286 
287 	if (irqline != 16)
288 	{
289 		if (irqline <= ((sh2.sr >> 4) & 15)) /* If the cpu forbids this interrupt */
290 			return;
291 
292 		/* if this is an sh2 internal irq, use its vector*/
293 		if (sh2.internal_irq_level == irqline)
294 		{
295 			vector = sh2.internal_irq_vector;
296 			log_cb(RETRO_LOG_DEBUG, LOGPRE "SH-2 #%d exception #%d (internal vector: $%x) after [%s]\n", cpu_getactivecpu(), irqline, vector, message);
297 		}
298 		else
299 		{
300 			if(sh2.m[0x38] & 0x00010000)
301 			{
302 				vector = sh2.irq_callback(irqline);
303 				log_cb(RETRO_LOG_DEBUG, LOGPRE "SH-2 #%d exception #%d (external vector: $%x) after [%s]\n", cpu_getactivecpu(), irqline, vector, message);
304 			}
305 			else
306 			{
307 				sh2.irq_callback(irqline);
308 				vector = 64 + irqline/2;
309 				log_cb(RETRO_LOG_DEBUG, LOGPRE "SH-2 #%d exception #%d (autovector: $%x) after [%s]\n", cpu_getactivecpu(), irqline, vector, message);
310 			}
311 		}
312 	}
313 	else
314 	{
315 		vector = 11;
316 		log_cb(RETRO_LOG_DEBUG, LOGPRE "SH-2 #%d nmi exception (autovector: $%x) after [%s]\n", cpu_getactivecpu(), vector, message);
317 	}
318 
319 	sh2.r[15] -= 4;
320 	WL( sh2.r[15], sh2.sr );		/* push SR onto stack */
321 	sh2.r[15] -= 4;
322 	WL( sh2.r[15], sh2.pc );		/* push PC onto stack */
323 
324 	/* set I flags in SR */
325 	if (irqline > SH2_INT_15)
326 		sh2.sr = sh2.sr | I;
327 	else
328 		sh2.sr = (sh2.sr & ~I) | (irqline << 4);
329 
330 	/* fetch PC */
331 	sh2.pc = RL( sh2.vbr + vector * 4 );
332 	change_pc32bedw(sh2.pc & AM);
333 }
334 
335 #define CHECK_PENDING_IRQ(message)				\
336 do {											\
337 	int irq = -1;								\
338 	if (sh2.pending_irq & (1 <<  0)) irq =	0;	\
339 	if (sh2.pending_irq & (1 <<  1)) irq =	1;	\
340 	if (sh2.pending_irq & (1 <<  2)) irq =	2;	\
341 	if (sh2.pending_irq & (1 <<  3)) irq =	3;	\
342 	if (sh2.pending_irq & (1 <<  4)) irq =	4;	\
343 	if (sh2.pending_irq & (1 <<  5)) irq =	5;	\
344 	if (sh2.pending_irq & (1 <<  6)) irq =	6;	\
345 	if (sh2.pending_irq & (1 <<  7)) irq =	7;	\
346 	if (sh2.pending_irq & (1 <<  8)) irq =	8;	\
347 	if (sh2.pending_irq & (1 <<  9)) irq =	9;	\
348 	if (sh2.pending_irq & (1 << 10)) irq = 10;	\
349 	if (sh2.pending_irq & (1 << 11)) irq = 11;	\
350 	if (sh2.pending_irq & (1 << 12)) irq = 12;	\
351 	if (sh2.pending_irq & (1 << 13)) irq = 13;	\
352 	if (sh2.pending_irq & (1 << 14)) irq = 14;	\
353 	if (sh2.pending_irq & (1 << 15)) irq = 15;	\
354 	if ((sh2.internal_irq_level != -1) && (sh2.internal_irq_level > irq)) irq = sh2.internal_irq_level; \
355 	if (irq >= 0)								\
356 		sh2_exception(message,irq); 			\
357 } while(0)
358 
359 /* Layout of the registers in the debugger */
360 static UINT8 sh2_reg_layout[] = {
361 	SH2_PC, 	SH2_R15, 	SH2_SR, 	SH2_PR,  -1,
362 	SH2_GBR,	SH2_VBR,	SH2_MACH,	SH2_MACL,-1,
363 	SH2_R0, 	SH2_R1, 	SH2_R2, 	SH2_R3,  -1,
364 	SH2_R4, 	SH2_R5, 	SH2_R6, 	SH2_R7,  -1,
365 	SH2_R8, 	SH2_R9, 	SH2_R10,	SH2_R11, -1,
366 	SH2_R12,	SH2_R13,	SH2_R14,	SH2_EA,   0
367 };
368 
369 /* Layout of the debugger windows x,y,w,h */
370 static UINT8 sh2_win_layout[] = {
371 	0, 0,80, 6,	/* register window (top rows) */
372 	0, 7,39,15,	/* disassembler window	*/
373 	40, 7,39, 7,	/* memory #1 window (left) */
374 	40,15,39, 7,	/* memory #2 window (right) */
375 	0,23,80, 1,	/* command line window (bottom rows) */
376 };
377 
378 /*	code				 cycles  t-bit
379  *	0011 nnnn mmmm 1100  1		 -
380  *	ADD 	Rm,Rn
381  */
ADD(UINT32 m,UINT32 n)382 static INLINE void ADD(UINT32 m, UINT32 n)
383 {
384 	sh2.r[n] += sh2.r[m];
385 }
386 
387 /*	code				 cycles  t-bit
388  *	0111 nnnn iiii iiii  1		 -
389  *	ADD 	#imm,Rn
390  */
ADDI(UINT32 i,UINT32 n)391 static INLINE void ADDI(UINT32 i, UINT32 n)
392 {
393 	sh2.r[n] += (INT32)(INT16)(INT8)i;
394 }
395 
396 /*	code				 cycles  t-bit
397  *	0011 nnnn mmmm 1110  1		 carry
398  *	ADDC	Rm,Rn
399  */
ADDC(UINT32 m,UINT32 n)400 static INLINE void ADDC(UINT32 m, UINT32 n)
401 {
402 	UINT32 tmp0, tmp1;
403 
404 	tmp1 = sh2.r[n] + sh2.r[m];
405 	tmp0 = sh2.r[n];
406 	sh2.r[n] = tmp1 + (sh2.sr & T);
407 	if (tmp0 > tmp1)
408 		sh2.sr |= T;
409 	else
410 		sh2.sr &= ~T;
411 	if (tmp1 > sh2.r[n])
412 		sh2.sr |= T;
413 }
414 
415 /*	code				 cycles  t-bit
416  *	0011 nnnn mmmm 1111  1		 overflow
417  *	ADDV	Rm,Rn
418  */
ADDV(UINT32 m,UINT32 n)419 static INLINE void ADDV(UINT32 m, UINT32 n)
420 {
421 	INT32 dest, src, ans;
422 
423 	if ((INT32) sh2.r[n] >= 0)
424 		dest = 0;
425 	else
426 		dest = 1;
427 	if ((INT32) sh2.r[m] >= 0)
428 		src = 0;
429 	else
430 		src = 1;
431 	src += dest;
432 	sh2.r[n] += sh2.r[m];
433 	if ((INT32) sh2.r[n] >= 0)
434 		ans = 0;
435 	else
436 		ans = 1;
437 	ans += dest;
438 	if (src == 0 || src == 2)
439 	{
440 		if (ans == 1)
441 			sh2.sr |= T;
442 		else
443 			sh2.sr &= ~T;
444 	}
445 	else
446 		sh2.sr &= ~T;
447 }
448 
449 /*	code				 cycles  t-bit
450  *	0010 nnnn mmmm 1001  1		 -
451  *	AND 	Rm,Rn
452  */
AND(UINT32 m,UINT32 n)453 static INLINE void AND(UINT32 m, UINT32 n)
454 {
455 	sh2.r[n] &= sh2.r[m];
456 }
457 
458 
459 /*	code				 cycles  t-bit
460  *	1100 1001 iiii iiii  1		 -
461  *	AND 	#imm,R0
462  */
ANDI(UINT32 i)463 static INLINE void ANDI(UINT32 i)
464 {
465 	sh2.r[0] &= i;
466 }
467 
468 /*	code				 cycles  t-bit
469  *	1100 1101 iiii iiii  1		 -
470  *	AND.B	#imm,@(R0,GBR)
471  */
ANDM(UINT32 i)472 static INLINE void ANDM(UINT32 i)
473 {
474 	UINT32 temp;
475 
476 	sh2.ea = sh2.gbr + sh2.r[0];
477 	temp = i & RB( sh2.ea );
478 	WB( sh2.ea, temp );
479 	sh2_icount -= 2;
480 }
481 
482 /*	code				 cycles  t-bit
483  *	1000 1011 dddd dddd  3/1	 -
484  *	BF		disp8
485  */
BF(UINT32 d)486 static INLINE void BF(UINT32 d)
487 {
488 	if ((sh2.sr & T) == 0)
489 	{
490 		INT32 disp = ((INT32)d << 24) >> 24;
491 		sh2.pc = sh2.ea = sh2.pc + disp * 2 + 2;
492 		change_pc32bedw(sh2.pc & AM);
493 		sh2_icount -= 2;
494 	}
495 }
496 
497 /*	code				 cycles  t-bit
498  *	1000 1111 dddd dddd  3/1	 -
499  *	BFS 	disp8
500  */
BFS(UINT32 d)501 static INLINE void BFS(UINT32 d)
502 {
503 	if ((sh2.sr & T) == 0)
504 	{
505 		INT32 disp = ((INT32)d << 24) >> 24;
506 		sh2.delay = sh2.pc;
507 		sh2.pc = sh2.ea = sh2.pc + disp * 2 + 2;
508 		sh2_icount--;
509 	}
510 }
511 
512 /*	code				 cycles  t-bit
513  *	1010 dddd dddd dddd  2		 -
514  *	BRA 	disp12
515  */
BRA(UINT32 d)516 static INLINE void BRA(UINT32 d)
517 {
518 	INT32 disp = ((INT32)d << 20) >> 20;
519 
520 #if BUSY_LOOP_HACKS
521 	if (disp == -2)
522 	{
523 		UINT32 next_opcode = RW(sh2.ppc & AM);
524 		/* BRA	$
525 		 * NOP
526 		 */
527 		if (next_opcode == 0x0009)
528 			sh2_icount %= 3;	/* cycles for BRA $ and NOP taken (3) */
529 	}
530 #endif
531 	sh2.delay = sh2.pc;
532 	sh2.pc = sh2.ea = sh2.pc + disp * 2 + 2;
533 	sh2_icount--;
534 }
535 
536 /*	code				 cycles  t-bit
537  *	0000 mmmm 0010 0011  2		 -
538  *	BRAF	Rm
539  */
BRAF(UINT32 m)540 static INLINE void BRAF(UINT32 m)
541 {
542 	sh2.delay = sh2.pc;
543 	sh2.pc += sh2.r[m] + 2;
544 	sh2_icount--;
545 }
546 
547 /*	code				 cycles  t-bit
548  *	1011 dddd dddd dddd  2		 -
549  *	BSR 	disp12
550  */
BSR(UINT32 d)551 static INLINE void BSR(UINT32 d)
552 {
553 	INT32 disp = ((INT32)d << 20) >> 20;
554 
555 	sh2.pr = sh2.pc + 2;
556 	sh2.delay = sh2.pc;
557 	sh2.pc = sh2.ea = sh2.pc + disp * 2 + 2;
558 	sh2_icount--;
559 }
560 
561 /*	code				 cycles  t-bit
562  *	0000 mmmm 0000 0011  2		 -
563  *	BSRF	Rm
564  */
BSRF(UINT32 m)565 static INLINE void BSRF(UINT32 m)
566 {
567 	sh2.pr = sh2.pc + 2;
568 	sh2.delay = sh2.pc;
569 	sh2.pc += sh2.r[m] + 2;
570 	sh2_icount--;
571 }
572 
573 /*	code				 cycles  t-bit
574  *	1000 1001 dddd dddd  3/1	 -
575  *	BT		disp8
576  */
BT(UINT32 d)577 static INLINE void BT(UINT32 d)
578 {
579 	if ((sh2.sr & T) != 0)
580 	{
581 		INT32 disp = ((INT32)d << 24) >> 24;
582 		sh2.pc = sh2.ea = sh2.pc + disp * 2 + 2;
583 		change_pc32bedw(sh2.pc & AM);
584 		sh2_icount -= 2;
585 	}
586 }
587 
588 /*	code				 cycles  t-bit
589  *	1000 1101 dddd dddd  2/1	 -
590  *	BTS 	disp8
591  */
BTS(UINT32 d)592 static INLINE void BTS(UINT32 d)
593 {
594 	if ((sh2.sr & T) != 0)
595 	{
596 		INT32 disp = ((INT32)d << 24) >> 24;
597 		sh2.delay = sh2.pc;
598 		sh2.pc = sh2.ea = sh2.pc + disp * 2 + 2;
599 		sh2_icount--;
600 	}
601 }
602 
603 /*	code				 cycles  t-bit
604  *	0000 0000 0010 1000  1		 -
605  *	CLRMAC
606  */
CLRMAC(void)607 static INLINE void CLRMAC(void)
608 {
609 	sh2.mach = 0;
610 	sh2.macl = 0;
611 }
612 
613 /*	code				 cycles  t-bit
614  *	0000 0000 0000 1000  1		 -
615  *	CLRT
616  */
CLRT(void)617 static INLINE void CLRT(void)
618 {
619 	sh2.sr &= ~T;
620 }
621 
622 /*	code				 cycles  t-bit
623  *	0011 nnnn mmmm 0000  1		 comparison result
624  *	CMP_EQ	Rm,Rn
625  */
CMPEQ(UINT32 m,UINT32 n)626 static INLINE void CMPEQ(UINT32 m, UINT32 n)
627 {
628 	if (sh2.r[n] == sh2.r[m])
629 		sh2.sr |= T;
630 	else
631 		sh2.sr &= ~T;
632 }
633 
634 /*	code				 cycles  t-bit
635  *	0011 nnnn mmmm 0011  1		 comparison result
636  *	CMP_GE	Rm,Rn
637  */
CMPGE(UINT32 m,UINT32 n)638 static INLINE void CMPGE(UINT32 m, UINT32 n)
639 {
640 	if ((INT32) sh2.r[n] >= (INT32) sh2.r[m])
641 		sh2.sr |= T;
642 	else
643 		sh2.sr &= ~T;
644 }
645 
646 /*	code				 cycles  t-bit
647  *	0011 nnnn mmmm 0111  1		 comparison result
648  *	CMP_GT	Rm,Rn
649  */
CMPGT(UINT32 m,UINT32 n)650 static INLINE void CMPGT(UINT32 m, UINT32 n)
651 {
652 	if ((INT32) sh2.r[n] > (INT32) sh2.r[m])
653 		sh2.sr |= T;
654 	else
655 		sh2.sr &= ~T;
656 }
657 
658 /*	code				 cycles  t-bit
659  *	0011 nnnn mmmm 0110  1		 comparison result
660  *	CMP_HI	Rm,Rn
661  */
CMPHI(UINT32 m,UINT32 n)662 static INLINE void CMPHI(UINT32 m, UINT32 n)
663 {
664 	if ((UINT32) sh2.r[n] > (UINT32) sh2.r[m])
665 		sh2.sr |= T;
666 	else
667 		sh2.sr &= ~T;
668 }
669 
670 /*	code				 cycles  t-bit
671  *	0011 nnnn mmmm 0010  1		 comparison result
672  *	CMP_HS	Rm,Rn
673  */
CMPHS(UINT32 m,UINT32 n)674 static INLINE void CMPHS(UINT32 m, UINT32 n)
675 {
676 	if ((UINT32) sh2.r[n] >= (UINT32) sh2.r[m])
677 		sh2.sr |= T;
678 	else
679 		sh2.sr &= ~T;
680 }
681 
682 
683 /*	code				 cycles  t-bit
684  *	0100 nnnn 0001 0101  1		 comparison result
685  *	CMP_PL	Rn
686  */
CMPPL(UINT32 n)687 static INLINE void CMPPL(UINT32 n)
688 {
689 	if ((INT32) sh2.r[n] > 0)
690 		sh2.sr |= T;
691 	else
692 		sh2.sr &= ~T;
693 }
694 
695 /*	code				 cycles  t-bit
696  *	0100 nnnn 0001 0001  1		 comparison result
697  *	CMP_PZ	Rn
698  */
CMPPZ(UINT32 n)699 static INLINE void CMPPZ(UINT32 n)
700 {
701 	if ((INT32) sh2.r[n] >= 0)
702 		sh2.sr |= T;
703 	else
704 		sh2.sr &= ~T;
705 }
706 
707 /*	code				 cycles  t-bit
708  *	0010 nnnn mmmm 1100  1		 comparison result
709  * CMP_STR	Rm,Rn
710  */
CMPSTR(UINT32 m,UINT32 n)711 static INLINE void CMPSTR(UINT32 m, UINT32 n)
712  {
713   UINT32 temp;
714   INT32 HH, HL, LH, LL;
715   temp = sh2.r[n] ^ sh2.r[m];
716   HH = (temp >> 24) & 0xff;
717   HL = (temp >> 16) & 0xff;
718   LH = (temp >> 8) & 0xff;
719   LL = temp & 0xff;
720   if (HH && HL && LH && LL)
721    sh2.sr &= ~T;
722   else
723    sh2.sr |= T;
724  }
725 
726 
727 /*	code				 cycles  t-bit
728  *	1000 1000 iiii iiii  1		 comparison result
729  *	CMP/EQ #imm,R0
730  */
CMPIM(UINT32 i)731 static INLINE void CMPIM(UINT32 i)
732 {
733 	UINT32 imm = (UINT32)(INT32)(INT16)(INT8)i;
734 
735 	if (sh2.r[0] == imm)
736 		sh2.sr |= T;
737 	else
738 		sh2.sr &= ~T;
739 }
740 
741 /*	code				 cycles  t-bit
742  *	0010 nnnn mmmm 0111  1		 calculation result
743  *	DIV0S	Rm,Rn
744  */
DIV0S(UINT32 m,UINT32 n)745 static INLINE void DIV0S(UINT32 m, UINT32 n)
746 {
747 	if ((sh2.r[n] & 0x80000000) == 0)
748 		sh2.sr &= ~Q;
749 	else
750 		sh2.sr |= Q;
751 	if ((sh2.r[m] & 0x80000000) == 0)
752 		sh2.sr &= ~M;
753 	else
754 		sh2.sr |= M;
755 	if ((sh2.r[m] ^ sh2.r[n]) & 0x80000000)
756 		sh2.sr |= T;
757 	else
758 		sh2.sr &= ~T;
759 }
760 
761 /*	code				 cycles  t-bit
762  *	0000 0000 0001 1001  1		 0
763  *	DIV0U
764  */
DIV0U(void)765 static INLINE void DIV0U(void)
766 {
767 	sh2.sr &= ~(M | Q | T);
768 }
769 
770 /*	code				 cycles  t-bit
771  *	0011 nnnn mmmm 0100  1		 calculation result
772  *	DIV1 Rm,Rn
773  */
DIV1(UINT32 m,UINT32 n)774 static INLINE void DIV1(UINT32 m, UINT32 n)
775 {
776 	UINT32 tmp0;
777 	UINT32 old_q;
778 
779 	old_q = sh2.sr & Q;
780 	if (0x80000000 & sh2.r[n])
781 		sh2.sr |= Q;
782 	else
783 		sh2.sr &= ~Q;
784 
785 	sh2.r[n] = (sh2.r[n] << 1) | (sh2.sr & T);
786 
787 	if (!old_q)
788 	{
789 		if (!(sh2.sr & M))
790 		{
791 			tmp0 = sh2.r[n];
792 			sh2.r[n] -= sh2.r[m];
793 			if(!(sh2.sr & Q))
794 				if(sh2.r[n] > tmp0)
795 					sh2.sr |= Q;
796 				else
797 					sh2.sr &= ~Q;
798 			else
799 				if(sh2.r[n] > tmp0)
800 					sh2.sr &= ~Q;
801 				else
802 					sh2.sr |= Q;
803 		}
804 		else
805 		{
806 			tmp0 = sh2.r[n];
807 			sh2.r[n] += sh2.r[m];
808 			if(!(sh2.sr & Q))
809 			{
810 				if(sh2.r[n] < tmp0)
811 					sh2.sr &= ~Q;
812 				else
813 					sh2.sr |= Q;
814 			}
815 			else
816 			{
817 				if(sh2.r[n] < tmp0)
818 					sh2.sr |= Q;
819 				else
820 					sh2.sr &= ~Q;
821 			}
822 		}
823 	}
824 	else
825 	{
826 		if (!(sh2.sr & M))
827 		{
828 			tmp0 = sh2.r[n];
829 			sh2.r[n] += sh2.r[m];
830 			if(!(sh2.sr & Q))
831 				if(sh2.r[n] < tmp0)
832 					sh2.sr |= Q;
833 				else
834 					sh2.sr &= ~Q;
835 			else
836 				if(sh2.r[n] < tmp0)
837 					sh2.sr &= ~Q;
838 				else
839 					sh2.sr |= Q;
840 		}
841 		else
842 		{
843 			tmp0 = sh2.r[n];
844 			sh2.r[n] -= sh2.r[m];
845 			if(!(sh2.sr & Q))
846 				if(sh2.r[n] > tmp0)
847 					sh2.sr &= ~Q;
848 				else
849 					sh2.sr |= Q;
850 			else
851 				if(sh2.r[n] > tmp0)
852 					sh2.sr |= Q;
853 				else
854 					sh2.sr &= ~Q;
855 		}
856 	}
857 
858 	tmp0 = (sh2.sr & (Q | M));
859 	if((!tmp0) || (tmp0 == 0x300)) /* if Q == M set T else clear T */
860 		sh2.sr |= T;
861 	else
862 		sh2.sr &= ~T;
863 }
864 
865 /*	DMULS.L Rm,Rn */
DMULS(UINT32 m,UINT32 n)866 static INLINE void DMULS(UINT32 m, UINT32 n)
867 {
868 	UINT32 RnL, RnH, RmL, RmH, Res0, Res1, Res2;
869 	UINT32 temp0, temp1, temp2, temp3;
870 	INT32 tempm, tempn, fnLmL;
871 
872 	tempn = (INT32) sh2.r[n];
873 	tempm = (INT32) sh2.r[m];
874 	if (tempn < 0)
875 		tempn = 0 - tempn;
876 	if (tempm < 0)
877 		tempm = 0 - tempm;
878 	if ((INT32) (sh2.r[n] ^ sh2.r[m]) < 0)
879 		fnLmL = -1;
880 	else
881 		fnLmL = 0;
882 	temp1 = (UINT32) tempn;
883 	temp2 = (UINT32) tempm;
884 	RnL = temp1 & 0x0000ffff;
885 	RnH = (temp1 >> 16) & 0x0000ffff;
886 	RmL = temp2 & 0x0000ffff;
887 	RmH = (temp2 >> 16) & 0x0000ffff;
888 	temp0 = RmL * RnL;
889 	temp1 = RmH * RnL;
890 	temp2 = RmL * RnH;
891 	temp3 = RmH * RnH;
892 	Res2 = 0;
893 	Res1 = temp1 + temp2;
894 	if (Res1 < temp1)
895 		Res2 += 0x00010000;
896 	temp1 = (Res1 << 16) & 0xffff0000;
897 	Res0 = temp0 + temp1;
898 	if (Res0 < temp0)
899 		Res2++;
900 	Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;
901 	if (fnLmL < 0)
902 	{
903 		Res2 = ~Res2;
904 		if (Res0 == 0)
905 			Res2++;
906 		else
907 			Res0 = (~Res0) + 1;
908 	}
909 	sh2.mach = Res2;
910 	sh2.macl = Res0;
911 	sh2_icount--;
912 }
913 
914 /*	DMULU.L Rm,Rn */
DMULU(UINT32 m,UINT32 n)915 static INLINE void DMULU(UINT32 m, UINT32 n)
916 {
917 	UINT32 RnL, RnH, RmL, RmH, Res0, Res1, Res2;
918 	UINT32 temp0, temp1, temp2, temp3;
919 
920 	RnL = sh2.r[n] & 0x0000ffff;
921 	RnH = (sh2.r[n] >> 16) & 0x0000ffff;
922 	RmL = sh2.r[m] & 0x0000ffff;
923 	RmH = (sh2.r[m] >> 16) & 0x0000ffff;
924 	temp0 = RmL * RnL;
925 	temp1 = RmH * RnL;
926 	temp2 = RmL * RnH;
927 	temp3 = RmH * RnH;
928 	Res2 = 0;
929 	Res1 = temp1 + temp2;
930 	if (Res1 < temp1)
931 		Res2 += 0x00010000;
932 	temp1 = (Res1 << 16) & 0xffff0000;
933 	Res0 = temp0 + temp1;
934 	if (Res0 < temp0)
935 		Res2++;
936 	Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;
937 	sh2.mach = Res2;
938 	sh2.macl = Res0;
939 	sh2_icount--;
940 }
941 
942 /*	DT		Rn */
DT(UINT32 n)943 static INLINE void DT(UINT32 n)
944 {
945 	sh2.r[n]--;
946 	if (sh2.r[n] == 0)
947 		sh2.sr |= T;
948 	else
949 		sh2.sr &= ~T;
950 #if BUSY_LOOP_HACKS
951 	{
952 		UINT32 next_opcode = RW(sh2.ppc & AM);
953 		/* DT	Rn
954 		 * BF	$-2
955 		 */
956 		if (next_opcode == 0x8bfd)
957 		{
958 			while (sh2.r[n] > 1 && sh2_icount > 4)
959 			{
960 				sh2.r[n]--;
961 				sh2_icount -= 4;	/* cycles for DT (1) and BF taken (3) */
962 			}
963 		}
964 	}
965 #endif
966 }
967 
968 /*	EXTS.B	Rm,Rn */
EXTSB(UINT32 m,UINT32 n)969 static INLINE void EXTSB(UINT32 m, UINT32 n)
970 {
971 	sh2.r[n] = ((INT32)sh2.r[m] << 24) >> 24;
972 }
973 
974 /*	EXTS.W	Rm,Rn */
EXTSW(UINT32 m,UINT32 n)975 static INLINE void EXTSW(UINT32 m, UINT32 n)
976 {
977 	sh2.r[n] = ((INT32)sh2.r[m] << 16) >> 16;
978 }
979 
980 /*	EXTU.B	Rm,Rn */
EXTUB(UINT32 m,UINT32 n)981 static INLINE void EXTUB(UINT32 m, UINT32 n)
982 {
983 	sh2.r[n] = sh2.r[m] & 0x000000ff;
984 }
985 
986 /*	EXTU.W	Rm,Rn */
EXTUW(UINT32 m,UINT32 n)987 static INLINE void EXTUW(UINT32 m, UINT32 n)
988 {
989 	sh2.r[n] = sh2.r[m] & 0x0000ffff;
990 }
991 
992 /*	JMP 	@Rm */
JMP(UINT32 m)993 static INLINE void JMP(UINT32 m)
994 {
995 	sh2.delay = sh2.pc;
996 	sh2.pc = sh2.ea = sh2.r[m];
997 }
998 
999 /*	JSR 	@Rm */
JSR(UINT32 m)1000 static INLINE void JSR(UINT32 m)
1001 {
1002 	sh2.delay = sh2.pc;
1003 	sh2.pr = sh2.pc + 2;
1004 	sh2.pc = sh2.ea = sh2.r[m];
1005 	sh2_icount--;
1006 }
1007 
1008 
1009 /*	LDC 	Rm,SR */
LDCSR(UINT32 m)1010 static INLINE void LDCSR(UINT32 m)
1011 {
1012 	sh2.sr = sh2.r[m] & FLAGS;
1013 	sh2.test_irq = 1;
1014 }
1015 
1016 /*	LDC 	Rm,GBR */
LDCGBR(UINT32 m)1017 static INLINE void LDCGBR(UINT32 m)
1018 {
1019 	sh2.gbr = sh2.r[m];
1020 }
1021 
1022 /*	LDC 	Rm,VBR */
LDCVBR(UINT32 m)1023 static INLINE void LDCVBR(UINT32 m)
1024 {
1025 	sh2.vbr = sh2.r[m];
1026 }
1027 
1028 /*	LDC.L	@Rm+,SR */
LDCMSR(UINT32 m)1029 static INLINE void LDCMSR(UINT32 m)
1030 {
1031 	sh2.ea = sh2.r[m];
1032 	sh2.sr = RL( sh2.ea ) & FLAGS;
1033 	sh2.r[m] += 4;
1034 	sh2_icount -= 2;
1035 	sh2.test_irq = 1;
1036 }
1037 
1038 /*	LDC.L	@Rm+,GBR */
LDCMGBR(UINT32 m)1039 static INLINE void LDCMGBR(UINT32 m)
1040 {
1041 	sh2.ea = sh2.r[m];
1042 	sh2.gbr = RL( sh2.ea );
1043 	sh2.r[m] += 4;
1044 	sh2_icount -= 2;
1045 }
1046 
1047 /*	LDC.L	@Rm+,VBR */
LDCMVBR(UINT32 m)1048 static INLINE void LDCMVBR(UINT32 m)
1049 {
1050 	sh2.ea = sh2.r[m];
1051 	sh2.vbr = RL( sh2.ea );
1052 	sh2.r[m] += 4;
1053 	sh2_icount -= 2;
1054 }
1055 
1056 /*	LDS 	Rm,MACH */
LDSMACH(UINT32 m)1057 static INLINE void LDSMACH(UINT32 m)
1058 {
1059 	sh2.mach = sh2.r[m];
1060 }
1061 
1062 /*	LDS 	Rm,MACL */
LDSMACL(UINT32 m)1063 static INLINE void LDSMACL(UINT32 m)
1064 {
1065 	sh2.macl = sh2.r[m];
1066 }
1067 
1068 /*	LDS 	Rm,PR */
LDSPR(UINT32 m)1069 static INLINE void LDSPR(UINT32 m)
1070 {
1071 	sh2.pr = sh2.r[m];
1072 }
1073 
1074 /*	LDS.L	@Rm+,MACH */
LDSMMACH(UINT32 m)1075 static INLINE void LDSMMACH(UINT32 m)
1076 {
1077 	sh2.ea = sh2.r[m];
1078 	sh2.mach = RL( sh2.ea );
1079 	sh2.r[m] += 4;
1080 }
1081 
1082 /*	LDS.L	@Rm+,MACL */
LDSMMACL(UINT32 m)1083 static INLINE void LDSMMACL(UINT32 m)
1084 {
1085 	sh2.ea = sh2.r[m];
1086 	sh2.macl = RL( sh2.ea );
1087 	sh2.r[m] += 4;
1088 }
1089 
1090 /*	LDS.L	@Rm+,PR */
LDSMPR(UINT32 m)1091 static INLINE void LDSMPR(UINT32 m)
1092 {
1093 	sh2.ea = sh2.r[m];
1094 	sh2.pr = RL( sh2.ea );
1095 	sh2.r[m] += 4;
1096 }
1097 
1098 /*	MAC.L	@Rm+,@Rn+ */
MAC_L(UINT32 m,UINT32 n)1099 static INLINE void MAC_L(UINT32 m, UINT32 n)
1100 {
1101 	UINT32 RnL, RnH, RmL, RmH, Res0, Res1, Res2;
1102 	UINT32 temp0, temp1, temp2, temp3;
1103 	INT32 tempm, tempn, fnLmL;
1104 
1105 	tempn = (INT32) RL( sh2.r[n] );
1106 	sh2.r[n] += 4;
1107 	tempm = (INT32) RL( sh2.r[m] );
1108 	sh2.r[m] += 4;
1109 	if ((INT32) (tempn ^ tempm) < 0)
1110 		fnLmL = -1;
1111 	else
1112 		fnLmL = 0;
1113 	if (tempn < 0)
1114 		tempn = 0 - tempn;
1115 	if (tempm < 0)
1116 		tempm = 0 - tempm;
1117 	temp1 = (UINT32) tempn;
1118 	temp2 = (UINT32) tempm;
1119 	RnL = temp1 & 0x0000ffff;
1120 	RnH = (temp1 >> 16) & 0x0000ffff;
1121 	RmL = temp2 & 0x0000ffff;
1122 	RmH = (temp2 >> 16) & 0x0000ffff;
1123 	temp0 = RmL * RnL;
1124 	temp1 = RmH * RnL;
1125 	temp2 = RmL * RnH;
1126 	temp3 = RmH * RnH;
1127 	Res2 = 0;
1128 	Res1 = temp1 + temp2;
1129 	if (Res1 < temp1)
1130 		Res2 += 0x00010000;
1131 	temp1 = (Res1 << 16) & 0xffff0000;
1132 	Res0 = temp0 + temp1;
1133 	if (Res0 < temp0)
1134 		Res2++;
1135 	Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;
1136 	if (fnLmL < 0)
1137 	{
1138 		Res2 = ~Res2;
1139 		if (Res0 == 0)
1140 			Res2++;
1141 		else
1142 			Res0 = (~Res0) + 1;
1143 	}
1144 	if (sh2.sr & S)
1145 	{
1146 		Res0 = sh2.macl + Res0;
1147 		if (sh2.macl > Res0)
1148 			Res2++;
1149 		Res2 += (sh2.mach & 0x0000ffff);
1150 		if (((INT32) Res2 < 0) && (Res2 < 0xffff8000))
1151 		{
1152 			Res2 = 0x00008000;
1153 			Res0 = 0x00000000;
1154 		}
1155 		else if (((INT32) Res2 > 0) && (Res2 > 0x00007fff))
1156 		{
1157 			Res2 = 0x00007fff;
1158 			Res0 = 0xffffffff;
1159 		}
1160 		sh2.mach = Res2;
1161 		sh2.macl = Res0;
1162 	}
1163 	else
1164 	{
1165 		Res0 = sh2.macl + Res0;
1166 		if (sh2.macl > Res0)
1167 			Res2++;
1168 		Res2 += sh2.mach;
1169 		sh2.mach = Res2;
1170 		sh2.macl = Res0;
1171 	}
1172 	sh2_icount -= 2;
1173 }
1174 
1175 /*	MAC.W	@Rm+,@Rn+ */
MAC_W(UINT32 m,UINT32 n)1176 static INLINE void MAC_W(UINT32 m, UINT32 n)
1177 {
1178 	INT32 tempm, tempn, dest, src, ans;
1179 	UINT32 templ;
1180 
1181 	tempn = (INT32) RW( sh2.r[n] );
1182 	sh2.r[n] += 2;
1183 	tempm = (INT32) RW( sh2.r[m] );
1184 	sh2.r[m] += 2;
1185 	templ = sh2.macl;
1186 	tempm = ((INT32) (short) tempn * (INT32) (short) tempm);
1187 	if ((INT32) sh2.macl >= 0)
1188 		dest = 0;
1189 	else
1190 		dest = 1;
1191 	if ((INT32) tempm >= 0)
1192 	{
1193 		src = 0;
1194 		tempn = 0;
1195 	}
1196 	else
1197 	{
1198 		src = 1;
1199 		tempn = 0xffffffff;
1200 	}
1201 	src += dest;
1202 	sh2.macl += tempm;
1203 	if ((INT32) sh2.macl >= 0)
1204 		ans = 0;
1205 	else
1206 		ans = 1;
1207 	ans += dest;
1208 	if (sh2.sr & S)
1209 	{
1210 		if (ans == 1)
1211 			{
1212 				if (src == 0)
1213 					sh2.macl = 0x7fffffff;
1214 				if (src == 2)
1215 					sh2.macl = 0x80000000;
1216 			}
1217 	}
1218 	else
1219 	{
1220 		sh2.mach += tempn;
1221 		if (templ > sh2.macl)
1222 			sh2.mach += 1;
1223 		}
1224 	sh2_icount -= 2;
1225 }
1226 
1227 /*	MOV 	Rm,Rn */
MOV(UINT32 m,UINT32 n)1228 static INLINE void MOV(UINT32 m, UINT32 n)
1229 {
1230 	sh2.r[n] = sh2.r[m];
1231 }
1232 
1233 /*	MOV.B	Rm,@Rn */
MOVBS(UINT32 m,UINT32 n)1234 static INLINE void MOVBS(UINT32 m, UINT32 n)
1235 {
1236 	sh2.ea = sh2.r[n];
1237 	WB( sh2.ea, sh2.r[m] & 0x000000ff);
1238 }
1239 
1240 /*	MOV.W	Rm,@Rn */
MOVWS(UINT32 m,UINT32 n)1241 static INLINE void MOVWS(UINT32 m, UINT32 n)
1242 {
1243 	sh2.ea = sh2.r[n];
1244 	WW( sh2.ea, sh2.r[m] & 0x0000ffff);
1245 }
1246 
1247 /*	MOV.L	Rm,@Rn */
MOVLS(UINT32 m,UINT32 n)1248 static INLINE void MOVLS(UINT32 m, UINT32 n)
1249 {
1250 	sh2.ea = sh2.r[n];
1251 	WL( sh2.ea, sh2.r[m] );
1252 }
1253 
1254 /*	MOV.B	@Rm,Rn */
MOVBL(UINT32 m,UINT32 n)1255 static INLINE void MOVBL(UINT32 m, UINT32 n)
1256 {
1257 	sh2.ea = sh2.r[m];
1258 	sh2.r[n] = (UINT32)(INT32)(INT16)(INT8) RB( sh2.ea );
1259 }
1260 
1261 /*	MOV.W	@Rm,Rn */
MOVWL(UINT32 m,UINT32 n)1262 static INLINE void MOVWL(UINT32 m, UINT32 n)
1263 {
1264 	sh2.ea = sh2.r[m];
1265 	sh2.r[n] = (UINT32)(INT32)(INT16) RW( sh2.ea );
1266 }
1267 
1268 /*	MOV.L	@Rm,Rn */
MOVLL(UINT32 m,UINT32 n)1269 static INLINE void MOVLL(UINT32 m, UINT32 n)
1270 {
1271 	sh2.ea = sh2.r[m];
1272 	sh2.r[n] = RL( sh2.ea );
1273 }
1274 
1275 /*	MOV.B	Rm,@-Rn */
MOVBM(UINT32 m,UINT32 n)1276 static INLINE void MOVBM(UINT32 m, UINT32 n)
1277 {
1278 	/* SMG : bug fix, was reading sh2.r[n] */
1279 	UINT32 data = sh2.r[m] & 0x000000ff;
1280 
1281 	sh2.r[n] -= 1;
1282 	WB( sh2.r[n], data );
1283 }
1284 
1285 /*	MOV.W	Rm,@-Rn */
MOVWM(UINT32 m,UINT32 n)1286 static INLINE void MOVWM(UINT32 m, UINT32 n)
1287 {
1288 	UINT32 data = sh2.r[m] & 0x0000ffff;
1289 
1290 	sh2.r[n] -= 2;
1291 	WW( sh2.r[n], data );
1292 }
1293 
1294 /*	MOV.L	Rm,@-Rn */
MOVLM(UINT32 m,UINT32 n)1295 static INLINE void MOVLM(UINT32 m, UINT32 n)
1296 {
1297 	UINT32 data = sh2.r[m];
1298 
1299 	sh2.r[n] -= 4;
1300 	WL( sh2.r[n], data );
1301 }
1302 
1303 /*	MOV.B	@Rm+,Rn */
MOVBP(UINT32 m,UINT32 n)1304 static INLINE void MOVBP(UINT32 m, UINT32 n)
1305 {
1306 	sh2.r[n] = (UINT32)(INT32)(INT16)(INT8) RB( sh2.r[m] );
1307 	if (n != m)
1308 		sh2.r[m] += 1;
1309 }
1310 
1311 /*	MOV.W	@Rm+,Rn */
MOVWP(UINT32 m,UINT32 n)1312 static INLINE void MOVWP(UINT32 m, UINT32 n)
1313 {
1314 	sh2.r[n] = (UINT32)(INT32)(INT16) RW( sh2.r[m] );
1315 	if (n != m)
1316 		sh2.r[m] += 2;
1317 }
1318 
1319 /*	MOV.L	@Rm+,Rn */
MOVLP(UINT32 m,UINT32 n)1320 static INLINE void MOVLP(UINT32 m, UINT32 n)
1321 {
1322 	sh2.r[n] = RL( sh2.r[m] );
1323 	if (n != m)
1324 		sh2.r[m] += 4;
1325 }
1326 
1327 /*	MOV.B	Rm,@(R0,Rn) */
MOVBS0(UINT32 m,UINT32 n)1328 static INLINE void MOVBS0(UINT32 m, UINT32 n)
1329 {
1330 	sh2.ea = sh2.r[n] + sh2.r[0];
1331 	WB( sh2.ea, sh2.r[m] & 0x000000ff );
1332 }
1333 
1334 /*	MOV.W	Rm,@(R0,Rn) */
MOVWS0(UINT32 m,UINT32 n)1335 static INLINE void MOVWS0(UINT32 m, UINT32 n)
1336 {
1337 	sh2.ea = sh2.r[n] + sh2.r[0];
1338 	WW( sh2.ea, sh2.r[m] & 0x0000ffff );
1339 }
1340 
1341 /*	MOV.L	Rm,@(R0,Rn) */
MOVLS0(UINT32 m,UINT32 n)1342 static INLINE void MOVLS0(UINT32 m, UINT32 n)
1343 {
1344 	sh2.ea = sh2.r[n] + sh2.r[0];
1345 	WL( sh2.ea, sh2.r[m] );
1346 }
1347 
1348 /*	MOV.B	@(R0,Rm),Rn */
MOVBL0(UINT32 m,UINT32 n)1349 static INLINE void MOVBL0(UINT32 m, UINT32 n)
1350 {
1351 	sh2.ea = sh2.r[m] + sh2.r[0];
1352 	sh2.r[n] = (UINT32)(INT32)(INT16)(INT8) RB( sh2.ea );
1353 }
1354 
1355 /*	MOV.W	@(R0,Rm),Rn */
MOVWL0(UINT32 m,UINT32 n)1356 static INLINE void MOVWL0(UINT32 m, UINT32 n)
1357 {
1358 	sh2.ea = sh2.r[m] + sh2.r[0];
1359 	sh2.r[n] = (UINT32)(INT32)(INT16) RW( sh2.ea );
1360 }
1361 
1362 /*	MOV.L	@(R0,Rm),Rn */
MOVLL0(UINT32 m,UINT32 n)1363 static INLINE void MOVLL0(UINT32 m, UINT32 n)
1364 {
1365 	sh2.ea = sh2.r[m] + sh2.r[0];
1366 	sh2.r[n] = RL( sh2.ea );
1367 }
1368 
1369 /*	MOV 	#imm,Rn */
MOVI(UINT32 i,UINT32 n)1370 static INLINE void MOVI(UINT32 i, UINT32 n)
1371 {
1372 	sh2.r[n] = (UINT32)(INT32)(INT16)(INT8) i;
1373 }
1374 
1375 /*	MOV.W	@(disp8,PC),Rn */
MOVWI(UINT32 d,UINT32 n)1376 static INLINE void MOVWI(UINT32 d, UINT32 n)
1377 {
1378 	UINT32 disp = d & 0xff;
1379 	sh2.ea = sh2.pc + disp * 2 + 2;
1380 	sh2.r[n] = (UINT32)(INT32)(INT16) RW( sh2.ea );
1381 }
1382 
1383 /*	MOV.L	@(disp8,PC),Rn */
MOVLI(UINT32 d,UINT32 n)1384 static INLINE void MOVLI(UINT32 d, UINT32 n)
1385 {
1386 	UINT32 disp = d & 0xff;
1387 	sh2.ea = ((sh2.pc + 2) & ~3) + disp * 4;
1388 	sh2.r[n] = RL( sh2.ea );
1389 }
1390 
1391 /*	MOV.B	@(disp8,GBR),R0 */
MOVBLG(UINT32 d)1392 static INLINE void MOVBLG(UINT32 d)
1393 {
1394 	UINT32 disp = d & 0xff;
1395 	sh2.ea = sh2.gbr + disp;
1396 	sh2.r[0] = (UINT32)(INT32)(INT16)(INT8) RB( sh2.ea );
1397 }
1398 
1399 /*	MOV.W	@(disp8,GBR),R0 */
MOVWLG(UINT32 d)1400 static INLINE void MOVWLG(UINT32 d)
1401 {
1402 	UINT32 disp = d & 0xff;
1403 	sh2.ea = sh2.gbr + disp * 2;
1404 	sh2.r[0] = (INT32)(INT16) RW( sh2.ea );
1405 }
1406 
1407 /*	MOV.L	@(disp8,GBR),R0 */
MOVLLG(UINT32 d)1408 static INLINE void MOVLLG(UINT32 d)
1409 {
1410 	UINT32 disp = d & 0xff;
1411 	sh2.ea = sh2.gbr + disp * 4;
1412 	sh2.r[0] = RL( sh2.ea );
1413 }
1414 
1415 /*	MOV.B	R0,@(disp8,GBR) */
MOVBSG(UINT32 d)1416 static INLINE void MOVBSG(UINT32 d)
1417 {
1418 	UINT32 disp = d & 0xff;
1419 	sh2.ea = sh2.gbr + disp;
1420 	WB( sh2.ea, sh2.r[0] & 0x000000ff );
1421 }
1422 
1423 /*	MOV.W	R0,@(disp8,GBR) */
MOVWSG(UINT32 d)1424 static INLINE void MOVWSG(UINT32 d)
1425 {
1426 	UINT32 disp = d & 0xff;
1427 	sh2.ea = sh2.gbr + disp * 2;
1428 	WW( sh2.ea, sh2.r[0] & 0x0000ffff );
1429 }
1430 
1431 /*	MOV.L	R0,@(disp8,GBR) */
MOVLSG(UINT32 d)1432 static INLINE void MOVLSG(UINT32 d)
1433 {
1434 	UINT32 disp = d & 0xff;
1435 	sh2.ea = sh2.gbr + disp * 4;
1436 	WL( sh2.ea, sh2.r[0] );
1437 }
1438 
1439 /*	MOV.B	R0,@(disp4,Rn) */
MOVBS4(UINT32 d,UINT32 n)1440 static INLINE void MOVBS4(UINT32 d, UINT32 n)
1441 {
1442 	UINT32 disp = d & 0x0f;
1443 	sh2.ea = sh2.r[n] + disp;
1444 	WB( sh2.ea, sh2.r[0] & 0x000000ff );
1445 }
1446 
1447 /*	MOV.W	R0,@(disp4,Rn) */
MOVWS4(UINT32 d,UINT32 n)1448 static INLINE void MOVWS4(UINT32 d, UINT32 n)
1449 {
1450 	UINT32 disp = d & 0x0f;
1451 	sh2.ea = sh2.r[n] + disp * 2;
1452 	WW( sh2.ea, sh2.r[0] & 0x0000ffff );
1453 }
1454 
1455 /* MOV.L Rm,@(disp4,Rn) */
MOVLS4(UINT32 m,UINT32 d,UINT32 n)1456 static INLINE void MOVLS4(UINT32 m, UINT32 d, UINT32 n)
1457 {
1458 	UINT32 disp = d & 0x0f;
1459 	sh2.ea = sh2.r[n] + disp * 4;
1460 	WL( sh2.ea, sh2.r[m] );
1461 }
1462 
1463 /*	MOV.B	@(disp4,Rm),R0 */
MOVBL4(UINT32 m,UINT32 d)1464 static INLINE void MOVBL4(UINT32 m, UINT32 d)
1465 {
1466 	UINT32 disp = d & 0x0f;
1467 	sh2.ea = sh2.r[m] + disp;
1468 	sh2.r[0] = (UINT32)(INT32)(INT16)(INT8) RB( sh2.ea );
1469 }
1470 
1471 /*	MOV.W	@(disp4,Rm),R0 */
MOVWL4(UINT32 m,UINT32 d)1472 static INLINE void MOVWL4(UINT32 m, UINT32 d)
1473 {
1474 	UINT32 disp = d & 0x0f;
1475 	sh2.ea = sh2.r[m] + disp * 2;
1476 	sh2.r[0] = (UINT32)(INT32)(INT16) RW( sh2.ea );
1477 }
1478 
1479 /*	MOV.L	@(disp4,Rm),Rn */
MOVLL4(UINT32 m,UINT32 d,UINT32 n)1480 static INLINE void MOVLL4(UINT32 m, UINT32 d, UINT32 n)
1481 {
1482 	UINT32 disp = d & 0x0f;
1483 	sh2.ea = sh2.r[m] + disp * 4;
1484 	sh2.r[n] = RL( sh2.ea );
1485 }
1486 
1487 /*	MOVA	@(disp8,PC),R0 */
MOVA(UINT32 d)1488 static INLINE void MOVA(UINT32 d)
1489 {
1490 	UINT32 disp = d & 0xff;
1491 	sh2.ea = ((sh2.pc + 2) & ~3) + disp * 4;
1492 	sh2.r[0] = sh2.ea;
1493 }
1494 
1495 /*	MOVT	Rn */
MOVT(UINT32 n)1496 static INLINE void MOVT(UINT32 n)
1497 {
1498 	sh2.r[n] = sh2.sr & T;
1499 }
1500 
1501 /*	MUL.L	Rm,Rn */
MULL(UINT32 m,UINT32 n)1502 static INLINE void MULL(UINT32 m, UINT32 n)
1503 {
1504 	sh2.macl = sh2.r[n] * sh2.r[m];
1505 	sh2_icount--;
1506 }
1507 
1508 /*	MULS	Rm,Rn */
MULS(UINT32 m,UINT32 n)1509 static INLINE void MULS(UINT32 m, UINT32 n)
1510 {
1511 	sh2.macl = (INT16) sh2.r[n] * (INT16) sh2.r[m];
1512 }
1513 
1514 /*	MULU	Rm,Rn */
MULU(UINT32 m,UINT32 n)1515 static INLINE void MULU(UINT32 m, UINT32 n)
1516 {
1517 	sh2.macl = (UINT16) sh2.r[n] * (UINT16) sh2.r[m];
1518 }
1519 
1520 /*	NEG 	Rm,Rn */
NEG(UINT32 m,UINT32 n)1521 static INLINE void NEG(UINT32 m, UINT32 n)
1522 {
1523 	sh2.r[n] = 0 - sh2.r[m];
1524 }
1525 
1526 /*	NEGC	Rm,Rn */
NEGC(UINT32 m,UINT32 n)1527 static INLINE void NEGC(UINT32 m, UINT32 n)
1528 {
1529 	UINT32 temp;
1530 
1531 	temp = sh2.r[m];
1532 	sh2.r[n] = -temp - (sh2.sr & T);
1533 	if (temp || (sh2.sr & T))
1534 		sh2.sr |= T;
1535 	else
1536 		sh2.sr &= ~T;
1537 }
1538 
1539 /*	NOP */
NOP(void)1540 static INLINE void NOP(void)
1541 {
1542 }
1543 
1544 /*	NOT 	Rm,Rn */
NOT(UINT32 m,UINT32 n)1545 static INLINE void NOT(UINT32 m, UINT32 n)
1546 {
1547 	sh2.r[n] = ~sh2.r[m];
1548 }
1549 
1550 /*	OR		Rm,Rn */
OR(UINT32 m,UINT32 n)1551 static INLINE void OR(UINT32 m, UINT32 n)
1552 {
1553 	sh2.r[n] |= sh2.r[m];
1554 }
1555 
1556 /*	OR		#imm,R0 */
ORI(UINT32 i)1557 static INLINE void ORI(UINT32 i)
1558 {
1559 	sh2.r[0] |= i;
1560 	sh2_icount -= 2;
1561 }
1562 
1563 /*	OR.B	#imm,@(R0,GBR) */
ORM(UINT32 i)1564 static INLINE void ORM(UINT32 i)
1565 {
1566 	UINT32 temp;
1567 
1568 	sh2.ea = sh2.gbr + sh2.r[0];
1569 	temp = RB( sh2.ea );
1570 	temp |= i;
1571 	WB( sh2.ea, temp );
1572 }
1573 
1574 /*	ROTCL	Rn */
ROTCL(UINT32 n)1575 static INLINE void ROTCL(UINT32 n)
1576 {
1577 	UINT32 temp;
1578 
1579 	temp = (sh2.r[n] >> 31) & T;
1580 	sh2.r[n] = (sh2.r[n] << 1) | (sh2.sr & T);
1581 	sh2.sr = (sh2.sr & ~T) | temp;
1582 }
1583 
1584 /*	ROTCR	Rn */
ROTCR(UINT32 n)1585 static INLINE void ROTCR(UINT32 n)
1586 {
1587 	UINT32 temp;
1588 	temp = (sh2.sr & T) << 31;
1589 	if (sh2.r[n] & T)
1590 		sh2.sr |= T;
1591 	else
1592 		sh2.sr &= ~T;
1593 	sh2.r[n] = (sh2.r[n] >> 1) | temp;
1594 }
1595 
1596 /*	ROTL	Rn */
ROTL(UINT32 n)1597 static INLINE void ROTL(UINT32 n)
1598 {
1599 	sh2.sr = (sh2.sr & ~T) | ((sh2.r[n] >> 31) & T);
1600 	sh2.r[n] = (sh2.r[n] << 1) | (sh2.r[n] >> 31);
1601 }
1602 
1603 /*	ROTR	Rn */
ROTR(UINT32 n)1604 static INLINE void ROTR(UINT32 n)
1605 {
1606 	sh2.sr = (sh2.sr & ~T) | (sh2.r[n] & T);
1607 	sh2.r[n] = (sh2.r[n] >> 1) | (sh2.r[n] << 31);
1608 }
1609 
1610 /*	RTE */
RTE(void)1611 static INLINE void RTE(void)
1612 {
1613 	sh2.ea = sh2.r[15];
1614 	sh2.delay = sh2.pc;
1615 	sh2.pc = RL( sh2.ea );
1616 	sh2.r[15] += 4;
1617 	sh2.ea = sh2.r[15];
1618 	sh2.sr = RL( sh2.ea ) & FLAGS;
1619 	sh2.r[15] += 4;
1620 	sh2_icount -= 3;
1621 	sh2.test_irq = 1;
1622 }
1623 
1624 /*	RTS */
RTS(void)1625 static INLINE void RTS(void)
1626 {
1627 	sh2.delay = sh2.pc;
1628 	sh2.pc = sh2.ea = sh2.pr;
1629 	sh2_icount--;
1630 }
1631 
1632 /*	SETT */
SETT(void)1633 static INLINE void SETT(void)
1634 {
1635 	sh2.sr |= T;
1636 }
1637 
1638 /*	SHAL	Rn		(same as SHLL) */
SHAL(UINT32 n)1639 static INLINE void SHAL(UINT32 n)
1640 {
1641 	sh2.sr = (sh2.sr & ~T) | ((sh2.r[n] >> 31) & T);
1642 	sh2.r[n] <<= 1;
1643 }
1644 
1645 /*	SHAR	Rn */
SHAR(UINT32 n)1646 static INLINE void SHAR(UINT32 n)
1647 {
1648 	sh2.sr = (sh2.sr & ~T) | (sh2.r[n] & T);
1649 	sh2.r[n] = (UINT32)((INT32)sh2.r[n] >> 1);
1650 }
1651 
1652 /*	SHLL	Rn		(same as SHAL) */
SHLL(UINT32 n)1653 static INLINE void SHLL(UINT32 n)
1654 {
1655 	sh2.sr = (sh2.sr & ~T) | ((sh2.r[n] >> 31) & T);
1656 	sh2.r[n] <<= 1;
1657 }
1658 
1659 /*	SHLL2	Rn */
SHLL2(UINT32 n)1660 static INLINE void SHLL2(UINT32 n)
1661 {
1662 	sh2.r[n] <<= 2;
1663 }
1664 
1665 /*	SHLL8	Rn */
SHLL8(UINT32 n)1666 static INLINE void SHLL8(UINT32 n)
1667 {
1668 	sh2.r[n] <<= 8;
1669 }
1670 
1671 /*	SHLL16	Rn */
SHLL16(UINT32 n)1672 static INLINE void SHLL16(UINT32 n)
1673 {
1674 	sh2.r[n] <<= 16;
1675 }
1676 
1677 /*	SHLR	Rn */
SHLR(UINT32 n)1678 static INLINE void SHLR(UINT32 n)
1679 {
1680 	sh2.sr = (sh2.sr & ~T) | (sh2.r[n] & T);
1681 	sh2.r[n] >>= 1;
1682 }
1683 
1684 /*	SHLR2	Rn */
SHLR2(UINT32 n)1685 static INLINE void SHLR2(UINT32 n)
1686 {
1687 	sh2.r[n] >>= 2;
1688 }
1689 
1690 /*	SHLR8	Rn */
SHLR8(UINT32 n)1691 static INLINE void SHLR8(UINT32 n)
1692 {
1693 	sh2.r[n] >>= 8;
1694 }
1695 
1696 /*	SHLR16	Rn */
SHLR16(UINT32 n)1697 static INLINE void SHLR16(UINT32 n)
1698 {
1699 	sh2.r[n] >>= 16;
1700 }
1701 
1702 /*	SLEEP */
SLEEP(void)1703 static INLINE void SLEEP(void)
1704 {
1705 	sh2.pc -= 2;
1706 	sh2_icount -= 2;
1707 	/* Wait_for_exception; */
1708 }
1709 
1710 /*	STC 	SR,Rn */
STCSR(UINT32 n)1711 static INLINE void STCSR(UINT32 n)
1712 {
1713 	sh2.r[n] = sh2.sr;
1714 }
1715 
1716 /*	STC 	GBR,Rn */
STCGBR(UINT32 n)1717 static INLINE void STCGBR(UINT32 n)
1718 {
1719 	sh2.r[n] = sh2.gbr;
1720 }
1721 
1722 /*	STC 	VBR,Rn */
STCVBR(UINT32 n)1723 static INLINE void STCVBR(UINT32 n)
1724 {
1725 	sh2.r[n] = sh2.vbr;
1726 }
1727 
1728 /*	STC.L	SR,@-Rn */
STCMSR(UINT32 n)1729 static INLINE void STCMSR(UINT32 n)
1730 {
1731 	sh2.r[n] -= 4;
1732 	sh2.ea = sh2.r[n];
1733 	WL( sh2.ea, sh2.sr );
1734 	sh2_icount--;
1735 }
1736 
1737 /*	STC.L	GBR,@-Rn */
STCMGBR(UINT32 n)1738 static INLINE void STCMGBR(UINT32 n)
1739 {
1740 	sh2.r[n] -= 4;
1741 	sh2.ea = sh2.r[n];
1742 	WL( sh2.ea, sh2.gbr );
1743 	sh2_icount--;
1744 }
1745 
1746 /*	STC.L	VBR,@-Rn */
STCMVBR(UINT32 n)1747 static INLINE void STCMVBR(UINT32 n)
1748 {
1749 	sh2.r[n] -= 4;
1750 	sh2.ea = sh2.r[n];
1751 	WL( sh2.ea, sh2.vbr );
1752 	sh2_icount--;
1753 }
1754 
1755 /*	STS 	MACH,Rn */
STSMACH(UINT32 n)1756 static INLINE void STSMACH(UINT32 n)
1757 {
1758 	sh2.r[n] = sh2.mach;
1759 }
1760 
1761 /*	STS 	MACL,Rn */
STSMACL(UINT32 n)1762 static INLINE void STSMACL(UINT32 n)
1763 {
1764 	sh2.r[n] = sh2.macl;
1765 }
1766 
1767 /*	STS 	PR,Rn */
STSPR(UINT32 n)1768 static INLINE void STSPR(UINT32 n)
1769 {
1770 	sh2.r[n] = sh2.pr;
1771 }
1772 
1773 /*	STS.L	MACH,@-Rn */
STSMMACH(UINT32 n)1774 static INLINE void STSMMACH(UINT32 n)
1775 {
1776 	sh2.r[n] -= 4;
1777 	sh2.ea = sh2.r[n];
1778 	WL( sh2.ea, sh2.mach );
1779 }
1780 
1781 /*	STS.L	MACL,@-Rn */
STSMMACL(UINT32 n)1782 static INLINE void STSMMACL(UINT32 n)
1783 {
1784 	sh2.r[n] -= 4;
1785 	sh2.ea = sh2.r[n];
1786 	WL( sh2.ea, sh2.macl );
1787 }
1788 
1789 /*	STS.L	PR,@-Rn */
STSMPR(UINT32 n)1790 static INLINE void STSMPR(UINT32 n)
1791 {
1792 	sh2.r[n] -= 4;
1793 	sh2.ea = sh2.r[n];
1794 	WL( sh2.ea, sh2.pr );
1795 }
1796 
1797 /*	SUB 	Rm,Rn */
SUB(UINT32 m,UINT32 n)1798 static INLINE void SUB(UINT32 m, UINT32 n)
1799 {
1800 	sh2.r[n] -= sh2.r[m];
1801 }
1802 
1803 /*	SUBC	Rm,Rn */
SUBC(UINT32 m,UINT32 n)1804 static INLINE void SUBC(UINT32 m, UINT32 n)
1805 {
1806 	UINT32 tmp0, tmp1;
1807 
1808 	tmp1 = sh2.r[n] - sh2.r[m];
1809 	tmp0 = sh2.r[n];
1810 	sh2.r[n] = tmp1 - (sh2.sr & T);
1811 	if (tmp0 < tmp1)
1812 		sh2.sr |= T;
1813 	else
1814 		sh2.sr &= ~T;
1815 	if (tmp1 < sh2.r[n])
1816 		sh2.sr |= T;
1817 }
1818 
1819 /*	SUBV	Rm,Rn */
SUBV(UINT32 m,UINT32 n)1820 static INLINE void SUBV(UINT32 m, UINT32 n)
1821 {
1822 	INT32 dest, src, ans;
1823 
1824 	if ((INT32) sh2.r[n] >= 0)
1825 		dest = 0;
1826 	else
1827 		dest = 1;
1828 	if ((INT32) sh2.r[m] >= 0)
1829 		src = 0;
1830 	else
1831 		src = 1;
1832 	src += dest;
1833 	sh2.r[n] -= sh2.r[m];
1834 	if ((INT32) sh2.r[n] >= 0)
1835 		ans = 0;
1836 	else
1837 		ans = 1;
1838 	ans += dest;
1839 	if (src == 1)
1840 	{
1841 		if (ans == 1)
1842 			sh2.sr |= T;
1843 		else
1844 			sh2.sr &= ~T;
1845 	}
1846 	else
1847 		sh2.sr &= ~T;
1848 }
1849 
1850 /*	SWAP.B	Rm,Rn */
SWAPB(UINT32 m,UINT32 n)1851 static INLINE void SWAPB(UINT32 m, UINT32 n)
1852 {
1853 	UINT32 temp0, temp1;
1854 
1855 	temp0 = sh2.r[m] & 0xffff0000;
1856 	temp1 = (sh2.r[m] & 0x000000ff) << 8;
1857 	sh2.r[n] = (sh2.r[m] >> 8) & 0x000000ff;
1858 	sh2.r[n] = sh2.r[n] | temp1 | temp0;
1859 }
1860 
1861 /*	SWAP.W	Rm,Rn */
SWAPW(UINT32 m,UINT32 n)1862 static INLINE void SWAPW(UINT32 m, UINT32 n)
1863 {
1864 	UINT32 temp;
1865 
1866 	temp = (sh2.r[m] >> 16) & 0x0000ffff;
1867 	sh2.r[n] = (sh2.r[m] << 16) | temp;
1868 }
1869 
1870 /*	TAS.B	@Rn */
TAS(UINT32 n)1871 static INLINE void TAS(UINT32 n)
1872 {
1873 	UINT32 temp;
1874 	sh2.ea = sh2.r[n];
1875 	/* Bus Lock enable */
1876 	temp = RB( sh2.ea );
1877 	if (temp == 0)
1878 		sh2.sr |= T;
1879 	else
1880 		sh2.sr &= ~T;
1881 	temp |= 0x80;
1882 	/* Bus Lock disable */
1883 	WB( sh2.ea, temp );
1884 	sh2_icount -= 3;
1885 }
1886 
1887 /*	TRAPA	#imm */
TRAPA(UINT32 i)1888 static INLINE void TRAPA(UINT32 i)
1889 {
1890 	UINT32 imm = i & 0xff;
1891 
1892 	sh2.ea = sh2.vbr + imm * 4;
1893 
1894 	sh2.r[15] -= 4;
1895 	WL( sh2.r[15], sh2.sr );
1896 	sh2.r[15] -= 4;
1897 	WL( sh2.r[15], sh2.pc );
1898 
1899 	sh2.pc = RL( sh2.ea );
1900 	change_pc32bedw(sh2.pc & AM);
1901 
1902 	sh2_icount -= 7;
1903 }
1904 
1905 /*	TST 	Rm,Rn */
TST(UINT32 m,UINT32 n)1906 static INLINE void TST(UINT32 m, UINT32 n)
1907 {
1908 	if ((sh2.r[n] & sh2.r[m]) == 0)
1909 		sh2.sr |= T;
1910 	else
1911 		sh2.sr &= ~T;
1912 }
1913 
1914 /*	TST 	#imm,R0 */
TSTI(UINT32 i)1915 static INLINE void TSTI(UINT32 i)
1916 {
1917 	UINT32 imm = i & 0xff;
1918 
1919 	if ((imm & sh2.r[0]) == 0)
1920 		sh2.sr |= T;
1921 	else
1922 		sh2.sr &= ~T;
1923 }
1924 
1925 /*	TST.B	#imm,@(R0,GBR) */
TSTM(UINT32 i)1926 static INLINE void TSTM(UINT32 i)
1927 {
1928 	UINT32 imm = i & 0xff;
1929 
1930 	sh2.ea = sh2.gbr + sh2.r[0];
1931 	if ((imm & RB( sh2.ea )) == 0)
1932 		sh2.sr |= T;
1933 	else
1934 		sh2.sr &= ~T;
1935 	sh2_icount -= 2;
1936 }
1937 
1938 /*	XOR 	Rm,Rn */
XOR(UINT32 m,UINT32 n)1939 static INLINE void XOR(UINT32 m, UINT32 n)
1940 {
1941 	sh2.r[n] ^= sh2.r[m];
1942 }
1943 
1944 /*	XOR 	#imm,R0 */
XORI(UINT32 i)1945 static INLINE void XORI(UINT32 i)
1946 {
1947 	UINT32 imm = i & 0xff;
1948 	sh2.r[0] ^= imm;
1949 }
1950 
1951 /*	XOR.B	#imm,@(R0,GBR) */
XORM(UINT32 i)1952 static INLINE void XORM(UINT32 i)
1953 {
1954 	UINT32 imm = i & 0xff;
1955 	UINT32 temp;
1956 
1957 	sh2.ea = sh2.gbr + sh2.r[0];
1958 	temp = RB( sh2.ea );
1959 	temp ^= imm;
1960 	WB( sh2.ea, temp );
1961 	sh2_icount -= 2;
1962 }
1963 
1964 /*	XTRCT	Rm,Rn */
XTRCT(UINT32 m,UINT32 n)1965 static INLINE void XTRCT(UINT32 m, UINT32 n)
1966 {
1967 	UINT32 temp;
1968 
1969 	temp = (sh2.r[m] << 16) & 0xffff0000;
1970 	sh2.r[n] = (sh2.r[n] >> 16) & 0x0000ffff;
1971 	sh2.r[n] |= temp;
1972 }
1973 
1974 /*****************************************************************************
1975  *	OPCODE DISPATCHERS
1976  *****************************************************************************/
1977 
op0000(UINT16 opcode)1978 static INLINE void op0000(UINT16 opcode)
1979 {
1980 	switch (opcode & 0x3F)
1981 	{
1982 	case 0x00: NOP();						break;
1983 	case 0x01: NOP();						break;
1984 	case 0x02: STCSR(Rn);					break;
1985 	case 0x03: BSRF(Rn);					break;
1986 	case 0x04: MOVBS0(Rm, Rn);				break;
1987 	case 0x05: MOVWS0(Rm, Rn);				break;
1988 	case 0x06: MOVLS0(Rm, Rn);				break;
1989 	case 0x07: MULL(Rm, Rn);				break;
1990 	case 0x08: CLRT();						break;
1991 	case 0x09: NOP();						break;
1992 	case 0x0a: STSMACH(Rn); 				break;
1993 	case 0x0b: RTS();						break;
1994 	case 0x0c: MOVBL0(Rm, Rn);				break;
1995 	case 0x0d: MOVWL0(Rm, Rn);				break;
1996 	case 0x0e: MOVLL0(Rm, Rn);				break;
1997 	case 0x0f: MAC_L(Rm, Rn);				break;
1998 
1999 	case 0x10: NOP();						break;
2000 	case 0x11: NOP();						break;
2001 	case 0x12: STCGBR(Rn);					break;
2002 	case 0x13: NOP();						break;
2003 	case 0x14: MOVBS0(Rm, Rn);				break;
2004 	case 0x15: MOVWS0(Rm, Rn);				break;
2005 	case 0x16: MOVLS0(Rm, Rn);				break;
2006 	case 0x17: MULL(Rm, Rn);				break;
2007 	case 0x18: SETT();						break;
2008 	case 0x19: DIV0U(); 					break;
2009 	case 0x1a: STSMACL(Rn); 				break;
2010 	case 0x1b: SLEEP(); 					break;
2011 	case 0x1c: MOVBL0(Rm, Rn);				break;
2012 	case 0x1d: MOVWL0(Rm, Rn);				break;
2013 	case 0x1e: MOVLL0(Rm, Rn);				break;
2014 	case 0x1f: MAC_L(Rm, Rn);				break;
2015 
2016 	case 0x20: NOP();						break;
2017 	case 0x21: NOP();						break;
2018 	case 0x22: STCVBR(Rn);					break;
2019 	case 0x23: BRAF(Rn);					break;
2020 	case 0x24: MOVBS0(Rm, Rn);				break;
2021 	case 0x25: MOVWS0(Rm, Rn);				break;
2022 	case 0x26: MOVLS0(Rm, Rn);				break;
2023 	case 0x27: MULL(Rm, Rn);				break;
2024 	case 0x28: CLRMAC();					break;
2025 	case 0x29: MOVT(Rn);					break;
2026 	case 0x2a: STSPR(Rn);					break;
2027 	case 0x2b: RTE();						break;
2028 	case 0x2c: MOVBL0(Rm, Rn);				break;
2029 	case 0x2d: MOVWL0(Rm, Rn);				break;
2030 	case 0x2e: MOVLL0(Rm, Rn);				break;
2031 	case 0x2f: MAC_L(Rm, Rn);				break;
2032 
2033 	case 0x30: NOP();						break;
2034 	case 0x31: NOP();						break;
2035 	case 0x32: NOP();						break;
2036 	case 0x33: NOP();						break;
2037 	case 0x34: MOVBS0(Rm, Rn);				break;
2038 	case 0x35: MOVWS0(Rm, Rn);				break;
2039 	case 0x36: MOVLS0(Rm, Rn);				break;
2040 	case 0x37: MULL(Rm, Rn);				break;
2041 	case 0x38: NOP();						break;
2042 	case 0x39: NOP();						break;
2043 	case 0x3c: MOVBL0(Rm, Rn);				break;
2044 	case 0x3d: MOVWL0(Rm, Rn);				break;
2045 	case 0x3e: MOVLL0(Rm, Rn);				break;
2046 	case 0x3f: MAC_L(Rm, Rn);				break;
2047 	case 0x3a: NOP();						break;
2048 	case 0x3b: NOP();						break;
2049 	}
2050 }
2051 
op0001(UINT16 opcode)2052 static INLINE void op0001(UINT16 opcode)
2053 {
2054 	MOVLS4(Rm, opcode & 0x0f, Rn);
2055 }
2056 
op0010(UINT16 opcode)2057 static INLINE void op0010(UINT16 opcode)
2058 {
2059 	switch (opcode & 15)
2060 	{
2061 	case  0: MOVBS(Rm, Rn); 				break;
2062 	case  1: MOVWS(Rm, Rn); 				break;
2063 	case  2: MOVLS(Rm, Rn); 				break;
2064 	case  3: NOP(); 						break;
2065 	case  4: MOVBM(Rm, Rn); 				break;
2066 	case  5: MOVWM(Rm, Rn); 				break;
2067 	case  6: MOVLM(Rm, Rn); 				break;
2068 	case  7: DIV0S(Rm, Rn); 				break;
2069 	case  8: TST(Rm, Rn);					break;
2070 	case  9: AND(Rm, Rn);					break;
2071 	case 10: XOR(Rm, Rn);					break;
2072 	case 11: OR(Rm, Rn);					break;
2073 	case 12: CMPSTR(Rm, Rn);				break;
2074 	case 13: XTRCT(Rm, Rn); 				break;
2075 	case 14: MULU(Rm, Rn);					break;
2076 	case 15: MULS(Rm, Rn);					break;
2077 	}
2078 }
2079 
op0011(UINT16 opcode)2080 static INLINE void op0011(UINT16 opcode)
2081 {
2082 	switch (opcode & 15)
2083 	{
2084 	case  0: CMPEQ(Rm, Rn); 				break;
2085 	case  1: NOP(); 						break;
2086 	case  2: CMPHS(Rm, Rn); 				break;
2087 	case  3: CMPGE(Rm, Rn); 				break;
2088 	case  4: DIV1(Rm, Rn);					break;
2089 	case  5: DMULU(Rm, Rn); 				break;
2090 	case  6: CMPHI(Rm, Rn); 				break;
2091 	case  7: CMPGT(Rm, Rn); 				break;
2092 	case  8: SUB(Rm, Rn);					break;
2093 	case  9: NOP(); 						break;
2094 	case 10: SUBC(Rm, Rn);					break;
2095 	case 11: SUBV(Rm, Rn);					break;
2096 	case 12: ADD(Rm, Rn);					break;
2097 	case 13: DMULS(Rm, Rn); 				break;
2098 	case 14: ADDC(Rm, Rn);					break;
2099 	case 15: ADDV(Rm, Rn);					break;
2100 	}
2101 }
2102 
op0100(UINT16 opcode)2103 static INLINE void op0100(UINT16 opcode)
2104 {
2105 	switch (opcode & 0x3F)
2106 	{
2107 	case 0x00: SHLL(Rn);					break;
2108 	case 0x01: SHLR(Rn);					break;
2109 	case 0x02: STSMMACH(Rn);				break;
2110 	case 0x03: STCMSR(Rn);					break;
2111 	case 0x04: ROTL(Rn);					break;
2112 	case 0x05: ROTR(Rn);					break;
2113 	case 0x06: LDSMMACH(Rn);				break;
2114 	case 0x07: LDCMSR(Rn);					break;
2115 	case 0x08: SHLL2(Rn);					break;
2116 	case 0x09: SHLR2(Rn);					break;
2117 	case 0x0a: LDSMACH(Rn); 				break;
2118 	case 0x0b: JSR(Rn); 					break;
2119 	case 0x0c: NOP();						break;
2120 	case 0x0d: NOP();						break;
2121 	case 0x0e: LDCSR(Rn);					break;
2122 	case 0x0f: MAC_W(Rm, Rn);				break;
2123 
2124 	case 0x10: DT(Rn);						break;
2125 	case 0x11: CMPPZ(Rn);					break;
2126 	case 0x12: STSMMACL(Rn);				break;
2127 	case 0x13: STCMGBR(Rn); 				break;
2128 	case 0x14: NOP();						break;
2129 	case 0x15: CMPPL(Rn);					break;
2130 	case 0x16: LDSMMACL(Rn);				break;
2131 	case 0x17: LDCMGBR(Rn); 				break;
2132 	case 0x18: SHLL8(Rn);					break;
2133 	case 0x19: SHLR8(Rn);					break;
2134 	case 0x1a: LDSMACL(Rn); 				break;
2135 	case 0x1b: TAS(Rn); 					break;
2136 	case 0x1c: NOP();						break;
2137 	case 0x1d: NOP();						break;
2138 	case 0x1e: LDCGBR(Rn);					break;
2139 	case 0x1f: MAC_W(Rm, Rn);				break;
2140 
2141 	case 0x20: SHAL(Rn);					break;
2142 	case 0x21: SHAR(Rn);					break;
2143 	case 0x22: STSMPR(Rn);					break;
2144 	case 0x23: STCMVBR(Rn); 				break;
2145 	case 0x24: ROTCL(Rn);					break;
2146 	case 0x25: ROTCR(Rn);					break;
2147 	case 0x26: LDSMPR(Rn);					break;
2148 	case 0x27: LDCMVBR(Rn); 				break;
2149 	case 0x28: SHLL16(Rn);					break;
2150 	case 0x29: SHLR16(Rn);					break;
2151 	case 0x2a: LDSPR(Rn);					break;
2152 	case 0x2b: JMP(Rn); 					break;
2153 	case 0x2c: NOP();						break;
2154 	case 0x2d: NOP();						break;
2155 	case 0x2e: LDCVBR(Rn);					break;
2156 	case 0x2f: MAC_W(Rm, Rn);				break;
2157 
2158 	case 0x30: NOP();						break;
2159 	case 0x31: NOP();						break;
2160 	case 0x32: NOP();						break;
2161 	case 0x33: NOP();						break;
2162 	case 0x34: NOP();						break;
2163 	case 0x35: NOP();						break;
2164 	case 0x36: NOP();						break;
2165 	case 0x37: NOP();						break;
2166 	case 0x38: NOP();						break;
2167 	case 0x39: NOP();						break;
2168 	case 0x3a: NOP();						break;
2169 	case 0x3b: NOP();						break;
2170 	case 0x3c: NOP();						break;
2171 	case 0x3d: NOP();						break;
2172 	case 0x3e: NOP();						break;
2173 	case 0x3f: MAC_W(Rm, Rn);				break;
2174 	}
2175 }
2176 
op0101(UINT16 opcode)2177 static INLINE void op0101(UINT16 opcode)
2178 {
2179 	MOVLL4(Rm, opcode & 0x0f, Rn);
2180 }
2181 
op0110(UINT16 opcode)2182 static INLINE void op0110(UINT16 opcode)
2183 {
2184 	switch (opcode & 15)
2185 	{
2186 	case  0: MOVBL(Rm, Rn); 				break;
2187 	case  1: MOVWL(Rm, Rn); 				break;
2188 	case  2: MOVLL(Rm, Rn); 				break;
2189 	case  3: MOV(Rm, Rn);					break;
2190 	case  4: MOVBP(Rm, Rn); 				break;
2191 	case  5: MOVWP(Rm, Rn); 				break;
2192 	case  6: MOVLP(Rm, Rn); 				break;
2193 	case  7: NOT(Rm, Rn);					break;
2194 	case  8: SWAPB(Rm, Rn); 				break;
2195 	case  9: SWAPW(Rm, Rn); 				break;
2196 	case 10: NEGC(Rm, Rn);					break;
2197 	case 11: NEG(Rm, Rn);					break;
2198 	case 12: EXTUB(Rm, Rn); 				break;
2199 	case 13: EXTUW(Rm, Rn); 				break;
2200 	case 14: EXTSB(Rm, Rn); 				break;
2201 	case 15: EXTSW(Rm, Rn); 				break;
2202 	}
2203 }
2204 
op0111(UINT16 opcode)2205 static INLINE void op0111(UINT16 opcode)
2206 {
2207 	ADDI(opcode & 0xff, Rn);
2208 }
2209 
op1000(UINT16 opcode)2210 static INLINE void op1000(UINT16 opcode)
2211 {
2212 	switch ((opcode >> 8) & 15)
2213 	{
2214 	case  0: MOVBS4(opcode & 0x0f, Rm); 	break;
2215 	case  1: MOVWS4(opcode & 0x0f, Rm); 	break;
2216 	case  2: NOP(); 						break;
2217 	case  3: NOP(); 						break;
2218 	case  4: MOVBL4(Rm, opcode & 0x0f); 	break;
2219 	case  5: MOVWL4(Rm, opcode & 0x0f); 	break;
2220 	case  6: NOP(); 						break;
2221 	case  7: NOP(); 						break;
2222 	case  8: CMPIM(opcode & 0xff);			break;
2223 	case  9: BT(opcode & 0xff); 			break;
2224 	case 10: NOP(); 						break;
2225 	case 11: BF(opcode & 0xff); 			break;
2226 	case 12: NOP(); 						break;
2227 	case 13: BTS(opcode & 0xff);			break;
2228 	case 14: NOP(); 						break;
2229 	case 15: BFS(opcode & 0xff);			break;
2230 	}
2231 }
2232 
2233 
op1001(UINT16 opcode)2234 static INLINE void op1001(UINT16 opcode)
2235 {
2236 	MOVWI(opcode & 0xff, Rn);
2237 }
2238 
op1010(UINT16 opcode)2239 static INLINE void op1010(UINT16 opcode)
2240 {
2241 	BRA(opcode & 0xfff);
2242 }
2243 
op1011(UINT16 opcode)2244 static INLINE void op1011(UINT16 opcode)
2245 {
2246 	BSR(opcode & 0xfff);
2247 }
2248 
op1100(UINT16 opcode)2249 static INLINE void op1100(UINT16 opcode)
2250 {
2251 	switch ((opcode >> 8) & 15)
2252 	{
2253 	case  0: MOVBSG(opcode & 0xff); 		break;
2254 	case  1: MOVWSG(opcode & 0xff); 		break;
2255 	case  2: MOVLSG(opcode & 0xff); 		break;
2256 	case  3: TRAPA(opcode & 0xff);			break;
2257 	case  4: MOVBLG(opcode & 0xff); 		break;
2258 	case  5: MOVWLG(opcode & 0xff); 		break;
2259 	case  6: MOVLLG(opcode & 0xff); 		break;
2260 	case  7: MOVA(opcode & 0xff);			break;
2261 	case  8: TSTI(opcode & 0xff);			break;
2262 	case  9: ANDI(opcode & 0xff);			break;
2263 	case 10: XORI(opcode & 0xff);			break;
2264 	case 11: ORI(opcode & 0xff);			break;
2265 	case 12: TSTM(opcode & 0xff);			break;
2266 	case 13: ANDM(opcode & 0xff);			break;
2267 	case 14: XORM(opcode & 0xff);			break;
2268 	case 15: ORM(opcode & 0xff);			break;
2269 	}
2270 }
2271 
op1101(UINT16 opcode)2272 static INLINE void op1101(UINT16 opcode)
2273 {
2274 	MOVLI(opcode & 0xff, Rn);
2275 }
2276 
op1110(UINT16 opcode)2277 static INLINE void op1110(UINT16 opcode)
2278 {
2279 	MOVI(opcode & 0xff, Rn);
2280 }
2281 
op1111(UINT16 opcode)2282 static INLINE void op1111(UINT16 opcode)
2283 {
2284 	NOP();
2285 }
2286 
2287 /*****************************************************************************
2288  *	MAME CPU INTERFACE
2289  *****************************************************************************/
2290 
sh2_reset(void * param)2291 void sh2_reset(void *param)
2292 {
2293 	void *tsave, *tsaved0, *tsaved1;
2294 	UINT32 *m;
2295 
2296 	struct sh2_config *conf = param;
2297 
2298 	m = sh2.m;
2299 	tsave = sh2.timer;
2300 	tsaved0 = sh2.dma_timer[0];
2301 	tsaved1 = sh2.dma_timer[1];
2302 	memset(&sh2, 0, sizeof(SH2));
2303 	sh2.timer = tsave;
2304 	sh2.dma_timer[0] = tsaved0;
2305 	sh2.dma_timer[1] = tsaved1;
2306 	sh2.m = m;
2307 	memset(sh2.m, 0, 0x200);
2308 
2309 	if(conf)
2310 		sh2.is_slave = conf->is_slave;
2311 	else
2312 		sh2.is_slave = 0;
2313 
2314 	sh2.cpu_number = cpu_getactivecpu();
2315 
2316 	sh2.pc = RL(0);
2317 	sh2.r[15] = RL(4);
2318 	sh2.sr = I;
2319 	change_pc32bedw(sh2.pc & AM);
2320 
2321 	sh2.internal_irq_level = -1;
2322 }
2323 
2324 /* Shut down CPU core */
sh2_exit(void)2325 void sh2_exit(void)
2326 {
2327 	if (sh2.m)
2328 		free(sh2.m);
2329 	sh2.m = NULL;
2330 }
2331 
2332 /* Execute cycles - returns number of cycles actually run */
sh2_execute(int cycles)2333 int sh2_execute(int cycles)
2334 {
2335 	sh2_icount = cycles;
2336 
2337 	if (sh2.cpu_off)
2338 		return 0;
2339 
2340 	do
2341 	{
2342 		UINT32 opcode;
2343 
2344 		if (sh2.delay)
2345 		{
2346 			opcode = RW(sh2.delay & AM);
2347 			change_pc32bedw(sh2.pc & AM);
2348 			sh2.pc -= 2;
2349 		}
2350 		else
2351 			opcode = RW(sh2.pc & AM);
2352 
2353 		CALL_MAME_DEBUG;
2354 
2355 		sh2.delay = 0;
2356 		sh2.pc += 2;
2357 		sh2.ppc = sh2.pc;
2358 
2359 		switch ((opcode >> 12) & 15)
2360 		{
2361 		case  0: op0000(opcode); break;
2362 		case  1: op0001(opcode); break;
2363 		case  2: op0010(opcode); break;
2364 		case  3: op0011(opcode); break;
2365 		case  4: op0100(opcode); break;
2366 		case  5: op0101(opcode); break;
2367 		case  6: op0110(opcode); break;
2368 		case  7: op0111(opcode); break;
2369 		case  8: op1000(opcode); break;
2370 		case  9: op1001(opcode); break;
2371 		case 10: op1010(opcode); break;
2372 		case 11: op1011(opcode); break;
2373 		case 12: op1100(opcode); break;
2374 		case 13: op1101(opcode); break;
2375 		case 14: op1110(opcode); break;
2376 		default: op1111(opcode); break;
2377 		}
2378 
2379 		if(sh2.test_irq && !sh2.delay)
2380 		{
2381 			CHECK_PENDING_IRQ("mame_sh2_execute");
2382 			sh2.test_irq = 0;
2383 		}
2384 		sh2_icount--;
2385 	} while( sh2_icount > 0 );
2386 
2387 	return cycles - sh2_icount;
2388 }
2389 
2390 /* Get registers, return context size */
sh2_get_context(void * dst)2391 unsigned sh2_get_context(void *dst)
2392 {
2393 	if( dst )
2394 		memcpy(dst, &sh2, sizeof(SH2));
2395 	return sizeof(SH2);
2396 }
2397 
2398 /* Set registers */
sh2_set_context(void * src)2399 void sh2_set_context(void *src)
2400 {
2401 	if( src )
2402 		memcpy(&sh2, src, sizeof(SH2));
2403 }
2404 
sh2_timer_resync(void)2405 static void sh2_timer_resync(void)
2406 {
2407 	int divider = div_tab[(sh2.m[5] >> 8) & 3];
2408 	UINT32 cur_time = cpunum_gettotalcycles(sh2.cpu_number);
2409 
2410 	if(divider)
2411 		sh2.frc += (cur_time - sh2.frc_base) >> divider;
2412 	sh2.frc_base = cur_time;
2413 }
2414 
sh2_timer_activate(void)2415 static void sh2_timer_activate(void)
2416 {
2417 	int max_delta = 0xfffff;
2418 	UINT16 frc;
2419 
2420 	timer_adjust(sh2.timer, TIME_NEVER, 0, 0);
2421 
2422 	frc = sh2.frc;
2423 	if(!(sh2.m[4] & OCFA)) {
2424 		UINT16 delta = sh2.ocra - frc;
2425 		if(delta < max_delta)
2426 			max_delta = delta;
2427 	}
2428 
2429 	if(!(sh2.m[4] & OCFB) && (sh2.ocra <= sh2.ocrb || !(sh2.m[4] & 0x010000))) {
2430 		UINT16 delta = sh2.ocrb - frc;
2431 		if(delta < max_delta)
2432 			max_delta = delta;
2433 	}
2434 
2435 	if(!(sh2.m[4] & OVF) && !(sh2.m[4] & 0x010000)) {
2436 		int delta = 0x10000 - frc;
2437 		if(delta < max_delta)
2438 			max_delta = delta;
2439 	}
2440 
2441 	if(max_delta != 0xfffff) {
2442 		int divider = div_tab[(sh2.m[5] >> 8) & 3];
2443 		if(divider) {
2444 			max_delta <<= divider;
2445 			sh2.frc_base = cpunum_gettotalcycles(sh2.cpu_number);
2446 			timer_adjust(sh2.timer, TIME_IN_CYCLES(max_delta, sh2.cpu_number), sh2.cpu_number, 0);
2447 		} else {
2448 			log_cb(RETRO_LOG_DEBUG, LOGPRE "SH2.%d: Timer event in %d cycles of external clock", sh2.cpu_number, max_delta);
2449 		}
2450 	}
2451 }
2452 
sh2_recalc_irq(void)2453 static void sh2_recalc_irq(void)
2454 {
2455 	int irq = 0, vector = -1;
2456 	int level;
2457 
2458 	/* Timer irqs*/
2459 	if((sh2.m[4]>>8) & sh2.m[4] & (ICF|OCFA|OCFB|OVF))
2460 	{
2461 		level = (sh2.m[0x18] >> 24) & 15;
2462 		if(level > irq)
2463 		{
2464 			int mask = (sh2.m[4]>>8) & sh2.m[4];
2465 			irq = level;
2466 			if(mask & ICF)
2467 				vector = (sh2.m[0x19] >> 8) & 0x7f;
2468 			else if(mask & (OCFA|OCFB))
2469 				vector = sh2.m[0x19] & 0x7f;
2470 			else
2471 				vector = (sh2.m[0x1a] >> 24) & 0x7f;
2472 		}
2473 	}
2474 
2475 	/* DMA irqs*/
2476 	if((sh2.m[0x63] & 6) == 6) {
2477 		level = (sh2.m[0x38] >> 8) & 15;
2478 		if(level > irq) {
2479 			irq = level;
2480 			vector = (sh2.m[0x68] >> 24) & 0x7f;
2481 		}
2482 	}
2483 
2484 	if((sh2.m[0x67] & 6) == 6) {
2485 		level = (sh2.m[0x38] >> 8) & 15;
2486 		if(level > irq) {
2487 			irq = level;
2488 			vector = (sh2.m[0x6a] >> 24) & 0x7f;
2489 		}
2490 	}
2491 
2492 	sh2.internal_irq_level = irq;
2493 	sh2.internal_irq_vector = vector;
2494 	sh2.test_irq = 1;
2495 }
2496 
sh2_timer_callback(int cpunum)2497 static void sh2_timer_callback(int cpunum)
2498 {
2499 	UINT16 frc;
2500 
2501 	cpuintrf_push_context(cpunum);
2502 	sh2_timer_resync();
2503 
2504 	frc = sh2.frc;
2505 
2506 	if(frc == sh2.ocrb)
2507 		sh2.m[4] |= OCFB;
2508 
2509 	if(frc == 0x0000)
2510 		sh2.m[4] |= OVF;
2511 
2512 	if(frc == sh2.ocra)
2513 	{
2514 		sh2.m[4] |= OCFA;
2515 
2516 		if(sh2.m[4] & 0x010000)
2517 			sh2.frc = 0;
2518 	}
2519 
2520 	sh2_recalc_irq();
2521 	sh2_timer_activate();
2522 
2523 	cpuintrf_pop_context();
2524 }
2525 
sh2_dmac_callback(int dma)2526 static void sh2_dmac_callback(int dma)
2527 {
2528 	int cpunum = dma >> 1;
2529 	dma &= 1;
2530 
2531 	cpuintrf_push_context(cpunum);
2532 	log_cb(RETRO_LOG_DEBUG, LOGPRE "SH2.%d: DMA %d complete\n", cpunum, dma);
2533 	sh2.m[0x63+4*dma] |= 2;
2534 	sh2.dma_timer_active[dma] = 0;
2535 	sh2_recalc_irq();
2536 	cpuintrf_pop_context();
2537 }
2538 
sh2_dmac_check(int dma)2539 static void sh2_dmac_check(int dma)
2540 {
2541 	if(sh2.m[0x63+4*dma] & sh2.m[0x6c] & 1)
2542 	{
2543 		if(!sh2.dma_timer_active[dma] && !(sh2.m[0x63+4*dma] & 2))
2544 		{
2545 			int incs, incd, size;
2546 			UINT32 src, dst, count;
2547 			incd = (sh2.m[0x63+4*dma] >> 14) & 3;
2548 			incs = (sh2.m[0x63+4*dma] >> 12) & 3;
2549 			size = (sh2.m[0x63+4*dma] >> 10) & 3;
2550 			if(incd == 3 || incs == 3)
2551 			{
2552 				log_cb(RETRO_LOG_DEBUG, LOGPRE "SH2: DMA: bad increment values (%d, %d, %d, %04x)\n", incd, incs, size, sh2.m[0x63+4*dma]);
2553 				return;
2554 			}
2555 			src   = sh2.m[0x60+4*dma];
2556 			dst   = sh2.m[0x61+4*dma];
2557 			count = sh2.m[0x62+4*dma];
2558 			if(!count)
2559 				count = 0x1000000;
2560 
2561 			log_cb(RETRO_LOG_DEBUG, LOGPRE "SH2: DMA %d start %x, %x, %x, %04x, %d, %d, %d\n", dma, src, dst, count, sh2.m[0x63+4*dma], incs, incd, size);
2562 
2563 			sh2.dma_timer_active[dma] = 1;
2564 			timer_adjust(sh2.dma_timer[dma], TIME_IN_CYCLES(2*count+1, sh2.cpu_number), (sh2.cpu_number<<1)|dma, 0);
2565 
2566 			src &= AM;
2567 			dst &= AM;
2568 
2569 			switch(size)
2570 			{
2571 			case 0:
2572 				for(;count > 0; count --)
2573 				{
2574 					if(incs == 2)
2575 						src --;
2576 					if(incd == 2)
2577 						dst --;
2578 					cpu_writemem32bedw(dst, cpu_readmem32bedw(src));
2579 					if(incs == 1)
2580 						src ++;
2581 					if(incd == 1)
2582 						dst ++;
2583 				}
2584 				break;
2585 			case 1:
2586 				src &= ~1;
2587 				dst &= ~1;
2588 				for(;count > 0; count --)
2589 				{
2590 					if(incs == 2)
2591 						src -= 2;
2592 					if(incd == 2)
2593 						dst -= 2;
2594 					cpu_writemem32bedw_word(dst, cpu_readmem32bedw_word(src));
2595 					if(incs == 1)
2596 						src += 2;
2597 					if(incd == 1)
2598 						dst += 2;
2599 				}
2600 				break;
2601 			case 2:
2602 				src &= ~3;
2603 				dst &= ~3;
2604 				for(;count > 0; count --)
2605 				{
2606 					if(incs == 2)
2607 						src -= 4;
2608 					if(incd == 2)
2609 						dst -= 4;
2610 					cpu_writemem32bedw_dword(dst, cpu_readmem32bedw_dword(src));
2611 					if(incs == 1)
2612 						src += 4;
2613 					if(incd == 1)
2614 						dst += 4;
2615 				}
2616 				break;
2617 			case 3:
2618 				src &= ~3;
2619 				dst &= ~3;
2620 				count &= ~3;
2621 				for(;count > 0; count -= 4)
2622 				{
2623 					if(incd == 2)
2624 						dst -= 16;
2625 					cpu_writemem32bedw_dword(dst, cpu_readmem32bedw_dword(src));
2626 					cpu_writemem32bedw_dword(dst+4, cpu_readmem32bedw_dword(src+4));
2627 					cpu_writemem32bedw_dword(dst+8, cpu_readmem32bedw_dword(src+8));
2628 					cpu_writemem32bedw_dword(dst+12, cpu_readmem32bedw_dword(src+12));
2629 					src += 16;
2630 					if(incd == 1)
2631 						dst += 16;
2632 				}
2633 				break;
2634 			}
2635 		}
2636 	}
2637 	else
2638 	{
2639 		if(sh2.dma_timer_active[dma])
2640 		{
2641 			log_cb(RETRO_LOG_DEBUG, LOGPRE "SH2: DMA %d cancelled in-flight", dma);
2642 			timer_adjust(sh2.dma_timer[dma], TIME_NEVER, 0, 0);
2643 			sh2.dma_timer_active[dma] = 0;
2644 		}
2645 	}
2646 }
2647 
WRITE32_HANDLER(sh2_internal_w)2648 WRITE32_HANDLER( sh2_internal_w )
2649 {
2650 	UINT32 old = sh2.m[offset];
2651 	COMBINE_DATA(sh2.m+offset);
2652 
2653 	/*	if(offset != 0x20)*/
2654 	/*		log_cb(RETRO_LOG_DEBUG, LOGPRE "sh2_internal_w:  Write %08x (%x), %08x @ %08x\n", 0xfffffe00+offset*4, offset, data, mem_mask);*/
2655 
2656 	switch( offset )
2657 	{
2658 		/* Timers*/
2659 	case 0x04: /* TIER, FTCSR, FRC*/
2660 		if((mem_mask & 0x00ffffff) != 0xffffff)
2661 			sh2_timer_resync();
2662 		log_cb(RETRO_LOG_DEBUG, LOGPRE "SH2.%d: TIER write %04x @ %04x\n", sh2.cpu_number, data >> 16, mem_mask>>16);
2663 		sh2.m[4] = (sh2.m[4] & ~(ICF|OCFA|OCFB|OVF)) | (old & sh2.m[4] & (ICF|OCFA|OCFB|OVF));
2664 		COMBINE_DATA(&sh2.frc);
2665 		if((mem_mask & 0x00ffffff) != 0xffffff)
2666 			sh2_timer_activate();
2667 		sh2_recalc_irq();
2668 		break;
2669 	case 0x05: /* OCRx, TCR, TOCR*/
2670 		log_cb(RETRO_LOG_DEBUG, LOGPRE "SH2.%d: TCR write %08x @ %08x\n", sh2.cpu_number, data, mem_mask);
2671 		sh2_timer_resync();
2672 		if(sh2.m[5] & 0x10)
2673 			sh2.ocrb = (sh2.ocrb & (mem_mask >> 16)) | ((data & ~mem_mask) >> 16);
2674 		else
2675 			sh2.ocra = (sh2.ocra & (mem_mask >> 16)) | ((data & ~mem_mask) >> 16);
2676 		sh2_timer_activate();
2677 		break;
2678 
2679 	case 0x06: /* ICR*/
2680 		break;
2681 
2682 		/* Interrupt vectors*/
2683 	case 0x18: /* IPRB, VCRA*/
2684 	case 0x19: /* VCRB, VCRC*/
2685 	case 0x1a: /* VCRD*/
2686 		sh2_recalc_irq();
2687 		break;
2688 
2689 		/* DMA*/
2690 	case 0x1c: /* DRCR0, DRCR1*/
2691 		break;
2692 
2693 		/* Watchdog*/
2694 	case 0x20: /* WTCNT, RSTCSR*/
2695 		break;
2696 
2697 		/* Standby and cache*/
2698 	case 0x24: /* SBYCR, CCR*/
2699 		break;
2700 
2701 		/* Interrupt vectors cont.*/
2702 	case 0x38: /* ICR, IRPA*/
2703 		break;
2704 	case 0x39: /* VCRWDT*/
2705 		break;
2706 
2707 		/* Division box*/
2708 	case 0x40: /* DVSR*/
2709 		break;
2710 	case 0x41: /* DVDNT*/
2711 		{
2712 			INT32 a = sh2.m[0x41];
2713 			INT32 b = sh2.m[0x40];
2714 			log_cb(RETRO_LOG_DEBUG, LOGPRE "SH2 #%d div+mod %d/%d\n", cpu_getactivecpu(), a, b);
2715 			if (b)
2716 			{
2717 				sh2.m[0x45] = a / b;
2718 				sh2.m[0x44] = a % b;
2719 			}
2720 			else
2721 			{
2722 				sh2.m[0x42] |= 0x00010000;
2723 				sh2.m[0x45] = 0x7fffffff;
2724 				sh2.m[0x44] = 0x7fffffff;
2725 				sh2_recalc_irq();
2726 			}
2727 			break;
2728 		}
2729 	case 0x42: /* DVCR*/
2730 		sh2.m[0x42] = (sh2.m[0x42] & ~0x00001000) | (old & sh2.m[0x42] & 0x00010000);
2731 		sh2_recalc_irq();
2732 		break;
2733 	case 0x43: /* VCRDIV*/
2734 		sh2_recalc_irq();
2735 		break;
2736 	case 0x44: /* DVDNTH*/
2737 		break;
2738 	case 0x45: /* DVDNTL*/
2739 		{
2740 			INT64 a = sh2.m[0x45] | ((UINT64)(sh2.m[0x44]) << 32);
2741 			INT64 b = sh2.m[0x40];
2742 			log_cb(RETRO_LOG_DEBUG, LOGPRE "SH2 #%d div+mod %lld/%lld\n", cpu_getactivecpu(), a, b);
2743 			if (b)
2744 			{
2745 				INT64 q = a / b;
2746 				if (q != (INT32)q)
2747 				{
2748 					sh2.m[0x42] |= 0x00010000;
2749 					sh2.m[0x45] = 0x7fffffff;
2750 					sh2.m[0x44] = 0x7fffffff;
2751 					sh2_recalc_irq();
2752 				}
2753 				else
2754 				{
2755 					sh2.m[0x45] = q;
2756 					sh2.m[0x44] = a % b;
2757 				}
2758 			}
2759 			else
2760 			{
2761 				sh2.m[0x42] |= 0x00010000;
2762 				sh2.m[0x45] = 0x7fffffff;
2763 				sh2.m[0x44] = 0x7fffffff;
2764 				sh2_recalc_irq();
2765 			}
2766 			break;
2767 		}
2768 
2769 		/* DMA controller*/
2770 	case 0x60: /* SAR0*/
2771 	case 0x61: /* DAR0*/
2772 		break;
2773 	case 0x62: /* DTCR0*/
2774 		sh2.m[0x62] &= 0xffffff;
2775 		break;
2776 	case 0x63: /* CHCR0*/
2777 		sh2.m[0x63] = (sh2.m[0x63] & ~2) | (old & sh2.m[0x63] & 2);
2778 		sh2_dmac_check(0);
2779 		break;
2780 	case 0x64: /* SAR1*/
2781 	case 0x65: /* DAR1*/
2782 		break;
2783 	case 0x66: /* DTCR1*/
2784 		sh2.m[0x66] &= 0xffffff;
2785 		break;
2786 	case 0x67: /* CHCR1*/
2787 		sh2.m[0x67] = (sh2.m[0x67] & ~2) | (old & sh2.m[0x67] & 2);
2788 		sh2_dmac_check(1);
2789 		break;
2790 	case 0x68: /* VCRDMA0*/
2791 	case 0x6a: /* VCRDMA1*/
2792 		sh2_recalc_irq();
2793 		break;
2794 	case 0x6c: /* DMAOR*/
2795 		sh2.m[0x6c] = (sh2.m[0x6c] & ~6) | (old & sh2.m[0x6c] & 6);
2796 		sh2_dmac_check(0);
2797 		sh2_dmac_check(1);
2798 		break;
2799 
2800 		/* Bus controller*/
2801 	case 0x78: /* BCR1*/
2802 	case 0x79: /* BCR2*/
2803 	case 0x7a: /* WCR*/
2804 	case 0x7b: /* MCR*/
2805 	case 0x7c: /* RTCSR*/
2806 	case 0x7d: /* RTCNT*/
2807 	case 0x7e: /* RTCOR*/
2808 		break;
2809 
2810 	default:
2811 		log_cb(RETRO_LOG_DEBUG, LOGPRE "sh2_internal_w:  Unmapped write %08x, %08x @ %08x\n", 0xfffffe00+offset*4, data, mem_mask);
2812 		break;
2813 	}
2814 }
2815 
READ32_HANDLER(sh2_internal_r)2816 READ32_HANDLER( sh2_internal_r )
2817 {
2818 	/*	log_cb(RETRO_LOG_DEBUG, LOGPRE "sh2_internal_r:  Read %08x (%x) @ %08x\n", 0xfffffe00+offset*4, offset, mem_mask);*/
2819 	switch( offset )
2820 	{
2821 	case 0x04: /* TIER, FTCSR, FRC*/
2822 		sh2_timer_resync();
2823 		return (sh2.m[4] & 0xffff0000) | sh2.frc;
2824 	case 0x05: /* OCRx, TCR, TOCR*/
2825 		if(sh2.m[5] & 0x10)
2826 			return (sh2.ocrb << 16) | (sh2.m[5] & 0xffff);
2827 		else
2828 			return (sh2.ocra << 16) | (sh2.m[5] & 0xffff);
2829 	case 0x06: /* ICR*/
2830 		return sh2.icr << 16;
2831 
2832 	case 0x38: /* ICR, IPRA*/
2833 		return (sh2.m[0x38] & 0x7fffffff) | (sh2.nmi_line_state == ASSERT_LINE ? 0 : 0x80000000);
2834 
2835 	case 0x78: /* BCR1*/
2836 		return sh2.is_slave ? 0x00008000 : 0;
2837 
2838 	case 0x41: /* dvdntl mirrors*/
2839 	case 0x47:
2840 		return sh2.m[0x45];
2841 
2842 	case 0x46: /* dvdnth mirror*/
2843 		return sh2.m[0x44];
2844 	}
2845 	return sh2.m[offset];
2846 }
2847 
sh2_set_frt_input(int cpunum,int state)2848 void sh2_set_frt_input(int cpunum, int state)
2849 {
2850 	if(state == PULSE_LINE)
2851 	{
2852 		sh2_set_frt_input(cpunum, ASSERT_LINE);
2853 		sh2_set_frt_input(cpunum, CLEAR_LINE);
2854 		return;
2855 	}
2856 
2857 	cpuintrf_push_context(cpunum);
2858 
2859 	if(sh2.frt_input == state) {
2860 		cpuintrf_pop_context();
2861 		return;
2862 	}
2863 
2864 	sh2.frt_input = state;
2865 
2866 	if(sh2.m[5] & 0x8000) {
2867 		if(state == CLEAR_LINE) {
2868 			cpuintrf_pop_context();
2869 			return;
2870 		}
2871 	} else {
2872 		if(state == ASSERT_LINE) {
2873 			cpuintrf_pop_context();
2874 			return;
2875 		}
2876 	}
2877 
2878 	sh2_timer_resync();
2879 	sh2.icr = sh2.frc;
2880 	sh2.m[4] |= ICF;
2881 	log_cb(RETRO_LOG_DEBUG, LOGPRE "SH2.%d: ICF activated (%x)\n", sh2.cpu_number, sh2.pc & AM);
2882 	sh2_recalc_irq();
2883 	cpuintrf_pop_context();
2884 }
2885 
sh2_get_reg(int regnum)2886 unsigned sh2_get_reg(int regnum)
2887 {
2888 	switch( regnum )
2889 	{
2890 	case REG_PREVIOUSPC:
2891 		return sh2.ppc;
2892 	case REG_PC:
2893 	case SH2_PC:
2894 		if (sh2.delay)
2895 			return sh2.delay & AM;
2896 		return sh2.pc & AM;
2897 	case REG_SP:   return sh2.r[15];
2898 	case SH2_PR:   return sh2.pr;
2899 	case SH2_SR:   return sh2.sr;
2900 	case SH2_GBR:  return sh2.gbr;
2901 	case SH2_VBR:  return sh2.vbr;
2902 	case SH2_MACH: return sh2.mach;
2903 	case SH2_MACL: return sh2.macl;
2904 	case SH2_R0:   return sh2.r[ 0];
2905 	case SH2_R1:   return sh2.r[ 1];
2906 	case SH2_R2:   return sh2.r[ 2];
2907 	case SH2_R3:   return sh2.r[ 3];
2908 	case SH2_R4:   return sh2.r[ 4];
2909 	case SH2_R5:   return sh2.r[ 5];
2910 	case SH2_R6:   return sh2.r[ 6];
2911 	case SH2_R7:   return sh2.r[ 7];
2912 	case SH2_R8:   return sh2.r[ 8];
2913 	case SH2_R9:   return sh2.r[ 9];
2914 	case SH2_R10:  return sh2.r[10];
2915 	case SH2_R11:  return sh2.r[11];
2916 	case SH2_R12:  return sh2.r[12];
2917 	case SH2_R13:  return sh2.r[13];
2918 	case SH2_R14:  return sh2.r[14];
2919 	case SH2_R15:  return sh2.r[15];
2920 	case SH2_EA:   return sh2.ea;
2921 	}
2922 	return 0;
2923 }
2924 
sh2_set_reg(int regnum,unsigned val)2925 void sh2_set_reg (int regnum, unsigned val)
2926 {
2927 	switch( regnum )
2928 	{
2929 	case SH2_PC:
2930 	case REG_PC:
2931 		sh2.pc = val;
2932 		sh2.delay = 0;
2933 		break;
2934 	case REG_SP:   sh2.r[15] = val;    break;
2935 	case SH2_PR:   sh2.pr = val;	   break;
2936 	case SH2_SR:
2937 		sh2.sr = val;
2938 		CHECK_PENDING_IRQ("sh2_set_reg");
2939 		break;
2940 	case SH2_GBR:  sh2.gbr = val;	   break;
2941 	case SH2_VBR:  sh2.vbr = val;	   break;
2942 	case SH2_MACH: sh2.mach = val;	   break;
2943 	case SH2_MACL: sh2.macl = val;	   break;
2944 	case SH2_R0:   sh2.r[ 0] = val;    break;
2945 	case SH2_R1:   sh2.r[ 1] = val;    break;
2946 	case SH2_R2:   sh2.r[ 2] = val;    break;
2947 	case SH2_R3:   sh2.r[ 3] = val;    break;
2948 	case SH2_R4:   sh2.r[ 4] = val;    break;
2949 	case SH2_R5:   sh2.r[ 5] = val;    break;
2950 	case SH2_R6:   sh2.r[ 6] = val;    break;
2951 	case SH2_R7:   sh2.r[ 7] = val;    break;
2952 	case SH2_R8:   sh2.r[ 8] = val;    break;
2953 	case SH2_R9:   sh2.r[ 9] = val;    break;
2954 	case SH2_R10:  sh2.r[10] = val;    break;
2955 	case SH2_R11:  sh2.r[11] = val;    break;
2956 	case SH2_R12:  sh2.r[12] = val;    break;
2957 	case SH2_R13:  sh2.r[13] = val;    break;
2958 	case SH2_R14:  sh2.r[14] = val;    break;
2959 	case SH2_R15:  sh2.r[15] = val;    break;
2960 	case SH2_EA:   sh2.ea = val;	   break;
2961 	}
2962 }
2963 
sh2_set_irq_line(int irqline,int state)2964 void sh2_set_irq_line(int irqline, int state)
2965 {
2966 	if (irqline == IRQ_LINE_NMI)
2967     {
2968 		if (sh2.nmi_line_state == state)
2969 			return;
2970 		sh2.nmi_line_state = state;
2971 
2972 		if( state == CLEAR_LINE )
2973 			log_cb(RETRO_LOG_DEBUG, LOGPRE "SH-2 #%d cleared nmi\n", cpu_getactivecpu());
2974 		else
2975         {
2976 			log_cb(RETRO_LOG_DEBUG, LOGPRE "SH-2 #%d assert nmi\n", cpu_getactivecpu());
2977 			sh2_exception("sh2_set_irq_line/nmi", 16);
2978         }
2979 	}
2980 	else
2981 	{
2982 		if (sh2.irq_line_state[irqline] == state)
2983 			return;
2984 		sh2.irq_line_state[irqline] = state;
2985 
2986 		if( state == CLEAR_LINE )
2987 		{
2988 			log_cb(RETRO_LOG_DEBUG, LOGPRE "SH-2 #%d cleared irq #%d\n", cpu_getactivecpu(), irqline);
2989 			sh2.pending_irq &= ~(1 << irqline);
2990 		}
2991 		else
2992 		{
2993 			log_cb(RETRO_LOG_DEBUG, LOGPRE "SH-2 #%d assert irq #%d\n", cpu_getactivecpu(), irqline);
2994 			sh2.pending_irq |= 1 << irqline;
2995 			if(sh2.delay)
2996 				sh2.test_irq = 1;
2997 			else
2998 				CHECK_PENDING_IRQ("sh2_set_irq_line");
2999 		}
3000 	}
3001 }
3002 
sh2_set_irq_callback(int (* callback)(int irqline))3003 void sh2_set_irq_callback(int (*callback)(int irqline))
3004 {
3005 	sh2.irq_callback = callback;
3006 }
3007 
sh2_info(void * context,int regnum)3008 const char *sh2_info(void *context, int regnum)
3009 {
3010 	static char buffer[8][15+1];
3011 	static int which = 0;
3012 	SH2 *r = context;
3013 
3014 	which = (which + 1) % 8;
3015 	buffer[which][0] = '\0';
3016 	if( !context )
3017 		r = &sh2;
3018 
3019 	switch( regnum )
3020 	{
3021 	case CPU_INFO_REG+SH2_PC:  sprintf(buffer[which], "PC  :%08X", r->pc); break;
3022 	case CPU_INFO_REG+SH2_SR:  sprintf(buffer[which], "SR  :%08X", r->sr); break;
3023 	case CPU_INFO_REG+SH2_PR:  sprintf(buffer[which], "PR  :%08X", r->pr); break;
3024 	case CPU_INFO_REG+SH2_GBR: sprintf(buffer[which], "GBR :%08X", r->gbr); break;
3025 	case CPU_INFO_REG+SH2_VBR: sprintf(buffer[which], "VBR :%08X", r->vbr); break;
3026 	case CPU_INFO_REG+SH2_MACH:sprintf(buffer[which], "MACH:%08X", r->mach); break;
3027 	case CPU_INFO_REG+SH2_MACL:sprintf(buffer[which], "MACL:%08X", r->macl); break;
3028 	case CPU_INFO_REG+SH2_R0:  sprintf(buffer[which], "R0  :%08X", r->r[ 0]); break;
3029 	case CPU_INFO_REG+SH2_R1:  sprintf(buffer[which], "R1  :%08X", r->r[ 1]); break;
3030 	case CPU_INFO_REG+SH2_R2:  sprintf(buffer[which], "R2  :%08X", r->r[ 2]); break;
3031 	case CPU_INFO_REG+SH2_R3:  sprintf(buffer[which], "R3  :%08X", r->r[ 3]); break;
3032 	case CPU_INFO_REG+SH2_R4:  sprintf(buffer[which], "R4  :%08X", r->r[ 4]); break;
3033 	case CPU_INFO_REG+SH2_R5:  sprintf(buffer[which], "R5  :%08X", r->r[ 5]); break;
3034 	case CPU_INFO_REG+SH2_R6:  sprintf(buffer[which], "R6  :%08X", r->r[ 6]); break;
3035 	case CPU_INFO_REG+SH2_R7:  sprintf(buffer[which], "R7  :%08X", r->r[ 7]); break;
3036 	case CPU_INFO_REG+SH2_R8:  sprintf(buffer[which], "R8  :%08X", r->r[ 8]); break;
3037 	case CPU_INFO_REG+SH2_R9:  sprintf(buffer[which], "R9  :%08X", r->r[ 9]); break;
3038 	case CPU_INFO_REG+SH2_R10: sprintf(buffer[which], "R10 :%08X", r->r[10]); break;
3039 	case CPU_INFO_REG+SH2_R11: sprintf(buffer[which], "R11 :%08X", r->r[11]); break;
3040 	case CPU_INFO_REG+SH2_R12: sprintf(buffer[which], "R12 :%08X", r->r[12]); break;
3041 	case CPU_INFO_REG+SH2_R13: sprintf(buffer[which], "R13 :%08X", r->r[13]); break;
3042 	case CPU_INFO_REG+SH2_R14: sprintf(buffer[which], "R14 :%08X", r->r[14]); break;
3043 	case CPU_INFO_REG+SH2_R15: sprintf(buffer[which], "R15 :%08X", r->r[15]); break;
3044 	case CPU_INFO_REG+SH2_EA:  sprintf(buffer[which], "EA  :%08X", r->ea);    break;
3045 	case CPU_INFO_FLAGS:
3046 		sprintf(buffer[which], "%c%c%d%c%c",
3047 				r->sr & M ? 'M':'.',
3048 				r->sr & Q ? 'Q':'.',
3049 				(r->sr & I) >> 4,
3050 				r->sr & S ? 'S':'.',
3051 				r->sr & T ? 'T':'.');
3052 		break;
3053 	case CPU_INFO_NAME: return "SH-2";
3054 	case CPU_INFO_FAMILY: return "Hitachi SH7600";
3055 	case CPU_INFO_VERSION: return "1.01";
3056 	case CPU_INFO_FILE: return __FILE__;
3057 	case CPU_INFO_CREDITS: return "Copyright (c) 2000 Juergen Buchmueller, all rights reserved.";
3058 	case CPU_INFO_REG_LAYOUT: return (const char*)sh2_reg_layout;
3059 	case CPU_INFO_WIN_LAYOUT: return (const char*)sh2_win_layout;
3060 	}
3061 	return buffer[which];
3062 }
3063 
sh2_dasm(char * buffer,unsigned pc)3064 unsigned sh2_dasm(char *buffer, unsigned pc)
3065 {
3066 #ifdef MAME_DEBUG
3067 	return DasmSH2( buffer, pc );
3068 #else
3069 	sprintf( buffer, "$%02X", cpu_readop(pc) );
3070 	return 1;
3071 #endif
3072 }
3073 
sh2_init(void)3074 void sh2_init(void)
3075 {
3076 	int cpu = cpu_getactivecpu();
3077 
3078 	sh2.timer = timer_alloc(sh2_timer_callback);
3079 	timer_adjust(sh2.timer, TIME_NEVER, 0, 0);
3080 
3081 	sh2.dma_timer[0] = timer_alloc(sh2_dmac_callback);
3082 	timer_adjust(sh2.dma_timer[0], TIME_NEVER, 0, 0);
3083 
3084 	sh2.dma_timer[1] = timer_alloc(sh2_dmac_callback);
3085 	timer_adjust(sh2.dma_timer[1], TIME_NEVER, 0, 0);
3086 
3087 	sh2.m = malloc(0x200);
3088 	if (!sh2.m)
3089 	{
3090 		log_cb(RETRO_LOG_DEBUG, LOGPRE "SH2 failed to malloc FREGS\n");
3091 		/*raise( SIGABRT );*/
3092 	}
3093 
3094 	state_save_register_UINT32("sh2", cpu, "PC",  &sh2.pc, 1);
3095 	state_save_register_UINT32("sh2", cpu, "SP",  &sh2.r[15], 1);
3096 	state_save_register_UINT32("sh2", cpu, "SR",  &sh2.sr, 1);
3097 	state_save_register_UINT32("sh2", cpu, "PR",  &sh2.pr, 1);
3098 	state_save_register_UINT32("sh2", cpu, "GBR", &sh2.gbr, 1);
3099 	state_save_register_UINT32("sh2", cpu, "VBR", &sh2.vbr, 1);
3100 	state_save_register_UINT32("sh2", cpu, "MACH",&sh2.mach, 1);
3101 	state_save_register_UINT32("sh2", cpu, "MACL",&sh2.macl, 1);
3102 	state_save_register_UINT32("sh2", cpu, "R0",  &sh2.r[ 0], 1);
3103 	state_save_register_UINT32("sh2", cpu, "R1",  &sh2.r[ 1], 1);
3104 	state_save_register_UINT32("sh2", cpu, "R2",  &sh2.r[ 2], 1);
3105 	state_save_register_UINT32("sh2", cpu, "R3",  &sh2.r[ 3], 1);
3106 	state_save_register_UINT32("sh2", cpu, "R4",  &sh2.r[ 4], 1);
3107 	state_save_register_UINT32("sh2", cpu, "R5",  &sh2.r[ 5], 1);
3108 	state_save_register_UINT32("sh2", cpu, "R6",  &sh2.r[ 6], 1);
3109 	state_save_register_UINT32("sh2", cpu, "R7",  &sh2.r[ 7], 1);
3110 	state_save_register_UINT32("sh2", cpu, "R8",  &sh2.r[ 8], 1);
3111 	state_save_register_UINT32("sh2", cpu, "R9",  &sh2.r[ 9], 1);
3112 	state_save_register_UINT32("sh2", cpu, "R10", &sh2.r[10], 1);
3113 	state_save_register_UINT32("sh2", cpu, "R11", &sh2.r[11], 1);
3114 	state_save_register_UINT32("sh2", cpu, "R12", &sh2.r[12], 1);
3115 	state_save_register_UINT32("sh2", cpu, "R13", &sh2.r[13], 1);
3116 	state_save_register_UINT32("sh2", cpu, "R14", &sh2.r[14], 1);
3117 	state_save_register_UINT32("sh2", cpu, "EA", &sh2.ea, 1);
3118 	return;
3119 }
3120