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
112 #define INLINE static
\r
114 //CPU_DISASSEMBLE( sh2 );
\r
118 /* speed up delay loops, bail out of tight loops */
\r
119 //#define BUSY_LOOP_HACKS 1
\r
123 #define LOG(x) do { if (VERBOSE) logerror x; } while (0)
\r
126 INLINE UINT8 RB(sh2_state *sh2, offs_t A)
\r
128 if (A >= 0xe0000000)
\r
129 return sh2_internal_r(*sh2->internal, (A & 0x1fc)>>2, 0xff << (((~A) & 3)*8)) >> (((~A) & 3)*8);
\r
131 if (A >= 0xc0000000)
\r
132 return sh2->program->read_byte(A);
\r
134 if (A >= 0x40000000)
\r
137 return sh2->program->read_byte(A & AM);
\r
140 INLINE UINT16 RW(sh2_state *sh2, offs_t A)
\r
142 if (A >= 0xe0000000)
\r
143 return sh2_internal_r(*sh2->internal, (A & 0x1fc)>>2, 0xffff << (((~A) & 2)*8)) >> (((~A) & 2)*8);
\r
145 if (A >= 0xc0000000)
\r
146 return sh2->program->read_word(A);
\r
148 if (A >= 0x40000000)
\r
151 return sh2->program->read_word(A & AM);
\r
154 INLINE UINT32 RL(sh2_state *sh2, offs_t A)
\r
156 if (A >= 0xe0000000)
\r
157 return sh2_internal_r(*sh2->internal, (A & 0x1fc)>>2, 0xffffffff);
\r
159 if (A >= 0xc0000000)
\r
160 return sh2->program->read_dword(A);
\r
162 if (A >= 0x40000000)
\r
165 return sh2->program->read_dword(A & AM);
\r
168 INLINE void WB(sh2_state *sh2, offs_t A, UINT8 V)
\r
170 if (A >= 0xe0000000)
\r
172 sh2_internal_w(*sh2->internal, (A & 0x1fc)>>2, V << (((~A) & 3)*8), 0xff << (((~A) & 3)*8));
\r
176 if (A >= 0xc0000000)
\r
178 sh2->program->write_byte(A,V);
\r
182 if (A >= 0x40000000)
\r
185 sh2->program->write_byte(A & AM,V);
\r
188 INLINE void WW(sh2_state *sh2, offs_t A, UINT16 V)
\r
190 if (A >= 0xe0000000)
\r
192 sh2_internal_w(*sh2->internal, (A & 0x1fc)>>2, V << (((~A) & 2)*8), 0xffff << (((~A) & 2)*8));
\r
196 if (A >= 0xc0000000)
\r
198 sh2->program->write_word(A,V);
\r
202 if (A >= 0x40000000)
\r
205 sh2->program->write_word(A & AM,V);
\r
208 INLINE void WL(sh2_state *sh2, offs_t A, UINT32 V)
\r
210 if (A >= 0xe0000000)
\r
212 sh2_internal_w(*sh2->internal, (A & 0x1fc)>>2, V, 0xffffffff);
\r
216 if (A >= 0xc0000000)
\r
218 sh2->program->write_dword(A,V);
\r
222 if (A >= 0x40000000)
\r
225 sh2->program->write_dword(A & AM,V);
\r
229 /* code cycles t-bit
\r
230 * 0011 nnnn mmmm 1100 1 -
\r
233 INLINE void ADD(sh2_state *sh2, UINT32 m, UINT32 n)
\r
235 sh2->r[n] += sh2->r[m];
\r
238 /* code cycles t-bit
\r
239 * 0111 nnnn iiii iiii 1 -
\r
242 INLINE void ADDI(sh2_state *sh2, UINT32 i, UINT32 n)
\r
244 sh2->r[n] += (INT32)(INT16)(INT8)i;
\r
247 /* code cycles t-bit
\r
248 * 0011 nnnn mmmm 1110 1 carry
\r
251 INLINE void ADDC(sh2_state *sh2, UINT32 m, UINT32 n)
\r
255 tmp1 = sh2->r[n] + sh2->r[m];
\r
257 sh2->r[n] = tmp1 + (sh2->sr & T);
\r
262 if (tmp1 > sh2->r[n])
\r
266 /* code cycles t-bit
\r
267 * 0011 nnnn mmmm 1111 1 overflow
\r
270 INLINE void ADDV(sh2_state *sh2, UINT32 m, UINT32 n)
\r
272 INT32 dest, src, ans;
\r
274 if ((INT32) sh2->r[n] >= 0)
\r
278 if ((INT32) sh2->r[m] >= 0)
\r
283 sh2->r[n] += sh2->r[m];
\r
284 if ((INT32) sh2->r[n] >= 0)
\r
289 if (src == 0 || src == 2)
\r
300 /* code cycles t-bit
\r
301 * 0010 nnnn mmmm 1001 1 -
\r
304 INLINE void AND(sh2_state *sh2, UINT32 m, UINT32 n)
\r
306 sh2->r[n] &= sh2->r[m];
\r
310 /* code cycles t-bit
\r
311 * 1100 1001 iiii iiii 1 -
\r
314 INLINE void ANDI(sh2_state *sh2, UINT32 i)
\r
319 /* code cycles t-bit
\r
320 * 1100 1101 iiii iiii 1 -
\r
321 * AND.B #imm,@(R0,GBR)
\r
323 INLINE void ANDM(sh2_state *sh2, UINT32 i)
\r
327 sh2->ea = sh2->gbr + sh2->r[0];
\r
328 temp = i & RB( sh2, sh2->ea );
\r
329 WB( sh2, sh2->ea, temp );
\r
333 /* code cycles t-bit
\r
334 * 1000 1011 dddd dddd 3/1 -
\r
337 INLINE void BF(sh2_state *sh2, UINT32 d)
\r
339 if ((sh2->sr & T) == 0)
\r
341 INT32 disp = ((INT32)d << 24) >> 24;
\r
342 sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;
\r
347 /* code cycles t-bit
\r
348 * 1000 1111 dddd dddd 3/1 -
\r
351 INLINE void BFS(sh2_state *sh2, UINT32 d)
\r
353 sh2->delay = sh2->pc;
\r
356 if ((sh2->sr & T) == 0)
\r
358 INT32 disp = ((INT32)d << 24) >> 24;
\r
359 sh2->pc = sh2->ea = sh2->pc + disp * 2;
\r
364 /* code cycles t-bit
\r
365 * 1010 dddd dddd dddd 2 -
\r
368 INLINE void BRA(sh2_state *sh2, UINT32 d)
\r
370 INT32 disp = ((INT32)d << 20) >> 20;
\r
372 #if BUSY_LOOP_HACKS
\r
375 UINT32 next_opcode = RW( sh2, sh2->ppc & AM );
\r
379 if (next_opcode == 0x0009)
\r
380 sh2->icount %= 3; /* cycles for BRA $ and NOP taken (3) */
\r
383 sh2->delay = sh2->pc;
\r
384 sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;
\r
388 /* code cycles t-bit
\r
389 * 0000 mmmm 0010 0011 2 -
\r
392 INLINE void BRAF(sh2_state *sh2, UINT32 m)
\r
394 sh2->delay = sh2->pc;
\r
395 sh2->pc += sh2->r[m] + 2;
\r
399 /* code cycles t-bit
\r
400 * 1011 dddd dddd dddd 2 -
\r
403 INLINE void BSR(sh2_state *sh2, UINT32 d)
\r
405 INT32 disp = ((INT32)d << 20) >> 20;
\r
407 sh2->pr = sh2->pc + 2;
\r
408 sh2->delay = sh2->pc;
\r
409 sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;
\r
413 /* code cycles t-bit
\r
414 * 0000 mmmm 0000 0011 2 -
\r
417 INLINE void BSRF(sh2_state *sh2, UINT32 m)
\r
419 sh2->pr = sh2->pc + 2;
\r
420 sh2->delay = sh2->pc;
\r
421 sh2->pc += sh2->r[m] + 2;
\r
425 /* code cycles t-bit
\r
426 * 1000 1001 dddd dddd 3/1 -
\r
429 INLINE void BT(sh2_state *sh2, UINT32 d)
\r
431 if ((sh2->sr & T) != 0)
\r
433 INT32 disp = ((INT32)d << 24) >> 24;
\r
434 sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;
\r
439 /* code cycles t-bit
\r
440 * 1000 1101 dddd dddd 2/1 -
\r
443 INLINE void BTS(sh2_state *sh2, UINT32 d)
\r
445 sh2->delay = sh2->pc;
\r
448 if ((sh2->sr & T) != 0)
\r
450 INT32 disp = ((INT32)d << 24) >> 24;
\r
451 sh2->pc = sh2->ea = sh2->pc + disp * 2;
\r
456 /* code cycles t-bit
\r
457 * 0000 0000 0010 1000 1 -
\r
460 INLINE void CLRMAC(sh2_state *sh2)
\r
466 /* code cycles t-bit
\r
467 * 0000 0000 0000 1000 1 -
\r
470 INLINE void CLRT(sh2_state *sh2)
\r
475 /* code cycles t-bit
\r
476 * 0011 nnnn mmmm 0000 1 comparison result
\r
479 INLINE void CMPEQ(sh2_state *sh2, UINT32 m, UINT32 n)
\r
481 if (sh2->r[n] == sh2->r[m])
\r
487 /* code cycles t-bit
\r
488 * 0011 nnnn mmmm 0011 1 comparison result
\r
491 INLINE void CMPGE(sh2_state *sh2, UINT32 m, UINT32 n)
\r
493 if ((INT32) sh2->r[n] >= (INT32) sh2->r[m])
\r
499 /* code cycles t-bit
\r
500 * 0011 nnnn mmmm 0111 1 comparison result
\r
503 INLINE void CMPGT(sh2_state *sh2, UINT32 m, UINT32 n)
\r
505 if ((INT32) sh2->r[n] > (INT32) sh2->r[m])
\r
511 /* code cycles t-bit
\r
512 * 0011 nnnn mmmm 0110 1 comparison result
\r
515 INLINE void CMPHI(sh2_state *sh2, UINT32 m, UINT32 n)
\r
517 if ((UINT32) sh2->r[n] > (UINT32) sh2->r[m])
\r
523 /* code cycles t-bit
\r
524 * 0011 nnnn mmmm 0010 1 comparison result
\r
527 INLINE void CMPHS(sh2_state *sh2, UINT32 m, UINT32 n)
\r
529 if ((UINT32) sh2->r[n] >= (UINT32) sh2->r[m])
\r
536 /* code cycles t-bit
\r
537 * 0100 nnnn 0001 0101 1 comparison result
\r
540 INLINE void CMPPL(sh2_state *sh2, UINT32 n)
\r
542 if ((INT32) sh2->r[n] > 0)
\r
548 /* code cycles t-bit
\r
549 * 0100 nnnn 0001 0001 1 comparison result
\r
552 INLINE void CMPPZ(sh2_state *sh2, UINT32 n)
\r
554 if ((INT32) sh2->r[n] >= 0)
\r
560 /* code cycles t-bit
\r
561 * 0010 nnnn mmmm 1100 1 comparison result
\r
564 INLINE void CMPSTR(sh2_state *sh2, UINT32 m, UINT32 n)
\r
567 INT32 HH, HL, LH, LL;
\r
568 temp = sh2->r[n] ^ sh2->r[m];
\r
569 HH = (temp >> 24) & 0xff;
\r
570 HL = (temp >> 16) & 0xff;
\r
571 LH = (temp >> 8) & 0xff;
\r
573 if (HH && HL && LH && LL)
\r
580 /* code cycles t-bit
\r
581 * 1000 1000 iiii iiii 1 comparison result
\r
584 INLINE void CMPIM(sh2_state *sh2, UINT32 i)
\r
586 UINT32 imm = (UINT32)(INT32)(INT16)(INT8)i;
\r
588 if (sh2->r[0] == imm)
\r
594 /* code cycles t-bit
\r
595 * 0010 nnnn mmmm 0111 1 calculation result
\r
598 INLINE void DIV0S(sh2_state *sh2, UINT32 m, UINT32 n)
\r
600 if ((sh2->r[n] & 0x80000000) == 0)
\r
604 if ((sh2->r[m] & 0x80000000) == 0)
\r
608 if ((sh2->r[m] ^ sh2->r[n]) & 0x80000000)
\r
614 /* code cycles t-bit
\r
615 * 0000 0000 0001 1001 1 0
\r
618 INLINE void DIV0U(sh2_state *sh2)
\r
620 sh2->sr &= ~(M | Q | T);
\r
623 /* code cycles t-bit
\r
624 * 0011 nnnn mmmm 0100 1 calculation result
\r
627 INLINE void DIV1(sh2_state *sh2, UINT32 m, UINT32 n)
\r
632 old_q = sh2->sr & Q;
\r
633 if (0x80000000 & sh2->r[n])
\r
638 sh2->r[n] = (sh2->r[n] << 1) | (sh2->sr & T);
\r
642 if (!(sh2->sr & M))
\r
645 sh2->r[n] -= sh2->r[m];
\r
647 if(sh2->r[n] > tmp0)
\r
652 if(sh2->r[n] > tmp0)
\r
660 sh2->r[n] += sh2->r[m];
\r
663 if(sh2->r[n] < tmp0)
\r
670 if(sh2->r[n] < tmp0)
\r
679 if (!(sh2->sr & M))
\r
682 sh2->r[n] += sh2->r[m];
\r
684 if(sh2->r[n] < tmp0)
\r
689 if(sh2->r[n] < tmp0)
\r
697 sh2->r[n] -= sh2->r[m];
\r
699 if(sh2->r[n] > tmp0)
\r
704 if(sh2->r[n] > tmp0)
\r
711 tmp0 = (sh2->sr & (Q | M));
\r
712 if((!tmp0) || (tmp0 == 0x300)) /* if Q == M set T else clear T */
\r
718 /* DMULS.L Rm,Rn */
\r
719 INLINE void DMULS(sh2_state *sh2, UINT32 m, UINT32 n)
\r
721 UINT32 RnL, RnH, RmL, RmH, Res0, Res1, Res2;
\r
722 UINT32 temp0, temp1, temp2, temp3;
\r
723 INT32 tempm, tempn, fnLmL;
\r
725 tempn = (INT32) sh2->r[n];
\r
726 tempm = (INT32) sh2->r[m];
\r
731 if ((INT32) (sh2->r[n] ^ sh2->r[m]) < 0)
\r
735 temp1 = (UINT32) tempn;
\r
736 temp2 = (UINT32) tempm;
\r
737 RnL = temp1 & 0x0000ffff;
\r
738 RnH = (temp1 >> 16) & 0x0000ffff;
\r
739 RmL = temp2 & 0x0000ffff;
\r
740 RmH = (temp2 >> 16) & 0x0000ffff;
\r
746 Res1 = temp1 + temp2;
\r
748 Res2 += 0x00010000;
\r
749 temp1 = (Res1 << 16) & 0xffff0000;
\r
750 Res0 = temp0 + temp1;
\r
753 Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;
\r
760 Res0 = (~Res0) + 1;
\r
767 /* DMULU.L Rm,Rn */
\r
768 INLINE void DMULU(sh2_state *sh2, UINT32 m, UINT32 n)
\r
770 UINT32 RnL, RnH, RmL, RmH, Res0, Res1, Res2;
\r
771 UINT32 temp0, temp1, temp2, temp3;
\r
773 RnL = sh2->r[n] & 0x0000ffff;
\r
774 RnH = (sh2->r[n] >> 16) & 0x0000ffff;
\r
775 RmL = sh2->r[m] & 0x0000ffff;
\r
776 RmH = (sh2->r[m] >> 16) & 0x0000ffff;
\r
782 Res1 = temp1 + temp2;
\r
784 Res2 += 0x00010000;
\r
785 temp1 = (Res1 << 16) & 0xffff0000;
\r
786 Res0 = temp0 + temp1;
\r
789 Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;
\r
796 INLINE void DT(sh2_state *sh2, UINT32 n)
\r
799 if (sh2->r[n] == 0)
\r
803 #if BUSY_LOOP_HACKS
\r
805 UINT32 next_opcode = RW( sh2, sh2->ppc & AM );
\r
809 if (next_opcode == 0x8bfd)
\r
811 while (sh2->r[n] > 1 && sh2->icount > 4)
\r
814 sh2->icount -= 4; /* cycles for DT (1) and BF taken (3) */
\r
822 INLINE void EXTSB(sh2_state *sh2, UINT32 m, UINT32 n)
\r
824 sh2->r[n] = ((INT32)sh2->r[m] << 24) >> 24;
\r
828 INLINE void EXTSW(sh2_state *sh2, UINT32 m, UINT32 n)
\r
830 sh2->r[n] = ((INT32)sh2->r[m] << 16) >> 16;
\r
834 INLINE void EXTUB(sh2_state *sh2, UINT32 m, UINT32 n)
\r
836 sh2->r[n] = sh2->r[m] & 0x000000ff;
\r
840 INLINE void EXTUW(sh2_state *sh2, UINT32 m, UINT32 n)
\r
842 sh2->r[n] = sh2->r[m] & 0x0000ffff;
\r
846 INLINE void ILLEGAL(sh2_state *sh2)
\r
848 logerror("SH2: Illegal opcode at %08x\n", sh2->pc - 2);
\r
850 WL( sh2, sh2->r[15], sh2->sr ); /* push SR onto stack */
\r
852 WL( sh2, sh2->r[15], sh2->pc - 2 ); /* push PC onto stack */
\r
855 sh2->pc = RL( sh2, sh2->vbr + 4 * 4 );
\r
857 /* TODO: timing is a guess */
\r
863 INLINE void JMP(sh2_state *sh2, UINT32 m)
\r
865 sh2->delay = sh2->pc;
\r
866 sh2->pc = sh2->ea = sh2->r[m];
\r
871 INLINE void JSR(sh2_state *sh2, UINT32 m)
\r
873 sh2->delay = sh2->pc;
\r
874 sh2->pr = sh2->pc + 2;
\r
875 sh2->pc = sh2->ea = sh2->r[m];
\r
881 INLINE void LDCSR(sh2_state *sh2, UINT32 m)
\r
883 sh2->sr = sh2->r[m] & FLAGS;
\r
888 INLINE void LDCGBR(sh2_state *sh2, UINT32 m)
\r
890 sh2->gbr = sh2->r[m];
\r
894 INLINE void LDCVBR(sh2_state *sh2, UINT32 m)
\r
896 sh2->vbr = sh2->r[m];
\r
899 /* LDC.L @Rm+,SR */
\r
900 INLINE void LDCMSR(sh2_state *sh2, UINT32 m)
\r
902 sh2->ea = sh2->r[m];
\r
903 sh2->sr = RL( sh2, sh2->ea ) & FLAGS;
\r
909 /* LDC.L @Rm+,GBR */
\r
910 INLINE void LDCMGBR(sh2_state *sh2, UINT32 m)
\r
912 sh2->ea = sh2->r[m];
\r
913 sh2->gbr = RL( sh2, sh2->ea );
\r
918 /* LDC.L @Rm+,VBR */
\r
919 INLINE void LDCMVBR(sh2_state *sh2, UINT32 m)
\r
921 sh2->ea = sh2->r[m];
\r
922 sh2->vbr = RL( sh2, sh2->ea );
\r
928 INLINE void LDSMACH(sh2_state *sh2, UINT32 m)
\r
930 sh2->mach = sh2->r[m];
\r
934 INLINE void LDSMACL(sh2_state *sh2, UINT32 m)
\r
936 sh2->macl = sh2->r[m];
\r
940 INLINE void LDSPR(sh2_state *sh2, UINT32 m)
\r
942 sh2->pr = sh2->r[m];
\r
945 /* LDS.L @Rm+,MACH */
\r
946 INLINE void LDSMMACH(sh2_state *sh2, UINT32 m)
\r
948 sh2->ea = sh2->r[m];
\r
949 sh2->mach = RL( sh2, sh2->ea );
\r
953 /* LDS.L @Rm+,MACL */
\r
954 INLINE void LDSMMACL(sh2_state *sh2, UINT32 m)
\r
956 sh2->ea = sh2->r[m];
\r
957 sh2->macl = RL( sh2, sh2->ea );
\r
961 /* LDS.L @Rm+,PR */
\r
962 INLINE void LDSMPR(sh2_state *sh2, UINT32 m)
\r
964 sh2->ea = sh2->r[m];
\r
965 sh2->pr = RL( sh2, sh2->ea );
\r
969 /* MAC.L @Rm+,@Rn+ */
\r
970 INLINE void MAC_L(sh2_state *sh2, UINT32 m, UINT32 n)
\r
972 UINT32 RnL, RnH, RmL, RmH, Res0, Res1, Res2;
\r
973 UINT32 temp0, temp1, temp2, temp3;
\r
974 INT32 tempm, tempn, fnLmL;
\r
976 tempn = (INT32) RL( sh2, sh2->r[n] );
\r
978 tempm = (INT32) RL( sh2, sh2->r[m] );
\r
980 if ((INT32) (tempn ^ tempm) < 0)
\r
988 temp1 = (UINT32) tempn;
\r
989 temp2 = (UINT32) tempm;
\r
990 RnL = temp1 & 0x0000ffff;
\r
991 RnH = (temp1 >> 16) & 0x0000ffff;
\r
992 RmL = temp2 & 0x0000ffff;
\r
993 RmH = (temp2 >> 16) & 0x0000ffff;
\r
999 Res1 = temp1 + temp2;
\r
1001 Res2 += 0x00010000;
\r
1002 temp1 = (Res1 << 16) & 0xffff0000;
\r
1003 Res0 = temp0 + temp1;
\r
1006 Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;
\r
1013 Res0 = (~Res0) + 1;
\r
1017 Res0 = sh2->macl + Res0;
\r
1018 if (sh2->macl > Res0)
\r
1020 Res2 += (sh2->mach & 0x0000ffff);
\r
1021 if (((INT32) Res2 < 0) && (Res2 < 0xffff8000))
\r
1023 Res2 = 0x00008000;
\r
1024 Res0 = 0x00000000;
\r
1026 else if (((INT32) Res2 > 0) && (Res2 > 0x00007fff))
\r
1028 Res2 = 0x00007fff;
\r
1029 Res0 = 0xffffffff;
\r
1036 Res0 = sh2->macl + Res0;
\r
1037 if (sh2->macl > Res0)
\r
1039 Res2 += sh2->mach;
\r
1046 /* MAC.W @Rm+,@Rn+ */
\r
1047 INLINE void MAC_W(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1049 INT32 tempm, tempn, dest, src, ans;
\r
1052 tempn = (INT32) RW( sh2, sh2->r[n] );
\r
1054 tempm = (INT32) RW( sh2, sh2->r[m] );
\r
1056 templ = sh2->macl;
\r
1057 tempm = ((INT32) (short) tempn * (INT32) (short) tempm);
\r
1058 if ((INT32) sh2->macl >= 0)
\r
1062 if ((INT32) tempm >= 0)
\r
1070 tempn = 0xffffffff;
\r
1073 sh2->macl += tempm;
\r
1074 if ((INT32) sh2->macl >= 0)
\r
1084 sh2->macl = 0x7fffffff;
\r
1086 sh2->macl = 0x80000000;
\r
1091 sh2->mach += tempn;
\r
1092 if (templ > sh2->macl)
\r
1099 INLINE void MOV(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1101 sh2->r[n] = sh2->r[m];
\r
1104 /* MOV.B Rm,@Rn */
\r
1105 INLINE void MOVBS(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1107 sh2->ea = sh2->r[n];
\r
1108 WB( sh2, sh2->ea, sh2->r[m] & 0x000000ff);
\r
1111 /* MOV.W Rm,@Rn */
\r
1112 INLINE void MOVWS(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1114 sh2->ea = sh2->r[n];
\r
1115 WW( sh2, sh2->ea, sh2->r[m] & 0x0000ffff);
\r
1118 /* MOV.L Rm,@Rn */
\r
1119 INLINE void MOVLS(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1121 sh2->ea = sh2->r[n];
\r
1122 WL( sh2, sh2->ea, sh2->r[m] );
\r
1125 /* MOV.B @Rm,Rn */
\r
1126 INLINE void MOVBL(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1128 sh2->ea = sh2->r[m];
\r
1129 sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->ea );
\r
1132 /* MOV.W @Rm,Rn */
\r
1133 INLINE void MOVWL(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1135 sh2->ea = sh2->r[m];
\r
1136 sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2, sh2->ea );
\r
1139 /* MOV.L @Rm,Rn */
\r
1140 INLINE void MOVLL(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1142 sh2->ea = sh2->r[m];
\r
1143 sh2->r[n] = RL( sh2, sh2->ea );
\r
1146 /* MOV.B Rm,@-Rn */
\r
1147 INLINE void MOVBM(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1149 /* SMG : bug fix, was reading sh2->r[n] */
\r
1150 UINT32 data = sh2->r[m] & 0x000000ff;
\r
1153 WB( sh2, sh2->r[n], data );
\r
1156 /* MOV.W Rm,@-Rn */
\r
1157 INLINE void MOVWM(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1159 UINT32 data = sh2->r[m] & 0x0000ffff;
\r
1162 WW( sh2, sh2->r[n], data );
\r
1165 /* MOV.L Rm,@-Rn */
\r
1166 INLINE void MOVLM(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1168 UINT32 data = sh2->r[m];
\r
1171 WL( sh2, sh2->r[n], data );
\r
1174 /* MOV.B @Rm+,Rn */
\r
1175 INLINE void MOVBP(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1177 sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->r[m] );
\r
1182 /* MOV.W @Rm+,Rn */
\r
1183 INLINE void MOVWP(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1185 sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2, sh2->r[m] );
\r
1190 /* MOV.L @Rm+,Rn */
\r
1191 INLINE void MOVLP(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1193 sh2->r[n] = RL( sh2, sh2->r[m] );
\r
1198 /* MOV.B Rm,@(R0,Rn) */
\r
1199 INLINE void MOVBS0(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1201 sh2->ea = sh2->r[n] + sh2->r[0];
\r
1202 WB( sh2, sh2->ea, sh2->r[m] & 0x000000ff );
\r
1205 /* MOV.W Rm,@(R0,Rn) */
\r
1206 INLINE void MOVWS0(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1208 sh2->ea = sh2->r[n] + sh2->r[0];
\r
1209 WW( sh2, sh2->ea, sh2->r[m] & 0x0000ffff );
\r
1212 /* MOV.L Rm,@(R0,Rn) */
\r
1213 INLINE void MOVLS0(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1215 sh2->ea = sh2->r[n] + sh2->r[0];
\r
1216 WL( sh2, sh2->ea, sh2->r[m] );
\r
1219 /* MOV.B @(R0,Rm),Rn */
\r
1220 INLINE void MOVBL0(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1222 sh2->ea = sh2->r[m] + sh2->r[0];
\r
1223 sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->ea );
\r
1226 /* MOV.W @(R0,Rm),Rn */
\r
1227 INLINE void MOVWL0(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1229 sh2->ea = sh2->r[m] + sh2->r[0];
\r
1230 sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2, sh2->ea );
\r
1233 /* MOV.L @(R0,Rm),Rn */
\r
1234 INLINE void MOVLL0(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1236 sh2->ea = sh2->r[m] + sh2->r[0];
\r
1237 sh2->r[n] = RL( sh2, sh2->ea );
\r
1241 INLINE void MOVI(sh2_state *sh2, UINT32 i, UINT32 n)
\r
1243 sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) i;
\r
1246 /* MOV.W @(disp8,PC),Rn */
\r
1247 INLINE void MOVWI(sh2_state *sh2, UINT32 d, UINT32 n)
\r
1249 UINT32 disp = d & 0xff;
\r
1250 sh2->ea = sh2->pc + disp * 2 + 2;
\r
1251 sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2, sh2->ea );
\r
1254 /* MOV.L @(disp8,PC),Rn */
\r
1255 INLINE void MOVLI(sh2_state *sh2, UINT32 d, UINT32 n)
\r
1257 UINT32 disp = d & 0xff;
\r
1258 sh2->ea = ((sh2->pc + 2) & ~3) + disp * 4;
\r
1259 sh2->r[n] = RL( sh2, sh2->ea );
\r
1262 /* MOV.B @(disp8,GBR),R0 */
\r
1263 INLINE void MOVBLG(sh2_state *sh2, UINT32 d)
\r
1265 UINT32 disp = d & 0xff;
\r
1266 sh2->ea = sh2->gbr + disp;
\r
1267 sh2->r[0] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->ea );
\r
1270 /* MOV.W @(disp8,GBR),R0 */
\r
1271 INLINE void MOVWLG(sh2_state *sh2, UINT32 d)
\r
1273 UINT32 disp = d & 0xff;
\r
1274 sh2->ea = sh2->gbr + disp * 2;
\r
1275 sh2->r[0] = (INT32)(INT16) RW( sh2, sh2->ea );
\r
1278 /* MOV.L @(disp8,GBR),R0 */
\r
1279 INLINE void MOVLLG(sh2_state *sh2, UINT32 d)
\r
1281 UINT32 disp = d & 0xff;
\r
1282 sh2->ea = sh2->gbr + disp * 4;
\r
1283 sh2->r[0] = RL( sh2, sh2->ea );
\r
1286 /* MOV.B R0,@(disp8,GBR) */
\r
1287 INLINE void MOVBSG(sh2_state *sh2, UINT32 d)
\r
1289 UINT32 disp = d & 0xff;
\r
1290 sh2->ea = sh2->gbr + disp;
\r
1291 WB( sh2, sh2->ea, sh2->r[0] & 0x000000ff );
\r
1294 /* MOV.W R0,@(disp8,GBR) */
\r
1295 INLINE void MOVWSG(sh2_state *sh2, UINT32 d)
\r
1297 UINT32 disp = d & 0xff;
\r
1298 sh2->ea = sh2->gbr + disp * 2;
\r
1299 WW( sh2, sh2->ea, sh2->r[0] & 0x0000ffff );
\r
1302 /* MOV.L R0,@(disp8,GBR) */
\r
1303 INLINE void MOVLSG(sh2_state *sh2, UINT32 d)
\r
1305 UINT32 disp = d & 0xff;
\r
1306 sh2->ea = sh2->gbr + disp * 4;
\r
1307 WL( sh2, sh2->ea, sh2->r[0] );
\r
1310 /* MOV.B R0,@(disp4,Rn) */
\r
1311 INLINE void MOVBS4(sh2_state *sh2, UINT32 d, UINT32 n)
\r
1313 UINT32 disp = d & 0x0f;
\r
1314 sh2->ea = sh2->r[n] + disp;
\r
1315 WB( sh2, sh2->ea, sh2->r[0] & 0x000000ff );
\r
1318 /* MOV.W R0,@(disp4,Rn) */
\r
1319 INLINE void MOVWS4(sh2_state *sh2, UINT32 d, UINT32 n)
\r
1321 UINT32 disp = d & 0x0f;
\r
1322 sh2->ea = sh2->r[n] + disp * 2;
\r
1323 WW( sh2, sh2->ea, sh2->r[0] & 0x0000ffff );
\r
1326 /* MOV.L Rm,@(disp4,Rn) */
\r
1327 INLINE void MOVLS4(sh2_state *sh2, UINT32 m, UINT32 d, UINT32 n)
\r
1329 UINT32 disp = d & 0x0f;
\r
1330 sh2->ea = sh2->r[n] + disp * 4;
\r
1331 WL( sh2, sh2->ea, sh2->r[m] );
\r
1334 /* MOV.B @(disp4,Rm),R0 */
\r
1335 INLINE void MOVBL4(sh2_state *sh2, UINT32 m, UINT32 d)
\r
1337 UINT32 disp = d & 0x0f;
\r
1338 sh2->ea = sh2->r[m] + disp;
\r
1339 sh2->r[0] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->ea );
\r
1342 /* MOV.W @(disp4,Rm),R0 */
\r
1343 INLINE void MOVWL4(sh2_state *sh2, UINT32 m, UINT32 d)
\r
1345 UINT32 disp = d & 0x0f;
\r
1346 sh2->ea = sh2->r[m] + disp * 2;
\r
1347 sh2->r[0] = (UINT32)(INT32)(INT16) RW( sh2, sh2->ea );
\r
1350 /* MOV.L @(disp4,Rm),Rn */
\r
1351 INLINE void MOVLL4(sh2_state *sh2, UINT32 m, UINT32 d, UINT32 n)
\r
1353 UINT32 disp = d & 0x0f;
\r
1354 sh2->ea = sh2->r[m] + disp * 4;
\r
1355 sh2->r[n] = RL( sh2, sh2->ea );
\r
1358 /* MOVA @(disp8,PC),R0 */
\r
1359 INLINE void MOVA(sh2_state *sh2, UINT32 d)
\r
1361 UINT32 disp = d & 0xff;
\r
1362 sh2->ea = ((sh2->pc + 2) & ~3) + disp * 4;
\r
1363 sh2->r[0] = sh2->ea;
\r
1367 INLINE void MOVT(sh2_state *sh2, UINT32 n)
\r
1369 sh2->r[n] = sh2->sr & T;
\r
1373 INLINE void MULL(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1375 sh2->macl = sh2->r[n] * sh2->r[m];
\r
1380 INLINE void MULS(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1382 sh2->macl = (INT16) sh2->r[n] * (INT16) sh2->r[m];
\r
1386 INLINE void MULU(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1388 sh2->macl = (UINT16) sh2->r[n] * (UINT16) sh2->r[m];
\r
1392 INLINE void NEG(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1394 sh2->r[n] = 0 - sh2->r[m];
\r
1398 INLINE void NEGC(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1403 sh2->r[n] = -temp - (sh2->sr & T);
\r
1404 if (temp || (sh2->sr & T))
\r
1411 INLINE void NOP(void)
\r
1416 INLINE void NOT(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1418 sh2->r[n] = ~sh2->r[m];
\r
1422 INLINE void OR(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1424 sh2->r[n] |= sh2->r[m];
\r
1428 INLINE void ORI(sh2_state *sh2, UINT32 i)
\r
1433 /* OR.B #imm,@(R0,GBR) */
\r
1434 INLINE void ORM(sh2_state *sh2, UINT32 i)
\r
1438 sh2->ea = sh2->gbr + sh2->r[0];
\r
1439 temp = RB( sh2, sh2->ea );
\r
1441 WB( sh2, sh2->ea, temp );
\r
1446 INLINE void ROTCL(sh2_state *sh2, UINT32 n)
\r
1450 temp = (sh2->r[n] >> 31) & T;
\r
1451 sh2->r[n] = (sh2->r[n] << 1) | (sh2->sr & T);
\r
1452 sh2->sr = (sh2->sr & ~T) | temp;
\r
1456 INLINE void ROTCR(sh2_state *sh2, UINT32 n)
\r
1459 temp = (sh2->sr & T) << 31;
\r
1460 if (sh2->r[n] & T)
\r
1464 sh2->r[n] = (sh2->r[n] >> 1) | temp;
\r
1468 INLINE void ROTL(sh2_state *sh2, UINT32 n)
\r
1470 sh2->sr = (sh2->sr & ~T) | ((sh2->r[n] >> 31) & T);
\r
1471 sh2->r[n] = (sh2->r[n] << 1) | (sh2->r[n] >> 31);
\r
1475 INLINE void ROTR(sh2_state *sh2, UINT32 n)
\r
1477 sh2->sr = (sh2->sr & ~T) | (sh2->r[n] & T);
\r
1478 sh2->r[n] = (sh2->r[n] >> 1) | (sh2->r[n] << 31);
\r
1482 INLINE void RTE(sh2_state *sh2)
\r
1484 sh2->ea = sh2->r[15];
\r
1485 sh2->delay = sh2->pc;
\r
1486 sh2->pc = RL( sh2, sh2->ea );
\r
1488 sh2->ea = sh2->r[15];
\r
1489 sh2->sr = RL( sh2, sh2->ea ) & FLAGS;
\r
1492 sh2->test_irq = 1;
\r
1496 INLINE void RTS(sh2_state *sh2)
\r
1498 sh2->delay = sh2->pc;
\r
1499 sh2->pc = sh2->ea = sh2->pr;
\r
1504 INLINE void SETT(sh2_state *sh2)
\r
1509 /* SHAL Rn (same as SHLL) */
\r
1510 INLINE void SHAL(sh2_state *sh2, UINT32 n)
\r
1512 sh2->sr = (sh2->sr & ~T) | ((sh2->r[n] >> 31) & T);
\r
1517 INLINE void SHAR(sh2_state *sh2, UINT32 n)
\r
1519 sh2->sr = (sh2->sr & ~T) | (sh2->r[n] & T);
\r
1520 sh2->r[n] = (UINT32)((INT32)sh2->r[n] >> 1);
\r
1523 /* SHLL Rn (same as SHAL) */
\r
1524 INLINE void SHLL(sh2_state *sh2, UINT32 n)
\r
1526 sh2->sr = (sh2->sr & ~T) | ((sh2->r[n] >> 31) & T);
\r
1531 INLINE void SHLL2(sh2_state *sh2, UINT32 n)
\r
1537 INLINE void SHLL8(sh2_state *sh2, UINT32 n)
\r
1543 INLINE void SHLL16(sh2_state *sh2, UINT32 n)
\r
1549 INLINE void SHLR(sh2_state *sh2, UINT32 n)
\r
1551 sh2->sr = (sh2->sr & ~T) | (sh2->r[n] & T);
\r
1556 INLINE void SHLR2(sh2_state *sh2, UINT32 n)
\r
1562 INLINE void SHLR8(sh2_state *sh2, UINT32 n)
\r
1568 INLINE void SHLR16(sh2_state *sh2, UINT32 n)
\r
1574 INLINE void SLEEP(sh2_state *sh2)
\r
1576 //if(sh2->sleep_mode != 2)
\r
1579 /* Wait_for_exception; */
\r
1580 /*if(sh2->sleep_mode == 0)
\r
1581 sh2->sleep_mode = 1;
\r
1582 else if(sh2->sleep_mode == 2)
\r
1583 sh2->sleep_mode = 0;*/
\r
1587 INLINE void STCSR(sh2_state *sh2, UINT32 n)
\r
1589 sh2->r[n] = sh2->sr;
\r
1593 INLINE void STCGBR(sh2_state *sh2, UINT32 n)
\r
1595 sh2->r[n] = sh2->gbr;
\r
1599 INLINE void STCVBR(sh2_state *sh2, UINT32 n)
\r
1601 sh2->r[n] = sh2->vbr;
\r
1604 /* STC.L SR,@-Rn */
\r
1605 INLINE void STCMSR(sh2_state *sh2, UINT32 n)
\r
1608 sh2->ea = sh2->r[n];
\r
1609 WL( sh2, sh2->ea, sh2->sr );
\r
1613 /* STC.L GBR,@-Rn */
\r
1614 INLINE void STCMGBR(sh2_state *sh2, UINT32 n)
\r
1617 sh2->ea = sh2->r[n];
\r
1618 WL( sh2, sh2->ea, sh2->gbr );
\r
1622 /* STC.L VBR,@-Rn */
\r
1623 INLINE void STCMVBR(sh2_state *sh2, UINT32 n)
\r
1626 sh2->ea = sh2->r[n];
\r
1627 WL( sh2, sh2->ea, sh2->vbr );
\r
1632 INLINE void STSMACH(sh2_state *sh2, UINT32 n)
\r
1634 sh2->r[n] = sh2->mach;
\r
1638 INLINE void STSMACL(sh2_state *sh2, UINT32 n)
\r
1640 sh2->r[n] = sh2->macl;
\r
1644 INLINE void STSPR(sh2_state *sh2, UINT32 n)
\r
1646 sh2->r[n] = sh2->pr;
\r
1649 /* STS.L MACH,@-Rn */
\r
1650 INLINE void STSMMACH(sh2_state *sh2, UINT32 n)
\r
1653 sh2->ea = sh2->r[n];
\r
1654 WL( sh2, sh2->ea, sh2->mach );
\r
1657 /* STS.L MACL,@-Rn */
\r
1658 INLINE void STSMMACL(sh2_state *sh2, UINT32 n)
\r
1661 sh2->ea = sh2->r[n];
\r
1662 WL( sh2, sh2->ea, sh2->macl );
\r
1665 /* STS.L PR,@-Rn */
\r
1666 INLINE void STSMPR(sh2_state *sh2, UINT32 n)
\r
1669 sh2->ea = sh2->r[n];
\r
1670 WL( sh2, sh2->ea, sh2->pr );
\r
1674 INLINE void SUB(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1676 sh2->r[n] -= sh2->r[m];
\r
1680 INLINE void SUBC(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1682 UINT32 tmp0, tmp1;
\r
1684 tmp1 = sh2->r[n] - sh2->r[m];
\r
1686 sh2->r[n] = tmp1 - (sh2->sr & T);
\r
1691 if (tmp1 < sh2->r[n])
\r
1696 INLINE void SUBV(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1698 INT32 dest, src, ans;
\r
1700 if ((INT32) sh2->r[n] >= 0)
\r
1704 if ((INT32) sh2->r[m] >= 0)
\r
1709 sh2->r[n] -= sh2->r[m];
\r
1710 if ((INT32) sh2->r[n] >= 0)
\r
1726 /* SWAP.B Rm,Rn */
\r
1727 INLINE void SWAPB(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1729 UINT32 temp0, temp1;
\r
1731 temp0 = sh2->r[m] & 0xffff0000;
\r
1732 temp1 = (sh2->r[m] & 0x000000ff) << 8;
\r
1733 sh2->r[n] = (sh2->r[m] >> 8) & 0x000000ff;
\r
1734 sh2->r[n] = sh2->r[n] | temp1 | temp0;
\r
1737 /* SWAP.W Rm,Rn */
\r
1738 INLINE void SWAPW(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1742 temp = (sh2->r[m] >> 16) & 0x0000ffff;
\r
1743 sh2->r[n] = (sh2->r[m] << 16) | temp;
\r
1747 INLINE void TAS(sh2_state *sh2, UINT32 n)
\r
1750 sh2->ea = sh2->r[n];
\r
1751 /* Bus Lock enable */
\r
1752 temp = RB( sh2, sh2->ea );
\r
1758 /* Bus Lock disable */
\r
1759 WB( sh2, sh2->ea, temp );
\r
1764 INLINE void TRAPA(sh2_state *sh2, UINT32 i)
\r
1766 UINT32 imm = i & 0xff;
\r
1768 sh2->ea = sh2->vbr + imm * 4;
\r
1771 WL( sh2, sh2->r[15], sh2->sr );
\r
1773 WL( sh2, sh2->r[15], sh2->pc );
\r
1775 sh2->pc = RL( sh2, sh2->ea );
\r
1781 INLINE void TST(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1783 if ((sh2->r[n] & sh2->r[m]) == 0)
\r
1790 INLINE void TSTI(sh2_state *sh2, UINT32 i)
\r
1792 UINT32 imm = i & 0xff;
\r
1794 if ((imm & sh2->r[0]) == 0)
\r
1800 /* TST.B #imm,@(R0,GBR) */
\r
1801 INLINE void TSTM(sh2_state *sh2, UINT32 i)
\r
1803 UINT32 imm = i & 0xff;
\r
1805 sh2->ea = sh2->gbr + sh2->r[0];
\r
1806 if ((imm & RB( sh2, sh2->ea )) == 0)
\r
1814 INLINE void XOR(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1816 sh2->r[n] ^= sh2->r[m];
\r
1820 INLINE void XORI(sh2_state *sh2, UINT32 i)
\r
1822 UINT32 imm = i & 0xff;
\r
1826 /* XOR.B #imm,@(R0,GBR) */
\r
1827 INLINE void XORM(sh2_state *sh2, UINT32 i)
\r
1829 UINT32 imm = i & 0xff;
\r
1832 sh2->ea = sh2->gbr + sh2->r[0];
\r
1833 temp = RB( sh2, sh2->ea );
\r
1835 WB( sh2, sh2->ea, temp );
\r
1840 INLINE void XTRCT(sh2_state *sh2, UINT32 m, UINT32 n)
\r
1844 temp = (sh2->r[m] << 16) & 0xffff0000;
\r
1845 sh2->r[n] = (sh2->r[n] >> 16) & 0x0000ffff;
\r
1846 sh2->r[n] |= temp;
\r
1849 /*****************************************************************************
\r
1850 * OPCODE DISPATCHERS
\r
1851 *****************************************************************************/
\r
1853 INLINE void op0000(sh2_state *sh2, UINT16 opcode)
\r
1855 switch (opcode & 0x3F)
\r
1857 case 0x00: ILLEGAL(sh2); rlog(0); break;
\r
1858 case 0x01: ILLEGAL(sh2); rlog(0); break;
\r
1859 case 0x02: STCSR(sh2, Rn); rlog(LRN); break;
\r
1860 case 0x03: BSRF(sh2, Rn); rlog(LRN); break;
\r
1861 case 0x04: MOVBS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1862 case 0x05: MOVWS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1863 case 0x06: MOVLS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1864 case 0x07: MULL(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;
\r
1865 case 0x08: CLRT(sh2); rlog(0); break;
\r
1866 case 0x09: NOP(); rlog(0); break;
\r
1867 case 0x0a: STSMACH(sh2, Rn); rlog(LRN); rlog1(SHR_MACH); break;
\r
1868 case 0x0b: RTS(sh2); rlog(0); rlog1(SHR_PR); break;
\r
1869 case 0x0c: MOVBL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1870 case 0x0d: MOVWL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1871 case 0x0e: MOVLL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1872 case 0x0f: MAC_L(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
1874 case 0x10: ILLEGAL(sh2); rlog(0); break;
\r
1875 case 0x11: ILLEGAL(sh2); rlog(0); break;
\r
1876 case 0x12: STCGBR(sh2, Rn); rlog(LRN); rlog1(SHR_GBR); break;
\r
1877 case 0x13: ILLEGAL(sh2); rlog(0); break;
\r
1878 case 0x14: MOVBS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1879 case 0x15: MOVWS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1880 case 0x16: MOVLS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1881 case 0x17: MULL(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;
\r
1882 case 0x18: SETT(sh2); rlog(0); break;
\r
1883 case 0x19: DIV0U(sh2); rlog(0); break;
\r
1884 case 0x1a: STSMACL(sh2, Rn); rlog(LRN); rlog1(SHR_MACL); break;
\r
1885 case 0x1b: SLEEP(sh2); rlog(0); break;
\r
1886 case 0x1c: MOVBL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1887 case 0x1d: MOVWL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1888 case 0x1e: MOVLL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1889 case 0x1f: MAC_L(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
1891 case 0x20: ILLEGAL(sh2); rlog(0); break;
\r
1892 case 0x21: ILLEGAL(sh2); rlog(0); break;
\r
1893 case 0x22: STCVBR(sh2, Rn); rlog(LRN); rlog1(SHR_VBR); break;
\r
1894 case 0x23: BRAF(sh2, Rn); rlog(LRN); break;
\r
1895 case 0x24: MOVBS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1896 case 0x25: MOVWS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1897 case 0x26: MOVLS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1898 case 0x27: MULL(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;
\r
1899 case 0x28: CLRMAC(sh2); rlog(0); rlog2(SHR_MACL,SHR_MACH); break;
\r
1900 case 0x29: MOVT(sh2, Rn); rlog(LRN); break;
\r
1901 case 0x2a: STSPR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;
\r
1902 case 0x2b: RTE(sh2); rlog(0); break;
\r
1903 case 0x2c: MOVBL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1904 case 0x2d: MOVWL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1905 case 0x2e: MOVLL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1906 case 0x2f: MAC_L(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
1908 case 0x30: ILLEGAL(sh2); rlog(0); break;
\r
1909 case 0x31: ILLEGAL(sh2); rlog(0); break;
\r
1910 case 0x32: ILLEGAL(sh2); rlog(0); break;
\r
1911 case 0x33: ILLEGAL(sh2); rlog(0); break;
\r
1912 case 0x34: MOVBS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1913 case 0x35: MOVWS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1914 case 0x36: MOVLS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1915 case 0x37: MULL(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;
\r
1916 case 0x38: ILLEGAL(sh2); rlog(0); break;
\r
1917 case 0x39: ILLEGAL(sh2); rlog(0); break;
\r
1918 case 0x3c: MOVBL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1919 case 0x3d: MOVWL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1920 case 0x3e: MOVLL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;
\r
1921 case 0x3f: MAC_L(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
1922 case 0x3a: ILLEGAL(sh2); rlog(0); break;
\r
1923 case 0x3b: ILLEGAL(sh2); rlog(0); break;
\r
1927 INLINE void op0001(sh2_state *sh2, UINT16 opcode)
\r
1929 MOVLS4(sh2, Rm, opcode & 0x0f, Rn);
\r
1933 INLINE void op0010(sh2_state *sh2, UINT16 opcode)
\r
1935 switch (opcode & 15)
\r
1937 case 0: MOVBS(sh2, Rm, Rn); rlog(LRNM); break;
\r
1938 case 1: MOVWS(sh2, Rm, Rn); rlog(LRNM); break;
\r
1939 case 2: MOVLS(sh2, Rm, Rn); rlog(LRNM); break;
\r
1940 case 3: ILLEGAL(sh2); rlog(0); break;
\r
1941 case 4: MOVBM(sh2, Rm, Rn); rlog(LRNM); break;
\r
1942 case 5: MOVWM(sh2, Rm, Rn); rlog(LRNM); break;
\r
1943 case 6: MOVLM(sh2, Rm, Rn); rlog(LRNM); break;
\r
1944 case 7: DIV0S(sh2, Rm, Rn); rlog(LRNM); break;
\r
1945 case 8: TST(sh2, Rm, Rn); rlog(LRNM); break;
\r
1946 case 9: AND(sh2, Rm, Rn); rlog(LRNM); break;
\r
1947 case 10: XOR(sh2, Rm, Rn); rlog(LRNM); break;
\r
1948 case 11: OR(sh2, Rm, Rn); rlog(LRNM); break;
\r
1949 case 12: CMPSTR(sh2, Rm, Rn); rlog(LRNM); break;
\r
1950 case 13: XTRCT(sh2, Rm, Rn); rlog(LRNM); break;
\r
1951 case 14: MULU(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;
\r
1952 case 15: MULS(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;
\r
1956 INLINE void op0011(sh2_state *sh2, UINT16 opcode)
\r
1958 switch (opcode & 15)
\r
1960 case 0: CMPEQ(sh2, Rm, Rn); rlog(LRNM); break;
\r
1961 case 1: ILLEGAL(sh2); rlog(0); break;
\r
1962 case 2: CMPHS(sh2, Rm, Rn); rlog(LRNM); break;
\r
1963 case 3: CMPGE(sh2, Rm, Rn); rlog(LRNM); break;
\r
1964 case 4: DIV1(sh2, Rm, Rn); rlog(LRNM); break;
\r
1965 case 5: DMULU(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
1966 case 6: CMPHI(sh2, Rm, Rn); rlog(LRNM); break;
\r
1967 case 7: CMPGT(sh2, Rm, Rn); rlog(LRNM); break;
\r
1968 case 8: SUB(sh2, Rm, Rn); rlog(LRNM); break;
\r
1969 case 9: ILLEGAL(sh2); rlog(0); break;
\r
1970 case 10: SUBC(sh2, Rm, Rn); rlog(LRNM); break;
\r
1971 case 11: SUBV(sh2, Rm, Rn); rlog(LRNM); break;
\r
1972 case 12: ADD(sh2, Rm, Rn); rlog(LRNM); break;
\r
1973 case 13: DMULS(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
1974 case 14: ADDC(sh2, Rm, Rn); rlog(LRNM); break;
\r
1975 case 15: ADDV(sh2, Rm, Rn); rlog(LRNM); break;
\r
1979 INLINE void op0100(sh2_state *sh2, UINT16 opcode)
\r
1981 switch (opcode & 0x3F)
\r
1983 case 0x00: SHLL(sh2, Rn); rlog(LRN); break;
\r
1984 case 0x01: SHLR(sh2, Rn); rlog(LRN); break;
\r
1985 case 0x02: STSMMACH(sh2, Rn); rlog(LRN); rlog1(SHR_MACH); break;
\r
1986 case 0x03: STCMSR(sh2, Rn); rlog(LRN); break;
\r
1987 case 0x04: ROTL(sh2, Rn); rlog(LRN); break;
\r
1988 case 0x05: ROTR(sh2, Rn); rlog(LRN); break;
\r
1989 case 0x06: LDSMMACH(sh2, Rn); rlog(LRN); rlog1(SHR_MACH); break;
\r
1990 case 0x07: LDCMSR(sh2, Rn); rlog(LRN); break;
\r
1991 case 0x08: SHLL2(sh2, Rn); rlog(LRN); break;
\r
1992 case 0x09: SHLR2(sh2, Rn); rlog(LRN); break;
\r
1993 case 0x0a: LDSMACH(sh2, Rn); rlog(LRN); rlog1(SHR_MACH); break;
\r
1994 case 0x0b: JSR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;
\r
1995 case 0x0c: ILLEGAL(sh2); rlog(0); break;
\r
1996 case 0x0d: ILLEGAL(sh2); rlog(0); break;
\r
1997 case 0x0e: LDCSR(sh2, Rn); rlog(LRN); break;
\r
1998 case 0x0f: MAC_W(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
2000 case 0x10: DT(sh2, Rn); rlog(LRN); break;
\r
2001 case 0x11: CMPPZ(sh2, Rn); rlog(LRN); break;
\r
2002 case 0x12: STSMMACL(sh2, Rn); rlog(LRN); rlog1(SHR_MACL); break;
\r
2003 case 0x13: STCMGBR(sh2, Rn); rlog(LRN); rlog1(SHR_GBR); break;
\r
2004 case 0x14: ILLEGAL(sh2); rlog(0); break;
\r
2005 case 0x15: CMPPL(sh2, Rn); rlog(LRN); break;
\r
2006 case 0x16: LDSMMACL(sh2, Rn); rlog(LRN); rlog1(SHR_MACL); break;
\r
2007 case 0x17: LDCMGBR(sh2, Rn); rlog(LRN); rlog1(SHR_GBR); break;
\r
2008 case 0x18: SHLL8(sh2, Rn); rlog(LRN); break;
\r
2009 case 0x19: SHLR8(sh2, Rn); rlog(LRN); break;
\r
2010 case 0x1a: LDSMACL(sh2, Rn); rlog(LRN); rlog1(SHR_MACL); break;
\r
2011 case 0x1b: TAS(sh2, Rn); rlog(LRN); break;
\r
2012 case 0x1c: ILLEGAL(sh2); rlog(0); break;
\r
2013 case 0x1d: ILLEGAL(sh2); rlog(0); break;
\r
2014 case 0x1e: LDCGBR(sh2, Rn); rlog(LRN); rlog1(SHR_GBR); break;
\r
2015 case 0x1f: MAC_W(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
2017 case 0x20: SHAL(sh2, Rn); rlog(LRN); break;
\r
2018 case 0x21: SHAR(sh2, Rn); rlog(LRN); break;
\r
2019 case 0x22: STSMPR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;
\r
2020 case 0x23: STCMVBR(sh2, Rn); rlog(LRN); rlog1(SHR_VBR); break;
\r
2021 case 0x24: ROTCL(sh2, Rn); rlog(LRN); break;
\r
2022 case 0x25: ROTCR(sh2, Rn); rlog(LRN); break;
\r
2023 case 0x26: LDSMPR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;
\r
2024 case 0x27: LDCMVBR(sh2, Rn); rlog(LRN); rlog1(SHR_VBR); break;
\r
2025 case 0x28: SHLL16(sh2, Rn); rlog(LRN); break;
\r
2026 case 0x29: SHLR16(sh2, Rn); rlog(LRN); break;
\r
2027 case 0x2a: LDSPR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;
\r
2028 case 0x2b: JMP(sh2, Rn); rlog(LRN); break;
\r
2029 case 0x2c: ILLEGAL(sh2); rlog(0); break;
\r
2030 case 0x2d: ILLEGAL(sh2); rlog(0); break;
\r
2031 case 0x2e: LDCVBR(sh2, Rn); rlog(LRN); rlog1(SHR_VBR); break;
\r
2032 case 0x2f: MAC_W(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
2048 case 0x3e: ILLEGAL(sh2); rlog(0); break;
\r
2049 case 0x3f: MAC_W(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;
\r
2053 INLINE void op0101(sh2_state *sh2, UINT16 opcode)
\r
2055 MOVLL4(sh2, Rm, opcode & 0x0f, Rn);
\r
2059 INLINE void op0110(sh2_state *sh2, UINT16 opcode)
\r
2061 switch (opcode & 15)
\r
2063 case 0: MOVBL(sh2, Rm, Rn); break;
\r
2064 case 1: MOVWL(sh2, Rm, Rn); break;
\r
2065 case 2: MOVLL(sh2, Rm, Rn); break;
\r
2066 case 3: MOV(sh2, Rm, Rn); break;
\r
2067 case 4: MOVBP(sh2, Rm, Rn); break;
\r
2068 case 5: MOVWP(sh2, Rm, Rn); break;
\r
2069 case 6: MOVLP(sh2, Rm, Rn); break;
\r
2070 case 7: NOT(sh2, Rm, Rn); break;
\r
2071 case 8: SWAPB(sh2, Rm, Rn); break;
\r
2072 case 9: SWAPW(sh2, Rm, Rn); break;
\r
2073 case 10: NEGC(sh2, Rm, Rn); break;
\r
2074 case 11: NEG(sh2, Rm, Rn); break;
\r
2075 case 12: EXTUB(sh2, Rm, Rn); break;
\r
2076 case 13: EXTUW(sh2, Rm, Rn); break;
\r
2077 case 14: EXTSB(sh2, Rm, Rn); break;
\r
2078 case 15: EXTSW(sh2, Rm, Rn); break;
\r
2083 INLINE void op0111(sh2_state *sh2, UINT16 opcode)
\r
2085 ADDI(sh2, opcode & 0xff, Rn);
\r
2089 INLINE void op1000(sh2_state *sh2, UINT16 opcode)
\r
2091 switch ( opcode & (15<<8) )
\r
2093 case 0<< 8: MOVBS4(sh2, opcode & 0x0f, Rm); rlog(LRM); rlog1(0); break;
\r
2094 case 1<< 8: MOVWS4(sh2, opcode & 0x0f, Rm); rlog(LRM); rlog1(0); break;
\r
2095 case 2<< 8: ILLEGAL(sh2); rlog(0); break;
\r
2096 case 3<< 8: ILLEGAL(sh2); rlog(0); break;
\r
2097 case 4<< 8: MOVBL4(sh2, Rm, opcode & 0x0f); rlog(LRM); rlog1(0); break;
\r
2098 case 5<< 8: MOVWL4(sh2, Rm, opcode & 0x0f); rlog(LRM); rlog1(0); break;
\r
2099 case 6<< 8: ILLEGAL(sh2); rlog(0); break;
\r
2100 case 7<< 8: ILLEGAL(sh2); rlog(0); break;
\r
2101 case 8<< 8: CMPIM(sh2, opcode & 0xff); rlog(0); rlog1(0); break;
\r
2102 case 9<< 8: BT(sh2, opcode & 0xff); rlog(0); break;
\r
2103 case 10<< 8: ILLEGAL(sh2); rlog(0); break;
\r
2104 case 11<< 8: BF(sh2, opcode & 0xff); rlog(0); break;
\r
2105 case 12<< 8: ILLEGAL(sh2); rlog(0); break;
\r
2106 case 13<< 8: BTS(sh2, opcode & 0xff); rlog(0); break;
\r
2107 case 14<< 8: ILLEGAL(sh2); rlog(0); break;
\r
2108 case 15<< 8: BFS(sh2, opcode & 0xff); rlog(0); break;
\r
2113 INLINE void op1001(sh2_state *sh2, UINT16 opcode)
\r
2115 MOVWI(sh2, opcode & 0xff, Rn);
\r
2119 INLINE void op1010(sh2_state *sh2, UINT16 opcode)
\r
2121 BRA(sh2, opcode & 0xfff);
\r
2125 INLINE void op1011(sh2_state *sh2, UINT16 opcode)
\r
2127 BSR(sh2, opcode & 0xfff);
\r
2132 INLINE void op1100(sh2_state *sh2, UINT16 opcode)
\r
2134 switch (opcode & (15<<8))
\r
2136 case 0<<8: MOVBSG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2137 case 1<<8: MOVWSG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2138 case 2<<8: MOVLSG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2139 case 3<<8: TRAPA(sh2, opcode & 0xff); rlog1(SHR_VBR); break;
\r
2140 case 4<<8: MOVBLG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2141 case 5<<8: MOVWLG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2142 case 6<<8: MOVLLG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2143 case 7<<8: MOVA(sh2, opcode & 0xff); rlog1(0); break;
\r
2144 case 8<<8: TSTI(sh2, opcode & 0xff); rlog1(0); break;
\r
2145 case 9<<8: ANDI(sh2, opcode & 0xff); rlog1(0); break;
\r
2146 case 10<<8: XORI(sh2, opcode & 0xff); rlog1(0); break;
\r
2147 case 11<<8: ORI(sh2, opcode & 0xff); rlog1(0); break;
\r
2148 case 12<<8: TSTM(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2149 case 13<<8: ANDM(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2150 case 14<<8: XORM(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2151 case 15<<8: ORM(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;
\r
2156 INLINE void op1101(sh2_state *sh2, UINT16 opcode)
\r
2158 MOVLI(sh2, opcode & 0xff, Rn);
\r
2162 INLINE void op1110(sh2_state *sh2, UINT16 opcode)
\r
2164 MOVI(sh2, opcode & 0xff, Rn);
\r
2168 INLINE void op1111(sh2_state *sh2, UINT16 opcode)
\r