1 /*****************************************************************************
\r
4 * Portable Hitachi SH-2 (SH7600 family) emulator
\r
6 * Copyright Juergen Buchmueller <pullmoll@t-online.de>,
\r
7 * all rights reserved.
\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
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
26 *****************************************************************************/
\r
28 /*****************************************************************************
\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
36 20051129 Mariusz Wojcieszek
\r
37 - introduced memory_decrypted_read_word() for opcode fetching
\r
39 20050813 Mariusz Wojcieszek
\r
40 - fixed 64 bit / 32 bit division in division unit
\r
42 20031015 O. Galibert
\r
43 - dma fixes, thanks to sthief
\r
45 20031013 O. Galibert, A. Giles
\r
47 - multi-cpu simplifications
\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
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
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
70 20020302 Olivier Galibert (galibert@mame.net)
\r
71 - Fixed interrupt in delay slot
\r
78 - Fixed external division
\r
80 20020225 Olivier Galibert (galibert@mame.net)
\r
81 - Fixed interrupt handling
\r
83 20010207 Sylvain Glaize (mokona@puupuu.org)
\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
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
95 20010623 James Forshaw (TyRaNiD@totalise.net)
\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
100 20010701 James Forshaw (TyRaNiD@totalise.net)
\r
102 - Fixed DIV1 operation. Q bit now correctly generated
\r
104 20020218 Added save states (mokona@puupuu.org)
\r
106 *****************************************************************************/
\r
108 //#include "debugger.h"
\r
110 //#include "sh2comn.h"
\r
111 #define INLINE static
\r
113 //CPU_DISASSEMBLE( sh2 );
\r
117 /* speed up delay loops, bail out of tight loops */
\r
118 //#define BUSY_LOOP_HACKS 1
\r
122 #define LOG(x) do { if (VERBOSE) logerror x; } while (0)
\r
125 INLINE UINT8 RB(sh2_state *sh2, offs_t A)
\r
127 if (A >= 0xe0000000)
\r
128 return sh2_internal_r(*sh2->internal, (A & 0x1fc)>>2, 0xff << (((~A) & 3)*8)) >> (((~A) & 3)*8);
\r
130 if (A >= 0xc0000000)
\r
131 return sh2->program->read_byte(A);
\r
133 if (A >= 0x40000000)
\r
136 return sh2->program->read_byte(A & AM);
\r
139 INLINE UINT16 RW(sh2_state *sh2, offs_t A)
\r
141 if (A >= 0xe0000000)
\r
142 return sh2_internal_r(*sh2->internal, (A & 0x1fc)>>2, 0xffff << (((~A) & 2)*8)) >> (((~A) & 2)*8);
\r
144 if (A >= 0xc0000000)
\r
145 return sh2->program->read_word(A);
\r
147 if (A >= 0x40000000)
\r
150 return sh2->program->read_word(A & AM);
\r
153 INLINE UINT32 RL(sh2_state *sh2, offs_t A)
\r
155 if (A >= 0xe0000000)
\r
156 return sh2_internal_r(*sh2->internal, (A & 0x1fc)>>2, 0xffffffff);
\r
158 if (A >= 0xc0000000)
\r
159 return sh2->program->read_dword(A);
\r
161 if (A >= 0x40000000)
\r
164 return sh2->program->read_dword(A & AM);
\r
167 INLINE void WB(sh2_state *sh2, offs_t A, UINT8 V)
\r
169 if (A >= 0xe0000000)
\r
171 sh2_internal_w(*sh2->internal, (A & 0x1fc)>>2, V << (((~A) & 3)*8), 0xff << (((~A) & 3)*8));
\r
175 if (A >= 0xc0000000)
\r
177 sh2->program->write_byte(A,V);
\r
181 if (A >= 0x40000000)
\r
184 sh2->program->write_byte(A & AM,V);
\r
187 INLINE void WW(sh2_state *sh2, offs_t A, UINT16 V)
\r
189 if (A >= 0xe0000000)
\r
191 sh2_internal_w(*sh2->internal, (A & 0x1fc)>>2, V << (((~A) & 2)*8), 0xffff << (((~A) & 2)*8));
\r
195 if (A >= 0xc0000000)
\r
197 sh2->program->write_word(A,V);
\r
201 if (A >= 0x40000000)
\r
204 sh2->program->write_word(A & AM,V);
\r
207 INLINE void WL(sh2_state *sh2, offs_t A, UINT32 V)
\r
209 if (A >= 0xe0000000)
\r
211 sh2_internal_w(*sh2->internal, (A & 0x1fc)>>2, V, 0xffffffff);
\r
215 if (A >= 0xc0000000)
\r
217 sh2->program->write_dword(A,V);
\r
221 if (A >= 0x40000000)
\r
224 sh2->program->write_dword(A & AM,V);
\r
228 /* code cycles t-bit
\r
229 * 0011 nnnn mmmm 1100 1 -
\r
232 INLINE void ADD(sh2_state *sh2, UINT32 m, UINT32 n)
\r
234 sh2->r[n] += sh2->r[m];
\r
237 /* code cycles t-bit
\r
238 * 0111 nnnn iiii iiii 1 -
\r
241 INLINE void ADDI(sh2_state *sh2, UINT32 i, UINT32 n)
\r
243 sh2->r[n] += (INT32)(INT16)(INT8)i;
\r
246 /* code cycles t-bit
\r
247 * 0011 nnnn mmmm 1110 1 carry
\r
250 INLINE void ADDC(sh2_state *sh2, UINT32 m, UINT32 n)
\r
254 tmp1 = sh2->r[n] + sh2->r[m];
\r
256 sh2->r[n] = tmp1 + (sh2->sr & T);
\r
261 if (tmp1 > sh2->r[n])
\r
265 /* code cycles t-bit
\r
266 * 0011 nnnn mmmm 1111 1 overflow
\r
269 INLINE void ADDV(sh2_state *sh2, UINT32 m, UINT32 n)
\r
271 INT32 dest, src, ans;
\r
273 if ((INT32) sh2->r[n] >= 0)
\r
277 if ((INT32) sh2->r[m] >= 0)
\r
282 sh2->r[n] += sh2->r[m];
\r
283 if ((INT32) sh2->r[n] >= 0)
\r
288 if (src == 0 || src == 2)
\r
299 /* code cycles t-bit
\r
300 * 0010 nnnn mmmm 1001 1 -
\r
303 INLINE void AND(sh2_state *sh2, UINT32 m, UINT32 n)
\r
305 sh2->r[n] &= sh2->r[m];
\r
309 /* code cycles t-bit
\r
310 * 1100 1001 iiii iiii 1 -
\r
313 INLINE void ANDI(sh2_state *sh2, UINT32 i)
\r
318 /* code cycles t-bit
\r
319 * 1100 1101 iiii iiii 1 -
\r
320 * AND.B #imm,@(R0,GBR)
\r
322 INLINE void ANDM(sh2_state *sh2, UINT32 i)
\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
332 /* code cycles t-bit
\r
333 * 1000 1011 dddd dddd 3/1 -
\r
336 INLINE void BF(sh2_state *sh2, UINT32 d)
\r
338 if ((sh2->sr & T) == 0)
\r
340 INT32 disp = ((INT32)d << 24) >> 24;
\r
341 sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;
\r
346 /* code cycles t-bit
\r
347 * 1000 1111 dddd dddd 3/1 -
\r
350 INLINE void BFS(sh2_state *sh2, UINT32 d)
\r
352 sh2->delay = sh2->pc;
\r
355 if ((sh2->sr & T) == 0)
\r
357 INT32 disp = ((INT32)d << 24) >> 24;
\r
358 sh2->pc = sh2->ea = sh2->pc + disp * 2;
\r
363 /* code cycles t-bit
\r
364 * 1010 dddd dddd dddd 2 -
\r
367 INLINE void BRA(sh2_state *sh2, UINT32 d)
\r
369 INT32 disp = ((INT32)d << 20) >> 20;
\r
371 #if BUSY_LOOP_HACKS
\r
374 UINT32 next_opcode = RW( sh2, sh2->ppc & AM );
\r
378 if (next_opcode == 0x0009)
\r
379 sh2->icount %= 3; /* cycles for BRA $ and NOP taken (3) */
\r
382 sh2->delay = sh2->pc;
\r
383 sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;
\r
387 /* code cycles t-bit
\r
388 * 0000 mmmm 0010 0011 2 -
\r
391 INLINE void BRAF(sh2_state *sh2, UINT32 m)
\r
393 sh2->delay = sh2->pc;
\r
394 sh2->pc += sh2->r[m] + 2;
\r
398 /* code cycles t-bit
\r
399 * 1011 dddd dddd dddd 2 -
\r
402 INLINE void BSR(sh2_state *sh2, UINT32 d)
\r
404 INT32 disp = ((INT32)d << 20) >> 20;
\r
406 sh2->pr = sh2->pc + 2;
\r
407 sh2->delay = sh2->pc;
\r
408 sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;
\r
412 /* code cycles t-bit
\r
413 * 0000 mmmm 0000 0011 2 -
\r
416 INLINE void BSRF(sh2_state *sh2, UINT32 m)
\r
418 sh2->pr = sh2->pc + 2;
\r
419 sh2->delay = sh2->pc;
\r
420 sh2->pc += sh2->r[m] + 2;
\r
424 /* code cycles t-bit
\r
425 * 1000 1001 dddd dddd 3/1 -
\r
428 INLINE void BT(sh2_state *sh2, UINT32 d)
\r
430 if ((sh2->sr & T) != 0)
\r
432 INT32 disp = ((INT32)d << 24) >> 24;
\r
433 sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;
\r
438 /* code cycles t-bit
\r
439 * 1000 1101 dddd dddd 2/1 -
\r
442 INLINE void BTS(sh2_state *sh2, UINT32 d)
\r
444 sh2->delay = sh2->pc;
\r
447 if ((sh2->sr & T) != 0)
\r
449 INT32 disp = ((INT32)d << 24) >> 24;
\r
450 sh2->pc = sh2->ea = sh2->pc + disp * 2;
\r
455 /* code cycles t-bit
\r
456 * 0000 0000 0010 1000 1 -
\r
459 INLINE void CLRMAC(sh2_state *sh2)
\r
465 /* code cycles t-bit
\r
466 * 0000 0000 0000 1000 1 -
\r
469 INLINE void CLRT(sh2_state *sh2)
\r
474 /* code cycles t-bit
\r
475 * 0011 nnnn mmmm 0000 1 comparison result
\r
478 INLINE void CMPEQ(sh2_state *sh2, UINT32 m, UINT32 n)
\r
480 if (sh2->r[n] == sh2->r[m])
\r
486 /* code cycles t-bit
\r
487 * 0011 nnnn mmmm 0011 1 comparison result
\r
490 INLINE void CMPGE(sh2_state *sh2, UINT32 m, UINT32 n)
\r
492 if ((INT32) sh2->r[n] >= (INT32) sh2->r[m])
\r
498 /* code cycles t-bit
\r
499 * 0011 nnnn mmmm 0111 1 comparison result
\r
502 INLINE void CMPGT(sh2_state *sh2, UINT32 m, UINT32 n)
\r
504 if ((INT32) sh2->r[n] > (INT32) sh2->r[m])
\r
510 /* code cycles t-bit
\r
511 * 0011 nnnn mmmm 0110 1 comparison result
\r
514 INLINE void CMPHI(sh2_state *sh2, UINT32 m, UINT32 n)
\r
516 if ((UINT32) sh2->r[n] > (UINT32) sh2->r[m])
\r
522 /* code cycles t-bit
\r
523 * 0011 nnnn mmmm 0010 1 comparison result
\r
526 INLINE void CMPHS(sh2_state *sh2, UINT32 m, UINT32 n)
\r
528 if ((UINT32) sh2->r[n] >= (UINT32) sh2->r[m])
\r
535 /* code cycles t-bit
\r
536 * 0100 nnnn 0001 0101 1 comparison result
\r
539 INLINE void CMPPL(sh2_state *sh2, UINT32 n)
\r
541 if ((INT32) sh2->r[n] > 0)
\r
547 /* code cycles t-bit
\r
548 * 0100 nnnn 0001 0001 1 comparison result
\r
551 INLINE void CMPPZ(sh2_state *sh2, UINT32 n)
\r
553 if ((INT32) sh2->r[n] >= 0)
\r
559 /* code cycles t-bit
\r
560 * 0010 nnnn mmmm 1100 1 comparison result
\r
563 INLINE void CMPSTR(sh2_state *sh2, UINT32 m, UINT32 n)
\r
566 INT32 HH, HL, LH, LL;
\r
567 temp = sh2->r[n] ^ sh2->r[m];
\r
568 HH = (temp >> 24) & 0xff;
\r
569 HL = (temp >> 16) & 0xff;
\r
570 LH = (temp >> 8) & 0xff;
\r
572 if (HH && HL && LH && LL)
\r
579 /* code cycles t-bit
\r
580 * 1000 1000 iiii iiii 1 comparison result
\r
583 INLINE void CMPIM(sh2_state *sh2, UINT32 i)
\r
585 UINT32 imm = (UINT32)(INT32)(INT16)(INT8)i;
\r
587 if (sh2->r[0] == imm)
\r
593 /* code cycles t-bit
\r
594 * 0010 nnnn mmmm 0111 1 calculation result
\r
597 INLINE void DIV0S(sh2_state *sh2, UINT32 m, UINT32 n)
\r
599 if ((sh2->r[n] & 0x80000000) == 0)
\r
603 if ((sh2->r[m] & 0x80000000) == 0)
\r
607 if ((sh2->r[m] ^ sh2->r[n]) & 0x80000000)
\r
613 /* code cycles t-bit
\r
614 * 0000 0000 0001 1001 1 0
\r
617 INLINE void DIV0U(sh2_state *sh2)
\r
619 sh2->sr &= ~(M | Q | T);
\r
622 /* code cycles t-bit
\r
623 * 0011 nnnn mmmm 0100 1 calculation result
\r
626 INLINE void DIV1(sh2_state *sh2, UINT32 m, UINT32 n)
\r
631 old_q = sh2->sr & Q;
\r
632 if (0x80000000 & sh2->r[n])
\r
637 sh2->r[n] = (sh2->r[n] << 1) | (sh2->sr & T);
\r
641 if (!(sh2->sr & M))
\r
644 sh2->r[n] -= sh2->r[m];
\r
646 if(sh2->r[n] > tmp0)
\r
651 if(sh2->r[n] > tmp0)
\r
659 sh2->r[n] += sh2->r[m];
\r
662 if(sh2->r[n] < tmp0)
\r
669 if(sh2->r[n] < tmp0)
\r
678 if (!(sh2->sr & M))
\r
681 sh2->r[n] += sh2->r[m];
\r
683 if(sh2->r[n] < tmp0)
\r
688 if(sh2->r[n] < tmp0)
\r
696 sh2->r[n] -= sh2->r[m];
\r
698 if(sh2->r[n] > tmp0)
\r
703 if(sh2->r[n] > tmp0)
\r
710 tmp0 = (sh2->sr & (Q | M));
\r
711 if((!tmp0) || (tmp0 == 0x300)) /* if Q == M set T else clear T */
\r
717 /* DMULS.L Rm,Rn */
\r
718 INLINE void DMULS(sh2_state *sh2, UINT32 m, UINT32 n)
\r
720 UINT32 RnL, RnH, RmL, RmH, Res0, Res1, Res2;
\r
721 UINT32 temp0, temp1, temp2, temp3;
\r
722 INT32 tempm, tempn, fnLmL;
\r
724 tempn = (INT32) sh2->r[n];
\r
725 tempm = (INT32) sh2->r[m];
\r
730 if ((INT32) (sh2->r[n] ^ sh2->r[m]) < 0)
\r
734 temp1 = (UINT32) tempn;
\r
735 temp2 = (UINT32) tempm;
\r
736 RnL = temp1 & 0x0000ffff;
\r
737 RnH = (temp1 >> 16) & 0x0000ffff;
\r
738 RmL = temp2 & 0x0000ffff;
\r
739 RmH = (temp2 >> 16) & 0x0000ffff;
\r
745 Res1 = temp1 + temp2;
\r
747 Res2 += 0x00010000;
\r
748 temp1 = (Res1 << 16) & 0xffff0000;
\r
749 Res0 = temp0 + temp1;
\r
752 Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;
\r
759 Res0 = (~Res0) + 1;
\r
766 /* DMULU.L Rm,Rn */
\r
767 INLINE void DMULU(sh2_state *sh2, UINT32 m, UINT32 n)
\r
769 UINT32 RnL, RnH, RmL, RmH, Res0, Res1, Res2;
\r
770 UINT32 temp0, temp1, temp2, temp3;
\r
772 RnL = sh2->r[n] & 0x0000ffff;
\r
773 RnH = (sh2->r[n] >> 16) & 0x0000ffff;
\r
774 RmL = sh2->r[m] & 0x0000ffff;
\r
775 RmH = (sh2->r[m] >> 16) & 0x0000ffff;
\r
781 Res1 = temp1 + temp2;
\r
783 Res2 += 0x00010000;
\r
784 temp1 = (Res1 << 16) & 0xffff0000;
\r
785 Res0 = temp0 + temp1;
\r
788 Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;
\r
795 INLINE void DT(sh2_state *sh2, UINT32 n)
\r
798 if (sh2->r[n] == 0)
\r
802 #if BUSY_LOOP_HACKS
\r
804 UINT32 next_opcode = RW( sh2, sh2->ppc & AM );
\r
808 if (next_opcode == 0x8bfd)
\r
810 while (sh2->r[n] > 1 && sh2->icount > 4)
\r
813 sh2->icount -= 4; /* cycles for DT (1) and BF taken (3) */
\r
821 INLINE void EXTSB(sh2_state *sh2, UINT32 m, UINT32 n)
\r
823 sh2->r[n] = ((INT32)sh2->r[m] << 24) >> 24;
\r
827 INLINE void EXTSW(sh2_state *sh2, UINT32 m, UINT32 n)
\r
829 sh2->r[n] = ((INT32)sh2->r[m] << 16) >> 16;
\r
833 INLINE void EXTUB(sh2_state *sh2, UINT32 m, UINT32 n)
\r
835 sh2->r[n] = sh2->r[m] & 0x000000ff;
\r
839 INLINE void EXTUW(sh2_state *sh2, UINT32 m, UINT32 n)
\r
841 sh2->r[n] = sh2->r[m] & 0x0000ffff;
\r
845 INLINE void ILLEGAL(sh2_state *sh2)
\r
847 logerror("SH2: Illegal opcode at %08x\n", sh2->pc - 2);
\r
849 WL( sh2, sh2->r[15], sh2->sr ); /* push SR onto stack */
\r
851 WL( sh2, sh2->r[15], sh2->pc - 2 ); /* push PC onto stack */
\r
854 sh2->pc = RL( sh2, sh2->vbr + 4 * 4 );
\r
856 /* TODO: timing is a guess */
\r
862 INLINE void JMP(sh2_state *sh2, UINT32 m)
\r
864 sh2->delay = sh2->pc;
\r
865 sh2->pc = sh2->ea = sh2->r[m];
\r
870 INLINE void JSR(sh2_state *sh2, UINT32 m)
\r
872 sh2->delay = sh2->pc;
\r
873 sh2->pr = sh2->pc + 2;
\r
874 sh2->pc = sh2->ea = sh2->r[m];
\r
880 INLINE void LDCSR(sh2_state *sh2, UINT32 m)
\r
882 sh2->sr = sh2->r[m] & FLAGS;
\r
887 INLINE void LDCGBR(sh2_state *sh2, UINT32 m)
\r
889 sh2->gbr = sh2->r[m];
\r
893 INLINE void LDCVBR(sh2_state *sh2, UINT32 m)
\r
895 sh2->vbr = sh2->r[m];
\r
898 /* LDC.L @Rm+,SR */
\r
899 INLINE void LDCMSR(sh2_state *sh2, UINT32 m)
\r
901 sh2->ea = sh2->r[m];
\r
902 sh2->sr = RL( sh2, sh2->ea ) & FLAGS;
\r
908 /* LDC.L @Rm+,GBR */
\r
909 INLINE void LDCMGBR(sh2_state *sh2, UINT32 m)
\r
911 sh2->ea = sh2->r[m];
\r
912 sh2->gbr = RL( sh2, sh2->ea );
\r
917 /* LDC.L @Rm+,VBR */
\r
918 INLINE void LDCMVBR(sh2_state *sh2, UINT32 m)
\r
920 sh2->ea = sh2->r[m];
\r
921 sh2->vbr = RL( sh2, sh2->ea );
\r
927 INLINE void LDSMACH(sh2_state *sh2, UINT32 m)
\r
929 sh2->mach = sh2->r[m];
\r
933 INLINE void LDSMACL(sh2_state *sh2, UINT32 m)
\r
935 sh2->macl = sh2->r[m];
\r
939 INLINE void LDSPR(sh2_state *sh2, UINT32 m)
\r
941 sh2->pr = sh2->r[m];
\r
944 /* LDS.L @Rm+,MACH */
\r
945 INLINE void LDSMMACH(sh2_state *sh2, UINT32 m)
\r
947 sh2->ea = sh2->r[m];
\r
948 sh2->mach = RL( sh2, sh2->ea );
\r
952 /* LDS.L @Rm+,MACL */
\r
953 INLINE void LDSMMACL(sh2_state *sh2, UINT32 m)
\r
955 sh2->ea = sh2->r[m];
\r
956 sh2->macl = RL( sh2, sh2->ea );
\r
960 /* LDS.L @Rm+,PR */
\r
961 INLINE void LDSMPR(sh2_state *sh2, UINT32 m)
\r
963 sh2->ea = sh2->r[m];
\r
964 sh2->pr = RL( sh2, sh2->ea );
\r
968 /* MAC.L @Rm+,@Rn+ */
\r
969 INLINE void MAC_L(sh2_state *sh2, UINT32 m, UINT32 n)
\r
971 UINT32 RnL, RnH, RmL, RmH, Res0, Res1, Res2;
\r
972 UINT32 temp0, temp1, temp2, temp3;
\r
973 INT32 tempm, tempn, fnLmL;
\r
975 tempn = (INT32) RL( sh2, sh2->r[n] );
\r
977 tempm = (INT32) RL( sh2, sh2->r[m] );
\r
979 if ((INT32) (tempn ^ tempm) < 0)
\r
987 temp1 = (UINT32) tempn;
\r
988 temp2 = (UINT32) tempm;
\r
989 RnL = temp1 & 0x0000ffff;
\r
990 RnH = (temp1 >> 16) & 0x0000ffff;
\r
991 RmL = temp2 & 0x0000ffff;
\r
992 RmH = (temp2 >> 16) & 0x0000ffff;
\r
998 Res1 = temp1 + temp2;
\r
1000 Res2 += 0x00010000;
\r
1001 temp1 = (Res1 << 16) & 0xffff0000;
\r
1002 Res0 = temp0 + temp1;
\r
1005 Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;
\r
1012 Res0 = (~Res0) + 1;
\r
1016 Res0 = sh2->macl + Res0;
\r
1017 if (sh2->macl > Res0)
\r
1019 Res2 += (sh2->mach & 0x0000ffff);
\r
1020 if (((INT32) Res2 < 0) && (Res2 < 0xffff8000))
\r
1022 Res2 = 0x00008000;
\r
1023 Res0 = 0x00000000;
\r
1025 else if (((INT32) Res2 > 0) && (Res2 > 0x00007fff))
\r
1027 Res2 = 0x00007fff;
\r
1028 Res0 = 0xffffffff;
\r
1035 Res0 = sh2->macl + Res0;
\r
1036 if (sh2->macl > Res0)
\r
1038 Res2 += sh2->mach;
\r
1045 /* MAC.W @Rm+,@Rn+ */
\r
1046 INLINE void MAC_W(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1048 INT32 tempm, tempn, dest, src, ans;
\r
1051 tempn = (INT32) RW( sh2, sh2->r[n] );
\r
1053 tempm = (INT32) RW( sh2, sh2->r[m] );
\r
1055 templ = sh2->macl;
\r
1056 tempm = ((INT32) (short) tempn * (INT32) (short) tempm);
\r
1057 if ((INT32) sh2->macl >= 0)
\r
1061 if ((INT32) tempm >= 0)
\r
1069 tempn = 0xffffffff;
\r
1072 sh2->macl += tempm;
\r
1073 if ((INT32) sh2->macl >= 0)
\r
1083 sh2->macl = 0x7fffffff;
\r
1085 sh2->macl = 0x80000000;
\r
1090 sh2->mach += tempn;
\r
1091 if (templ > sh2->macl)
\r
1098 INLINE void MOV(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1100 sh2->r[n] = sh2->r[m];
\r
1103 /* MOV.B Rm,@Rn */
\r
1104 INLINE void MOVBS(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1106 sh2->ea = sh2->r[n];
\r
1107 WB( sh2, sh2->ea, sh2->r[m] & 0x000000ff);
\r
1110 /* MOV.W Rm,@Rn */
\r
1111 INLINE void MOVWS(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1113 sh2->ea = sh2->r[n];
\r
1114 WW( sh2, sh2->ea, sh2->r[m] & 0x0000ffff);
\r
1117 /* MOV.L Rm,@Rn */
\r
1118 INLINE void MOVLS(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1120 sh2->ea = sh2->r[n];
\r
1121 WL( sh2, sh2->ea, sh2->r[m] );
\r
1124 /* MOV.B @Rm,Rn */
\r
1125 INLINE void MOVBL(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1127 sh2->ea = sh2->r[m];
\r
1128 sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->ea );
\r
1131 /* MOV.W @Rm,Rn */
\r
1132 INLINE void MOVWL(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1134 sh2->ea = sh2->r[m];
\r
1135 sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2, sh2->ea );
\r
1138 /* MOV.L @Rm,Rn */
\r
1139 INLINE void MOVLL(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1141 sh2->ea = sh2->r[m];
\r
1142 sh2->r[n] = RL( sh2, sh2->ea );
\r
1145 /* MOV.B Rm,@-Rn */
\r
1146 INLINE void MOVBM(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1148 /* SMG : bug fix, was reading sh2->r[n] */
\r
1149 UINT32 data = sh2->r[m] & 0x000000ff;
\r
1152 WB( sh2, sh2->r[n], data );
\r
1155 /* MOV.W Rm,@-Rn */
\r
1156 INLINE void MOVWM(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1158 UINT32 data = sh2->r[m] & 0x0000ffff;
\r
1161 WW( sh2, sh2->r[n], data );
\r
1164 /* MOV.L Rm,@-Rn */
\r
1165 INLINE void MOVLM(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1167 UINT32 data = sh2->r[m];
\r
1170 WL( sh2, sh2->r[n], data );
\r
1173 /* MOV.B @Rm+,Rn */
\r
1174 INLINE void MOVBP(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1176 sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->r[m] );
\r
1181 /* MOV.W @Rm+,Rn */
\r
1182 INLINE void MOVWP(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1184 sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2, sh2->r[m] );
\r
1189 /* MOV.L @Rm+,Rn */
\r
1190 INLINE void MOVLP(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1192 sh2->r[n] = RL( sh2, sh2->r[m] );
\r
1197 /* MOV.B Rm,@(R0,Rn) */
\r
1198 INLINE void MOVBS0(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1200 sh2->ea = sh2->r[n] + sh2->r[0];
\r
1201 WB( sh2, sh2->ea, sh2->r[m] & 0x000000ff );
\r
1204 /* MOV.W Rm,@(R0,Rn) */
\r
1205 INLINE void MOVWS0(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1207 sh2->ea = sh2->r[n] + sh2->r[0];
\r
1208 WW( sh2, sh2->ea, sh2->r[m] & 0x0000ffff );
\r
1211 /* MOV.L Rm,@(R0,Rn) */
\r
1212 INLINE void MOVLS0(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1214 sh2->ea = sh2->r[n] + sh2->r[0];
\r
1215 WL( sh2, sh2->ea, sh2->r[m] );
\r
1218 /* MOV.B @(R0,Rm),Rn */
\r
1219 INLINE void MOVBL0(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1221 sh2->ea = sh2->r[m] + sh2->r[0];
\r
1222 sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->ea );
\r
1225 /* MOV.W @(R0,Rm),Rn */
\r
1226 INLINE void MOVWL0(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1228 sh2->ea = sh2->r[m] + sh2->r[0];
\r
1229 sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2, sh2->ea );
\r
1232 /* MOV.L @(R0,Rm),Rn */
\r
1233 INLINE void MOVLL0(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1235 sh2->ea = sh2->r[m] + sh2->r[0];
\r
1236 sh2->r[n] = RL( sh2, sh2->ea );
\r
1240 INLINE void MOVI(sh2_state *sh2, UINT32 i, UINT32 n)
\r
1242 sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) i;
\r
1245 /* MOV.W @(disp8,PC),Rn */
\r
1246 INLINE void MOVWI(sh2_state *sh2, UINT32 d, UINT32 n)
\r
1248 UINT32 disp = d & 0xff;
\r
1249 sh2->ea = sh2->pc + disp * 2 + 2;
\r
1250 sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2, sh2->ea );
\r
1253 /* MOV.L @(disp8,PC),Rn */
\r
1254 INLINE void MOVLI(sh2_state *sh2, UINT32 d, UINT32 n)
\r
1256 UINT32 disp = d & 0xff;
\r
1257 sh2->ea = ((sh2->pc + 2) & ~3) + disp * 4;
\r
1258 sh2->r[n] = RL( sh2, sh2->ea );
\r
1261 /* MOV.B @(disp8,GBR),R0 */
\r
1262 INLINE void MOVBLG(sh2_state *sh2, UINT32 d)
\r
1264 UINT32 disp = d & 0xff;
\r
1265 sh2->ea = sh2->gbr + disp;
\r
1266 sh2->r[0] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->ea );
\r
1269 /* MOV.W @(disp8,GBR),R0 */
\r
1270 INLINE void MOVWLG(sh2_state *sh2, UINT32 d)
\r
1272 UINT32 disp = d & 0xff;
\r
1273 sh2->ea = sh2->gbr + disp * 2;
\r
1274 sh2->r[0] = (INT32)(INT16) RW( sh2, sh2->ea );
\r
1277 /* MOV.L @(disp8,GBR),R0 */
\r
1278 INLINE void MOVLLG(sh2_state *sh2, UINT32 d)
\r
1280 UINT32 disp = d & 0xff;
\r
1281 sh2->ea = sh2->gbr + disp * 4;
\r
1282 sh2->r[0] = RL( sh2, sh2->ea );
\r
1285 /* MOV.B R0,@(disp8,GBR) */
\r
1286 INLINE void MOVBSG(sh2_state *sh2, UINT32 d)
\r
1288 UINT32 disp = d & 0xff;
\r
1289 sh2->ea = sh2->gbr + disp;
\r
1290 WB( sh2, sh2->ea, sh2->r[0] & 0x000000ff );
\r
1293 /* MOV.W R0,@(disp8,GBR) */
\r
1294 INLINE void MOVWSG(sh2_state *sh2, UINT32 d)
\r
1296 UINT32 disp = d & 0xff;
\r
1297 sh2->ea = sh2->gbr + disp * 2;
\r
1298 WW( sh2, sh2->ea, sh2->r[0] & 0x0000ffff );
\r
1301 /* MOV.L R0,@(disp8,GBR) */
\r
1302 INLINE void MOVLSG(sh2_state *sh2, UINT32 d)
\r
1304 UINT32 disp = d & 0xff;
\r
1305 sh2->ea = sh2->gbr + disp * 4;
\r
1306 WL( sh2, sh2->ea, sh2->r[0] );
\r
1309 /* MOV.B R0,@(disp4,Rn) */
\r
1310 INLINE void MOVBS4(sh2_state *sh2, UINT32 d, UINT32 n)
\r
1312 UINT32 disp = d & 0x0f;
\r
1313 sh2->ea = sh2->r[n] + disp;
\r
1314 WB( sh2, sh2->ea, sh2->r[0] & 0x000000ff );
\r
1317 /* MOV.W R0,@(disp4,Rn) */
\r
1318 INLINE void MOVWS4(sh2_state *sh2, UINT32 d, UINT32 n)
\r
1320 UINT32 disp = d & 0x0f;
\r
1321 sh2->ea = sh2->r[n] + disp * 2;
\r
1322 WW( sh2, sh2->ea, sh2->r[0] & 0x0000ffff );
\r
1325 /* MOV.L Rm,@(disp4,Rn) */
\r
1326 INLINE void MOVLS4(sh2_state *sh2, UINT32 m, UINT32 d, UINT32 n)
\r
1328 UINT32 disp = d & 0x0f;
\r
1329 sh2->ea = sh2->r[n] + disp * 4;
\r
1330 WL( sh2, sh2->ea, sh2->r[m] );
\r
1333 /* MOV.B @(disp4,Rm),R0 */
\r
1334 INLINE void MOVBL4(sh2_state *sh2, UINT32 m, UINT32 d)
\r
1336 UINT32 disp = d & 0x0f;
\r
1337 sh2->ea = sh2->r[m] + disp;
\r
1338 sh2->r[0] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->ea );
\r
1341 /* MOV.W @(disp4,Rm),R0 */
\r
1342 INLINE void MOVWL4(sh2_state *sh2, UINT32 m, UINT32 d)
\r
1344 UINT32 disp = d & 0x0f;
\r
1345 sh2->ea = sh2->r[m] + disp * 2;
\r
1346 sh2->r[0] = (UINT32)(INT32)(INT16) RW( sh2, sh2->ea );
\r
1349 /* MOV.L @(disp4,Rm),Rn */
\r
1350 INLINE void MOVLL4(sh2_state *sh2, UINT32 m, UINT32 d, UINT32 n)
\r
1352 UINT32 disp = d & 0x0f;
\r
1353 sh2->ea = sh2->r[m] + disp * 4;
\r
1354 sh2->r[n] = RL( sh2, sh2->ea );
\r
1357 /* MOVA @(disp8,PC),R0 */
\r
1358 INLINE void MOVA(sh2_state *sh2, UINT32 d)
\r
1360 UINT32 disp = d & 0xff;
\r
1361 sh2->ea = ((sh2->pc + 2) & ~3) + disp * 4;
\r
1362 sh2->r[0] = sh2->ea;
\r
1366 INLINE void MOVT(sh2_state *sh2, UINT32 n)
\r
1368 sh2->r[n] = sh2->sr & T;
\r
1372 INLINE void MULL(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1374 sh2->macl = sh2->r[n] * sh2->r[m];
\r
1379 INLINE void MULS(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1381 sh2->macl = (INT16) sh2->r[n] * (INT16) sh2->r[m];
\r
1385 INLINE void MULU(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1387 sh2->macl = (UINT16) sh2->r[n] * (UINT16) sh2->r[m];
\r
1391 INLINE void NEG(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1393 sh2->r[n] = 0 - sh2->r[m];
\r
1397 INLINE void NEGC(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1402 sh2->r[n] = -temp - (sh2->sr & T);
\r
1403 if (temp || (sh2->sr & T))
\r
1410 INLINE void NOP(void)
\r
1415 INLINE void NOT(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1417 sh2->r[n] = ~sh2->r[m];
\r
1421 INLINE void OR(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1423 sh2->r[n] |= sh2->r[m];
\r
1427 INLINE void ORI(sh2_state *sh2, UINT32 i)
\r
1432 /* OR.B #imm,@(R0,GBR) */
\r
1433 INLINE void ORM(sh2_state *sh2, UINT32 i)
\r
1437 sh2->ea = sh2->gbr + sh2->r[0];
\r
1438 temp = RB( sh2, sh2->ea );
\r
1440 WB( sh2, sh2->ea, temp );
\r
1445 INLINE void ROTCL(sh2_state *sh2, UINT32 n)
\r
1449 temp = (sh2->r[n] >> 31) & T;
\r
1450 sh2->r[n] = (sh2->r[n] << 1) | (sh2->sr & T);
\r
1451 sh2->sr = (sh2->sr & ~T) | temp;
\r
1455 INLINE void ROTCR(sh2_state *sh2, UINT32 n)
\r
1458 temp = (sh2->sr & T) << 31;
\r
1459 if (sh2->r[n] & T)
\r
1463 sh2->r[n] = (sh2->r[n] >> 1) | temp;
\r
1467 INLINE void ROTL(sh2_state *sh2, UINT32 n)
\r
1469 sh2->sr = (sh2->sr & ~T) | ((sh2->r[n] >> 31) & T);
\r
1470 sh2->r[n] = (sh2->r[n] << 1) | (sh2->r[n] >> 31);
\r
1474 INLINE void ROTR(sh2_state *sh2, UINT32 n)
\r
1476 sh2->sr = (sh2->sr & ~T) | (sh2->r[n] & T);
\r
1477 sh2->r[n] = (sh2->r[n] >> 1) | (sh2->r[n] << 31);
\r
1481 INLINE void RTE(sh2_state *sh2)
\r
1483 sh2->ea = sh2->r[15];
\r
1484 sh2->delay = sh2->pc;
\r
1485 sh2->pc = RL( sh2, sh2->ea );
\r
1487 sh2->ea = sh2->r[15];
\r
1488 sh2->sr = RL( sh2, sh2->ea ) & FLAGS;
\r
1491 sh2->test_irq = 1;
\r
1495 INLINE void RTS(sh2_state *sh2)
\r
1497 sh2->delay = sh2->pc;
\r
1498 sh2->pc = sh2->ea = sh2->pr;
\r
1503 INLINE void SETT(sh2_state *sh2)
\r
1508 /* SHAL Rn (same as SHLL) */
\r
1509 INLINE void SHAL(sh2_state *sh2, UINT32 n)
\r
1511 sh2->sr = (sh2->sr & ~T) | ((sh2->r[n] >> 31) & T);
\r
1516 INLINE void SHAR(sh2_state *sh2, UINT32 n)
\r
1518 sh2->sr = (sh2->sr & ~T) | (sh2->r[n] & T);
\r
1519 sh2->r[n] = (UINT32)((INT32)sh2->r[n] >> 1);
\r
1522 /* SHLL Rn (same as SHAL) */
\r
1523 INLINE void SHLL(sh2_state *sh2, UINT32 n)
\r
1525 sh2->sr = (sh2->sr & ~T) | ((sh2->r[n] >> 31) & T);
\r
1530 INLINE void SHLL2(sh2_state *sh2, UINT32 n)
\r
1536 INLINE void SHLL8(sh2_state *sh2, UINT32 n)
\r
1542 INLINE void SHLL16(sh2_state *sh2, UINT32 n)
\r
1548 INLINE void SHLR(sh2_state *sh2, UINT32 n)
\r
1550 sh2->sr = (sh2->sr & ~T) | (sh2->r[n] & T);
\r
1555 INLINE void SHLR2(sh2_state *sh2, UINT32 n)
\r
1561 INLINE void SHLR8(sh2_state *sh2, UINT32 n)
\r
1567 INLINE void SHLR16(sh2_state *sh2, UINT32 n)
\r
1573 INLINE void SLEEP(sh2_state *sh2)
\r
1575 //if(sh2->sleep_mode != 2)
\r
1578 /* Wait_for_exception; */
\r
1579 /*if(sh2->sleep_mode == 0)
\r
1580 sh2->sleep_mode = 1;
\r
1581 else if(sh2->sleep_mode == 2)
\r
1582 sh2->sleep_mode = 0;*/
\r
1586 INLINE void STCSR(sh2_state *sh2, UINT32 n)
\r
1588 sh2->r[n] = sh2->sr;
\r
1592 INLINE void STCGBR(sh2_state *sh2, UINT32 n)
\r
1594 sh2->r[n] = sh2->gbr;
\r
1598 INLINE void STCVBR(sh2_state *sh2, UINT32 n)
\r
1600 sh2->r[n] = sh2->vbr;
\r
1603 /* STC.L SR,@-Rn */
\r
1604 INLINE void STCMSR(sh2_state *sh2, UINT32 n)
\r
1607 sh2->ea = sh2->r[n];
\r
1608 WL( sh2, sh2->ea, sh2->sr );
\r
1612 /* STC.L GBR,@-Rn */
\r
1613 INLINE void STCMGBR(sh2_state *sh2, UINT32 n)
\r
1616 sh2->ea = sh2->r[n];
\r
1617 WL( sh2, sh2->ea, sh2->gbr );
\r
1621 /* STC.L VBR,@-Rn */
\r
1622 INLINE void STCMVBR(sh2_state *sh2, UINT32 n)
\r
1625 sh2->ea = sh2->r[n];
\r
1626 WL( sh2, sh2->ea, sh2->vbr );
\r
1631 INLINE void STSMACH(sh2_state *sh2, UINT32 n)
\r
1633 sh2->r[n] = sh2->mach;
\r
1637 INLINE void STSMACL(sh2_state *sh2, UINT32 n)
\r
1639 sh2->r[n] = sh2->macl;
\r
1643 INLINE void STSPR(sh2_state *sh2, UINT32 n)
\r
1645 sh2->r[n] = sh2->pr;
\r
1648 /* STS.L MACH,@-Rn */
\r
1649 INLINE void STSMMACH(sh2_state *sh2, UINT32 n)
\r
1652 sh2->ea = sh2->r[n];
\r
1653 WL( sh2, sh2->ea, sh2->mach );
\r
1656 /* STS.L MACL,@-Rn */
\r
1657 INLINE void STSMMACL(sh2_state *sh2, UINT32 n)
\r
1660 sh2->ea = sh2->r[n];
\r
1661 WL( sh2, sh2->ea, sh2->macl );
\r
1664 /* STS.L PR,@-Rn */
\r
1665 INLINE void STSMPR(sh2_state *sh2, UINT32 n)
\r
1668 sh2->ea = sh2->r[n];
\r
1669 WL( sh2, sh2->ea, sh2->pr );
\r
1673 INLINE void SUB(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1675 sh2->r[n] -= sh2->r[m];
\r
1679 INLINE void SUBC(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1681 UINT32 tmp0, tmp1;
\r
1683 tmp1 = sh2->r[n] - sh2->r[m];
\r
1685 sh2->r[n] = tmp1 - (sh2->sr & T);
\r
1690 if (tmp1 < sh2->r[n])
\r
1695 INLINE void SUBV(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1697 INT32 dest, src, ans;
\r
1699 if ((INT32) sh2->r[n] >= 0)
\r
1703 if ((INT32) sh2->r[m] >= 0)
\r
1708 sh2->r[n] -= sh2->r[m];
\r
1709 if ((INT32) sh2->r[n] >= 0)
\r
1725 /* SWAP.B Rm,Rn */
\r
1726 INLINE void SWAPB(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1728 UINT32 temp0, temp1;
\r
1730 temp0 = sh2->r[m] & 0xffff0000;
\r
1731 temp1 = (sh2->r[m] & 0x000000ff) << 8;
\r
1732 sh2->r[n] = (sh2->r[m] >> 8) & 0x000000ff;
\r
1733 sh2->r[n] = sh2->r[n] | temp1 | temp0;
\r
1736 /* SWAP.W Rm,Rn */
\r
1737 INLINE void SWAPW(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1741 temp = (sh2->r[m] >> 16) & 0x0000ffff;
\r
1742 sh2->r[n] = (sh2->r[m] << 16) | temp;
\r
1746 INLINE void TAS(sh2_state *sh2, UINT32 n)
\r
1749 sh2->ea = sh2->r[n];
\r
1750 /* Bus Lock enable */
\r
1751 temp = RB( sh2, sh2->ea );
\r
1757 /* Bus Lock disable */
\r
1758 WB( sh2, sh2->ea, temp );
\r
1763 INLINE void TRAPA(sh2_state *sh2, UINT32 i)
\r
1765 UINT32 imm = i & 0xff;
\r
1767 sh2->ea = sh2->vbr + imm * 4;
\r
1770 WL( sh2, sh2->r[15], sh2->sr );
\r
1772 WL( sh2, sh2->r[15], sh2->pc );
\r
1774 sh2->pc = RL( sh2, sh2->ea );
\r
1780 INLINE void TST(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1782 if ((sh2->r[n] & sh2->r[m]) == 0)
\r
1789 INLINE void TSTI(sh2_state *sh2, UINT32 i)
\r
1791 UINT32 imm = i & 0xff;
\r
1793 if ((imm & sh2->r[0]) == 0)
\r
1799 /* TST.B #imm,@(R0,GBR) */
\r
1800 INLINE void TSTM(sh2_state *sh2, UINT32 i)
\r
1802 UINT32 imm = i & 0xff;
\r
1804 sh2->ea = sh2->gbr + sh2->r[0];
\r
1805 if ((imm & RB( sh2, sh2->ea )) == 0)
\r
1813 INLINE void XOR(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1815 sh2->r[n] ^= sh2->r[m];
\r
1819 INLINE void XORI(sh2_state *sh2, UINT32 i)
\r
1821 UINT32 imm = i & 0xff;
\r
1825 /* XOR.B #imm,@(R0,GBR) */
\r
1826 INLINE void XORM(sh2_state *sh2, UINT32 i)
\r
1828 UINT32 imm = i & 0xff;
\r
1831 sh2->ea = sh2->gbr + sh2->r[0];
\r
1832 temp = RB( sh2, sh2->ea );
\r
1834 WB( sh2, sh2->ea, temp );
\r
1839 INLINE void XTRCT(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1843 temp = (sh2->r[m] << 16) & 0xffff0000;
\r
1844 sh2->r[n] = (sh2->r[n] >> 16) & 0x0000ffff;
\r
1845 sh2->r[n] |= temp;
\r
1848 /*****************************************************************************
\r
1849 * OPCODE DISPATCHERS
\r
1850 *****************************************************************************/
\r
1852 INLINE void op0000(sh2_state *sh2, UINT16 opcode)
\r
1854 switch (opcode & 0x3F)
\r
1856 case 0x00: ILLEGAL(sh2); rlog(0); break;
\r
1857 case 0x01: ILLEGAL(sh2); rlog(0); break;
\r
1858 case 0x02: STCSR(sh2, Rn); rlog(LRN); break;
\r
1859 case 0x03: BSRF(sh2, Rn); rlog(LRN); break;
\r
1860 case 0x04: MOVBS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1861 case 0x05: MOVWS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1862 case 0x06: MOVLS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1863 case 0x07: MULL(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;
\r
1864 case 0x08: CLRT(sh2); rlog(0); break;
\r
1865 case 0x09: NOP(); rlog(0); break;
\r
1866 case 0x0a: STSMACH(sh2, Rn); rlog(LRN); rlog1(SHR_MACH); break;
\r
1867 case 0x0b: RTS(sh2); rlog(0); rlog1(SHR_PR); break;
\r
1868 case 0x0c: MOVBL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1869 case 0x0d: MOVWL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1870 case 0x0e: MOVLL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1871 case 0x0f: MAC_L(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
1873 case 0x10: ILLEGAL(sh2); rlog(0); break;
\r
1874 case 0x11: ILLEGAL(sh2); rlog(0); break;
\r
1875 case 0x12: STCGBR(sh2, Rn); rlog(LRN); rlog1(SHR_GBR); break;
\r
1876 case 0x13: ILLEGAL(sh2); rlog(0); break;
\r
1877 case 0x14: MOVBS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1878 case 0x15: MOVWS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1879 case 0x16: MOVLS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1880 case 0x17: MULL(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;
\r
1881 case 0x18: SETT(sh2); rlog(0); break;
\r
1882 case 0x19: DIV0U(sh2); rlog(0); break;
\r
1883 case 0x1a: STSMACL(sh2, Rn); rlog(LRN); rlog1(SHR_MACL); break;
\r
1884 case 0x1b: SLEEP(sh2); rlog(0); break;
\r
1885 case 0x1c: MOVBL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1886 case 0x1d: MOVWL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1887 case 0x1e: MOVLL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1888 case 0x1f: MAC_L(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
1890 case 0x20: ILLEGAL(sh2); rlog(0); break;
\r
1891 case 0x21: ILLEGAL(sh2); rlog(0); break;
\r
1892 case 0x22: STCVBR(sh2, Rn); rlog(LRN); rlog1(SHR_VBR); break;
\r
1893 case 0x23: BRAF(sh2, Rn); rlog(LRN); break;
\r
1894 case 0x24: MOVBS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1895 case 0x25: MOVWS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1896 case 0x26: MOVLS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1897 case 0x27: MULL(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;
\r
1898 case 0x28: CLRMAC(sh2); rlog(0); rlog2(SHR_MACL,SHR_MACH); break;
\r
1899 case 0x29: MOVT(sh2, Rn); rlog(LRN); break;
\r
1900 case 0x2a: STSPR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;
\r
1901 case 0x2b: RTE(sh2); rlog(0); break;
\r
1902 case 0x2c: MOVBL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1903 case 0x2d: MOVWL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1904 case 0x2e: MOVLL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1905 case 0x2f: MAC_L(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
1907 case 0x30: ILLEGAL(sh2); rlog(0); break;
\r
1908 case 0x31: ILLEGAL(sh2); rlog(0); break;
\r
1909 case 0x32: ILLEGAL(sh2); rlog(0); break;
\r
1910 case 0x33: ILLEGAL(sh2); rlog(0); break;
\r
1911 case 0x34: MOVBS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1912 case 0x35: MOVWS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1913 case 0x36: MOVLS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1914 case 0x37: MULL(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;
\r
1915 case 0x38: ILLEGAL(sh2); rlog(0); break;
\r
1916 case 0x39: ILLEGAL(sh2); rlog(0); break;
\r
1917 case 0x3c: MOVBL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1918 case 0x3d: MOVWL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1919 case 0x3e: MOVLL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1920 case 0x3f: MAC_L(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
1921 case 0x3a: ILLEGAL(sh2); rlog(0); break;
\r
1922 case 0x3b: ILLEGAL(sh2); rlog(0); break;
\r
1926 INLINE void op0001(sh2_state *sh2, UINT16 opcode)
\r
1928 MOVLS4(sh2, Rm, opcode & 0x0f, Rn);
\r
1932 INLINE void op0010(sh2_state *sh2, UINT16 opcode)
\r
1934 switch (opcode & 15)
\r
1936 case 0: MOVBS(sh2, Rm, Rn); rlog(LRNM); break;
\r
1937 case 1: MOVWS(sh2, Rm, Rn); rlog(LRNM); break;
\r
1938 case 2: MOVLS(sh2, Rm, Rn); rlog(LRNM); break;
\r
1939 case 3: ILLEGAL(sh2); rlog(0); break;
\r
1940 case 4: MOVBM(sh2, Rm, Rn); rlog(LRNM); break;
\r
1941 case 5: MOVWM(sh2, Rm, Rn); rlog(LRNM); break;
\r
1942 case 6: MOVLM(sh2, Rm, Rn); rlog(LRNM); break;
\r
1943 case 7: DIV0S(sh2, Rm, Rn); rlog(LRNM); break;
\r
1944 case 8: TST(sh2, Rm, Rn); rlog(LRNM); break;
\r
1945 case 9: AND(sh2, Rm, Rn); rlog(LRNM); break;
\r
1946 case 10: XOR(sh2, Rm, Rn); rlog(LRNM); break;
\r
1947 case 11: OR(sh2, Rm, Rn); rlog(LRNM); break;
\r
1948 case 12: CMPSTR(sh2, Rm, Rn); rlog(LRNM); break;
\r
1949 case 13: XTRCT(sh2, Rm, Rn); rlog(LRNM); break;
\r
1950 case 14: MULU(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;
\r
1951 case 15: MULS(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;
\r
1955 INLINE void op0011(sh2_state *sh2, UINT16 opcode)
\r
1957 switch (opcode & 15)
\r
1959 case 0: CMPEQ(sh2, Rm, Rn); rlog(LRNM); break;
\r
1960 case 1: ILLEGAL(sh2); rlog(0); break;
\r
1961 case 2: CMPHS(sh2, Rm, Rn); rlog(LRNM); break;
\r
1962 case 3: CMPGE(sh2, Rm, Rn); rlog(LRNM); break;
\r
1963 case 4: DIV1(sh2, Rm, Rn); rlog(LRNM); break;
\r
1964 case 5: DMULU(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
1965 case 6: CMPHI(sh2, Rm, Rn); rlog(LRNM); break;
\r
1966 case 7: CMPGT(sh2, Rm, Rn); rlog(LRNM); break;
\r
1967 case 8: SUB(sh2, Rm, Rn); rlog(LRNM); break;
\r
1968 case 9: ILLEGAL(sh2); rlog(0); break;
\r
1969 case 10: SUBC(sh2, Rm, Rn); rlog(LRNM); break;
\r
1970 case 11: SUBV(sh2, Rm, Rn); rlog(LRNM); break;
\r
1971 case 12: ADD(sh2, Rm, Rn); rlog(LRNM); break;
\r
1972 case 13: DMULS(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
1973 case 14: ADDC(sh2, Rm, Rn); rlog(LRNM); break;
\r
1974 case 15: ADDV(sh2, Rm, Rn); rlog(LRNM); break;
\r
1978 INLINE void op0100(sh2_state *sh2, UINT16 opcode)
\r
1980 switch (opcode & 0x3F)
\r
1982 case 0x00: SHLL(sh2, Rn); rlog(LRN); break;
\r
1983 case 0x01: SHLR(sh2, Rn); rlog(LRN); break;
\r
1984 case 0x02: STSMMACH(sh2, Rn); rlog(LRN); rlog1(SHR_MACH); break;
\r
1985 case 0x03: STCMSR(sh2, Rn); rlog(LRN); break;
\r
1986 case 0x04: ROTL(sh2, Rn); rlog(LRN); break;
\r
1987 case 0x05: ROTR(sh2, Rn); rlog(LRN); break;
\r
1988 case 0x06: LDSMMACH(sh2, Rn); rlog(LRN); rlog1(SHR_MACH); break;
\r
1989 case 0x07: LDCMSR(sh2, Rn); rlog(LRN); break;
\r
1990 case 0x08: SHLL2(sh2, Rn); rlog(LRN); break;
\r
1991 case 0x09: SHLR2(sh2, Rn); rlog(LRN); break;
\r
1992 case 0x0a: LDSMACH(sh2, Rn); rlog(LRN); rlog1(SHR_MACH); break;
\r
1993 case 0x0b: JSR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;
\r
1994 case 0x0c: ILLEGAL(sh2); rlog(0); break;
\r
1995 case 0x0d: ILLEGAL(sh2); rlog(0); break;
\r
1996 case 0x0e: LDCSR(sh2, Rn); rlog(LRN); break;
\r
1997 case 0x0f: MAC_W(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
1999 case 0x10: DT(sh2, Rn); rlog(LRN); break;
\r
2000 case 0x11: CMPPZ(sh2, Rn); rlog(LRN); break;
\r
2001 case 0x12: STSMMACL(sh2, Rn); rlog(LRN); rlog1(SHR_MACL); break;
\r
2002 case 0x13: STCMGBR(sh2, Rn); rlog(LRN); rlog1(SHR_GBR); break;
\r
2003 case 0x14: ILLEGAL(sh2); rlog(0); break;
\r
2004 case 0x15: CMPPL(sh2, Rn); rlog(LRN); break;
\r
2005 case 0x16: LDSMMACL(sh2, Rn); rlog(LRN); rlog1(SHR_MACL); break;
\r
2006 case 0x17: LDCMGBR(sh2, Rn); rlog(LRN); rlog1(SHR_GBR); break;
\r
2007 case 0x18: SHLL8(sh2, Rn); rlog(LRN); break;
\r
2008 case 0x19: SHLR8(sh2, Rn); rlog(LRN); break;
\r
2009 case 0x1a: LDSMACL(sh2, Rn); rlog(LRN); rlog1(SHR_MACL); break;
\r
2010 case 0x1b: TAS(sh2, Rn); rlog(LRN); break;
\r
2011 case 0x1c: ILLEGAL(sh2); rlog(0); break;
\r
2012 case 0x1d: ILLEGAL(sh2); rlog(0); break;
\r
2013 case 0x1e: LDCGBR(sh2, Rn); rlog(LRN); rlog1(SHR_GBR); break;
\r
2014 case 0x1f: MAC_W(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
2016 case 0x20: SHAL(sh2, Rn); rlog(LRN); break;
\r
2017 case 0x21: SHAR(sh2, Rn); rlog(LRN); break;
\r
2018 case 0x22: STSMPR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;
\r
2019 case 0x23: STCMVBR(sh2, Rn); rlog(LRN); rlog1(SHR_VBR); break;
\r
2020 case 0x24: ROTCL(sh2, Rn); rlog(LRN); break;
\r
2021 case 0x25: ROTCR(sh2, Rn); rlog(LRN); break;
\r
2022 case 0x26: LDSMPR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;
\r
2023 case 0x27: LDCMVBR(sh2, Rn); rlog(LRN); rlog1(SHR_VBR); break;
\r
2024 case 0x28: SHLL16(sh2, Rn); rlog(LRN); break;
\r
2025 case 0x29: SHLR16(sh2, Rn); rlog(LRN); break;
\r
2026 case 0x2a: LDSPR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;
\r
2027 case 0x2b: JMP(sh2, Rn); rlog(LRN); break;
\r
2028 case 0x2c: ILLEGAL(sh2); rlog(0); break;
\r
2029 case 0x2d: ILLEGAL(sh2); rlog(0); break;
\r
2030 case 0x2e: LDCVBR(sh2, Rn); rlog(LRN); rlog1(SHR_VBR); break;
\r
2031 case 0x2f: MAC_W(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
2047 case 0x3e: ILLEGAL(sh2); rlog(0); break;
\r
2048 case 0x3f: MAC_W(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
2052 INLINE void op0101(sh2_state *sh2, UINT16 opcode)
\r
2054 MOVLL4(sh2, Rm, opcode & 0x0f, Rn);
\r
2058 INLINE void op0110(sh2_state *sh2, UINT16 opcode)
\r
2060 switch (opcode & 15)
\r
2062 case 0: MOVBL(sh2, Rm, Rn); break;
\r
2063 case 1: MOVWL(sh2, Rm, Rn); break;
\r
2064 case 2: MOVLL(sh2, Rm, Rn); break;
\r
2065 case 3: MOV(sh2, Rm, Rn); break;
\r
2066 case 4: MOVBP(sh2, Rm, Rn); break;
\r
2067 case 5: MOVWP(sh2, Rm, Rn); break;
\r
2068 case 6: MOVLP(sh2, Rm, Rn); break;
\r
2069 case 7: NOT(sh2, Rm, Rn); break;
\r
2070 case 8: SWAPB(sh2, Rm, Rn); break;
\r
2071 case 9: SWAPW(sh2, Rm, Rn); break;
\r
2072 case 10: NEGC(sh2, Rm, Rn); break;
\r
2073 case 11: NEG(sh2, Rm, Rn); break;
\r
2074 case 12: EXTUB(sh2, Rm, Rn); break;
\r
2075 case 13: EXTUW(sh2, Rm, Rn); break;
\r
2076 case 14: EXTSB(sh2, Rm, Rn); break;
\r
2077 case 15: EXTSW(sh2, Rm, Rn); break;
\r
2082 INLINE void op0111(sh2_state *sh2, UINT16 opcode)
\r
2084 ADDI(sh2, opcode & 0xff, Rn);
\r
2088 INLINE void op1000(sh2_state *sh2, UINT16 opcode)
\r
2090 switch ( opcode & (15<<8) )
\r
2092 case 0<< 8: MOVBS4(sh2, opcode & 0x0f, Rm); rlog(LRM); rlog1(0); break;
\r
2093 case 1<< 8: MOVWS4(sh2, opcode & 0x0f, Rm); rlog(LRM); rlog1(0); break;
\r
2094 case 2<< 8: ILLEGAL(sh2); rlog(0); break;
\r
2095 case 3<< 8: ILLEGAL(sh2); rlog(0); break;
\r
2096 case 4<< 8: MOVBL4(sh2, Rm, opcode & 0x0f); rlog(LRM); rlog1(0); break;
\r
2097 case 5<< 8: MOVWL4(sh2, Rm, opcode & 0x0f); rlog(LRM); rlog1(0); break;
\r
2098 case 6<< 8: ILLEGAL(sh2); rlog(0); break;
\r
2099 case 7<< 8: ILLEGAL(sh2); rlog(0); break;
\r
2100 case 8<< 8: CMPIM(sh2, opcode & 0xff); rlog(0); rlog1(0); break;
\r
2101 case 9<< 8: BT(sh2, opcode & 0xff); rlog(0); break;
\r
2102 case 10<< 8: ILLEGAL(sh2); rlog(0); break;
\r
2103 case 11<< 8: BF(sh2, opcode & 0xff); rlog(0); break;
\r
2104 case 12<< 8: ILLEGAL(sh2); rlog(0); break;
\r
2105 case 13<< 8: BTS(sh2, opcode & 0xff); rlog(0); break;
\r
2106 case 14<< 8: ILLEGAL(sh2); rlog(0); break;
\r
2107 case 15<< 8: BFS(sh2, opcode & 0xff); rlog(0); break;
\r
2112 INLINE void op1001(sh2_state *sh2, UINT16 opcode)
\r
2114 MOVWI(sh2, opcode & 0xff, Rn);
\r
2118 INLINE void op1010(sh2_state *sh2, UINT16 opcode)
\r
2120 BRA(sh2, opcode & 0xfff);
\r
2124 INLINE void op1011(sh2_state *sh2, UINT16 opcode)
\r
2126 BSR(sh2, opcode & 0xfff);
\r
2131 INLINE void op1100(sh2_state *sh2, UINT16 opcode)
\r
2133 switch (opcode & (15<<8))
\r
2135 case 0<<8: MOVBSG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2136 case 1<<8: MOVWSG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2137 case 2<<8: MOVLSG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2138 case 3<<8: TRAPA(sh2, opcode & 0xff); rlog1(SHR_VBR); break;
\r
2139 case 4<<8: MOVBLG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2140 case 5<<8: MOVWLG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2141 case 6<<8: MOVLLG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2142 case 7<<8: MOVA(sh2, opcode & 0xff); rlog1(0); break;
\r
2143 case 8<<8: TSTI(sh2, opcode & 0xff); rlog1(0); break;
\r
2144 case 9<<8: ANDI(sh2, opcode & 0xff); rlog1(0); break;
\r
2145 case 10<<8: XORI(sh2, opcode & 0xff); rlog1(0); break;
\r
2146 case 11<<8: ORI(sh2, opcode & 0xff); rlog1(0); break;
\r
2147 case 12<<8: TSTM(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2148 case 13<<8: ANDM(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2149 case 14<<8: XORM(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2150 case 15<<8: ORM(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2155 INLINE void op1101(sh2_state *sh2, UINT16 opcode)
\r
2157 MOVLI(sh2, opcode & 0xff, Rn);
\r
2161 INLINE void op1110(sh2_state *sh2, UINT16 opcode)
\r
2163 MOVI(sh2, opcode & 0xff, Rn);
\r
2167 INLINE void op1111(sh2_state *sh2, UINT16 opcode)
\r