sh2: timing fixes
[picodrive.git] / cpu / sh2 / mame / sh2.c
... / ...
CommitLineData
1/*****************************************************************************\r
2 *\r
3 * sh2.c\r
4 * Portable Hitachi SH-2 (SH7600 family) emulator\r
5 *\r
6 * Copyright Juergen Buchmueller <pullmoll@t-online.de>,\r
7 * all rights reserved.\r
8 *\r
9 * - This source code is released as freeware for non-commercial purposes.\r
10 * - You are free to use and redistribute this code in modified or\r
11 * unmodified form, provided you list me in the credits.\r
12 * - If you modify this source code, you must add a notice to each modified\r
13 * source file that it has been changed. If you're a nice person, you\r
14 * will clearly mark each change too. :)\r
15 * - If you wish to use this for commercial purposes, please contact me at\r
16 * pullmoll@t-online.de\r
17 * - The author of this copywritten work reserves the right to change the\r
18 * terms of its usage and license at any time, including retroactively\r
19 * - This entire notice must remain in the source code.\r
20 *\r
21 * This work is based on <tiraniddo@hotmail.com> C/C++ implementation of\r
22 * the SH-2 CPU core and was adapted to the MAME CPU core requirements.\r
23 * Thanks also go to Chuck Mason <chukjr@sundail.net> and Olivier Galibert\r
24 * <galibert@pobox.com> for letting me peek into their SEMU code :-)\r
25 *\r
26 *****************************************************************************/\r
27\r
28/*****************************************************************************\r
29 Changes\r
30 20130129 Angelo Salese\r
31 - added illegal opcode exception handling, side effect of some Saturn games\r
32 on loading like Feda or Falcom Classics Vol. 1\r
33 (i.e. Master CPU Incautiously transfers memory from CD to work RAM H, and\r
34 wipes out Slave CPU program code too while at it).\r
35\r
36 20051129 Mariusz Wojcieszek\r
37 - introduced memory_decrypted_read_word() for opcode fetching\r
38\r
39 20050813 Mariusz Wojcieszek\r
40 - fixed 64 bit / 32 bit division in division unit\r
41\r
42 20031015 O. Galibert\r
43 - dma fixes, thanks to sthief\r
44\r
45 20031013 O. Galibert, A. Giles\r
46 - timer fixes\r
47 - multi-cpu simplifications\r
48\r
49 20030915 O. Galibert\r
50 - fix DMA1 irq vector\r
51 - ignore writes to DRCRx\r
52 - fix cpu number issues\r
53 - fix slave/master recognition\r
54 - fix wrong-cpu-in-context problem with the timers\r
55\r
56 20021020 O. Galibert\r
57 - DMA implementation, lightly tested\r
58 - delay slot in debugger fixed\r
59 - add divide box mirrors\r
60 - Nicola-ify the indentation\r
61 - Uncrapify sh2_internal_*\r
62 - Put back nmi support that had been lost somehow\r
63\r
64 20020914 R. Belmont\r
65 - Initial SH2 internal timers implementation, based on code by O. Galibert.\r
66 Makes music work in galspanic4/s/s2, panic street, cyvern, other SKNS games.\r
67 - Fix to external division, thanks to "spice" on the E2J board.\r
68 Corrects behavior of s1945ii turret boss.\r
69\r
70 20020302 Olivier Galibert (galibert@mame.net)\r
71 - Fixed interrupt in delay slot\r
72 - Fixed rotcr\r
73 - Fixed div1\r
74 - Fixed mulu\r
75 - Fixed negc\r
76\r
77 20020301 R. Belmont\r
78 - Fixed external division\r
79\r
80 20020225 Olivier Galibert (galibert@mame.net)\r
81 - Fixed interrupt handling\r
82\r
83 20010207 Sylvain Glaize (mokona@puupuu.org)\r
84\r
85 - Bug fix in INLINE void MOVBM(UINT32 m, UINT32 n) (see comment)\r
86 - Support of full 32 bit addressing (RB, RW, RL and WB, WW, WL functions)\r
87 reason : when the two high bits of the address are set, access is\r
88 done directly in the cache data array. The SUPER KANEKO NOVA SYSTEM\r
89 sets the stack pointer here, using these addresses as usual RAM access.\r
90\r
91 No real cache support has been added.\r
92 - Read/Write memory format correction (_bew to _bedw) (see also SH2\r
93 definition in cpuintrf.c and DasmSH2(..) in sh2dasm.c )\r
94\r
95 20010623 James Forshaw (TyRaNiD@totalise.net)\r
96\r
97 - Modified operation of sh2_exception. Done cause mame irq system is stupid, and\r
98 doesnt really seem designed for any more than 8 interrupt lines.\r
99\r
100 20010701 James Forshaw (TyRaNiD@totalise.net)\r
101\r
102 - Fixed DIV1 operation. Q bit now correctly generated\r
103\r
104 20020218 Added save states (mokona@puupuu.org)\r
105\r
106 *****************************************************************************/\r
107\r
108//#include "debugger.h"\r
109//#include "sh2.h"\r
110//#include "sh2comn.h"\r
111#define INLINE static\r
112\r
113//CPU_DISASSEMBLE( sh2 );\r
114\r
115#ifndef USE_SH2DRC\r
116\r
117/* speed up delay loops, bail out of tight loops */\r
118#define BUSY_LOOP_HACKS 1\r
119\r
120#define VERBOSE 0\r
121\r
122#define LOG(x) do { if (VERBOSE) logerror x; } while (0)\r
123\r
124#if 0\r
125INLINE UINT8 RB(sh2_state *sh2, offs_t A)\r
126{\r
127 if (A >= 0xe0000000)\r
128 return sh2_internal_r(*sh2->internal, (A & 0x1fc)>>2, 0xff << (((~A) & 3)*8)) >> (((~A) & 3)*8);\r
129\r
130 if (A >= 0xc0000000)\r
131 return sh2->program->read_byte(A);\r
132\r
133 if (A >= 0x40000000)\r
134 return 0xa5;\r
135\r
136 return sh2->program->read_byte(A & AM);\r
137}\r
138\r
139INLINE UINT16 RW(sh2_state *sh2, offs_t A)\r
140{\r
141 if (A >= 0xe0000000)\r
142 return sh2_internal_r(*sh2->internal, (A & 0x1fc)>>2, 0xffff << (((~A) & 2)*8)) >> (((~A) & 2)*8);\r
143\r
144 if (A >= 0xc0000000)\r
145 return sh2->program->read_word(A);\r
146\r
147 if (A >= 0x40000000)\r
148 return 0xa5a5;\r
149\r
150 return sh2->program->read_word(A & AM);\r
151}\r
152\r
153INLINE UINT32 RL(sh2_state *sh2, offs_t A)\r
154{\r
155 if (A >= 0xe0000000)\r
156 return sh2_internal_r(*sh2->internal, (A & 0x1fc)>>2, 0xffffffff);\r
157\r
158 if (A >= 0xc0000000)\r
159 return sh2->program->read_dword(A);\r
160\r
161 if (A >= 0x40000000)\r
162 return 0xa5a5a5a5;\r
163\r
164 return sh2->program->read_dword(A & AM);\r
165}\r
166\r
167INLINE void WB(sh2_state *sh2, offs_t A, UINT8 V)\r
168{\r
169 if (A >= 0xe0000000)\r
170 {\r
171 sh2_internal_w(*sh2->internal, (A & 0x1fc)>>2, V << (((~A) & 3)*8), 0xff << (((~A) & 3)*8));\r
172 return;\r
173 }\r
174\r
175 if (A >= 0xc0000000)\r
176 {\r
177 sh2->program->write_byte(A,V);\r
178 return;\r
179 }\r
180\r
181 if (A >= 0x40000000)\r
182 return;\r
183\r
184 sh2->program->write_byte(A & AM,V);\r
185}\r
186\r
187INLINE void WW(sh2_state *sh2, offs_t A, UINT16 V)\r
188{\r
189 if (A >= 0xe0000000)\r
190 {\r
191 sh2_internal_w(*sh2->internal, (A & 0x1fc)>>2, V << (((~A) & 2)*8), 0xffff << (((~A) & 2)*8));\r
192 return;\r
193 }\r
194\r
195 if (A >= 0xc0000000)\r
196 {\r
197 sh2->program->write_word(A,V);\r
198 return;\r
199 }\r
200\r
201 if (A >= 0x40000000)\r
202 return;\r
203\r
204 sh2->program->write_word(A & AM,V);\r
205}\r
206\r
207INLINE void WL(sh2_state *sh2, offs_t A, UINT32 V)\r
208{\r
209 if (A >= 0xe0000000)\r
210 {\r
211 sh2_internal_w(*sh2->internal, (A & 0x1fc)>>2, V, 0xffffffff);\r
212 return;\r
213 }\r
214\r
215 if (A >= 0xc0000000)\r
216 {\r
217 sh2->program->write_dword(A,V);\r
218 return;\r
219 }\r
220\r
221 if (A >= 0x40000000)\r
222 return;\r
223\r
224 sh2->program->write_dword(A & AM,V);\r
225}\r
226#endif\r
227\r
228/* code cycles t-bit\r
229 * 0011 nnnn mmmm 1100 1 -\r
230 * ADD Rm,Rn\r
231 */\r
232INLINE void ADD(sh2_state *sh2, UINT32 m, UINT32 n)\r
233{\r
234 sh2->r[n] += sh2->r[m];\r
235}\r
236\r
237/* code cycles t-bit\r
238 * 0111 nnnn iiii iiii 1 -\r
239 * ADD #imm,Rn\r
240 */\r
241INLINE void ADDI(sh2_state *sh2, UINT32 i, UINT32 n)\r
242{\r
243 sh2->r[n] += (INT32)(INT16)(INT8)i;\r
244}\r
245\r
246/* code cycles t-bit\r
247 * 0011 nnnn mmmm 1110 1 carry\r
248 * ADDC Rm,Rn\r
249 */\r
250INLINE void ADDC(sh2_state *sh2, UINT32 m, UINT32 n)\r
251{\r
252 UINT32 tmp0, tmp1;\r
253\r
254 tmp1 = sh2->r[n] + sh2->r[m];\r
255 tmp0 = sh2->r[n];\r
256 sh2->r[n] = tmp1 + (sh2->sr & T);\r
257 if (tmp0 > tmp1)\r
258 sh2->sr |= T;\r
259 else\r
260 sh2->sr &= ~T;\r
261 if (tmp1 > sh2->r[n])\r
262 sh2->sr |= T;\r
263}\r
264\r
265/* code cycles t-bit\r
266 * 0011 nnnn mmmm 1111 1 overflow\r
267 * ADDV Rm,Rn\r
268 */\r
269INLINE void ADDV(sh2_state *sh2, UINT32 m, UINT32 n)\r
270{\r
271 INT32 dest, src, ans;\r
272\r
273 if ((INT32) sh2->r[n] >= 0)\r
274 dest = 0;\r
275 else\r
276 dest = 1;\r
277 if ((INT32) sh2->r[m] >= 0)\r
278 src = 0;\r
279 else\r
280 src = 1;\r
281 src += dest;\r
282 sh2->r[n] += sh2->r[m];\r
283 if ((INT32) sh2->r[n] >= 0)\r
284 ans = 0;\r
285 else\r
286 ans = 1;\r
287 ans += dest;\r
288 if (src == 0 || src == 2)\r
289 {\r
290 if (ans == 1)\r
291 sh2->sr |= T;\r
292 else\r
293 sh2->sr &= ~T;\r
294 }\r
295 else\r
296 sh2->sr &= ~T;\r
297}\r
298\r
299/* code cycles t-bit\r
300 * 0010 nnnn mmmm 1001 1 -\r
301 * AND Rm,Rn\r
302 */\r
303INLINE void AND(sh2_state *sh2, UINT32 m, UINT32 n)\r
304{\r
305 sh2->r[n] &= sh2->r[m];\r
306}\r
307\r
308\r
309/* code cycles t-bit\r
310 * 1100 1001 iiii iiii 1 -\r
311 * AND #imm,R0\r
312 */\r
313INLINE void ANDI(sh2_state *sh2, UINT32 i)\r
314{\r
315 sh2->r[0] &= i;\r
316}\r
317\r
318/* code cycles t-bit\r
319 * 1100 1101 iiii iiii 1 -\r
320 * AND.B #imm,@(R0,GBR)\r
321 */\r
322INLINE void ANDM(sh2_state *sh2, UINT32 i)\r
323{\r
324 UINT32 temp;\r
325\r
326 sh2->ea = sh2->gbr + sh2->r[0];\r
327 temp = i & RB( sh2, sh2->ea );\r
328 WB( sh2, sh2->ea, temp );\r
329 sh2->icount -= 2;\r
330}\r
331\r
332/* code cycles t-bit\r
333 * 1000 1011 dddd dddd 3/1 -\r
334 * BF disp8\r
335 */\r
336INLINE void BF(sh2_state *sh2, UINT32 d)\r
337{\r
338 if ((sh2->sr & T) == 0)\r
339 {\r
340 INT32 disp = ((INT32)d << 24) >> 24;\r
341 sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;\r
342 sh2->icount -= 2;\r
343 }\r
344}\r
345\r
346/* code cycles t-bit\r
347 * 1000 1111 dddd dddd 3/1 -\r
348 * BFS disp8\r
349 */\r
350INLINE void BFS(sh2_state *sh2, UINT32 d)\r
351{\r
352 if ((sh2->sr & T) == 0)\r
353 {\r
354 INT32 disp = ((INT32)d << 24) >> 24;\r
355 sh2->delay = sh2->pc;\r
356 sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;\r
357 sh2->icount--;\r
358 }\r
359}\r
360\r
361/* code cycles t-bit\r
362 * 1010 dddd dddd dddd 2 -\r
363 * BRA disp12\r
364 */\r
365INLINE void BRA(sh2_state *sh2, UINT32 d)\r
366{\r
367 INT32 disp = ((INT32)d << 20) >> 20;\r
368\r
369#if BUSY_LOOP_HACKS\r
370 if (disp == -2)\r
371 {\r
372 UINT32 next_opcode = RW( sh2, sh2->ppc & AM );\r
373 /* BRA $\r
374 * NOP\r
375 */\r
376 if (next_opcode == 0x0009)\r
377 sh2->icount %= 3; /* cycles for BRA $ and NOP taken (3) */\r
378 }\r
379#endif\r
380 sh2->delay = sh2->pc;\r
381 sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;\r
382 sh2->icount--;\r
383}\r
384\r
385/* code cycles t-bit\r
386 * 0000 mmmm 0010 0011 2 -\r
387 * BRAF Rm\r
388 */\r
389INLINE void BRAF(sh2_state *sh2, UINT32 m)\r
390{\r
391 sh2->delay = sh2->pc;\r
392 sh2->pc += sh2->r[m] + 2;\r
393 sh2->icount--;\r
394}\r
395\r
396/* code cycles t-bit\r
397 * 1011 dddd dddd dddd 2 -\r
398 * BSR disp12\r
399 */\r
400INLINE void BSR(sh2_state *sh2, UINT32 d)\r
401{\r
402 INT32 disp = ((INT32)d << 20) >> 20;\r
403\r
404 sh2->pr = sh2->pc + 2;\r
405 sh2->delay = sh2->pc;\r
406 sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;\r
407 sh2->icount--;\r
408}\r
409\r
410/* code cycles t-bit\r
411 * 0000 mmmm 0000 0011 2 -\r
412 * BSRF Rm\r
413 */\r
414INLINE void BSRF(sh2_state *sh2, UINT32 m)\r
415{\r
416 sh2->pr = sh2->pc + 2;\r
417 sh2->delay = sh2->pc;\r
418 sh2->pc += sh2->r[m] + 2;\r
419 sh2->icount--;\r
420}\r
421\r
422/* code cycles t-bit\r
423 * 1000 1001 dddd dddd 3/1 -\r
424 * BT disp8\r
425 */\r
426INLINE void BT(sh2_state *sh2, UINT32 d)\r
427{\r
428 if ((sh2->sr & T) != 0)\r
429 {\r
430 INT32 disp = ((INT32)d << 24) >> 24;\r
431 sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;\r
432 sh2->icount -= 2;\r
433 }\r
434}\r
435\r
436/* code cycles t-bit\r
437 * 1000 1101 dddd dddd 2/1 -\r
438 * BTS disp8\r
439 */\r
440INLINE void BTS(sh2_state *sh2, UINT32 d)\r
441{\r
442 if ((sh2->sr & T) != 0)\r
443 {\r
444 INT32 disp = ((INT32)d << 24) >> 24;\r
445 sh2->delay = sh2->pc;\r
446 sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;\r
447 sh2->icount--;\r
448 }\r
449}\r
450\r
451/* code cycles t-bit\r
452 * 0000 0000 0010 1000 1 -\r
453 * CLRMAC\r
454 */\r
455INLINE void CLRMAC(sh2_state *sh2)\r
456{\r
457 sh2->mach = 0;\r
458 sh2->macl = 0;\r
459}\r
460\r
461/* code cycles t-bit\r
462 * 0000 0000 0000 1000 1 -\r
463 * CLRT\r
464 */\r
465INLINE void CLRT(sh2_state *sh2)\r
466{\r
467 sh2->sr &= ~T;\r
468}\r
469\r
470/* code cycles t-bit\r
471 * 0011 nnnn mmmm 0000 1 comparison result\r
472 * CMP_EQ Rm,Rn\r
473 */\r
474INLINE void CMPEQ(sh2_state *sh2, UINT32 m, UINT32 n)\r
475{\r
476 if (sh2->r[n] == sh2->r[m])\r
477 sh2->sr |= T;\r
478 else\r
479 sh2->sr &= ~T;\r
480}\r
481\r
482/* code cycles t-bit\r
483 * 0011 nnnn mmmm 0011 1 comparison result\r
484 * CMP_GE Rm,Rn\r
485 */\r
486INLINE void CMPGE(sh2_state *sh2, UINT32 m, UINT32 n)\r
487{\r
488 if ((INT32) sh2->r[n] >= (INT32) sh2->r[m])\r
489 sh2->sr |= T;\r
490 else\r
491 sh2->sr &= ~T;\r
492}\r
493\r
494/* code cycles t-bit\r
495 * 0011 nnnn mmmm 0111 1 comparison result\r
496 * CMP_GT Rm,Rn\r
497 */\r
498INLINE void CMPGT(sh2_state *sh2, UINT32 m, UINT32 n)\r
499{\r
500 if ((INT32) sh2->r[n] > (INT32) sh2->r[m])\r
501 sh2->sr |= T;\r
502 else\r
503 sh2->sr &= ~T;\r
504}\r
505\r
506/* code cycles t-bit\r
507 * 0011 nnnn mmmm 0110 1 comparison result\r
508 * CMP_HI Rm,Rn\r
509 */\r
510INLINE void CMPHI(sh2_state *sh2, UINT32 m, UINT32 n)\r
511{\r
512 if ((UINT32) sh2->r[n] > (UINT32) sh2->r[m])\r
513 sh2->sr |= T;\r
514 else\r
515 sh2->sr &= ~T;\r
516}\r
517\r
518/* code cycles t-bit\r
519 * 0011 nnnn mmmm 0010 1 comparison result\r
520 * CMP_HS Rm,Rn\r
521 */\r
522INLINE void CMPHS(sh2_state *sh2, UINT32 m, UINT32 n)\r
523{\r
524 if ((UINT32) sh2->r[n] >= (UINT32) sh2->r[m])\r
525 sh2->sr |= T;\r
526 else\r
527 sh2->sr &= ~T;\r
528}\r
529\r
530\r
531/* code cycles t-bit\r
532 * 0100 nnnn 0001 0101 1 comparison result\r
533 * CMP_PL Rn\r
534 */\r
535INLINE void CMPPL(sh2_state *sh2, UINT32 n)\r
536{\r
537 if ((INT32) sh2->r[n] > 0)\r
538 sh2->sr |= T;\r
539 else\r
540 sh2->sr &= ~T;\r
541}\r
542\r
543/* code cycles t-bit\r
544 * 0100 nnnn 0001 0001 1 comparison result\r
545 * CMP_PZ Rn\r
546 */\r
547INLINE void CMPPZ(sh2_state *sh2, UINT32 n)\r
548{\r
549 if ((INT32) sh2->r[n] >= 0)\r
550 sh2->sr |= T;\r
551 else\r
552 sh2->sr &= ~T;\r
553}\r
554\r
555/* code cycles t-bit\r
556 * 0010 nnnn mmmm 1100 1 comparison result\r
557 * CMP_STR Rm,Rn\r
558 */\r
559INLINE void CMPSTR(sh2_state *sh2, UINT32 m, UINT32 n)\r
560 {\r
561 UINT32 temp;\r
562 INT32 HH, HL, LH, LL;\r
563 temp = sh2->r[n] ^ sh2->r[m];\r
564 HH = (temp >> 24) & 0xff;\r
565 HL = (temp >> 16) & 0xff;\r
566 LH = (temp >> 8) & 0xff;\r
567 LL = temp & 0xff;\r
568 if (HH && HL && LH && LL)\r
569 sh2->sr &= ~T;\r
570 else\r
571 sh2->sr |= T;\r
572 }\r
573\r
574\r
575/* code cycles t-bit\r
576 * 1000 1000 iiii iiii 1 comparison result\r
577 * CMP/EQ #imm,R0\r
578 */\r
579INLINE void CMPIM(sh2_state *sh2, UINT32 i)\r
580{\r
581 UINT32 imm = (UINT32)(INT32)(INT16)(INT8)i;\r
582\r
583 if (sh2->r[0] == imm)\r
584 sh2->sr |= T;\r
585 else\r
586 sh2->sr &= ~T;\r
587}\r
588\r
589/* code cycles t-bit\r
590 * 0010 nnnn mmmm 0111 1 calculation result\r
591 * DIV0S Rm,Rn\r
592 */\r
593INLINE void DIV0S(sh2_state *sh2, UINT32 m, UINT32 n)\r
594{\r
595 if ((sh2->r[n] & 0x80000000) == 0)\r
596 sh2->sr &= ~Q;\r
597 else\r
598 sh2->sr |= Q;\r
599 if ((sh2->r[m] & 0x80000000) == 0)\r
600 sh2->sr &= ~M;\r
601 else\r
602 sh2->sr |= M;\r
603 if ((sh2->r[m] ^ sh2->r[n]) & 0x80000000)\r
604 sh2->sr |= T;\r
605 else\r
606 sh2->sr &= ~T;\r
607}\r
608\r
609/* code cycles t-bit\r
610 * 0000 0000 0001 1001 1 0\r
611 * DIV0U\r
612 */\r
613INLINE void DIV0U(sh2_state *sh2)\r
614{\r
615 sh2->sr &= ~(M | Q | T);\r
616}\r
617\r
618/* code cycles t-bit\r
619 * 0011 nnnn mmmm 0100 1 calculation result\r
620 * DIV1 Rm,Rn\r
621 */\r
622INLINE void DIV1(sh2_state *sh2, UINT32 m, UINT32 n)\r
623{\r
624 UINT32 tmp0;\r
625 UINT32 old_q;\r
626\r
627 old_q = sh2->sr & Q;\r
628 if (0x80000000 & sh2->r[n])\r
629 sh2->sr |= Q;\r
630 else\r
631 sh2->sr &= ~Q;\r
632\r
633 sh2->r[n] = (sh2->r[n] << 1) | (sh2->sr & T);\r
634\r
635 if (!old_q)\r
636 {\r
637 if (!(sh2->sr & M))\r
638 {\r
639 tmp0 = sh2->r[n];\r
640 sh2->r[n] -= sh2->r[m];\r
641 if(!(sh2->sr & Q))\r
642 if(sh2->r[n] > tmp0)\r
643 sh2->sr |= Q;\r
644 else\r
645 sh2->sr &= ~Q;\r
646 else\r
647 if(sh2->r[n] > tmp0)\r
648 sh2->sr &= ~Q;\r
649 else\r
650 sh2->sr |= Q;\r
651 }\r
652 else\r
653 {\r
654 tmp0 = sh2->r[n];\r
655 sh2->r[n] += sh2->r[m];\r
656 if(!(sh2->sr & Q))\r
657 {\r
658 if(sh2->r[n] < tmp0)\r
659 sh2->sr &= ~Q;\r
660 else\r
661 sh2->sr |= Q;\r
662 }\r
663 else\r
664 {\r
665 if(sh2->r[n] < tmp0)\r
666 sh2->sr |= Q;\r
667 else\r
668 sh2->sr &= ~Q;\r
669 }\r
670 }\r
671 }\r
672 else\r
673 {\r
674 if (!(sh2->sr & M))\r
675 {\r
676 tmp0 = sh2->r[n];\r
677 sh2->r[n] += sh2->r[m];\r
678 if(!(sh2->sr & Q))\r
679 if(sh2->r[n] < tmp0)\r
680 sh2->sr |= Q;\r
681 else\r
682 sh2->sr &= ~Q;\r
683 else\r
684 if(sh2->r[n] < tmp0)\r
685 sh2->sr &= ~Q;\r
686 else\r
687 sh2->sr |= Q;\r
688 }\r
689 else\r
690 {\r
691 tmp0 = sh2->r[n];\r
692 sh2->r[n] -= sh2->r[m];\r
693 if(!(sh2->sr & Q))\r
694 if(sh2->r[n] > tmp0)\r
695 sh2->sr &= ~Q;\r
696 else\r
697 sh2->sr |= Q;\r
698 else\r
699 if(sh2->r[n] > tmp0)\r
700 sh2->sr |= Q;\r
701 else\r
702 sh2->sr &= ~Q;\r
703 }\r
704 }\r
705\r
706 tmp0 = (sh2->sr & (Q | M));\r
707 if((!tmp0) || (tmp0 == 0x300)) /* if Q == M set T else clear T */\r
708 sh2->sr |= T;\r
709 else\r
710 sh2->sr &= ~T;\r
711}\r
712\r
713/* DMULS.L Rm,Rn */\r
714INLINE void DMULS(sh2_state *sh2, UINT32 m, UINT32 n)\r
715{\r
716 UINT32 RnL, RnH, RmL, RmH, Res0, Res1, Res2;\r
717 UINT32 temp0, temp1, temp2, temp3;\r
718 INT32 tempm, tempn, fnLmL;\r
719\r
720 tempn = (INT32) sh2->r[n];\r
721 tempm = (INT32) sh2->r[m];\r
722 if (tempn < 0)\r
723 tempn = 0 - tempn;\r
724 if (tempm < 0)\r
725 tempm = 0 - tempm;\r
726 if ((INT32) (sh2->r[n] ^ sh2->r[m]) < 0)\r
727 fnLmL = -1;\r
728 else\r
729 fnLmL = 0;\r
730 temp1 = (UINT32) tempn;\r
731 temp2 = (UINT32) tempm;\r
732 RnL = temp1 & 0x0000ffff;\r
733 RnH = (temp1 >> 16) & 0x0000ffff;\r
734 RmL = temp2 & 0x0000ffff;\r
735 RmH = (temp2 >> 16) & 0x0000ffff;\r
736 temp0 = RmL * RnL;\r
737 temp1 = RmH * RnL;\r
738 temp2 = RmL * RnH;\r
739 temp3 = RmH * RnH;\r
740 Res2 = 0;\r
741 Res1 = temp1 + temp2;\r
742 if (Res1 < temp1)\r
743 Res2 += 0x00010000;\r
744 temp1 = (Res1 << 16) & 0xffff0000;\r
745 Res0 = temp0 + temp1;\r
746 if (Res0 < temp0)\r
747 Res2++;\r
748 Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;\r
749 if (fnLmL < 0)\r
750 {\r
751 Res2 = ~Res2;\r
752 if (Res0 == 0)\r
753 Res2++;\r
754 else\r
755 Res0 = (~Res0) + 1;\r
756 }\r
757 sh2->mach = Res2;\r
758 sh2->macl = Res0;\r
759 sh2->icount--;\r
760}\r
761\r
762/* DMULU.L Rm,Rn */\r
763INLINE void DMULU(sh2_state *sh2, UINT32 m, UINT32 n)\r
764{\r
765 UINT32 RnL, RnH, RmL, RmH, Res0, Res1, Res2;\r
766 UINT32 temp0, temp1, temp2, temp3;\r
767\r
768 RnL = sh2->r[n] & 0x0000ffff;\r
769 RnH = (sh2->r[n] >> 16) & 0x0000ffff;\r
770 RmL = sh2->r[m] & 0x0000ffff;\r
771 RmH = (sh2->r[m] >> 16) & 0x0000ffff;\r
772 temp0 = RmL * RnL;\r
773 temp1 = RmH * RnL;\r
774 temp2 = RmL * RnH;\r
775 temp3 = RmH * RnH;\r
776 Res2 = 0;\r
777 Res1 = temp1 + temp2;\r
778 if (Res1 < temp1)\r
779 Res2 += 0x00010000;\r
780 temp1 = (Res1 << 16) & 0xffff0000;\r
781 Res0 = temp0 + temp1;\r
782 if (Res0 < temp0)\r
783 Res2++;\r
784 Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;\r
785 sh2->mach = Res2;\r
786 sh2->macl = Res0;\r
787 sh2->icount--;\r
788}\r
789\r
790/* DT Rn */\r
791INLINE void DT(sh2_state *sh2, UINT32 n)\r
792{\r
793 sh2->r[n]--;\r
794 if (sh2->r[n] == 0)\r
795 sh2->sr |= T;\r
796 else\r
797 sh2->sr &= ~T;\r
798#if BUSY_LOOP_HACKS\r
799 {\r
800 UINT32 next_opcode = RW( sh2, sh2->ppc & AM );\r
801 /* DT Rn\r
802 * BF $-2\r
803 */\r
804 if (next_opcode == 0x8bfd)\r
805 {\r
806 while (sh2->r[n] > 1 && sh2->icount > 4)\r
807 {\r
808 sh2->r[n]--;\r
809 sh2->icount -= 4; /* cycles for DT (1) and BF taken (3) */\r
810 }\r
811 }\r
812 }\r
813#endif\r
814}\r
815\r
816/* EXTS.B Rm,Rn */\r
817INLINE void EXTSB(sh2_state *sh2, UINT32 m, UINT32 n)\r
818{\r
819 sh2->r[n] = ((INT32)sh2->r[m] << 24) >> 24;\r
820}\r
821\r
822/* EXTS.W Rm,Rn */\r
823INLINE void EXTSW(sh2_state *sh2, UINT32 m, UINT32 n)\r
824{\r
825 sh2->r[n] = ((INT32)sh2->r[m] << 16) >> 16;\r
826}\r
827\r
828/* EXTU.B Rm,Rn */\r
829INLINE void EXTUB(sh2_state *sh2, UINT32 m, UINT32 n)\r
830{\r
831 sh2->r[n] = sh2->r[m] & 0x000000ff;\r
832}\r
833\r
834/* EXTU.W Rm,Rn */\r
835INLINE void EXTUW(sh2_state *sh2, UINT32 m, UINT32 n)\r
836{\r
837 sh2->r[n] = sh2->r[m] & 0x0000ffff;\r
838}\r
839\r
840/* ILLEGAL */\r
841INLINE void ILLEGAL(sh2_state *sh2)\r
842{\r
843 logerror("SH2: Illegal opcode at %08x\n", sh2->pc - 2);\r
844 sh2->r[15] -= 4;\r
845 WL( sh2, sh2->r[15], sh2->sr ); /* push SR onto stack */\r
846 sh2->r[15] -= 4;\r
847 WL( sh2, sh2->r[15], sh2->pc - 2 ); /* push PC onto stack */\r
848\r
849 /* fetch PC */\r
850 sh2->pc = RL( sh2, sh2->vbr + 4 * 4 );\r
851\r
852 /* TODO: timing is a guess */\r
853 sh2->icount -= 5;\r
854}\r
855\r
856\r
857/* JMP @Rm */\r
858INLINE void JMP(sh2_state *sh2, UINT32 m)\r
859{\r
860 sh2->delay = sh2->pc;\r
861 sh2->pc = sh2->ea = sh2->r[m];\r
862 sh2->icount--;\r
863}\r
864\r
865/* JSR @Rm */\r
866INLINE void JSR(sh2_state *sh2, UINT32 m)\r
867{\r
868 sh2->delay = sh2->pc;\r
869 sh2->pr = sh2->pc + 2;\r
870 sh2->pc = sh2->ea = sh2->r[m];\r
871 sh2->icount--;\r
872}\r
873\r
874\r
875/* LDC Rm,SR */\r
876INLINE void LDCSR(sh2_state *sh2, UINT32 m)\r
877{\r
878 sh2->sr = sh2->r[m] & FLAGS;\r
879 sh2->test_irq = 1;\r
880}\r
881\r
882/* LDC Rm,GBR */\r
883INLINE void LDCGBR(sh2_state *sh2, UINT32 m)\r
884{\r
885 sh2->gbr = sh2->r[m];\r
886}\r
887\r
888/* LDC Rm,VBR */\r
889INLINE void LDCVBR(sh2_state *sh2, UINT32 m)\r
890{\r
891 sh2->vbr = sh2->r[m];\r
892}\r
893\r
894/* LDC.L @Rm+,SR */\r
895INLINE void LDCMSR(sh2_state *sh2, UINT32 m)\r
896{\r
897 sh2->ea = sh2->r[m];\r
898 sh2->sr = RL( sh2, sh2->ea ) & FLAGS;\r
899 sh2->r[m] += 4;\r
900 sh2->icount -= 2;\r
901 sh2->test_irq = 1;\r
902}\r
903\r
904/* LDC.L @Rm+,GBR */\r
905INLINE void LDCMGBR(sh2_state *sh2, UINT32 m)\r
906{\r
907 sh2->ea = sh2->r[m];\r
908 sh2->gbr = RL( sh2, sh2->ea );\r
909 sh2->r[m] += 4;\r
910 sh2->icount -= 2;\r
911}\r
912\r
913/* LDC.L @Rm+,VBR */\r
914INLINE void LDCMVBR(sh2_state *sh2, UINT32 m)\r
915{\r
916 sh2->ea = sh2->r[m];\r
917 sh2->vbr = RL( sh2, sh2->ea );\r
918 sh2->r[m] += 4;\r
919 sh2->icount -= 2;\r
920}\r
921\r
922/* LDS Rm,MACH */\r
923INLINE void LDSMACH(sh2_state *sh2, UINT32 m)\r
924{\r
925 sh2->mach = sh2->r[m];\r
926}\r
927\r
928/* LDS Rm,MACL */\r
929INLINE void LDSMACL(sh2_state *sh2, UINT32 m)\r
930{\r
931 sh2->macl = sh2->r[m];\r
932}\r
933\r
934/* LDS Rm,PR */\r
935INLINE void LDSPR(sh2_state *sh2, UINT32 m)\r
936{\r
937 sh2->pr = sh2->r[m];\r
938}\r
939\r
940/* LDS.L @Rm+,MACH */\r
941INLINE void LDSMMACH(sh2_state *sh2, UINT32 m)\r
942{\r
943 sh2->ea = sh2->r[m];\r
944 sh2->mach = RL( sh2, sh2->ea );\r
945 sh2->r[m] += 4;\r
946}\r
947\r
948/* LDS.L @Rm+,MACL */\r
949INLINE void LDSMMACL(sh2_state *sh2, UINT32 m)\r
950{\r
951 sh2->ea = sh2->r[m];\r
952 sh2->macl = RL( sh2, sh2->ea );\r
953 sh2->r[m] += 4;\r
954}\r
955\r
956/* LDS.L @Rm+,PR */\r
957INLINE void LDSMPR(sh2_state *sh2, UINT32 m)\r
958{\r
959 sh2->ea = sh2->r[m];\r
960 sh2->pr = RL( sh2, sh2->ea );\r
961 sh2->r[m] += 4;\r
962}\r
963\r
964/* MAC.L @Rm+,@Rn+ */\r
965INLINE void MAC_L(sh2_state *sh2, UINT32 m, UINT32 n)\r
966{\r
967 UINT32 RnL, RnH, RmL, RmH, Res0, Res1, Res2;\r
968 UINT32 temp0, temp1, temp2, temp3;\r
969 INT32 tempm, tempn, fnLmL;\r
970\r
971 tempn = (INT32) RL( sh2, sh2->r[n] );\r
972 sh2->r[n] += 4;\r
973 tempm = (INT32) RL( sh2, sh2->r[m] );\r
974 sh2->r[m] += 4;\r
975 if ((INT32) (tempn ^ tempm) < 0)\r
976 fnLmL = -1;\r
977 else\r
978 fnLmL = 0;\r
979 if (tempn < 0)\r
980 tempn = 0 - tempn;\r
981 if (tempm < 0)\r
982 tempm = 0 - tempm;\r
983 temp1 = (UINT32) tempn;\r
984 temp2 = (UINT32) tempm;\r
985 RnL = temp1 & 0x0000ffff;\r
986 RnH = (temp1 >> 16) & 0x0000ffff;\r
987 RmL = temp2 & 0x0000ffff;\r
988 RmH = (temp2 >> 16) & 0x0000ffff;\r
989 temp0 = RmL * RnL;\r
990 temp1 = RmH * RnL;\r
991 temp2 = RmL * RnH;\r
992 temp3 = RmH * RnH;\r
993 Res2 = 0;\r
994 Res1 = temp1 + temp2;\r
995 if (Res1 < temp1)\r
996 Res2 += 0x00010000;\r
997 temp1 = (Res1 << 16) & 0xffff0000;\r
998 Res0 = temp0 + temp1;\r
999 if (Res0 < temp0)\r
1000 Res2++;\r
1001 Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;\r
1002 if (fnLmL < 0)\r
1003 {\r
1004 Res2 = ~Res2;\r
1005 if (Res0 == 0)\r
1006 Res2++;\r
1007 else\r
1008 Res0 = (~Res0) + 1;\r
1009 }\r
1010 if (sh2->sr & S)\r
1011 {\r
1012 Res0 = sh2->macl + Res0;\r
1013 if (sh2->macl > Res0)\r
1014 Res2++;\r
1015 Res2 += (sh2->mach & 0x0000ffff);\r
1016 if (((INT32) Res2 < 0) && (Res2 < 0xffff8000))\r
1017 {\r
1018 Res2 = 0x00008000;\r
1019 Res0 = 0x00000000;\r
1020 }\r
1021 else if (((INT32) Res2 > 0) && (Res2 > 0x00007fff))\r
1022 {\r
1023 Res2 = 0x00007fff;\r
1024 Res0 = 0xffffffff;\r
1025 }\r
1026 sh2->mach = Res2;\r
1027 sh2->macl = Res0;\r
1028 }\r
1029 else\r
1030 {\r
1031 Res0 = sh2->macl + Res0;\r
1032 if (sh2->macl > Res0)\r
1033 Res2++;\r
1034 Res2 += sh2->mach;\r
1035 sh2->mach = Res2;\r
1036 sh2->macl = Res0;\r
1037 }\r
1038 sh2->icount -= 2;\r
1039}\r
1040\r
1041/* MAC.W @Rm+,@Rn+ */\r
1042INLINE void MAC_W(sh2_state *sh2, UINT32 m, UINT32 n)\r
1043{\r
1044 INT32 tempm, tempn, dest, src, ans;\r
1045 UINT32 templ;\r
1046\r
1047 tempn = (INT32) RW( sh2, sh2->r[n] );\r
1048 sh2->r[n] += 2;\r
1049 tempm = (INT32) RW( sh2, sh2->r[m] );\r
1050 sh2->r[m] += 2;\r
1051 templ = sh2->macl;\r
1052 tempm = ((INT32) (short) tempn * (INT32) (short) tempm);\r
1053 if ((INT32) sh2->macl >= 0)\r
1054 dest = 0;\r
1055 else\r
1056 dest = 1;\r
1057 if ((INT32) tempm >= 0)\r
1058 {\r
1059 src = 0;\r
1060 tempn = 0;\r
1061 }\r
1062 else\r
1063 {\r
1064 src = 1;\r
1065 tempn = 0xffffffff;\r
1066 }\r
1067 src += dest;\r
1068 sh2->macl += tempm;\r
1069 if ((INT32) sh2->macl >= 0)\r
1070 ans = 0;\r
1071 else\r
1072 ans = 1;\r
1073 ans += dest;\r
1074 if (sh2->sr & S)\r
1075 {\r
1076 if (ans == 1)\r
1077 {\r
1078 if (src == 0)\r
1079 sh2->macl = 0x7fffffff;\r
1080 if (src == 2)\r
1081 sh2->macl = 0x80000000;\r
1082 }\r
1083 }\r
1084 else\r
1085 {\r
1086 sh2->mach += tempn;\r
1087 if (templ > sh2->macl)\r
1088 sh2->mach += 1;\r
1089 }\r
1090 sh2->icount -= 2;\r
1091}\r
1092\r
1093/* MOV Rm,Rn */\r
1094INLINE void MOV(sh2_state *sh2, UINT32 m, UINT32 n)\r
1095{\r
1096 sh2->r[n] = sh2->r[m];\r
1097}\r
1098\r
1099/* MOV.B Rm,@Rn */\r
1100INLINE void MOVBS(sh2_state *sh2, UINT32 m, UINT32 n)\r
1101{\r
1102 sh2->ea = sh2->r[n];\r
1103 WB( sh2, sh2->ea, sh2->r[m] & 0x000000ff);\r
1104}\r
1105\r
1106/* MOV.W Rm,@Rn */\r
1107INLINE void MOVWS(sh2_state *sh2, UINT32 m, UINT32 n)\r
1108{\r
1109 sh2->ea = sh2->r[n];\r
1110 WW( sh2, sh2->ea, sh2->r[m] & 0x0000ffff);\r
1111}\r
1112\r
1113/* MOV.L Rm,@Rn */\r
1114INLINE void MOVLS(sh2_state *sh2, UINT32 m, UINT32 n)\r
1115{\r
1116 sh2->ea = sh2->r[n];\r
1117 WL( sh2, sh2->ea, sh2->r[m] );\r
1118}\r
1119\r
1120/* MOV.B @Rm,Rn */\r
1121INLINE void MOVBL(sh2_state *sh2, UINT32 m, UINT32 n)\r
1122{\r
1123 sh2->ea = sh2->r[m];\r
1124 sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->ea );\r
1125}\r
1126\r
1127/* MOV.W @Rm,Rn */\r
1128INLINE void MOVWL(sh2_state *sh2, UINT32 m, UINT32 n)\r
1129{\r
1130 sh2->ea = sh2->r[m];\r
1131 sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2, sh2->ea );\r
1132}\r
1133\r
1134/* MOV.L @Rm,Rn */\r
1135INLINE void MOVLL(sh2_state *sh2, UINT32 m, UINT32 n)\r
1136{\r
1137 sh2->ea = sh2->r[m];\r
1138 sh2->r[n] = RL( sh2, sh2->ea );\r
1139}\r
1140\r
1141/* MOV.B Rm,@-Rn */\r
1142INLINE void MOVBM(sh2_state *sh2, UINT32 m, UINT32 n)\r
1143{\r
1144 /* SMG : bug fix, was reading sh2->r[n] */\r
1145 UINT32 data = sh2->r[m] & 0x000000ff;\r
1146\r
1147 sh2->r[n] -= 1;\r
1148 WB( sh2, sh2->r[n], data );\r
1149}\r
1150\r
1151/* MOV.W Rm,@-Rn */\r
1152INLINE void MOVWM(sh2_state *sh2, UINT32 m, UINT32 n)\r
1153{\r
1154 UINT32 data = sh2->r[m] & 0x0000ffff;\r
1155\r
1156 sh2->r[n] -= 2;\r
1157 WW( sh2, sh2->r[n], data );\r
1158}\r
1159\r
1160/* MOV.L Rm,@-Rn */\r
1161INLINE void MOVLM(sh2_state *sh2, UINT32 m, UINT32 n)\r
1162{\r
1163 UINT32 data = sh2->r[m];\r
1164\r
1165 sh2->r[n] -= 4;\r
1166 WL( sh2, sh2->r[n], data );\r
1167}\r
1168\r
1169/* MOV.B @Rm+,Rn */\r
1170INLINE void MOVBP(sh2_state *sh2, UINT32 m, UINT32 n)\r
1171{\r
1172 sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->r[m] );\r
1173 if (n != m)\r
1174 sh2->r[m] += 1;\r
1175}\r
1176\r
1177/* MOV.W @Rm+,Rn */\r
1178INLINE void MOVWP(sh2_state *sh2, UINT32 m, UINT32 n)\r
1179{\r
1180 sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2, sh2->r[m] );\r
1181 if (n != m)\r
1182 sh2->r[m] += 2;\r
1183}\r
1184\r
1185/* MOV.L @Rm+,Rn */\r
1186INLINE void MOVLP(sh2_state *sh2, UINT32 m, UINT32 n)\r
1187{\r
1188 sh2->r[n] = RL( sh2, sh2->r[m] );\r
1189 if (n != m)\r
1190 sh2->r[m] += 4;\r
1191}\r
1192\r
1193/* MOV.B Rm,@(R0,Rn) */\r
1194INLINE void MOVBS0(sh2_state *sh2, UINT32 m, UINT32 n)\r
1195{\r
1196 sh2->ea = sh2->r[n] + sh2->r[0];\r
1197 WB( sh2, sh2->ea, sh2->r[m] & 0x000000ff );\r
1198}\r
1199\r
1200/* MOV.W Rm,@(R0,Rn) */\r
1201INLINE void MOVWS0(sh2_state *sh2, UINT32 m, UINT32 n)\r
1202{\r
1203 sh2->ea = sh2->r[n] + sh2->r[0];\r
1204 WW( sh2, sh2->ea, sh2->r[m] & 0x0000ffff );\r
1205}\r
1206\r
1207/* MOV.L Rm,@(R0,Rn) */\r
1208INLINE void MOVLS0(sh2_state *sh2, UINT32 m, UINT32 n)\r
1209{\r
1210 sh2->ea = sh2->r[n] + sh2->r[0];\r
1211 WL( sh2, sh2->ea, sh2->r[m] );\r
1212}\r
1213\r
1214/* MOV.B @(R0,Rm),Rn */\r
1215INLINE void MOVBL0(sh2_state *sh2, UINT32 m, UINT32 n)\r
1216{\r
1217 sh2->ea = sh2->r[m] + sh2->r[0];\r
1218 sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->ea );\r
1219}\r
1220\r
1221/* MOV.W @(R0,Rm),Rn */\r
1222INLINE void MOVWL0(sh2_state *sh2, UINT32 m, UINT32 n)\r
1223{\r
1224 sh2->ea = sh2->r[m] + sh2->r[0];\r
1225 sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2, sh2->ea );\r
1226}\r
1227\r
1228/* MOV.L @(R0,Rm),Rn */\r
1229INLINE void MOVLL0(sh2_state *sh2, UINT32 m, UINT32 n)\r
1230{\r
1231 sh2->ea = sh2->r[m] + sh2->r[0];\r
1232 sh2->r[n] = RL( sh2, sh2->ea );\r
1233}\r
1234\r
1235/* MOV #imm,Rn */\r
1236INLINE void MOVI(sh2_state *sh2, UINT32 i, UINT32 n)\r
1237{\r
1238 sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) i;\r
1239}\r
1240\r
1241/* MOV.W @(disp8,PC),Rn */\r
1242INLINE void MOVWI(sh2_state *sh2, UINT32 d, UINT32 n)\r
1243{\r
1244 UINT32 disp = d & 0xff;\r
1245 sh2->ea = sh2->pc + disp * 2 + 2;\r
1246 sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2, sh2->ea );\r
1247}\r
1248\r
1249/* MOV.L @(disp8,PC),Rn */\r
1250INLINE void MOVLI(sh2_state *sh2, UINT32 d, UINT32 n)\r
1251{\r
1252 UINT32 disp = d & 0xff;\r
1253 sh2->ea = ((sh2->pc + 2) & ~3) + disp * 4;\r
1254 sh2->r[n] = RL( sh2, sh2->ea );\r
1255}\r
1256\r
1257/* MOV.B @(disp8,GBR),R0 */\r
1258INLINE void MOVBLG(sh2_state *sh2, UINT32 d)\r
1259{\r
1260 UINT32 disp = d & 0xff;\r
1261 sh2->ea = sh2->gbr + disp;\r
1262 sh2->r[0] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->ea );\r
1263}\r
1264\r
1265/* MOV.W @(disp8,GBR),R0 */\r
1266INLINE void MOVWLG(sh2_state *sh2, UINT32 d)\r
1267{\r
1268 UINT32 disp = d & 0xff;\r
1269 sh2->ea = sh2->gbr + disp * 2;\r
1270 sh2->r[0] = (INT32)(INT16) RW( sh2, sh2->ea );\r
1271}\r
1272\r
1273/* MOV.L @(disp8,GBR),R0 */\r
1274INLINE void MOVLLG(sh2_state *sh2, UINT32 d)\r
1275{\r
1276 UINT32 disp = d & 0xff;\r
1277 sh2->ea = sh2->gbr + disp * 4;\r
1278 sh2->r[0] = RL( sh2, sh2->ea );\r
1279}\r
1280\r
1281/* MOV.B R0,@(disp8,GBR) */\r
1282INLINE void MOVBSG(sh2_state *sh2, UINT32 d)\r
1283{\r
1284 UINT32 disp = d & 0xff;\r
1285 sh2->ea = sh2->gbr + disp;\r
1286 WB( sh2, sh2->ea, sh2->r[0] & 0x000000ff );\r
1287}\r
1288\r
1289/* MOV.W R0,@(disp8,GBR) */\r
1290INLINE void MOVWSG(sh2_state *sh2, UINT32 d)\r
1291{\r
1292 UINT32 disp = d & 0xff;\r
1293 sh2->ea = sh2->gbr + disp * 2;\r
1294 WW( sh2, sh2->ea, sh2->r[0] & 0x0000ffff );\r
1295}\r
1296\r
1297/* MOV.L R0,@(disp8,GBR) */\r
1298INLINE void MOVLSG(sh2_state *sh2, UINT32 d)\r
1299{\r
1300 UINT32 disp = d & 0xff;\r
1301 sh2->ea = sh2->gbr + disp * 4;\r
1302 WL( sh2, sh2->ea, sh2->r[0] );\r
1303}\r
1304\r
1305/* MOV.B R0,@(disp4,Rn) */\r
1306INLINE void MOVBS4(sh2_state *sh2, UINT32 d, UINT32 n)\r
1307{\r
1308 UINT32 disp = d & 0x0f;\r
1309 sh2->ea = sh2->r[n] + disp;\r
1310 WB( sh2, sh2->ea, sh2->r[0] & 0x000000ff );\r
1311}\r
1312\r
1313/* MOV.W R0,@(disp4,Rn) */\r
1314INLINE void MOVWS4(sh2_state *sh2, UINT32 d, UINT32 n)\r
1315{\r
1316 UINT32 disp = d & 0x0f;\r
1317 sh2->ea = sh2->r[n] + disp * 2;\r
1318 WW( sh2, sh2->ea, sh2->r[0] & 0x0000ffff );\r
1319}\r
1320\r
1321/* MOV.L Rm,@(disp4,Rn) */\r
1322INLINE void MOVLS4(sh2_state *sh2, UINT32 m, UINT32 d, UINT32 n)\r
1323{\r
1324 UINT32 disp = d & 0x0f;\r
1325 sh2->ea = sh2->r[n] + disp * 4;\r
1326 WL( sh2, sh2->ea, sh2->r[m] );\r
1327}\r
1328\r
1329/* MOV.B @(disp4,Rm),R0 */\r
1330INLINE void MOVBL4(sh2_state *sh2, UINT32 m, UINT32 d)\r
1331{\r
1332 UINT32 disp = d & 0x0f;\r
1333 sh2->ea = sh2->r[m] + disp;\r
1334 sh2->r[0] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->ea );\r
1335}\r
1336\r
1337/* MOV.W @(disp4,Rm),R0 */\r
1338INLINE void MOVWL4(sh2_state *sh2, UINT32 m, UINT32 d)\r
1339{\r
1340 UINT32 disp = d & 0x0f;\r
1341 sh2->ea = sh2->r[m] + disp * 2;\r
1342 sh2->r[0] = (UINT32)(INT32)(INT16) RW( sh2, sh2->ea );\r
1343}\r
1344\r
1345/* MOV.L @(disp4,Rm),Rn */\r
1346INLINE void MOVLL4(sh2_state *sh2, UINT32 m, UINT32 d, UINT32 n)\r
1347{\r
1348 UINT32 disp = d & 0x0f;\r
1349 sh2->ea = sh2->r[m] + disp * 4;\r
1350 sh2->r[n] = RL( sh2, sh2->ea );\r
1351}\r
1352\r
1353/* MOVA @(disp8,PC),R0 */\r
1354INLINE void MOVA(sh2_state *sh2, UINT32 d)\r
1355{\r
1356 UINT32 disp = d & 0xff;\r
1357 sh2->ea = ((sh2->pc + 2) & ~3) + disp * 4;\r
1358 sh2->r[0] = sh2->ea;\r
1359}\r
1360\r
1361/* MOVT Rn */\r
1362INLINE void MOVT(sh2_state *sh2, UINT32 n)\r
1363{\r
1364 sh2->r[n] = sh2->sr & T;\r
1365}\r
1366\r
1367/* MUL.L Rm,Rn */\r
1368INLINE void MULL(sh2_state *sh2, UINT32 m, UINT32 n)\r
1369{\r
1370 sh2->macl = sh2->r[n] * sh2->r[m];\r
1371 sh2->icount--;\r
1372}\r
1373\r
1374/* MULS Rm,Rn */\r
1375INLINE void MULS(sh2_state *sh2, UINT32 m, UINT32 n)\r
1376{\r
1377 sh2->macl = (INT16) sh2->r[n] * (INT16) sh2->r[m];\r
1378}\r
1379\r
1380/* MULU Rm,Rn */\r
1381INLINE void MULU(sh2_state *sh2, UINT32 m, UINT32 n)\r
1382{\r
1383 sh2->macl = (UINT16) sh2->r[n] * (UINT16) sh2->r[m];\r
1384}\r
1385\r
1386/* NEG Rm,Rn */\r
1387INLINE void NEG(sh2_state *sh2, UINT32 m, UINT32 n)\r
1388{\r
1389 sh2->r[n] = 0 - sh2->r[m];\r
1390}\r
1391\r
1392/* NEGC Rm,Rn */\r
1393INLINE void NEGC(sh2_state *sh2, UINT32 m, UINT32 n)\r
1394{\r
1395 UINT32 temp;\r
1396\r
1397 temp = sh2->r[m];\r
1398 sh2->r[n] = -temp - (sh2->sr & T);\r
1399 if (temp || (sh2->sr & T))\r
1400 sh2->sr |= T;\r
1401 else\r
1402 sh2->sr &= ~T;\r
1403}\r
1404\r
1405/* NOP */\r
1406INLINE void NOP(void)\r
1407{\r
1408}\r
1409\r
1410/* NOT Rm,Rn */\r
1411INLINE void NOT(sh2_state *sh2, UINT32 m, UINT32 n)\r
1412{\r
1413 sh2->r[n] = ~sh2->r[m];\r
1414}\r
1415\r
1416/* OR Rm,Rn */\r
1417INLINE void OR(sh2_state *sh2, UINT32 m, UINT32 n)\r
1418{\r
1419 sh2->r[n] |= sh2->r[m];\r
1420}\r
1421\r
1422/* OR #imm,R0 */\r
1423INLINE void ORI(sh2_state *sh2, UINT32 i)\r
1424{\r
1425 sh2->r[0] |= i;\r
1426}\r
1427\r
1428/* OR.B #imm,@(R0,GBR) */\r
1429INLINE void ORM(sh2_state *sh2, UINT32 i)\r
1430{\r
1431 UINT32 temp;\r
1432\r
1433 sh2->ea = sh2->gbr + sh2->r[0];\r
1434 temp = RB( sh2, sh2->ea );\r
1435 temp |= i;\r
1436 WB( sh2, sh2->ea, temp );\r
1437 sh2->icount -= 2;\r
1438}\r
1439\r
1440/* ROTCL Rn */\r
1441INLINE void ROTCL(sh2_state *sh2, UINT32 n)\r
1442{\r
1443 UINT32 temp;\r
1444\r
1445 temp = (sh2->r[n] >> 31) & T;\r
1446 sh2->r[n] = (sh2->r[n] << 1) | (sh2->sr & T);\r
1447 sh2->sr = (sh2->sr & ~T) | temp;\r
1448}\r
1449\r
1450/* ROTCR Rn */\r
1451INLINE void ROTCR(sh2_state *sh2, UINT32 n)\r
1452{\r
1453 UINT32 temp;\r
1454 temp = (sh2->sr & T) << 31;\r
1455 if (sh2->r[n] & T)\r
1456 sh2->sr |= T;\r
1457 else\r
1458 sh2->sr &= ~T;\r
1459 sh2->r[n] = (sh2->r[n] >> 1) | temp;\r
1460}\r
1461\r
1462/* ROTL Rn */\r
1463INLINE void ROTL(sh2_state *sh2, UINT32 n)\r
1464{\r
1465 sh2->sr = (sh2->sr & ~T) | ((sh2->r[n] >> 31) & T);\r
1466 sh2->r[n] = (sh2->r[n] << 1) | (sh2->r[n] >> 31);\r
1467}\r
1468\r
1469/* ROTR Rn */\r
1470INLINE void ROTR(sh2_state *sh2, UINT32 n)\r
1471{\r
1472 sh2->sr = (sh2->sr & ~T) | (sh2->r[n] & T);\r
1473 sh2->r[n] = (sh2->r[n] >> 1) | (sh2->r[n] << 31);\r
1474}\r
1475\r
1476/* RTE */\r
1477INLINE void RTE(sh2_state *sh2)\r
1478{\r
1479 sh2->ea = sh2->r[15];\r
1480 sh2->delay = sh2->pc;\r
1481 sh2->pc = RL( sh2, sh2->ea );\r
1482 sh2->r[15] += 4;\r
1483 sh2->ea = sh2->r[15];\r
1484 sh2->sr = RL( sh2, sh2->ea ) & FLAGS;\r
1485 sh2->r[15] += 4;\r
1486 sh2->icount -= 3;\r
1487 sh2->test_irq = 1;\r
1488}\r
1489\r
1490/* RTS */\r
1491INLINE void RTS(sh2_state *sh2)\r
1492{\r
1493 sh2->delay = sh2->pc;\r
1494 sh2->pc = sh2->ea = sh2->pr;\r
1495 sh2->icount--;\r
1496}\r
1497\r
1498/* SETT */\r
1499INLINE void SETT(sh2_state *sh2)\r
1500{\r
1501 sh2->sr |= T;\r
1502}\r
1503\r
1504/* SHAL Rn (same as SHLL) */\r
1505INLINE void SHAL(sh2_state *sh2, UINT32 n)\r
1506{\r
1507 sh2->sr = (sh2->sr & ~T) | ((sh2->r[n] >> 31) & T);\r
1508 sh2->r[n] <<= 1;\r
1509}\r
1510\r
1511/* SHAR Rn */\r
1512INLINE void SHAR(sh2_state *sh2, UINT32 n)\r
1513{\r
1514 sh2->sr = (sh2->sr & ~T) | (sh2->r[n] & T);\r
1515 sh2->r[n] = (UINT32)((INT32)sh2->r[n] >> 1);\r
1516}\r
1517\r
1518/* SHLL Rn (same as SHAL) */\r
1519INLINE void SHLL(sh2_state *sh2, UINT32 n)\r
1520{\r
1521 sh2->sr = (sh2->sr & ~T) | ((sh2->r[n] >> 31) & T);\r
1522 sh2->r[n] <<= 1;\r
1523}\r
1524\r
1525/* SHLL2 Rn */\r
1526INLINE void SHLL2(sh2_state *sh2, UINT32 n)\r
1527{\r
1528 sh2->r[n] <<= 2;\r
1529}\r
1530\r
1531/* SHLL8 Rn */\r
1532INLINE void SHLL8(sh2_state *sh2, UINT32 n)\r
1533{\r
1534 sh2->r[n] <<= 8;\r
1535}\r
1536\r
1537/* SHLL16 Rn */\r
1538INLINE void SHLL16(sh2_state *sh2, UINT32 n)\r
1539{\r
1540 sh2->r[n] <<= 16;\r
1541}\r
1542\r
1543/* SHLR Rn */\r
1544INLINE void SHLR(sh2_state *sh2, UINT32 n)\r
1545{\r
1546 sh2->sr = (sh2->sr & ~T) | (sh2->r[n] & T);\r
1547 sh2->r[n] >>= 1;\r
1548}\r
1549\r
1550/* SHLR2 Rn */\r
1551INLINE void SHLR2(sh2_state *sh2, UINT32 n)\r
1552{\r
1553 sh2->r[n] >>= 2;\r
1554}\r
1555\r
1556/* SHLR8 Rn */\r
1557INLINE void SHLR8(sh2_state *sh2, UINT32 n)\r
1558{\r
1559 sh2->r[n] >>= 8;\r
1560}\r
1561\r
1562/* SHLR16 Rn */\r
1563INLINE void SHLR16(sh2_state *sh2, UINT32 n)\r
1564{\r
1565 sh2->r[n] >>= 16;\r
1566}\r
1567\r
1568/* SLEEP */\r
1569INLINE void SLEEP(sh2_state *sh2)\r
1570{\r
1571 //if(sh2->sleep_mode != 2)\r
1572 sh2->pc -= 2;\r
1573 sh2->icount -= 2;\r
1574 /* Wait_for_exception; */\r
1575 /*if(sh2->sleep_mode == 0)\r
1576 sh2->sleep_mode = 1;\r
1577 else if(sh2->sleep_mode == 2)\r
1578 sh2->sleep_mode = 0;*/\r
1579}\r
1580\r
1581/* STC SR,Rn */\r
1582INLINE void STCSR(sh2_state *sh2, UINT32 n)\r
1583{\r
1584 sh2->r[n] = sh2->sr;\r
1585}\r
1586\r
1587/* STC GBR,Rn */\r
1588INLINE void STCGBR(sh2_state *sh2, UINT32 n)\r
1589{\r
1590 sh2->r[n] = sh2->gbr;\r
1591}\r
1592\r
1593/* STC VBR,Rn */\r
1594INLINE void STCVBR(sh2_state *sh2, UINT32 n)\r
1595{\r
1596 sh2->r[n] = sh2->vbr;\r
1597}\r
1598\r
1599/* STC.L SR,@-Rn */\r
1600INLINE void STCMSR(sh2_state *sh2, UINT32 n)\r
1601{\r
1602 sh2->r[n] -= 4;\r
1603 sh2->ea = sh2->r[n];\r
1604 WL( sh2, sh2->ea, sh2->sr );\r
1605 sh2->icount--;\r
1606}\r
1607\r
1608/* STC.L GBR,@-Rn */\r
1609INLINE void STCMGBR(sh2_state *sh2, UINT32 n)\r
1610{\r
1611 sh2->r[n] -= 4;\r
1612 sh2->ea = sh2->r[n];\r
1613 WL( sh2, sh2->ea, sh2->gbr );\r
1614 sh2->icount--;\r
1615}\r
1616\r
1617/* STC.L VBR,@-Rn */\r
1618INLINE void STCMVBR(sh2_state *sh2, UINT32 n)\r
1619{\r
1620 sh2->r[n] -= 4;\r
1621 sh2->ea = sh2->r[n];\r
1622 WL( sh2, sh2->ea, sh2->vbr );\r
1623 sh2->icount--;\r
1624}\r
1625\r
1626/* STS MACH,Rn */\r
1627INLINE void STSMACH(sh2_state *sh2, UINT32 n)\r
1628{\r
1629 sh2->r[n] = sh2->mach;\r
1630}\r
1631\r
1632/* STS MACL,Rn */\r
1633INLINE void STSMACL(sh2_state *sh2, UINT32 n)\r
1634{\r
1635 sh2->r[n] = sh2->macl;\r
1636}\r
1637\r
1638/* STS PR,Rn */\r
1639INLINE void STSPR(sh2_state *sh2, UINT32 n)\r
1640{\r
1641 sh2->r[n] = sh2->pr;\r
1642}\r
1643\r
1644/* STS.L MACH,@-Rn */\r
1645INLINE void STSMMACH(sh2_state *sh2, UINT32 n)\r
1646{\r
1647 sh2->r[n] -= 4;\r
1648 sh2->ea = sh2->r[n];\r
1649 WL( sh2, sh2->ea, sh2->mach );\r
1650}\r
1651\r
1652/* STS.L MACL,@-Rn */\r
1653INLINE void STSMMACL(sh2_state *sh2, UINT32 n)\r
1654{\r
1655 sh2->r[n] -= 4;\r
1656 sh2->ea = sh2->r[n];\r
1657 WL( sh2, sh2->ea, sh2->macl );\r
1658}\r
1659\r
1660/* STS.L PR,@-Rn */\r
1661INLINE void STSMPR(sh2_state *sh2, UINT32 n)\r
1662{\r
1663 sh2->r[n] -= 4;\r
1664 sh2->ea = sh2->r[n];\r
1665 WL( sh2, sh2->ea, sh2->pr );\r
1666}\r
1667\r
1668/* SUB Rm,Rn */\r
1669INLINE void SUB(sh2_state *sh2, UINT32 m, UINT32 n)\r
1670{\r
1671 sh2->r[n] -= sh2->r[m];\r
1672}\r
1673\r
1674/* SUBC Rm,Rn */\r
1675INLINE void SUBC(sh2_state *sh2, UINT32 m, UINT32 n)\r
1676{\r
1677 UINT32 tmp0, tmp1;\r
1678\r
1679 tmp1 = sh2->r[n] - sh2->r[m];\r
1680 tmp0 = sh2->r[n];\r
1681 sh2->r[n] = tmp1 - (sh2->sr & T);\r
1682 if (tmp0 < tmp1)\r
1683 sh2->sr |= T;\r
1684 else\r
1685 sh2->sr &= ~T;\r
1686 if (tmp1 < sh2->r[n])\r
1687 sh2->sr |= T;\r
1688}\r
1689\r
1690/* SUBV Rm,Rn */\r
1691INLINE void SUBV(sh2_state *sh2, UINT32 m, UINT32 n)\r
1692{\r
1693 INT32 dest, src, ans;\r
1694\r
1695 if ((INT32) sh2->r[n] >= 0)\r
1696 dest = 0;\r
1697 else\r
1698 dest = 1;\r
1699 if ((INT32) sh2->r[m] >= 0)\r
1700 src = 0;\r
1701 else\r
1702 src = 1;\r
1703 src += dest;\r
1704 sh2->r[n] -= sh2->r[m];\r
1705 if ((INT32) sh2->r[n] >= 0)\r
1706 ans = 0;\r
1707 else\r
1708 ans = 1;\r
1709 ans += dest;\r
1710 if (src == 1)\r
1711 {\r
1712 if (ans == 1)\r
1713 sh2->sr |= T;\r
1714 else\r
1715 sh2->sr &= ~T;\r
1716 }\r
1717 else\r
1718 sh2->sr &= ~T;\r
1719}\r
1720\r
1721/* SWAP.B Rm,Rn */\r
1722INLINE void SWAPB(sh2_state *sh2, UINT32 m, UINT32 n)\r
1723{\r
1724 UINT32 temp0, temp1;\r
1725\r
1726 temp0 = sh2->r[m] & 0xffff0000;\r
1727 temp1 = (sh2->r[m] & 0x000000ff) << 8;\r
1728 sh2->r[n] = (sh2->r[m] >> 8) & 0x000000ff;\r
1729 sh2->r[n] = sh2->r[n] | temp1 | temp0;\r
1730}\r
1731\r
1732/* SWAP.W Rm,Rn */\r
1733INLINE void SWAPW(sh2_state *sh2, UINT32 m, UINT32 n)\r
1734{\r
1735 UINT32 temp;\r
1736\r
1737 temp = (sh2->r[m] >> 16) & 0x0000ffff;\r
1738 sh2->r[n] = (sh2->r[m] << 16) | temp;\r
1739}\r
1740\r
1741/* TAS.B @Rn */\r
1742INLINE void TAS(sh2_state *sh2, UINT32 n)\r
1743{\r
1744 UINT32 temp;\r
1745 sh2->ea = sh2->r[n];\r
1746 /* Bus Lock enable */\r
1747 temp = RB( sh2, sh2->ea );\r
1748 if (temp == 0)\r
1749 sh2->sr |= T;\r
1750 else\r
1751 sh2->sr &= ~T;\r
1752 temp |= 0x80;\r
1753 /* Bus Lock disable */\r
1754 WB( sh2, sh2->ea, temp );\r
1755 sh2->icount -= 3;\r
1756}\r
1757\r
1758/* TRAPA #imm */\r
1759INLINE void TRAPA(sh2_state *sh2, UINT32 i)\r
1760{\r
1761 UINT32 imm = i & 0xff;\r
1762\r
1763 sh2->ea = sh2->vbr + imm * 4;\r
1764\r
1765 sh2->r[15] -= 4;\r
1766 WL( sh2, sh2->r[15], sh2->sr );\r
1767 sh2->r[15] -= 4;\r
1768 WL( sh2, sh2->r[15], sh2->pc );\r
1769\r
1770 sh2->pc = RL( sh2, sh2->ea );\r
1771\r
1772 sh2->icount -= 7;\r
1773}\r
1774\r
1775/* TST Rm,Rn */\r
1776INLINE void TST(sh2_state *sh2, UINT32 m, UINT32 n)\r
1777{\r
1778 if ((sh2->r[n] & sh2->r[m]) == 0)\r
1779 sh2->sr |= T;\r
1780 else\r
1781 sh2->sr &= ~T;\r
1782}\r
1783\r
1784/* TST #imm,R0 */\r
1785INLINE void TSTI(sh2_state *sh2, UINT32 i)\r
1786{\r
1787 UINT32 imm = i & 0xff;\r
1788\r
1789 if ((imm & sh2->r[0]) == 0)\r
1790 sh2->sr |= T;\r
1791 else\r
1792 sh2->sr &= ~T;\r
1793}\r
1794\r
1795/* TST.B #imm,@(R0,GBR) */\r
1796INLINE void TSTM(sh2_state *sh2, UINT32 i)\r
1797{\r
1798 UINT32 imm = i & 0xff;\r
1799\r
1800 sh2->ea = sh2->gbr + sh2->r[0];\r
1801 if ((imm & RB( sh2, sh2->ea )) == 0)\r
1802 sh2->sr |= T;\r
1803 else\r
1804 sh2->sr &= ~T;\r
1805 sh2->icount -= 2;\r
1806}\r
1807\r
1808/* XOR Rm,Rn */\r
1809INLINE void XOR(sh2_state *sh2, UINT32 m, UINT32 n)\r
1810{\r
1811 sh2->r[n] ^= sh2->r[m];\r
1812}\r
1813\r
1814/* XOR #imm,R0 */\r
1815INLINE void XORI(sh2_state *sh2, UINT32 i)\r
1816{\r
1817 UINT32 imm = i & 0xff;\r
1818 sh2->r[0] ^= imm;\r
1819}\r
1820\r
1821/* XOR.B #imm,@(R0,GBR) */\r
1822INLINE void XORM(sh2_state *sh2, UINT32 i)\r
1823{\r
1824 UINT32 imm = i & 0xff;\r
1825 UINT32 temp;\r
1826\r
1827 sh2->ea = sh2->gbr + sh2->r[0];\r
1828 temp = RB( sh2, sh2->ea );\r
1829 temp ^= imm;\r
1830 WB( sh2, sh2->ea, temp );\r
1831 sh2->icount -= 2;\r
1832}\r
1833\r
1834/* XTRCT Rm,Rn */\r
1835INLINE void XTRCT(sh2_state *sh2, UINT32 m, UINT32 n)\r
1836{\r
1837 UINT32 temp;\r
1838\r
1839 temp = (sh2->r[m] << 16) & 0xffff0000;\r
1840 sh2->r[n] = (sh2->r[n] >> 16) & 0x0000ffff;\r
1841 sh2->r[n] |= temp;\r
1842}\r
1843\r
1844/*****************************************************************************\r
1845 * OPCODE DISPATCHERS\r
1846 *****************************************************************************/\r
1847\r
1848INLINE void op0000(sh2_state *sh2, UINT16 opcode)\r
1849{\r
1850 switch (opcode & 0x3F)\r
1851 {\r
1852 case 0x00: ILLEGAL(sh2); rlog(0); break;\r
1853 case 0x01: ILLEGAL(sh2); rlog(0); break;\r
1854 case 0x02: STCSR(sh2, Rn); rlog(LRN); break;\r
1855 case 0x03: BSRF(sh2, Rn); rlog(LRN); break;\r
1856 case 0x04: MOVBS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r
1857 case 0x05: MOVWS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r
1858 case 0x06: MOVLS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r
1859 case 0x07: MULL(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;\r
1860 case 0x08: CLRT(sh2); rlog(0); break;\r
1861 case 0x09: NOP(); rlog(0); break;\r
1862 case 0x0a: STSMACH(sh2, Rn); rlog(LRN); rlog1(SHR_MACH); break;\r
1863 case 0x0b: RTS(sh2); rlog(0); rlog1(SHR_PR); break;\r
1864 case 0x0c: MOVBL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r
1865 case 0x0d: MOVWL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r
1866 case 0x0e: MOVLL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r
1867 case 0x0f: MAC_L(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;\r
1868\r
1869 case 0x10: ILLEGAL(sh2); rlog(0); break;\r
1870 case 0x11: ILLEGAL(sh2); rlog(0); break;\r
1871 case 0x12: STCGBR(sh2, Rn); rlog(LRN); rlog1(SHR_GBR); break;\r
1872 case 0x13: ILLEGAL(sh2); rlog(0); break;\r
1873 case 0x14: MOVBS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r
1874 case 0x15: MOVWS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r
1875 case 0x16: MOVLS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r
1876 case 0x17: MULL(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;\r
1877 case 0x18: SETT(sh2); rlog(0); break;\r
1878 case 0x19: DIV0U(sh2); rlog(0); break;\r
1879 case 0x1a: STSMACL(sh2, Rn); rlog(LRN); rlog1(SHR_MACL); break;\r
1880 case 0x1b: SLEEP(sh2); rlog(0); break;\r
1881 case 0x1c: MOVBL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r
1882 case 0x1d: MOVWL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r
1883 case 0x1e: MOVLL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r
1884 case 0x1f: MAC_L(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;\r
1885\r
1886 case 0x20: ILLEGAL(sh2); rlog(0); break;\r
1887 case 0x21: ILLEGAL(sh2); rlog(0); break;\r
1888 case 0x22: STCVBR(sh2, Rn); rlog(LRN); rlog1(SHR_VBR); break;\r
1889 case 0x23: BRAF(sh2, Rn); rlog(LRN); break;\r
1890 case 0x24: MOVBS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r
1891 case 0x25: MOVWS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r
1892 case 0x26: MOVLS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r
1893 case 0x27: MULL(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;\r
1894 case 0x28: CLRMAC(sh2); rlog(0); rlog2(SHR_MACL,SHR_MACH); break;\r
1895 case 0x29: MOVT(sh2, Rn); rlog(LRN); break;\r
1896 case 0x2a: STSPR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;\r
1897 case 0x2b: RTE(sh2); rlog(0); break;\r
1898 case 0x2c: MOVBL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r
1899 case 0x2d: MOVWL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r
1900 case 0x2e: MOVLL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r
1901 case 0x2f: MAC_L(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;\r
1902\r
1903 case 0x30: ILLEGAL(sh2); rlog(0); break;\r
1904 case 0x31: ILLEGAL(sh2); rlog(0); break;\r
1905 case 0x32: ILLEGAL(sh2); rlog(0); break;\r
1906 case 0x33: ILLEGAL(sh2); rlog(0); break;\r
1907 case 0x34: MOVBS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r
1908 case 0x35: MOVWS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r
1909 case 0x36: MOVLS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r
1910 case 0x37: MULL(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;\r
1911 case 0x38: ILLEGAL(sh2); rlog(0); break;\r
1912 case 0x39: ILLEGAL(sh2); rlog(0); break;\r
1913 case 0x3c: MOVBL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r
1914 case 0x3d: MOVWL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r
1915 case 0x3e: MOVLL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r
1916 case 0x3f: MAC_L(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;\r
1917 case 0x3a: ILLEGAL(sh2); rlog(0); break;\r
1918 case 0x3b: ILLEGAL(sh2); rlog(0); break;\r
1919 }\r
1920}\r
1921\r
1922INLINE void op0001(sh2_state *sh2, UINT16 opcode)\r
1923{\r
1924 MOVLS4(sh2, Rm, opcode & 0x0f, Rn);\r
1925 rlog(LRNM);\r
1926}\r
1927\r
1928INLINE void op0010(sh2_state *sh2, UINT16 opcode)\r
1929{\r
1930 switch (opcode & 15)\r
1931 {\r
1932 case 0: MOVBS(sh2, Rm, Rn); rlog(LRNM); break;\r
1933 case 1: MOVWS(sh2, Rm, Rn); rlog(LRNM); break;\r
1934 case 2: MOVLS(sh2, Rm, Rn); rlog(LRNM); break;\r
1935 case 3: ILLEGAL(sh2); rlog(0); break;\r
1936 case 4: MOVBM(sh2, Rm, Rn); rlog(LRNM); break;\r
1937 case 5: MOVWM(sh2, Rm, Rn); rlog(LRNM); break;\r
1938 case 6: MOVLM(sh2, Rm, Rn); rlog(LRNM); break;\r
1939 case 7: DIV0S(sh2, Rm, Rn); rlog(LRNM); break;\r
1940 case 8: TST(sh2, Rm, Rn); rlog(LRNM); break;\r
1941 case 9: AND(sh2, Rm, Rn); rlog(LRNM); break;\r
1942 case 10: XOR(sh2, Rm, Rn); rlog(LRNM); break;\r
1943 case 11: OR(sh2, Rm, Rn); rlog(LRNM); break;\r
1944 case 12: CMPSTR(sh2, Rm, Rn); rlog(LRNM); break;\r
1945 case 13: XTRCT(sh2, Rm, Rn); rlog(LRNM); break;\r
1946 case 14: MULU(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;\r
1947 case 15: MULS(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;\r
1948 }\r
1949}\r
1950\r
1951INLINE void op0011(sh2_state *sh2, UINT16 opcode)\r
1952{\r
1953 switch (opcode & 15)\r
1954 {\r
1955 case 0: CMPEQ(sh2, Rm, Rn); rlog(LRNM); break;\r
1956 case 1: ILLEGAL(sh2); rlog(0); break;\r
1957 case 2: CMPHS(sh2, Rm, Rn); rlog(LRNM); break;\r
1958 case 3: CMPGE(sh2, Rm, Rn); rlog(LRNM); break;\r
1959 case 4: DIV1(sh2, Rm, Rn); rlog(LRNM); break;\r
1960 case 5: DMULU(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;\r
1961 case 6: CMPHI(sh2, Rm, Rn); rlog(LRNM); break;\r
1962 case 7: CMPGT(sh2, Rm, Rn); rlog(LRNM); break;\r
1963 case 8: SUB(sh2, Rm, Rn); rlog(LRNM); break;\r
1964 case 9: ILLEGAL(sh2); rlog(0); break;\r
1965 case 10: SUBC(sh2, Rm, Rn); rlog(LRNM); break;\r
1966 case 11: SUBV(sh2, Rm, Rn); rlog(LRNM); break;\r
1967 case 12: ADD(sh2, Rm, Rn); rlog(LRNM); break;\r
1968 case 13: DMULS(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;\r
1969 case 14: ADDC(sh2, Rm, Rn); rlog(LRNM); break;\r
1970 case 15: ADDV(sh2, Rm, Rn); rlog(LRNM); break;\r
1971 }\r
1972}\r
1973\r
1974INLINE void op0100(sh2_state *sh2, UINT16 opcode)\r
1975{\r
1976 switch (opcode & 0x3F)\r
1977 {\r
1978 case 0x00: SHLL(sh2, Rn); rlog(LRN); break;\r
1979 case 0x01: SHLR(sh2, Rn); rlog(LRN); break;\r
1980 case 0x02: STSMMACH(sh2, Rn); rlog(LRN); rlog1(SHR_MACH); break;\r
1981 case 0x03: STCMSR(sh2, Rn); rlog(LRN); break;\r
1982 case 0x04: ROTL(sh2, Rn); rlog(LRN); break;\r
1983 case 0x05: ROTR(sh2, Rn); rlog(LRN); break;\r
1984 case 0x06: LDSMMACH(sh2, Rn); rlog(LRN); rlog1(SHR_MACH); break;\r
1985 case 0x07: LDCMSR(sh2, Rn); rlog(LRN); break;\r
1986 case 0x08: SHLL2(sh2, Rn); rlog(LRN); break;\r
1987 case 0x09: SHLR2(sh2, Rn); rlog(LRN); break;\r
1988 case 0x0a: LDSMACH(sh2, Rn); rlog(LRN); rlog1(SHR_MACH); break;\r
1989 case 0x0b: JSR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;\r
1990 case 0x0c: ILLEGAL(sh2); rlog(0); break;\r
1991 case 0x0d: ILLEGAL(sh2); rlog(0); break;\r
1992 case 0x0e: LDCSR(sh2, Rn); rlog(LRN); break;\r
1993 case 0x0f: MAC_W(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;\r
1994\r
1995 case 0x10: DT(sh2, Rn); rlog(LRN); break;\r
1996 case 0x11: CMPPZ(sh2, Rn); rlog(LRN); break;\r
1997 case 0x12: STSMMACL(sh2, Rn); rlog(LRN); rlog1(SHR_MACL); break;\r
1998 case 0x13: STCMGBR(sh2, Rn); rlog(LRN); rlog1(SHR_GBR); break;\r
1999 case 0x14: ILLEGAL(sh2); rlog(0); break;\r
2000 case 0x15: CMPPL(sh2, Rn); rlog(LRN); break;\r
2001 case 0x16: LDSMMACL(sh2, Rn); rlog(LRN); rlog1(SHR_MACL); break;\r
2002 case 0x17: LDCMGBR(sh2, Rn); rlog(LRN); rlog1(SHR_GBR); break;\r
2003 case 0x18: SHLL8(sh2, Rn); rlog(LRN); break;\r
2004 case 0x19: SHLR8(sh2, Rn); rlog(LRN); break;\r
2005 case 0x1a: LDSMACL(sh2, Rn); rlog(LRN); rlog1(SHR_MACL); break;\r
2006 case 0x1b: TAS(sh2, Rn); rlog(LRN); break;\r
2007 case 0x1c: ILLEGAL(sh2); rlog(0); break;\r
2008 case 0x1d: ILLEGAL(sh2); rlog(0); break;\r
2009 case 0x1e: LDCGBR(sh2, Rn); rlog(LRN); rlog1(SHR_GBR); break;\r
2010 case 0x1f: MAC_W(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;\r
2011\r
2012 case 0x20: SHAL(sh2, Rn); rlog(LRN); break;\r
2013 case 0x21: SHAR(sh2, Rn); rlog(LRN); break;\r
2014 case 0x22: STSMPR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;\r
2015 case 0x23: STCMVBR(sh2, Rn); rlog(LRN); rlog1(SHR_VBR); break;\r
2016 case 0x24: ROTCL(sh2, Rn); rlog(LRN); break;\r
2017 case 0x25: ROTCR(sh2, Rn); rlog(LRN); break;\r
2018 case 0x26: LDSMPR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;\r
2019 case 0x27: LDCMVBR(sh2, Rn); rlog(LRN); rlog1(SHR_VBR); break;\r
2020 case 0x28: SHLL16(sh2, Rn); rlog(LRN); break;\r
2021 case 0x29: SHLR16(sh2, Rn); rlog(LRN); break;\r
2022 case 0x2a: LDSPR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;\r
2023 case 0x2b: JMP(sh2, Rn); rlog(LRN); break;\r
2024 case 0x2c: ILLEGAL(sh2); rlog(0); break;\r
2025 case 0x2d: ILLEGAL(sh2); rlog(0); break;\r
2026 case 0x2e: LDCVBR(sh2, Rn); rlog(LRN); rlog1(SHR_VBR); break;\r
2027 case 0x2f: MAC_W(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;\r
2028\r
2029 case 0x30:\r
2030 case 0x31:\r
2031 case 0x32:\r
2032 case 0x33:\r
2033 case 0x34:\r
2034 case 0x35:\r
2035 case 0x36:\r
2036 case 0x37:\r
2037 case 0x38:\r
2038 case 0x39:\r
2039 case 0x3a:\r
2040 case 0x3b:\r
2041 case 0x3c:\r
2042 case 0x3d:\r
2043 case 0x3e: ILLEGAL(sh2); rlog(0); break;\r
2044 case 0x3f: MAC_W(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;\r
2045 }\r
2046}\r
2047\r
2048INLINE void op0101(sh2_state *sh2, UINT16 opcode)\r
2049{\r
2050 MOVLL4(sh2, Rm, opcode & 0x0f, Rn);\r
2051 rlog(LRNM);\r
2052}\r
2053\r
2054INLINE void op0110(sh2_state *sh2, UINT16 opcode)\r
2055{\r
2056 switch (opcode & 15)\r
2057 {\r
2058 case 0: MOVBL(sh2, Rm, Rn); break;\r
2059 case 1: MOVWL(sh2, Rm, Rn); break;\r
2060 case 2: MOVLL(sh2, Rm, Rn); break;\r
2061 case 3: MOV(sh2, Rm, Rn); break;\r
2062 case 4: MOVBP(sh2, Rm, Rn); break;\r
2063 case 5: MOVWP(sh2, Rm, Rn); break;\r
2064 case 6: MOVLP(sh2, Rm, Rn); break;\r
2065 case 7: NOT(sh2, Rm, Rn); break;\r
2066 case 8: SWAPB(sh2, Rm, Rn); break;\r
2067 case 9: SWAPW(sh2, Rm, Rn); break;\r
2068 case 10: NEGC(sh2, Rm, Rn); break;\r
2069 case 11: NEG(sh2, Rm, Rn); break;\r
2070 case 12: EXTUB(sh2, Rm, Rn); break;\r
2071 case 13: EXTUW(sh2, Rm, Rn); break;\r
2072 case 14: EXTSB(sh2, Rm, Rn); break;\r
2073 case 15: EXTSW(sh2, Rm, Rn); break;\r
2074 }\r
2075 rlog(LRNM);\r
2076}\r
2077\r
2078INLINE void op0111(sh2_state *sh2, UINT16 opcode)\r
2079{\r
2080 ADDI(sh2, opcode & 0xff, Rn);\r
2081 rlog(LRN);\r
2082}\r
2083\r
2084INLINE void op1000(sh2_state *sh2, UINT16 opcode)\r
2085{\r
2086 switch ( opcode & (15<<8) )\r
2087 {\r
2088 case 0<< 8: MOVBS4(sh2, opcode & 0x0f, Rm); rlog(LRM); rlog1(0); break;\r
2089 case 1<< 8: MOVWS4(sh2, opcode & 0x0f, Rm); rlog(LRM); rlog1(0); break;\r
2090 case 2<< 8: ILLEGAL(sh2); rlog(0); break;\r
2091 case 3<< 8: ILLEGAL(sh2); rlog(0); break;\r
2092 case 4<< 8: MOVBL4(sh2, Rm, opcode & 0x0f); rlog(LRM); rlog1(0); break;\r
2093 case 5<< 8: MOVWL4(sh2, Rm, opcode & 0x0f); rlog(LRM); rlog1(0); break;\r
2094 case 6<< 8: ILLEGAL(sh2); rlog(0); break;\r
2095 case 7<< 8: ILLEGAL(sh2); rlog(0); break;\r
2096 case 8<< 8: CMPIM(sh2, opcode & 0xff); rlog(0); rlog1(0); break;\r
2097 case 9<< 8: BT(sh2, opcode & 0xff); rlog(0); break;\r
2098 case 10<< 8: ILLEGAL(sh2); rlog(0); break;\r
2099 case 11<< 8: BF(sh2, opcode & 0xff); rlog(0); break;\r
2100 case 12<< 8: ILLEGAL(sh2); rlog(0); break;\r
2101 case 13<< 8: BTS(sh2, opcode & 0xff); rlog(0); break;\r
2102 case 14<< 8: ILLEGAL(sh2); rlog(0); break;\r
2103 case 15<< 8: BFS(sh2, opcode & 0xff); rlog(0); break;\r
2104 }\r
2105}\r
2106\r
2107\r
2108INLINE void op1001(sh2_state *sh2, UINT16 opcode)\r
2109{\r
2110 MOVWI(sh2, opcode & 0xff, Rn);\r
2111 rlog(LRN);\r
2112}\r
2113\r
2114INLINE void op1010(sh2_state *sh2, UINT16 opcode)\r
2115{\r
2116 BRA(sh2, opcode & 0xfff);\r
2117 rlog(0);\r
2118}\r
2119\r
2120INLINE void op1011(sh2_state *sh2, UINT16 opcode)\r
2121{\r
2122 BSR(sh2, opcode & 0xfff);\r
2123 rlog(0);\r
2124 rlog1(SHR_PR);\r
2125}\r
2126\r
2127INLINE void op1100(sh2_state *sh2, UINT16 opcode)\r
2128{\r
2129 switch (opcode & (15<<8))\r
2130 {\r
2131 case 0<<8: MOVBSG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;\r
2132 case 1<<8: MOVWSG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;\r
2133 case 2<<8: MOVLSG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;\r
2134 case 3<<8: TRAPA(sh2, opcode & 0xff); rlog1(SHR_VBR); break;\r
2135 case 4<<8: MOVBLG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;\r
2136 case 5<<8: MOVWLG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;\r
2137 case 6<<8: MOVLLG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;\r
2138 case 7<<8: MOVA(sh2, opcode & 0xff); rlog1(0); break;\r
2139 case 8<<8: TSTI(sh2, opcode & 0xff); rlog1(0); break;\r
2140 case 9<<8: ANDI(sh2, opcode & 0xff); rlog1(0); break;\r
2141 case 10<<8: XORI(sh2, opcode & 0xff); rlog1(0); break;\r
2142 case 11<<8: ORI(sh2, opcode & 0xff); rlog1(0); break;\r
2143 case 12<<8: TSTM(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;\r
2144 case 13<<8: ANDM(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;\r
2145 case 14<<8: XORM(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;\r
2146 case 15<<8: ORM(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;\r
2147 }\r
2148 rlog(0);\r
2149}\r
2150\r
2151INLINE void op1101(sh2_state *sh2, UINT16 opcode)\r
2152{\r
2153 MOVLI(sh2, opcode & 0xff, Rn);\r
2154 rlog(LRN);\r
2155}\r
2156\r
2157INLINE void op1110(sh2_state *sh2, UINT16 opcode)\r
2158{\r
2159 MOVI(sh2, opcode & 0xff, Rn);\r
2160 rlog(LRN);\r
2161}\r
2162\r
2163INLINE void op1111(sh2_state *sh2, UINT16 opcode)\r
2164{\r
2165 ILLEGAL(sh2);\r
2166 rlog(0);\r
2167}\r
2168\r
2169#endif\r