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 if ((sh2->sr & T) == 0)
\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
361 /* code cycles t-bit
\r
362 * 1010 dddd dddd dddd 2 -
\r
365 INLINE void BRA(sh2_state *sh2, UINT32 d)
\r
367 INT32 disp = ((INT32)d << 20) >> 20;
\r
369 #if BUSY_LOOP_HACKS
\r
372 UINT32 next_opcode = RW( sh2, sh2->ppc & AM );
\r
376 if (next_opcode == 0x0009)
\r
377 sh2->icount %= 3; /* cycles for BRA $ and NOP taken (3) */
\r
380 sh2->delay = sh2->pc;
\r
381 sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;
\r
385 /* code cycles t-bit
\r
386 * 0000 mmmm 0010 0011 2 -
\r
389 INLINE void BRAF(sh2_state *sh2, UINT32 m)
\r
391 sh2->delay = sh2->pc;
\r
392 sh2->pc += sh2->r[m] + 2;
\r
396 /* code cycles t-bit
\r
397 * 1011 dddd dddd dddd 2 -
\r
400 INLINE void BSR(sh2_state *sh2, UINT32 d)
\r
402 INT32 disp = ((INT32)d << 20) >> 20;
\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
410 /* code cycles t-bit
\r
411 * 0000 mmmm 0000 0011 2 -
\r
414 INLINE void BSRF(sh2_state *sh2, UINT32 m)
\r
416 sh2->pr = sh2->pc + 2;
\r
417 sh2->delay = sh2->pc;
\r
418 sh2->pc += sh2->r[m] + 2;
\r
422 /* code cycles t-bit
\r
423 * 1000 1001 dddd dddd 3/1 -
\r
426 INLINE void BT(sh2_state *sh2, UINT32 d)
\r
428 if ((sh2->sr & T) != 0)
\r
430 INT32 disp = ((INT32)d << 24) >> 24;
\r
431 sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;
\r
436 /* code cycles t-bit
\r
437 * 1000 1101 dddd dddd 2/1 -
\r
440 INLINE void BTS(sh2_state *sh2, UINT32 d)
\r
442 if ((sh2->sr & T) != 0)
\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
451 /* code cycles t-bit
\r
452 * 0000 0000 0010 1000 1 -
\r
455 INLINE void CLRMAC(sh2_state *sh2)
\r
461 /* code cycles t-bit
\r
462 * 0000 0000 0000 1000 1 -
\r
465 INLINE void CLRT(sh2_state *sh2)
\r
470 /* code cycles t-bit
\r
471 * 0011 nnnn mmmm 0000 1 comparison result
\r
474 INLINE void CMPEQ(sh2_state *sh2, UINT32 m, UINT32 n)
\r
476 if (sh2->r[n] == sh2->r[m])
\r
482 /* code cycles t-bit
\r
483 * 0011 nnnn mmmm 0011 1 comparison result
\r
486 INLINE void CMPGE(sh2_state *sh2, UINT32 m, UINT32 n)
\r
488 if ((INT32) sh2->r[n] >= (INT32) sh2->r[m])
\r
494 /* code cycles t-bit
\r
495 * 0011 nnnn mmmm 0111 1 comparison result
\r
498 INLINE void CMPGT(sh2_state *sh2, UINT32 m, UINT32 n)
\r
500 if ((INT32) sh2->r[n] > (INT32) sh2->r[m])
\r
506 /* code cycles t-bit
\r
507 * 0011 nnnn mmmm 0110 1 comparison result
\r
510 INLINE void CMPHI(sh2_state *sh2, UINT32 m, UINT32 n)
\r
512 if ((UINT32) sh2->r[n] > (UINT32) sh2->r[m])
\r
518 /* code cycles t-bit
\r
519 * 0011 nnnn mmmm 0010 1 comparison result
\r
522 INLINE void CMPHS(sh2_state *sh2, UINT32 m, UINT32 n)
\r
524 if ((UINT32) sh2->r[n] >= (UINT32) sh2->r[m])
\r
531 /* code cycles t-bit
\r
532 * 0100 nnnn 0001 0101 1 comparison result
\r
535 INLINE void CMPPL(sh2_state *sh2, UINT32 n)
\r
537 if ((INT32) sh2->r[n] > 0)
\r
543 /* code cycles t-bit
\r
544 * 0100 nnnn 0001 0001 1 comparison result
\r
547 INLINE void CMPPZ(sh2_state *sh2, UINT32 n)
\r
549 if ((INT32) sh2->r[n] >= 0)
\r
555 /* code cycles t-bit
\r
556 * 0010 nnnn mmmm 1100 1 comparison result
\r
559 INLINE void CMPSTR(sh2_state *sh2, UINT32 m, UINT32 n)
\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
568 if (HH && HL && LH && LL)
\r
575 /* code cycles t-bit
\r
576 * 1000 1000 iiii iiii 1 comparison result
\r
579 INLINE void CMPIM(sh2_state *sh2, UINT32 i)
\r
581 UINT32 imm = (UINT32)(INT32)(INT16)(INT8)i;
\r
583 if (sh2->r[0] == imm)
\r
589 /* code cycles t-bit
\r
590 * 0010 nnnn mmmm 0111 1 calculation result
\r
593 INLINE void DIV0S(sh2_state *sh2, UINT32 m, UINT32 n)
\r
595 if ((sh2->r[n] & 0x80000000) == 0)
\r
599 if ((sh2->r[m] & 0x80000000) == 0)
\r
603 if ((sh2->r[m] ^ sh2->r[n]) & 0x80000000)
\r
609 /* code cycles t-bit
\r
610 * 0000 0000 0001 1001 1 0
\r
613 INLINE void DIV0U(sh2_state *sh2)
\r
615 sh2->sr &= ~(M | Q | T);
\r
618 /* code cycles t-bit
\r
619 * 0011 nnnn mmmm 0100 1 calculation result
\r
622 INLINE void DIV1(sh2_state *sh2, UINT32 m, UINT32 n)
\r
627 old_q = sh2->sr & Q;
\r
628 if (0x80000000 & sh2->r[n])
\r
633 sh2->r[n] = (sh2->r[n] << 1) | (sh2->sr & T);
\r
637 if (!(sh2->sr & M))
\r
640 sh2->r[n] -= sh2->r[m];
\r
642 if(sh2->r[n] > tmp0)
\r
647 if(sh2->r[n] > tmp0)
\r
655 sh2->r[n] += sh2->r[m];
\r
658 if(sh2->r[n] < tmp0)
\r
665 if(sh2->r[n] < tmp0)
\r
674 if (!(sh2->sr & M))
\r
677 sh2->r[n] += sh2->r[m];
\r
679 if(sh2->r[n] < tmp0)
\r
684 if(sh2->r[n] < tmp0)
\r
692 sh2->r[n] -= sh2->r[m];
\r
694 if(sh2->r[n] > tmp0)
\r
699 if(sh2->r[n] > tmp0)
\r
706 tmp0 = (sh2->sr & (Q | M));
\r
707 if((!tmp0) || (tmp0 == 0x300)) /* if Q == M set T else clear T */
\r
713 /* DMULS.L Rm,Rn */
\r
714 INLINE void DMULS(sh2_state *sh2, UINT32 m, UINT32 n)
\r
716 UINT32 RnL, RnH, RmL, RmH, Res0, Res1, Res2;
\r
717 UINT32 temp0, temp1, temp2, temp3;
\r
718 INT32 tempm, tempn, fnLmL;
\r
720 tempn = (INT32) sh2->r[n];
\r
721 tempm = (INT32) sh2->r[m];
\r
726 if ((INT32) (sh2->r[n] ^ sh2->r[m]) < 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
741 Res1 = temp1 + temp2;
\r
743 Res2 += 0x00010000;
\r
744 temp1 = (Res1 << 16) & 0xffff0000;
\r
745 Res0 = temp0 + temp1;
\r
748 Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;
\r
755 Res0 = (~Res0) + 1;
\r
762 /* DMULU.L Rm,Rn */
\r
763 INLINE void DMULU(sh2_state *sh2, UINT32 m, UINT32 n)
\r
765 UINT32 RnL, RnH, RmL, RmH, Res0, Res1, Res2;
\r
766 UINT32 temp0, temp1, temp2, temp3;
\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
777 Res1 = temp1 + temp2;
\r
779 Res2 += 0x00010000;
\r
780 temp1 = (Res1 << 16) & 0xffff0000;
\r
781 Res0 = temp0 + temp1;
\r
784 Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;
\r
791 INLINE void DT(sh2_state *sh2, UINT32 n)
\r
794 if (sh2->r[n] == 0)
\r
798 #if BUSY_LOOP_HACKS
\r
800 UINT32 next_opcode = RW( sh2, sh2->ppc & AM );
\r
804 if (next_opcode == 0x8bfd)
\r
806 while (sh2->r[n] > 1 && sh2->icount > 4)
\r
809 sh2->icount -= 4; /* cycles for DT (1) and BF taken (3) */
\r
817 INLINE void EXTSB(sh2_state *sh2, UINT32 m, UINT32 n)
\r
819 sh2->r[n] = ((INT32)sh2->r[m] << 24) >> 24;
\r
823 INLINE void EXTSW(sh2_state *sh2, UINT32 m, UINT32 n)
\r
825 sh2->r[n] = ((INT32)sh2->r[m] << 16) >> 16;
\r
829 INLINE void EXTUB(sh2_state *sh2, UINT32 m, UINT32 n)
\r
831 sh2->r[n] = sh2->r[m] & 0x000000ff;
\r
835 INLINE void EXTUW(sh2_state *sh2, UINT32 m, UINT32 n)
\r
837 sh2->r[n] = sh2->r[m] & 0x0000ffff;
\r
841 INLINE void ILLEGAL(sh2_state *sh2)
\r
843 logerror("SH2: Illegal opcode at %08x\n", sh2->pc - 2);
\r
845 WL( sh2, sh2->r[15], sh2->sr ); /* push SR onto stack */
\r
847 WL( sh2, sh2->r[15], sh2->pc - 2 ); /* push PC onto stack */
\r
850 sh2->pc = RL( sh2, sh2->vbr + 4 * 4 );
\r
852 /* TODO: timing is a guess */
\r
858 INLINE void JMP(sh2_state *sh2, UINT32 m)
\r
860 sh2->delay = sh2->pc;
\r
861 sh2->pc = sh2->ea = sh2->r[m];
\r
865 INLINE void JSR(sh2_state *sh2, UINT32 m)
\r
867 sh2->delay = sh2->pc;
\r
868 sh2->pr = sh2->pc + 2;
\r
869 sh2->pc = sh2->ea = sh2->r[m];
\r
875 INLINE void LDCSR(sh2_state *sh2, UINT32 m)
\r
877 sh2->sr = sh2->r[m] & FLAGS;
\r
882 INLINE void LDCGBR(sh2_state *sh2, UINT32 m)
\r
884 sh2->gbr = sh2->r[m];
\r
888 INLINE void LDCVBR(sh2_state *sh2, UINT32 m)
\r
890 sh2->vbr = sh2->r[m];
\r
893 /* LDC.L @Rm+,SR */
\r
894 INLINE void LDCMSR(sh2_state *sh2, UINT32 m)
\r
896 sh2->ea = sh2->r[m];
\r
897 sh2->sr = RL( sh2, sh2->ea ) & FLAGS;
\r
903 /* LDC.L @Rm+,GBR */
\r
904 INLINE void LDCMGBR(sh2_state *sh2, UINT32 m)
\r
906 sh2->ea = sh2->r[m];
\r
907 sh2->gbr = RL( sh2, sh2->ea );
\r
912 /* LDC.L @Rm+,VBR */
\r
913 INLINE void LDCMVBR(sh2_state *sh2, UINT32 m)
\r
915 sh2->ea = sh2->r[m];
\r
916 sh2->vbr = RL( sh2, sh2->ea );
\r
922 INLINE void LDSMACH(sh2_state *sh2, UINT32 m)
\r
924 sh2->mach = sh2->r[m];
\r
928 INLINE void LDSMACL(sh2_state *sh2, UINT32 m)
\r
930 sh2->macl = sh2->r[m];
\r
934 INLINE void LDSPR(sh2_state *sh2, UINT32 m)
\r
936 sh2->pr = sh2->r[m];
\r
939 /* LDS.L @Rm+,MACH */
\r
940 INLINE void LDSMMACH(sh2_state *sh2, UINT32 m)
\r
942 sh2->ea = sh2->r[m];
\r
943 sh2->mach = RL( sh2, sh2->ea );
\r
947 /* LDS.L @Rm+,MACL */
\r
948 INLINE void LDSMMACL(sh2_state *sh2, UINT32 m)
\r
950 sh2->ea = sh2->r[m];
\r
951 sh2->macl = RL( sh2, sh2->ea );
\r
955 /* LDS.L @Rm+,PR */
\r
956 INLINE void LDSMPR(sh2_state *sh2, UINT32 m)
\r
958 sh2->ea = sh2->r[m];
\r
959 sh2->pr = RL( sh2, sh2->ea );
\r
963 /* MAC.L @Rm+,@Rn+ */
\r
964 INLINE void MAC_L(sh2_state *sh2, UINT32 m, UINT32 n)
\r
966 UINT32 RnL, RnH, RmL, RmH, Res0, Res1, Res2;
\r
967 UINT32 temp0, temp1, temp2, temp3;
\r
968 INT32 tempm, tempn, fnLmL;
\r
970 tempn = (INT32) RL( sh2, sh2->r[n] );
\r
972 tempm = (INT32) RL( sh2, sh2->r[m] );
\r
974 if ((INT32) (tempn ^ tempm) < 0)
\r
982 temp1 = (UINT32) tempn;
\r
983 temp2 = (UINT32) tempm;
\r
984 RnL = temp1 & 0x0000ffff;
\r
985 RnH = (temp1 >> 16) & 0x0000ffff;
\r
986 RmL = temp2 & 0x0000ffff;
\r
987 RmH = (temp2 >> 16) & 0x0000ffff;
\r
993 Res1 = temp1 + temp2;
\r
995 Res2 += 0x00010000;
\r
996 temp1 = (Res1 << 16) & 0xffff0000;
\r
997 Res0 = temp0 + temp1;
\r
1000 Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;
\r
1007 Res0 = (~Res0) + 1;
\r
1011 Res0 = sh2->macl + Res0;
\r
1012 if (sh2->macl > Res0)
\r
1014 Res2 += (sh2->mach & 0x0000ffff);
\r
1015 if (((INT32) Res2 < 0) && (Res2 < 0xffff8000))
\r
1017 Res2 = 0x00008000;
\r
1018 Res0 = 0x00000000;
\r
1020 else if (((INT32) Res2 > 0) && (Res2 > 0x00007fff))
\r
1022 Res2 = 0x00007fff;
\r
1023 Res0 = 0xffffffff;
\r
1030 Res0 = sh2->macl + Res0;
\r
1031 if (sh2->macl > Res0)
\r
1033 Res2 += sh2->mach;
\r
1040 /* MAC.W @Rm+,@Rn+ */
\r
1041 INLINE void MAC_W(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1043 INT32 tempm, tempn, dest, src, ans;
\r
1046 tempn = (INT32) RW( sh2, sh2->r[n] );
\r
1048 tempm = (INT32) RW( sh2, sh2->r[m] );
\r
1050 templ = sh2->macl;
\r
1051 tempm = ((INT32) (short) tempn * (INT32) (short) tempm);
\r
1052 if ((INT32) sh2->macl >= 0)
\r
1056 if ((INT32) tempm >= 0)
\r
1064 tempn = 0xffffffff;
\r
1067 sh2->macl += tempm;
\r
1068 if ((INT32) sh2->macl >= 0)
\r
1078 sh2->macl = 0x7fffffff;
\r
1080 sh2->macl = 0x80000000;
\r
1085 sh2->mach += tempn;
\r
1086 if (templ > sh2->macl)
\r
1093 INLINE void MOV(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1095 sh2->r[n] = sh2->r[m];
\r
1098 /* MOV.B Rm,@Rn */
\r
1099 INLINE void MOVBS(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1101 sh2->ea = sh2->r[n];
\r
1102 WB( sh2, sh2->ea, sh2->r[m] & 0x000000ff);
\r
1105 /* MOV.W Rm,@Rn */
\r
1106 INLINE void MOVWS(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1108 sh2->ea = sh2->r[n];
\r
1109 WW( sh2, sh2->ea, sh2->r[m] & 0x0000ffff);
\r
1112 /* MOV.L Rm,@Rn */
\r
1113 INLINE void MOVLS(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1115 sh2->ea = sh2->r[n];
\r
1116 WL( sh2, sh2->ea, sh2->r[m] );
\r
1119 /* MOV.B @Rm,Rn */
\r
1120 INLINE void MOVBL(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1122 sh2->ea = sh2->r[m];
\r
1123 sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->ea );
\r
1126 /* MOV.W @Rm,Rn */
\r
1127 INLINE void MOVWL(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1129 sh2->ea = sh2->r[m];
\r
1130 sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2, sh2->ea );
\r
1133 /* MOV.L @Rm,Rn */
\r
1134 INLINE void MOVLL(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1136 sh2->ea = sh2->r[m];
\r
1137 sh2->r[n] = RL( sh2, sh2->ea );
\r
1140 /* MOV.B Rm,@-Rn */
\r
1141 INLINE void MOVBM(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1143 /* SMG : bug fix, was reading sh2->r[n] */
\r
1144 UINT32 data = sh2->r[m] & 0x000000ff;
\r
1147 WB( sh2, sh2->r[n], data );
\r
1150 /* MOV.W Rm,@-Rn */
\r
1151 INLINE void MOVWM(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1153 UINT32 data = sh2->r[m] & 0x0000ffff;
\r
1156 WW( sh2, sh2->r[n], data );
\r
1159 /* MOV.L Rm,@-Rn */
\r
1160 INLINE void MOVLM(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1162 UINT32 data = sh2->r[m];
\r
1165 WL( sh2, sh2->r[n], data );
\r
1168 /* MOV.B @Rm+,Rn */
\r
1169 INLINE void MOVBP(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1171 sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->r[m] );
\r
1176 /* MOV.W @Rm+,Rn */
\r
1177 INLINE void MOVWP(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1179 sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2, sh2->r[m] );
\r
1184 /* MOV.L @Rm+,Rn */
\r
1185 INLINE void MOVLP(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1187 sh2->r[n] = RL( sh2, sh2->r[m] );
\r
1192 /* MOV.B Rm,@(R0,Rn) */
\r
1193 INLINE void MOVBS0(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1195 sh2->ea = sh2->r[n] + sh2->r[0];
\r
1196 WB( sh2, sh2->ea, sh2->r[m] & 0x000000ff );
\r
1199 /* MOV.W Rm,@(R0,Rn) */
\r
1200 INLINE void MOVWS0(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1202 sh2->ea = sh2->r[n] + sh2->r[0];
\r
1203 WW( sh2, sh2->ea, sh2->r[m] & 0x0000ffff );
\r
1206 /* MOV.L Rm,@(R0,Rn) */
\r
1207 INLINE void MOVLS0(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1209 sh2->ea = sh2->r[n] + sh2->r[0];
\r
1210 WL( sh2, sh2->ea, sh2->r[m] );
\r
1213 /* MOV.B @(R0,Rm),Rn */
\r
1214 INLINE void MOVBL0(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1216 sh2->ea = sh2->r[m] + sh2->r[0];
\r
1217 sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->ea );
\r
1220 /* MOV.W @(R0,Rm),Rn */
\r
1221 INLINE void MOVWL0(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1223 sh2->ea = sh2->r[m] + sh2->r[0];
\r
1224 sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2, sh2->ea );
\r
1227 /* MOV.L @(R0,Rm),Rn */
\r
1228 INLINE void MOVLL0(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1230 sh2->ea = sh2->r[m] + sh2->r[0];
\r
1231 sh2->r[n] = RL( sh2, sh2->ea );
\r
1235 INLINE void MOVI(sh2_state *sh2, UINT32 i, UINT32 n)
\r
1237 sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) i;
\r
1240 /* MOV.W @(disp8,PC),Rn */
\r
1241 INLINE void MOVWI(sh2_state *sh2, UINT32 d, UINT32 n)
\r
1243 UINT32 disp = d & 0xff;
\r
1244 sh2->ea = sh2->pc + disp * 2 + 2;
\r
1245 sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2, sh2->ea );
\r
1248 /* MOV.L @(disp8,PC),Rn */
\r
1249 INLINE void MOVLI(sh2_state *sh2, UINT32 d, UINT32 n)
\r
1251 UINT32 disp = d & 0xff;
\r
1252 sh2->ea = ((sh2->pc + 2) & ~3) + disp * 4;
\r
1253 sh2->r[n] = RL( sh2, sh2->ea );
\r
1256 /* MOV.B @(disp8,GBR),R0 */
\r
1257 INLINE void MOVBLG(sh2_state *sh2, UINT32 d)
\r
1259 UINT32 disp = d & 0xff;
\r
1260 sh2->ea = sh2->gbr + disp;
\r
1261 sh2->r[0] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->ea );
\r
1264 /* MOV.W @(disp8,GBR),R0 */
\r
1265 INLINE void MOVWLG(sh2_state *sh2, UINT32 d)
\r
1267 UINT32 disp = d & 0xff;
\r
1268 sh2->ea = sh2->gbr + disp * 2;
\r
1269 sh2->r[0] = (INT32)(INT16) RW( sh2, sh2->ea );
\r
1272 /* MOV.L @(disp8,GBR),R0 */
\r
1273 INLINE void MOVLLG(sh2_state *sh2, UINT32 d)
\r
1275 UINT32 disp = d & 0xff;
\r
1276 sh2->ea = sh2->gbr + disp * 4;
\r
1277 sh2->r[0] = RL( sh2, sh2->ea );
\r
1280 /* MOV.B R0,@(disp8,GBR) */
\r
1281 INLINE void MOVBSG(sh2_state *sh2, UINT32 d)
\r
1283 UINT32 disp = d & 0xff;
\r
1284 sh2->ea = sh2->gbr + disp;
\r
1285 WB( sh2, sh2->ea, sh2->r[0] & 0x000000ff );
\r
1288 /* MOV.W R0,@(disp8,GBR) */
\r
1289 INLINE void MOVWSG(sh2_state *sh2, UINT32 d)
\r
1291 UINT32 disp = d & 0xff;
\r
1292 sh2->ea = sh2->gbr + disp * 2;
\r
1293 WW( sh2, sh2->ea, sh2->r[0] & 0x0000ffff );
\r
1296 /* MOV.L R0,@(disp8,GBR) */
\r
1297 INLINE void MOVLSG(sh2_state *sh2, UINT32 d)
\r
1299 UINT32 disp = d & 0xff;
\r
1300 sh2->ea = sh2->gbr + disp * 4;
\r
1301 WL( sh2, sh2->ea, sh2->r[0] );
\r
1304 /* MOV.B R0,@(disp4,Rn) */
\r
1305 INLINE void MOVBS4(sh2_state *sh2, UINT32 d, UINT32 n)
\r
1307 UINT32 disp = d & 0x0f;
\r
1308 sh2->ea = sh2->r[n] + disp;
\r
1309 WB( sh2, sh2->ea, sh2->r[0] & 0x000000ff );
\r
1312 /* MOV.W R0,@(disp4,Rn) */
\r
1313 INLINE void MOVWS4(sh2_state *sh2, UINT32 d, UINT32 n)
\r
1315 UINT32 disp = d & 0x0f;
\r
1316 sh2->ea = sh2->r[n] + disp * 2;
\r
1317 WW( sh2, sh2->ea, sh2->r[0] & 0x0000ffff );
\r
1320 /* MOV.L Rm,@(disp4,Rn) */
\r
1321 INLINE void MOVLS4(sh2_state *sh2, UINT32 m, UINT32 d, UINT32 n)
\r
1323 UINT32 disp = d & 0x0f;
\r
1324 sh2->ea = sh2->r[n] + disp * 4;
\r
1325 WL( sh2, sh2->ea, sh2->r[m] );
\r
1328 /* MOV.B @(disp4,Rm),R0 */
\r
1329 INLINE void MOVBL4(sh2_state *sh2, UINT32 m, UINT32 d)
\r
1331 UINT32 disp = d & 0x0f;
\r
1332 sh2->ea = sh2->r[m] + disp;
\r
1333 sh2->r[0] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->ea );
\r
1336 /* MOV.W @(disp4,Rm),R0 */
\r
1337 INLINE void MOVWL4(sh2_state *sh2, UINT32 m, UINT32 d)
\r
1339 UINT32 disp = d & 0x0f;
\r
1340 sh2->ea = sh2->r[m] + disp * 2;
\r
1341 sh2->r[0] = (UINT32)(INT32)(INT16) RW( sh2, sh2->ea );
\r
1344 /* MOV.L @(disp4,Rm),Rn */
\r
1345 INLINE void MOVLL4(sh2_state *sh2, UINT32 m, UINT32 d, UINT32 n)
\r
1347 UINT32 disp = d & 0x0f;
\r
1348 sh2->ea = sh2->r[m] + disp * 4;
\r
1349 sh2->r[n] = RL( sh2, sh2->ea );
\r
1352 /* MOVA @(disp8,PC),R0 */
\r
1353 INLINE void MOVA(sh2_state *sh2, UINT32 d)
\r
1355 UINT32 disp = d & 0xff;
\r
1356 sh2->ea = ((sh2->pc + 2) & ~3) + disp * 4;
\r
1357 sh2->r[0] = sh2->ea;
\r
1361 INLINE void MOVT(sh2_state *sh2, UINT32 n)
\r
1363 sh2->r[n] = sh2->sr & T;
\r
1367 INLINE void MULL(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1369 sh2->macl = sh2->r[n] * sh2->r[m];
\r
1374 INLINE void MULS(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1376 sh2->macl = (INT16) sh2->r[n] * (INT16) sh2->r[m];
\r
1380 INLINE void MULU(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1382 sh2->macl = (UINT16) sh2->r[n] * (UINT16) sh2->r[m];
\r
1386 INLINE void NEG(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1388 sh2->r[n] = 0 - sh2->r[m];
\r
1392 INLINE void NEGC(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1397 sh2->r[n] = -temp - (sh2->sr & T);
\r
1398 if (temp || (sh2->sr & T))
\r
1405 INLINE void NOP(void)
\r
1410 INLINE void NOT(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1412 sh2->r[n] = ~sh2->r[m];
\r
1416 INLINE void OR(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1418 sh2->r[n] |= sh2->r[m];
\r
1422 INLINE void ORI(sh2_state *sh2, UINT32 i)
\r
1428 /* OR.B #imm,@(R0,GBR) */
\r
1429 INLINE void ORM(sh2_state *sh2, UINT32 i)
\r
1433 sh2->ea = sh2->gbr + sh2->r[0];
\r
1434 temp = RB( sh2, sh2->ea );
\r
1436 WB( sh2, sh2->ea, temp );
\r
1440 INLINE void ROTCL(sh2_state *sh2, UINT32 n)
\r
1444 temp = (sh2->r[n] >> 31) & T;
\r
1445 sh2->r[n] = (sh2->r[n] << 1) | (sh2->sr & T);
\r
1446 sh2->sr = (sh2->sr & ~T) | temp;
\r
1450 INLINE void ROTCR(sh2_state *sh2, UINT32 n)
\r
1453 temp = (sh2->sr & T) << 31;
\r
1454 if (sh2->r[n] & T)
\r
1458 sh2->r[n] = (sh2->r[n] >> 1) | temp;
\r
1462 INLINE void ROTL(sh2_state *sh2, UINT32 n)
\r
1464 sh2->sr = (sh2->sr & ~T) | ((sh2->r[n] >> 31) & T);
\r
1465 sh2->r[n] = (sh2->r[n] << 1) | (sh2->r[n] >> 31);
\r
1469 INLINE void ROTR(sh2_state *sh2, UINT32 n)
\r
1471 sh2->sr = (sh2->sr & ~T) | (sh2->r[n] & T);
\r
1472 sh2->r[n] = (sh2->r[n] >> 1) | (sh2->r[n] << 31);
\r
1476 INLINE void RTE(sh2_state *sh2)
\r
1478 sh2->ea = sh2->r[15];
\r
1479 sh2->delay = sh2->pc;
\r
1480 sh2->pc = RL( sh2, sh2->ea );
\r
1482 sh2->ea = sh2->r[15];
\r
1483 sh2->sr = RL( sh2, sh2->ea ) & FLAGS;
\r
1486 sh2->test_irq = 1;
\r
1490 INLINE void RTS(sh2_state *sh2)
\r
1492 sh2->delay = sh2->pc;
\r
1493 sh2->pc = sh2->ea = sh2->pr;
\r
1498 INLINE void SETT(sh2_state *sh2)
\r
1503 /* SHAL Rn (same as SHLL) */
\r
1504 INLINE void SHAL(sh2_state *sh2, UINT32 n)
\r
1506 sh2->sr = (sh2->sr & ~T) | ((sh2->r[n] >> 31) & T);
\r
1511 INLINE void SHAR(sh2_state *sh2, UINT32 n)
\r
1513 sh2->sr = (sh2->sr & ~T) | (sh2->r[n] & T);
\r
1514 sh2->r[n] = (UINT32)((INT32)sh2->r[n] >> 1);
\r
1517 /* SHLL Rn (same as SHAL) */
\r
1518 INLINE void SHLL(sh2_state *sh2, UINT32 n)
\r
1520 sh2->sr = (sh2->sr & ~T) | ((sh2->r[n] >> 31) & T);
\r
1525 INLINE void SHLL2(sh2_state *sh2, UINT32 n)
\r
1531 INLINE void SHLL8(sh2_state *sh2, UINT32 n)
\r
1537 INLINE void SHLL16(sh2_state *sh2, UINT32 n)
\r
1543 INLINE void SHLR(sh2_state *sh2, UINT32 n)
\r
1545 sh2->sr = (sh2->sr & ~T) | (sh2->r[n] & T);
\r
1550 INLINE void SHLR2(sh2_state *sh2, UINT32 n)
\r
1556 INLINE void SHLR8(sh2_state *sh2, UINT32 n)
\r
1562 INLINE void SHLR16(sh2_state *sh2, UINT32 n)
\r
1568 INLINE void SLEEP(sh2_state *sh2)
\r
1570 //if(sh2->sleep_mode != 2)
\r
1573 /* Wait_for_exception; */
\r
1574 /*if(sh2->sleep_mode == 0)
\r
1575 sh2->sleep_mode = 1;
\r
1576 else if(sh2->sleep_mode == 2)
\r
1577 sh2->sleep_mode = 0;*/
\r
1581 INLINE void STCSR(sh2_state *sh2, UINT32 n)
\r
1583 sh2->r[n] = sh2->sr;
\r
1587 INLINE void STCGBR(sh2_state *sh2, UINT32 n)
\r
1589 sh2->r[n] = sh2->gbr;
\r
1593 INLINE void STCVBR(sh2_state *sh2, UINT32 n)
\r
1595 sh2->r[n] = sh2->vbr;
\r
1598 /* STC.L SR,@-Rn */
\r
1599 INLINE void STCMSR(sh2_state *sh2, UINT32 n)
\r
1602 sh2->ea = sh2->r[n];
\r
1603 WL( sh2, sh2->ea, sh2->sr );
\r
1607 /* STC.L GBR,@-Rn */
\r
1608 INLINE void STCMGBR(sh2_state *sh2, UINT32 n)
\r
1611 sh2->ea = sh2->r[n];
\r
1612 WL( sh2, sh2->ea, sh2->gbr );
\r
1616 /* STC.L VBR,@-Rn */
\r
1617 INLINE void STCMVBR(sh2_state *sh2, UINT32 n)
\r
1620 sh2->ea = sh2->r[n];
\r
1621 WL( sh2, sh2->ea, sh2->vbr );
\r
1626 INLINE void STSMACH(sh2_state *sh2, UINT32 n)
\r
1628 sh2->r[n] = sh2->mach;
\r
1632 INLINE void STSMACL(sh2_state *sh2, UINT32 n)
\r
1634 sh2->r[n] = sh2->macl;
\r
1638 INLINE void STSPR(sh2_state *sh2, UINT32 n)
\r
1640 sh2->r[n] = sh2->pr;
\r
1643 /* STS.L MACH,@-Rn */
\r
1644 INLINE void STSMMACH(sh2_state *sh2, UINT32 n)
\r
1647 sh2->ea = sh2->r[n];
\r
1648 WL( sh2, sh2->ea, sh2->mach );
\r
1651 /* STS.L MACL,@-Rn */
\r
1652 INLINE void STSMMACL(sh2_state *sh2, UINT32 n)
\r
1655 sh2->ea = sh2->r[n];
\r
1656 WL( sh2, sh2->ea, sh2->macl );
\r
1659 /* STS.L PR,@-Rn */
\r
1660 INLINE void STSMPR(sh2_state *sh2, UINT32 n)
\r
1663 sh2->ea = sh2->r[n];
\r
1664 WL( sh2, sh2->ea, sh2->pr );
\r
1668 INLINE void SUB(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1670 sh2->r[n] -= sh2->r[m];
\r
1674 INLINE void SUBC(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1676 UINT32 tmp0, tmp1;
\r
1678 tmp1 = sh2->r[n] - sh2->r[m];
\r
1680 sh2->r[n] = tmp1 - (sh2->sr & T);
\r
1685 if (tmp1 < sh2->r[n])
\r
1690 INLINE void SUBV(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1692 INT32 dest, src, ans;
\r
1694 if ((INT32) sh2->r[n] >= 0)
\r
1698 if ((INT32) sh2->r[m] >= 0)
\r
1703 sh2->r[n] -= sh2->r[m];
\r
1704 if ((INT32) sh2->r[n] >= 0)
\r
1720 /* SWAP.B Rm,Rn */
\r
1721 INLINE void SWAPB(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1723 UINT32 temp0, temp1;
\r
1725 temp0 = sh2->r[m] & 0xffff0000;
\r
1726 temp1 = (sh2->r[m] & 0x000000ff) << 8;
\r
1727 sh2->r[n] = (sh2->r[m] >> 8) & 0x000000ff;
\r
1728 sh2->r[n] = sh2->r[n] | temp1 | temp0;
\r
1731 /* SWAP.W Rm,Rn */
\r
1732 INLINE void SWAPW(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1736 temp = (sh2->r[m] >> 16) & 0x0000ffff;
\r
1737 sh2->r[n] = (sh2->r[m] << 16) | temp;
\r
1741 INLINE void TAS(sh2_state *sh2, UINT32 n)
\r
1744 sh2->ea = sh2->r[n];
\r
1745 /* Bus Lock enable */
\r
1746 temp = RB( sh2, sh2->ea );
\r
1752 /* Bus Lock disable */
\r
1753 WB( sh2, sh2->ea, temp );
\r
1758 INLINE void TRAPA(sh2_state *sh2, UINT32 i)
\r
1760 UINT32 imm = i & 0xff;
\r
1762 sh2->ea = sh2->vbr + imm * 4;
\r
1765 WL( sh2, sh2->r[15], sh2->sr );
\r
1767 WL( sh2, sh2->r[15], sh2->pc );
\r
1769 sh2->pc = RL( sh2, sh2->ea );
\r
1775 INLINE void TST(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1777 if ((sh2->r[n] & sh2->r[m]) == 0)
\r
1784 INLINE void TSTI(sh2_state *sh2, UINT32 i)
\r
1786 UINT32 imm = i & 0xff;
\r
1788 if ((imm & sh2->r[0]) == 0)
\r
1794 /* TST.B #imm,@(R0,GBR) */
\r
1795 INLINE void TSTM(sh2_state *sh2, UINT32 i)
\r
1797 UINT32 imm = i & 0xff;
\r
1799 sh2->ea = sh2->gbr + sh2->r[0];
\r
1800 if ((imm & RB( sh2, sh2->ea )) == 0)
\r
1808 INLINE void XOR(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1810 sh2->r[n] ^= sh2->r[m];
\r
1814 INLINE void XORI(sh2_state *sh2, UINT32 i)
\r
1816 UINT32 imm = i & 0xff;
\r
1820 /* XOR.B #imm,@(R0,GBR) */
\r
1821 INLINE void XORM(sh2_state *sh2, UINT32 i)
\r
1823 UINT32 imm = i & 0xff;
\r
1826 sh2->ea = sh2->gbr + sh2->r[0];
\r
1827 temp = RB( sh2, sh2->ea );
\r
1829 WB( sh2, sh2->ea, temp );
\r
1834 INLINE void XTRCT(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1838 temp = (sh2->r[m] << 16) & 0xffff0000;
\r
1839 sh2->r[n] = (sh2->r[n] >> 16) & 0x0000ffff;
\r
1840 sh2->r[n] |= temp;
\r
1843 /*****************************************************************************
\r
1844 * OPCODE DISPATCHERS
\r
1845 *****************************************************************************/
\r
1847 INLINE void op0000(sh2_state *sh2, UINT16 opcode)
\r
1849 switch (opcode & 0x3F)
\r
1851 case 0x00: ILLEGAL(sh2); rlog(0); break;
\r
1852 case 0x01: ILLEGAL(sh2); rlog(0); break;
\r
1853 case 0x02: STCSR(sh2, Rn); rlog(LRN); break;
\r
1854 case 0x03: BSRF(sh2, Rn); rlog(LRN); break;
\r
1855 case 0x04: MOVBS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1856 case 0x05: MOVWS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1857 case 0x06: MOVLS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1858 case 0x07: MULL(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;
\r
1859 case 0x08: CLRT(sh2); rlog(0); break;
\r
1860 case 0x09: NOP(); rlog(0); break;
\r
1861 case 0x0a: STSMACH(sh2, Rn); rlog(LRN); rlog1(SHR_MACH); break;
\r
1862 case 0x0b: RTS(sh2); rlog(0); rlog1(SHR_PR); break;
\r
1863 case 0x0c: MOVBL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1864 case 0x0d: MOVWL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1865 case 0x0e: MOVLL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1866 case 0x0f: MAC_L(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
1868 case 0x10: ILLEGAL(sh2); rlog(0); break;
\r
1869 case 0x11: ILLEGAL(sh2); rlog(0); break;
\r
1870 case 0x12: STCGBR(sh2, Rn); rlog(LRN); rlog1(SHR_GBR); break;
\r
1871 case 0x13: ILLEGAL(sh2); rlog(0); break;
\r
1872 case 0x14: MOVBS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1873 case 0x15: MOVWS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1874 case 0x16: MOVLS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1875 case 0x17: MULL(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;
\r
1876 case 0x18: SETT(sh2); rlog(0); break;
\r
1877 case 0x19: DIV0U(sh2); rlog(0); break;
\r
1878 case 0x1a: STSMACL(sh2, Rn); rlog(LRN); rlog1(SHR_MACL); break;
\r
1879 case 0x1b: SLEEP(sh2); rlog(0); break;
\r
1880 case 0x1c: MOVBL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1881 case 0x1d: MOVWL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1882 case 0x1e: MOVLL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1883 case 0x1f: MAC_L(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
1885 case 0x20: ILLEGAL(sh2); rlog(0); break;
\r
1886 case 0x21: ILLEGAL(sh2); rlog(0); break;
\r
1887 case 0x22: STCVBR(sh2, Rn); rlog(LRN); rlog1(SHR_VBR); break;
\r
1888 case 0x23: BRAF(sh2, Rn); rlog(LRN); break;
\r
1889 case 0x24: MOVBS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1890 case 0x25: MOVWS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1891 case 0x26: MOVLS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1892 case 0x27: MULL(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;
\r
1893 case 0x28: CLRMAC(sh2); rlog(0); rlog2(SHR_MACL,SHR_MACH); break;
\r
1894 case 0x29: MOVT(sh2, Rn); rlog(LRN); break;
\r
1895 case 0x2a: STSPR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;
\r
1896 case 0x2b: RTE(sh2); rlog(0); break;
\r
1897 case 0x2c: MOVBL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1898 case 0x2d: MOVWL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1899 case 0x2e: MOVLL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1900 case 0x2f: MAC_L(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
1902 case 0x30: ILLEGAL(sh2); rlog(0); break;
\r
1903 case 0x31: ILLEGAL(sh2); rlog(0); break;
\r
1904 case 0x32: ILLEGAL(sh2); rlog(0); break;
\r
1905 case 0x33: ILLEGAL(sh2); rlog(0); break;
\r
1906 case 0x34: MOVBS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1907 case 0x35: MOVWS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1908 case 0x36: MOVLS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1909 case 0x37: MULL(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;
\r
1910 case 0x38: ILLEGAL(sh2); rlog(0); break;
\r
1911 case 0x39: ILLEGAL(sh2); rlog(0); break;
\r
1912 case 0x3c: MOVBL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1913 case 0x3d: MOVWL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1914 case 0x3e: MOVLL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1915 case 0x3f: MAC_L(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
1916 case 0x3a: ILLEGAL(sh2); rlog(0); break;
\r
1917 case 0x3b: ILLEGAL(sh2); rlog(0); break;
\r
1921 INLINE void op0001(sh2_state *sh2, UINT16 opcode)
\r
1923 MOVLS4(sh2, Rm, opcode & 0x0f, Rn);
\r
1927 INLINE void op0010(sh2_state *sh2, UINT16 opcode)
\r
1929 switch (opcode & 15)
\r
1931 case 0: MOVBS(sh2, Rm, Rn); rlog(LRNM); break;
\r
1932 case 1: MOVWS(sh2, Rm, Rn); rlog(LRNM); break;
\r
1933 case 2: MOVLS(sh2, Rm, Rn); rlog(LRNM); break;
\r
1934 case 3: ILLEGAL(sh2); rlog(0); break;
\r
1935 case 4: MOVBM(sh2, Rm, Rn); rlog(LRNM); break;
\r
1936 case 5: MOVWM(sh2, Rm, Rn); rlog(LRNM); break;
\r
1937 case 6: MOVLM(sh2, Rm, Rn); rlog(LRNM); break;
\r
1938 case 7: DIV0S(sh2, Rm, Rn); rlog(LRNM); break;
\r
1939 case 8: TST(sh2, Rm, Rn); rlog(LRNM); break;
\r
1940 case 9: AND(sh2, Rm, Rn); rlog(LRNM); break;
\r
1941 case 10: XOR(sh2, Rm, Rn); rlog(LRNM); break;
\r
1942 case 11: OR(sh2, Rm, Rn); rlog(LRNM); break;
\r
1943 case 12: CMPSTR(sh2, Rm, Rn); rlog(LRNM); break;
\r
1944 case 13: XTRCT(sh2, Rm, Rn); rlog(LRNM); break;
\r
1945 case 14: MULU(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;
\r
1946 case 15: MULS(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;
\r
1950 INLINE void op0011(sh2_state *sh2, UINT16 opcode)
\r
1952 switch (opcode & 15)
\r
1954 case 0: CMPEQ(sh2, Rm, Rn); rlog(LRNM); break;
\r
1955 case 1: ILLEGAL(sh2); rlog(0); break;
\r
1956 case 2: CMPHS(sh2, Rm, Rn); rlog(LRNM); break;
\r
1957 case 3: CMPGE(sh2, Rm, Rn); rlog(LRNM); break;
\r
1958 case 4: DIV1(sh2, Rm, Rn); rlog(LRNM); break;
\r
1959 case 5: DMULU(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
1960 case 6: CMPHI(sh2, Rm, Rn); rlog(LRNM); break;
\r
1961 case 7: CMPGT(sh2, Rm, Rn); rlog(LRNM); break;
\r
1962 case 8: SUB(sh2, Rm, Rn); rlog(LRNM); break;
\r
1963 case 9: ILLEGAL(sh2); rlog(0); break;
\r
1964 case 10: SUBC(sh2, Rm, Rn); rlog(LRNM); break;
\r
1965 case 11: SUBV(sh2, Rm, Rn); rlog(LRNM); break;
\r
1966 case 12: ADD(sh2, Rm, Rn); rlog(LRNM); break;
\r
1967 case 13: DMULS(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
1968 case 14: ADDC(sh2, Rm, Rn); rlog(LRNM); break;
\r
1969 case 15: ADDV(sh2, Rm, Rn); rlog(LRNM); break;
\r
1973 INLINE void op0100(sh2_state *sh2, UINT16 opcode)
\r
1975 switch (opcode & 0x3F)
\r
1977 case 0x00: SHLL(sh2, Rn); rlog(LRN); break;
\r
1978 case 0x01: SHLR(sh2, Rn); rlog(LRN); break;
\r
1979 case 0x02: STSMMACH(sh2, Rn); rlog(LRN); rlog1(SHR_MACH); break;
\r
1980 case 0x03: STCMSR(sh2, Rn); rlog(LRN); break;
\r
1981 case 0x04: ROTL(sh2, Rn); rlog(LRN); break;
\r
1982 case 0x05: ROTR(sh2, Rn); rlog(LRN); break;
\r
1983 case 0x06: LDSMMACH(sh2, Rn); rlog(LRN); rlog1(SHR_MACH); break;
\r
1984 case 0x07: LDCMSR(sh2, Rn); rlog(LRN); break;
\r
1985 case 0x08: SHLL2(sh2, Rn); rlog(LRN); break;
\r
1986 case 0x09: SHLR2(sh2, Rn); rlog(LRN); break;
\r
1987 case 0x0a: LDSMACH(sh2, Rn); rlog(LRN); rlog1(SHR_MACH); break;
\r
1988 case 0x0b: JSR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;
\r
1989 case 0x0c: ILLEGAL(sh2); rlog(0); break;
\r
1990 case 0x0d: ILLEGAL(sh2); rlog(0); break;
\r
1991 case 0x0e: LDCSR(sh2, Rn); rlog(LRN); break;
\r
1992 case 0x0f: MAC_W(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
1994 case 0x10: DT(sh2, Rn); rlog(LRN); break;
\r
1995 case 0x11: CMPPZ(sh2, Rn); rlog(LRN); break;
\r
1996 case 0x12: STSMMACL(sh2, Rn); rlog(LRN); rlog1(SHR_MACL); break;
\r
1997 case 0x13: STCMGBR(sh2, Rn); rlog(LRN); rlog1(SHR_GBR); break;
\r
1998 case 0x14: ILLEGAL(sh2); rlog(0); break;
\r
1999 case 0x15: CMPPL(sh2, Rn); rlog(LRN); break;
\r
2000 case 0x16: LDSMMACL(sh2, Rn); rlog(LRN); rlog1(SHR_MACL); break;
\r
2001 case 0x17: LDCMGBR(sh2, Rn); rlog(LRN); rlog1(SHR_GBR); break;
\r
2002 case 0x18: SHLL8(sh2, Rn); rlog(LRN); break;
\r
2003 case 0x19: SHLR8(sh2, Rn); rlog(LRN); break;
\r
2004 case 0x1a: LDSMACL(sh2, Rn); rlog(LRN); rlog1(SHR_MACL); break;
\r
2005 case 0x1b: TAS(sh2, Rn); rlog(LRN); break;
\r
2006 case 0x1c: ILLEGAL(sh2); rlog(0); break;
\r
2007 case 0x1d: ILLEGAL(sh2); rlog(0); break;
\r
2008 case 0x1e: LDCGBR(sh2, Rn); rlog(LRN); rlog1(SHR_GBR); break;
\r
2009 case 0x1f: MAC_W(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
2011 case 0x20: SHAL(sh2, Rn); rlog(LRN); break;
\r
2012 case 0x21: SHAR(sh2, Rn); rlog(LRN); break;
\r
2013 case 0x22: STSMPR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;
\r
2014 case 0x23: STCMVBR(sh2, Rn); rlog(LRN); rlog1(SHR_VBR); break;
\r
2015 case 0x24: ROTCL(sh2, Rn); rlog(LRN); break;
\r
2016 case 0x25: ROTCR(sh2, Rn); rlog(LRN); break;
\r
2017 case 0x26: LDSMPR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;
\r
2018 case 0x27: LDCMVBR(sh2, Rn); rlog(LRN); rlog1(SHR_VBR); break;
\r
2019 case 0x28: SHLL16(sh2, Rn); rlog(LRN); break;
\r
2020 case 0x29: SHLR16(sh2, Rn); rlog(LRN); break;
\r
2021 case 0x2a: LDSPR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;
\r
2022 case 0x2b: JMP(sh2, Rn); rlog(LRN); break;
\r
2023 case 0x2c: ILLEGAL(sh2); rlog(0); break;
\r
2024 case 0x2d: ILLEGAL(sh2); rlog(0); break;
\r
2025 case 0x2e: LDCVBR(sh2, Rn); rlog(LRN); rlog1(SHR_VBR); break;
\r
2026 case 0x2f: MAC_W(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
2042 case 0x3e: ILLEGAL(sh2); rlog(0); break;
\r
2043 case 0x3f: MAC_W(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
2047 INLINE void op0101(sh2_state *sh2, UINT16 opcode)
\r
2049 MOVLL4(sh2, Rm, opcode & 0x0f, Rn);
\r
2053 INLINE void op0110(sh2_state *sh2, UINT16 opcode)
\r
2055 switch (opcode & 15)
\r
2057 case 0: MOVBL(sh2, Rm, Rn); break;
\r
2058 case 1: MOVWL(sh2, Rm, Rn); break;
\r
2059 case 2: MOVLL(sh2, Rm, Rn); break;
\r
2060 case 3: MOV(sh2, Rm, Rn); break;
\r
2061 case 4: MOVBP(sh2, Rm, Rn); break;
\r
2062 case 5: MOVWP(sh2, Rm, Rn); break;
\r
2063 case 6: MOVLP(sh2, Rm, Rn); break;
\r
2064 case 7: NOT(sh2, Rm, Rn); break;
\r
2065 case 8: SWAPB(sh2, Rm, Rn); break;
\r
2066 case 9: SWAPW(sh2, Rm, Rn); break;
\r
2067 case 10: NEGC(sh2, Rm, Rn); break;
\r
2068 case 11: NEG(sh2, Rm, Rn); break;
\r
2069 case 12: EXTUB(sh2, Rm, Rn); break;
\r
2070 case 13: EXTUW(sh2, Rm, Rn); break;
\r
2071 case 14: EXTSB(sh2, Rm, Rn); break;
\r
2072 case 15: EXTSW(sh2, Rm, Rn); break;
\r
2077 INLINE void op0111(sh2_state *sh2, UINT16 opcode)
\r
2079 ADDI(sh2, opcode & 0xff, Rn);
\r
2083 INLINE void op1000(sh2_state *sh2, UINT16 opcode)
\r
2085 switch ( opcode & (15<<8) )
\r
2087 case 0<< 8: MOVBS4(sh2, opcode & 0x0f, Rm); rlog(LRM); rlog1(0); break;
\r
2088 case 1<< 8: MOVWS4(sh2, opcode & 0x0f, Rm); rlog(LRM); rlog1(0); break;
\r
2089 case 2<< 8: ILLEGAL(sh2); rlog(0); break;
\r
2090 case 3<< 8: ILLEGAL(sh2); rlog(0); break;
\r
2091 case 4<< 8: MOVBL4(sh2, Rm, opcode & 0x0f); rlog(LRM); rlog1(0); break;
\r
2092 case 5<< 8: MOVWL4(sh2, Rm, opcode & 0x0f); rlog(LRM); rlog1(0); break;
\r
2093 case 6<< 8: ILLEGAL(sh2); rlog(0); break;
\r
2094 case 7<< 8: ILLEGAL(sh2); rlog(0); break;
\r
2095 case 8<< 8: CMPIM(sh2, opcode & 0xff); rlog(0); rlog1(0); break;
\r
2096 case 9<< 8: BT(sh2, opcode & 0xff); rlog(0); break;
\r
2097 case 10<< 8: ILLEGAL(sh2); rlog(0); break;
\r
2098 case 11<< 8: BF(sh2, opcode & 0xff); rlog(0); break;
\r
2099 case 12<< 8: ILLEGAL(sh2); rlog(0); break;
\r
2100 case 13<< 8: BTS(sh2, opcode & 0xff); rlog(0); break;
\r
2101 case 14<< 8: ILLEGAL(sh2); rlog(0); break;
\r
2102 case 15<< 8: BFS(sh2, opcode & 0xff); rlog(0); break;
\r
2107 INLINE void op1001(sh2_state *sh2, UINT16 opcode)
\r
2109 MOVWI(sh2, opcode & 0xff, Rn);
\r
2113 INLINE void op1010(sh2_state *sh2, UINT16 opcode)
\r
2115 BRA(sh2, opcode & 0xfff);
\r
2119 INLINE void op1011(sh2_state *sh2, UINT16 opcode)
\r
2121 BSR(sh2, opcode & 0xfff);
\r
2126 INLINE void op1100(sh2_state *sh2, UINT16 opcode)
\r
2128 switch (opcode & (15<<8))
\r
2130 case 0<<8: MOVBSG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2131 case 1<<8: MOVWSG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2132 case 2<<8: MOVLSG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2133 case 3<<8: TRAPA(sh2, opcode & 0xff); rlog1(SHR_VBR); break;
\r
2134 case 4<<8: MOVBLG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2135 case 5<<8: MOVWLG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2136 case 6<<8: MOVLLG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2137 case 7<<8: MOVA(sh2, opcode & 0xff); rlog1(0); break;
\r
2138 case 8<<8: TSTI(sh2, opcode & 0xff); rlog1(0); break;
\r
2139 case 9<<8: ANDI(sh2, opcode & 0xff); rlog1(0); break;
\r
2140 case 10<<8: XORI(sh2, opcode & 0xff); rlog1(0); break;
\r
2141 case 11<<8: ORI(sh2, opcode & 0xff); rlog1(0); break;
\r
2142 case 12<<8: TSTM(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2143 case 13<<8: ANDM(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2144 case 14<<8: XORM(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2145 case 15<<8: ORM(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2150 INLINE void op1101(sh2_state *sh2, UINT16 opcode)
\r
2152 MOVLI(sh2, opcode & 0xff, Rn);
\r
2156 INLINE void op1110(sh2_state *sh2, UINT16 opcode)
\r
2158 MOVI(sh2, opcode & 0xff, Rn);
\r
2162 INLINE void op1111(sh2_state *sh2, UINT16 opcode)
\r