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 20051129 Mariusz Wojcieszek
\r
31 - introduced memory_decrypted_read_word() for opcode fetching
\r
33 20050813 Mariusz Wojcieszek
\r
34 - fixed 64 bit / 32 bit division in division unit
\r
36 20031015 O. Galibert
\r
37 - dma fixes, thanks to sthief
\r
39 20031013 O. Galibert, A. Giles
\r
41 - multi-cpu simplifications
\r
43 20030915 O. Galibert
\r
44 - fix DMA1 irq vector
\r
45 - ignore writes to DRCRx
\r
46 - fix cpu number issues
\r
47 - fix slave/master recognition
\r
48 - fix wrong-cpu-in-context problem with the timers
\r
50 20021020 O. Galibert
\r
51 - DMA implementation, lightly tested
\r
52 - delay slot in debugger fixed
\r
53 - add divide box mirrors
\r
54 - Nicola-ify the indentation
\r
55 - Uncrapify sh2_internal_*
\r
56 - Put back nmi support that had been lost somehow
\r
59 - Initial SH2 internal timers implementation, based on code by O. Galibert.
\r
60 Makes music work in galspanic4/s/s2, panic street, cyvern, other SKNS games.
\r
61 - Fix to external division, thanks to "spice" on the E2J board.
\r
62 Corrects behavior of s1945ii turret boss.
\r
64 20020302 Olivier Galibert (galibert@mame.net)
\r
65 - Fixed interrupt in delay slot
\r
72 - Fixed external division
\r
74 20020225 Olivier Galibert (galibert@mame.net)
\r
75 - Fixed interrupt handling
\r
77 20010207 Sylvain Glaize (mokona@puupuu.org)
\r
79 - Bug fix in INLINE void MOVBM(UINT32 m, UINT32 n) (see comment)
\r
80 - Support of full 32 bit addressing (RB, RW, RL and WB, WW, WL functions)
\r
81 reason : when the two high bits of the address are set, access is
\r
82 done directly in the cache data array. The SUPER KANEKO NOVA SYSTEM
\r
83 sets the stack pointer here, using these addresses as usual RAM access.
\r
85 No real cache support has been added.
\r
86 - Read/Write memory format correction (_bew to _bedw) (see also SH2
\r
87 definition in cpuintrf.c and DasmSH2(..) in sh2dasm.c )
\r
89 20010623 James Forshaw (TyRaNiD@totalise.net)
\r
91 - Modified operation of sh2_exception. Done cause mame irq system is stupid, and
\r
92 doesnt really seem designed for any more than 8 interrupt lines.
\r
94 20010701 James Forshaw (TyRaNiD@totalise.net)
\r
96 - Fixed DIV1 operation. Q bit now correctly generated
\r
98 20020218 Added save states (mokona@puupuu.org)
\r
100 *****************************************************************************/
\r
102 //#include "debugger.h"
\r
104 //#include "sh2comn.h"
\r
105 #define INLINE static
\r
107 //CPU_DISASSEMBLE( sh2 );
\r
111 /* speed up delay loops, bail out of tight loops */
\r
112 #define BUSY_LOOP_HACKS 1
\r
116 #define LOG(x) do { if (VERBOSE) logerror x; } while (0)
\r
122 INLINE UINT8 RB(offs_t A)
\r
124 if (A >= 0xe0000000)
\r
125 return sh2_internal_r(sh2->internal, (A & 0x1fc)>>2, 0xff << (((~A) & 3)*8)) >> (((~A) & 3)*8);
\r
127 if (A >= 0xc0000000)
\r
128 return memory_read_byte_32be(sh2->program, A);
\r
130 if (A >= 0x40000000)
\r
133 return memory_read_byte_32be(sh2->program, A & AM);
\r
136 INLINE UINT16 RW(offs_t A)
\r
138 if (A >= 0xe0000000)
\r
139 return sh2_internal_r(sh2->internal, (A & 0x1fc)>>2, 0xffff << (((~A) & 2)*8)) >> (((~A) & 2)*8);
\r
141 if (A >= 0xc0000000)
\r
142 return memory_read_word_32be(sh2->program, A);
\r
144 if (A >= 0x40000000)
\r
147 return memory_read_word_32be(sh2->program, A & AM);
\r
150 INLINE UINT32 RL(offs_t A)
\r
152 if (A >= 0xe0000000)
\r
153 return sh2_internal_r(sh2->internal, (A & 0x1fc)>>2, 0xffffffff);
\r
155 if (A >= 0xc0000000)
\r
156 return memory_read_dword_32be(sh2->program, A);
\r
158 if (A >= 0x40000000)
\r
161 return memory_read_dword_32be(sh2->program, A & AM);
\r
164 INLINE void WB(offs_t A, UINT8 V)
\r
167 if (A >= 0xe0000000)
\r
169 sh2_internal_w(sh2->internal, (A & 0x1fc)>>2, V << (((~A) & 3)*8), 0xff << (((~A) & 3)*8));
\r
173 if (A >= 0xc0000000)
\r
175 memory_write_byte_32be(sh2->program, A,V);
\r
179 if (A >= 0x40000000)
\r
182 memory_write_byte_32be(sh2->program, A & AM,V);
\r
185 INLINE void WW(offs_t A, UINT16 V)
\r
187 if (A >= 0xe0000000)
\r
189 sh2_internal_w(sh2->internal, (A & 0x1fc)>>2, V << (((~A) & 2)*8), 0xffff << (((~A) & 2)*8));
\r
193 if (A >= 0xc0000000)
\r
195 memory_write_word_32be(sh2->program, A,V);
\r
199 if (A >= 0x40000000)
\r
202 memory_write_word_32be(sh2->program, A & AM,V);
\r
205 INLINE void WL(offs_t A, UINT32 V)
\r
207 if (A >= 0xe0000000)
\r
209 sh2_internal_w(sh2->internal, (A & 0x1fc)>>2, V, 0xffffffff);
\r
213 if (A >= 0xc0000000)
\r
215 memory_write_dword_32be(sh2->program, A,V);
\r
219 if (A >= 0x40000000)
\r
222 memory_write_dword_32be(sh2->program, A & AM,V);
\r
226 /* code cycles t-bit
\r
227 * 0011 nnnn mmmm 1100 1 -
\r
230 INLINE void ADD(UINT32 m, UINT32 n)
\r
232 sh2->r[n] += sh2->r[m];
\r
235 /* code cycles t-bit
\r
236 * 0111 nnnn iiii iiii 1 -
\r
239 INLINE void ADDI(UINT32 i, UINT32 n)
\r
241 sh2->r[n] += (INT32)(INT16)(INT8)i;
\r
244 /* code cycles t-bit
\r
245 * 0011 nnnn mmmm 1110 1 carry
\r
248 INLINE void ADDC(UINT32 m, UINT32 n)
\r
252 tmp1 = sh2->r[n] + sh2->r[m];
\r
254 sh2->r[n] = tmp1 + (sh2->sr & T);
\r
259 if (tmp1 > sh2->r[n])
\r
263 /* code cycles t-bit
\r
264 * 0011 nnnn mmmm 1111 1 overflow
\r
267 INLINE void ADDV(UINT32 m, UINT32 n)
\r
269 INT32 dest, src, ans;
\r
271 if ((INT32) sh2->r[n] >= 0)
\r
275 if ((INT32) sh2->r[m] >= 0)
\r
280 sh2->r[n] += sh2->r[m];
\r
281 if ((INT32) sh2->r[n] >= 0)
\r
286 if (src == 0 || src == 2)
\r
297 /* code cycles t-bit
\r
298 * 0010 nnnn mmmm 1001 1 -
\r
301 INLINE void AND(UINT32 m, UINT32 n)
\r
303 sh2->r[n] &= sh2->r[m];
\r
307 /* code cycles t-bit
\r
308 * 1100 1001 iiii iiii 1 -
\r
311 INLINE void ANDI(UINT32 i)
\r
316 /* code cycles t-bit
\r
317 * 1100 1101 iiii iiii 1 -
\r
318 * AND.B #imm,@(R0,GBR)
\r
320 INLINE void ANDM(UINT32 i)
\r
324 sh2->ea = sh2->gbr + sh2->r[0];
\r
325 temp = i & RB( sh2->ea );
\r
326 WB( sh2->ea, temp );
\r
330 /* code cycles t-bit
\r
331 * 1000 1011 dddd dddd 3/1 -
\r
334 INLINE void BF(UINT32 d)
\r
336 if ((sh2->sr & T) == 0)
\r
338 INT32 disp = ((INT32)d << 24) >> 24;
\r
339 sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;
\r
344 /* code cycles t-bit
\r
345 * 1000 1111 dddd dddd 3/1 -
\r
348 INLINE void BFS(UINT32 d)
\r
350 if ((sh2->sr & T) == 0)
\r
352 INT32 disp = ((INT32)d << 24) >> 24;
\r
353 sh2->delay = sh2->pc;
\r
354 sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;
\r
359 /* code cycles t-bit
\r
360 * 1010 dddd dddd dddd 2 -
\r
363 INLINE void BRA(UINT32 d)
\r
365 INT32 disp = ((INT32)d << 20) >> 20;
\r
367 #if BUSY_LOOP_HACKS
\r
370 UINT32 next_opcode = RW(sh2->ppc & AM);
\r
374 if (next_opcode == 0x0009)
\r
375 sh2_icount %= 3; /* cycles for BRA $ and NOP taken (3) */
\r
378 sh2->delay = sh2->pc;
\r
379 sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;
\r
383 /* code cycles t-bit
\r
384 * 0000 mmmm 0010 0011 2 -
\r
387 INLINE void BRAF(UINT32 m)
\r
389 sh2->delay = sh2->pc;
\r
390 sh2->pc += sh2->r[m] + 2;
\r
394 /* code cycles t-bit
\r
395 * 1011 dddd dddd dddd 2 -
\r
398 INLINE void BSR(UINT32 d)
\r
400 INT32 disp = ((INT32)d << 20) >> 20;
\r
402 sh2->pr = sh2->pc + 2;
\r
403 sh2->delay = sh2->pc;
\r
404 sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;
\r
408 /* code cycles t-bit
\r
409 * 0000 mmmm 0000 0011 2 -
\r
412 INLINE void BSRF(UINT32 m)
\r
414 sh2->pr = sh2->pc + 2;
\r
415 sh2->delay = sh2->pc;
\r
416 sh2->pc += sh2->r[m] + 2;
\r
420 /* code cycles t-bit
\r
421 * 1000 1001 dddd dddd 3/1 -
\r
424 INLINE void BT(UINT32 d)
\r
426 if ((sh2->sr & T) != 0)
\r
428 INT32 disp = ((INT32)d << 24) >> 24;
\r
429 sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;
\r
434 /* code cycles t-bit
\r
435 * 1000 1101 dddd dddd 2/1 -
\r
438 INLINE void BTS(UINT32 d)
\r
440 if ((sh2->sr & T) != 0)
\r
442 INT32 disp = ((INT32)d << 24) >> 24;
\r
443 sh2->delay = sh2->pc;
\r
444 sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;
\r
449 /* code cycles t-bit
\r
450 * 0000 0000 0010 1000 1 -
\r
453 INLINE void CLRMAC(void)
\r
459 /* code cycles t-bit
\r
460 * 0000 0000 0000 1000 1 -
\r
463 INLINE void CLRT(void)
\r
468 /* code cycles t-bit
\r
469 * 0011 nnnn mmmm 0000 1 comparison result
\r
472 INLINE void CMPEQ(UINT32 m, UINT32 n)
\r
474 if (sh2->r[n] == sh2->r[m])
\r
480 /* code cycles t-bit
\r
481 * 0011 nnnn mmmm 0011 1 comparison result
\r
484 INLINE void CMPGE(UINT32 m, UINT32 n)
\r
486 if ((INT32) sh2->r[n] >= (INT32) sh2->r[m])
\r
492 /* code cycles t-bit
\r
493 * 0011 nnnn mmmm 0111 1 comparison result
\r
496 INLINE void CMPGT(UINT32 m, UINT32 n)
\r
498 if ((INT32) sh2->r[n] > (INT32) sh2->r[m])
\r
504 /* code cycles t-bit
\r
505 * 0011 nnnn mmmm 0110 1 comparison result
\r
508 INLINE void CMPHI(UINT32 m, UINT32 n)
\r
510 if ((UINT32) sh2->r[n] > (UINT32) sh2->r[m])
\r
516 /* code cycles t-bit
\r
517 * 0011 nnnn mmmm 0010 1 comparison result
\r
520 INLINE void CMPHS(UINT32 m, UINT32 n)
\r
522 if ((UINT32) sh2->r[n] >= (UINT32) sh2->r[m])
\r
529 /* code cycles t-bit
\r
530 * 0100 nnnn 0001 0101 1 comparison result
\r
533 INLINE void CMPPL(UINT32 n)
\r
535 if ((INT32) sh2->r[n] > 0)
\r
541 /* code cycles t-bit
\r
542 * 0100 nnnn 0001 0001 1 comparison result
\r
545 INLINE void CMPPZ(UINT32 n)
\r
547 if ((INT32) sh2->r[n] >= 0)
\r
553 /* code cycles t-bit
\r
554 * 0010 nnnn mmmm 1100 1 comparison result
\r
557 INLINE void CMPSTR(UINT32 m, UINT32 n)
\r
560 INT32 HH, HL, LH, LL;
\r
561 temp = sh2->r[n] ^ sh2->r[m];
\r
562 HH = (temp >> 24) & 0xff;
\r
563 HL = (temp >> 16) & 0xff;
\r
564 LH = (temp >> 8) & 0xff;
\r
566 if (HH && HL && LH && LL)
\r
573 /* code cycles t-bit
\r
574 * 1000 1000 iiii iiii 1 comparison result
\r
577 INLINE void CMPIM(UINT32 i)
\r
579 UINT32 imm = (UINT32)(INT32)(INT16)(INT8)i;
\r
581 if (sh2->r[0] == imm)
\r
587 /* code cycles t-bit
\r
588 * 0010 nnnn mmmm 0111 1 calculation result
\r
591 INLINE void DIV0S(UINT32 m, UINT32 n)
\r
593 if ((sh2->r[n] & 0x80000000) == 0)
\r
597 if ((sh2->r[m] & 0x80000000) == 0)
\r
601 if ((sh2->r[m] ^ sh2->r[n]) & 0x80000000)
\r
607 /* code cycles t-bit
\r
608 * 0000 0000 0001 1001 1 0
\r
611 INLINE void DIV0U(void)
\r
613 sh2->sr &= ~(M | Q | T);
\r
616 /* code cycles t-bit
\r
617 * 0011 nnnn mmmm 0100 1 calculation result
\r
620 INLINE void DIV1(UINT32 m, UINT32 n)
\r
625 old_q = sh2->sr & Q;
\r
626 if (0x80000000 & sh2->r[n])
\r
631 sh2->r[n] = (sh2->r[n] << 1) | (sh2->sr & T);
\r
635 if (!(sh2->sr & M))
\r
638 sh2->r[n] -= sh2->r[m];
\r
640 if(sh2->r[n] > tmp0)
\r
645 if(sh2->r[n] > tmp0)
\r
653 sh2->r[n] += sh2->r[m];
\r
656 if(sh2->r[n] < tmp0)
\r
663 if(sh2->r[n] < tmp0)
\r
672 if (!(sh2->sr & M))
\r
675 sh2->r[n] += sh2->r[m];
\r
677 if(sh2->r[n] < tmp0)
\r
682 if(sh2->r[n] < tmp0)
\r
690 sh2->r[n] -= sh2->r[m];
\r
692 if(sh2->r[n] > tmp0)
\r
697 if(sh2->r[n] > tmp0)
\r
704 tmp0 = (sh2->sr & (Q | M));
\r
705 if((!tmp0) || (tmp0 == 0x300)) /* if Q == M set T else clear T */
\r
711 /* DMULS.L Rm,Rn */
\r
712 INLINE void DMULS(UINT32 m, UINT32 n)
\r
714 UINT32 RnL, RnH, RmL, RmH, Res0, Res1, Res2;
\r
715 UINT32 temp0, temp1, temp2, temp3;
\r
716 INT32 tempm, tempn, fnLmL;
\r
718 tempn = (INT32) sh2->r[n];
\r
719 tempm = (INT32) sh2->r[m];
\r
724 if ((INT32) (sh2->r[n] ^ sh2->r[m]) < 0)
\r
728 temp1 = (UINT32) tempn;
\r
729 temp2 = (UINT32) tempm;
\r
730 RnL = temp1 & 0x0000ffff;
\r
731 RnH = (temp1 >> 16) & 0x0000ffff;
\r
732 RmL = temp2 & 0x0000ffff;
\r
733 RmH = (temp2 >> 16) & 0x0000ffff;
\r
739 Res1 = temp1 + temp2;
\r
741 Res2 += 0x00010000;
\r
742 temp1 = (Res1 << 16) & 0xffff0000;
\r
743 Res0 = temp0 + temp1;
\r
746 Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;
\r
753 Res0 = (~Res0) + 1;
\r
760 /* DMULU.L Rm,Rn */
\r
761 INLINE void DMULU(UINT32 m, UINT32 n)
\r
763 UINT32 RnL, RnH, RmL, RmH, Res0, Res1, Res2;
\r
764 UINT32 temp0, temp1, temp2, temp3;
\r
766 RnL = sh2->r[n] & 0x0000ffff;
\r
767 RnH = (sh2->r[n] >> 16) & 0x0000ffff;
\r
768 RmL = sh2->r[m] & 0x0000ffff;
\r
769 RmH = (sh2->r[m] >> 16) & 0x0000ffff;
\r
775 Res1 = temp1 + temp2;
\r
777 Res2 += 0x00010000;
\r
778 temp1 = (Res1 << 16) & 0xffff0000;
\r
779 Res0 = temp0 + temp1;
\r
782 Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;
\r
789 INLINE void DT(UINT32 n)
\r
792 if (sh2->r[n] == 0)
\r
796 #if BUSY_LOOP_HACKS
\r
798 UINT32 next_opcode = RW(sh2->ppc & AM);
\r
802 if (next_opcode == 0x8bfd)
\r
804 while (sh2->r[n] > 1 && sh2_icount > 4)
\r
807 sh2_icount -= 4; /* cycles for DT (1) and BF taken (3) */
\r
815 INLINE void EXTSB(UINT32 m, UINT32 n)
\r
817 sh2->r[n] = ((INT32)sh2->r[m] << 24) >> 24;
\r
821 INLINE void EXTSW(UINT32 m, UINT32 n)
\r
823 sh2->r[n] = ((INT32)sh2->r[m] << 16) >> 16;
\r
827 INLINE void EXTUB(UINT32 m, UINT32 n)
\r
829 sh2->r[n] = sh2->r[m] & 0x000000ff;
\r
833 INLINE void EXTUW(UINT32 m, UINT32 n)
\r
835 sh2->r[n] = sh2->r[m] & 0x0000ffff;
\r
839 INLINE void JMP(UINT32 m)
\r
841 sh2->delay = sh2->pc;
\r
842 sh2->pc = sh2->ea = sh2->r[m];
\r
846 INLINE void JSR(UINT32 m)
\r
848 sh2->delay = sh2->pc;
\r
849 sh2->pr = sh2->pc + 2;
\r
850 sh2->pc = sh2->ea = sh2->r[m];
\r
856 INLINE void LDCSR(UINT32 m)
\r
858 sh2->sr = sh2->r[m] & FLAGS;
\r
863 INLINE void LDCGBR(UINT32 m)
\r
865 sh2->gbr = sh2->r[m];
\r
869 INLINE void LDCVBR(UINT32 m)
\r
871 sh2->vbr = sh2->r[m];
\r
874 /* LDC.L @Rm+,SR */
\r
875 INLINE void LDCMSR(UINT32 m)
\r
877 sh2->ea = sh2->r[m];
\r
878 sh2->sr = RL( sh2->ea ) & FLAGS;
\r
884 /* LDC.L @Rm+,GBR */
\r
885 INLINE void LDCMGBR(UINT32 m)
\r
887 sh2->ea = sh2->r[m];
\r
888 sh2->gbr = RL( sh2->ea );
\r
893 /* LDC.L @Rm+,VBR */
\r
894 INLINE void LDCMVBR(UINT32 m)
\r
896 sh2->ea = sh2->r[m];
\r
897 sh2->vbr = RL( sh2->ea );
\r
903 INLINE void LDSMACH(UINT32 m)
\r
905 sh2->mach = sh2->r[m];
\r
909 INLINE void LDSMACL(UINT32 m)
\r
911 sh2->macl = sh2->r[m];
\r
915 INLINE void LDSPR(UINT32 m)
\r
917 sh2->pr = sh2->r[m];
\r
920 /* LDS.L @Rm+,MACH */
\r
921 INLINE void LDSMMACH(UINT32 m)
\r
923 sh2->ea = sh2->r[m];
\r
924 sh2->mach = RL( sh2->ea );
\r
928 /* LDS.L @Rm+,MACL */
\r
929 INLINE void LDSMMACL(UINT32 m)
\r
931 sh2->ea = sh2->r[m];
\r
932 sh2->macl = RL( sh2->ea );
\r
936 /* LDS.L @Rm+,PR */
\r
937 INLINE void LDSMPR(UINT32 m)
\r
939 sh2->ea = sh2->r[m];
\r
940 sh2->pr = RL( sh2->ea );
\r
944 /* MAC.L @Rm+,@Rn+ */
\r
945 INLINE void MAC_L(UINT32 m, UINT32 n)
\r
947 UINT32 RnL, RnH, RmL, RmH, Res0, Res1, Res2;
\r
948 UINT32 temp0, temp1, temp2, temp3;
\r
949 INT32 tempm, tempn, fnLmL;
\r
951 tempn = (INT32) RL( sh2->r[n] );
\r
953 tempm = (INT32) RL( sh2->r[m] );
\r
955 if ((INT32) (tempn ^ tempm) < 0)
\r
963 temp1 = (UINT32) tempn;
\r
964 temp2 = (UINT32) tempm;
\r
965 RnL = temp1 & 0x0000ffff;
\r
966 RnH = (temp1 >> 16) & 0x0000ffff;
\r
967 RmL = temp2 & 0x0000ffff;
\r
968 RmH = (temp2 >> 16) & 0x0000ffff;
\r
974 Res1 = temp1 + temp2;
\r
976 Res2 += 0x00010000;
\r
977 temp1 = (Res1 << 16) & 0xffff0000;
\r
978 Res0 = temp0 + temp1;
\r
981 Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;
\r
988 Res0 = (~Res0) + 1;
\r
992 Res0 = sh2->macl + Res0;
\r
993 if (sh2->macl > Res0)
\r
995 Res2 += (sh2->mach & 0x0000ffff);
\r
996 if (((INT32) Res2 < 0) && (Res2 < 0xffff8000))
\r
1001 else if (((INT32) Res2 > 0) && (Res2 > 0x00007fff))
\r
1003 Res2 = 0x00007fff;
\r
1004 Res0 = 0xffffffff;
\r
1011 Res0 = sh2->macl + Res0;
\r
1012 if (sh2->macl > Res0)
\r
1014 Res2 += sh2->mach;
\r
1021 /* MAC.W @Rm+,@Rn+ */
\r
1022 INLINE void MAC_W(UINT32 m, UINT32 n)
\r
1024 INT32 tempm, tempn, dest, src, ans;
\r
1027 tempn = (INT32) RW( sh2->r[n] );
\r
1029 tempm = (INT32) RW( sh2->r[m] );
\r
1031 templ = sh2->macl;
\r
1032 tempm = ((INT32) (short) tempn * (INT32) (short) tempm);
\r
1033 if ((INT32) sh2->macl >= 0)
\r
1037 if ((INT32) tempm >= 0)
\r
1045 tempn = 0xffffffff;
\r
1048 sh2->macl += tempm;
\r
1049 if ((INT32) sh2->macl >= 0)
\r
1059 sh2->macl = 0x7fffffff;
\r
1061 sh2->macl = 0x80000000;
\r
1066 sh2->mach += tempn;
\r
1067 if (templ > sh2->macl)
\r
1074 INLINE void MOV(UINT32 m, UINT32 n)
\r
1076 sh2->r[n] = sh2->r[m];
\r
1079 /* MOV.B Rm,@Rn */
\r
1080 INLINE void MOVBS(UINT32 m, UINT32 n)
\r
1082 sh2->ea = sh2->r[n];
\r
1083 WB( sh2->ea, sh2->r[m] & 0x000000ff);
\r
1086 /* MOV.W Rm,@Rn */
\r
1087 INLINE void MOVWS(UINT32 m, UINT32 n)
\r
1089 sh2->ea = sh2->r[n];
\r
1090 WW( sh2->ea, sh2->r[m] & 0x0000ffff);
\r
1093 /* MOV.L Rm,@Rn */
\r
1094 INLINE void MOVLS(UINT32 m, UINT32 n)
\r
1096 sh2->ea = sh2->r[n];
\r
1097 WL( sh2->ea, sh2->r[m] );
\r
1100 /* MOV.B @Rm,Rn */
\r
1101 INLINE void MOVBL(UINT32 m, UINT32 n)
\r
1103 sh2->ea = sh2->r[m];
\r
1104 sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) RB( sh2->ea );
\r
1107 /* MOV.W @Rm,Rn */
\r
1108 INLINE void MOVWL(UINT32 m, UINT32 n)
\r
1110 sh2->ea = sh2->r[m];
\r
1111 sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2->ea );
\r
1114 /* MOV.L @Rm,Rn */
\r
1115 INLINE void MOVLL(UINT32 m, UINT32 n)
\r
1117 sh2->ea = sh2->r[m];
\r
1118 sh2->r[n] = RL( sh2->ea );
\r
1121 /* MOV.B Rm,@-Rn */
\r
1122 INLINE void MOVBM(UINT32 m, UINT32 n)
\r
1124 /* SMG : bug fix, was reading sh2->r[n] */
\r
1125 UINT32 data = sh2->r[m] & 0x000000ff;
\r
1128 WB( sh2->r[n], data );
\r
1131 /* MOV.W Rm,@-Rn */
\r
1132 INLINE void MOVWM(UINT32 m, UINT32 n)
\r
1134 UINT32 data = sh2->r[m] & 0x0000ffff;
\r
1137 WW( sh2->r[n], data );
\r
1140 /* MOV.L Rm,@-Rn */
\r
1141 INLINE void MOVLM(UINT32 m, UINT32 n)
\r
1143 UINT32 data = sh2->r[m];
\r
1146 WL( sh2->r[n], data );
\r
1149 /* MOV.B @Rm+,Rn */
\r
1150 INLINE void MOVBP(UINT32 m, UINT32 n)
\r
1152 sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) RB( sh2->r[m] );
\r
1157 /* MOV.W @Rm+,Rn */
\r
1158 INLINE void MOVWP(UINT32 m, UINT32 n)
\r
1160 sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2->r[m] );
\r
1165 /* MOV.L @Rm+,Rn */
\r
1166 INLINE void MOVLP(UINT32 m, UINT32 n)
\r
1168 sh2->r[n] = RL( sh2->r[m] );
\r
1173 /* MOV.B Rm,@(R0,Rn) */
\r
1174 INLINE void MOVBS0(UINT32 m, UINT32 n)
\r
1176 sh2->ea = sh2->r[n] + sh2->r[0];
\r
1177 WB( sh2->ea, sh2->r[m] & 0x000000ff );
\r
1180 /* MOV.W Rm,@(R0,Rn) */
\r
1181 INLINE void MOVWS0(UINT32 m, UINT32 n)
\r
1183 sh2->ea = sh2->r[n] + sh2->r[0];
\r
1184 WW( sh2->ea, sh2->r[m] & 0x0000ffff );
\r
1187 /* MOV.L Rm,@(R0,Rn) */
\r
1188 INLINE void MOVLS0(UINT32 m, UINT32 n)
\r
1190 sh2->ea = sh2->r[n] + sh2->r[0];
\r
1191 WL( sh2->ea, sh2->r[m] );
\r
1194 /* MOV.B @(R0,Rm),Rn */
\r
1195 INLINE void MOVBL0(UINT32 m, UINT32 n)
\r
1197 sh2->ea = sh2->r[m] + sh2->r[0];
\r
1198 sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) RB( sh2->ea );
\r
1201 /* MOV.W @(R0,Rm),Rn */
\r
1202 INLINE void MOVWL0(UINT32 m, UINT32 n)
\r
1204 sh2->ea = sh2->r[m] + sh2->r[0];
\r
1205 sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2->ea );
\r
1208 /* MOV.L @(R0,Rm),Rn */
\r
1209 INLINE void MOVLL0(UINT32 m, UINT32 n)
\r
1211 sh2->ea = sh2->r[m] + sh2->r[0];
\r
1212 sh2->r[n] = RL( sh2->ea );
\r
1216 INLINE void MOVI(UINT32 i, UINT32 n)
\r
1218 sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) i;
\r
1221 /* MOV.W @(disp8,PC),Rn */
\r
1222 INLINE void MOVWI(UINT32 d, UINT32 n)
\r
1224 UINT32 disp = d & 0xff;
\r
1225 sh2->ea = sh2->pc + disp * 2 + 2;
\r
1226 sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2->ea );
\r
1229 /* MOV.L @(disp8,PC),Rn */
\r
1230 INLINE void MOVLI(UINT32 d, UINT32 n)
\r
1232 UINT32 disp = d & 0xff;
\r
1233 sh2->ea = ((sh2->pc + 2) & ~3) + disp * 4;
\r
1234 sh2->r[n] = RL( sh2->ea );
\r
1237 /* MOV.B @(disp8,GBR),R0 */
\r
1238 INLINE void MOVBLG(UINT32 d)
\r
1240 UINT32 disp = d & 0xff;
\r
1241 sh2->ea = sh2->gbr + disp;
\r
1242 sh2->r[0] = (UINT32)(INT32)(INT16)(INT8) RB( sh2->ea );
\r
1245 /* MOV.W @(disp8,GBR),R0 */
\r
1246 INLINE void MOVWLG(UINT32 d)
\r
1248 UINT32 disp = d & 0xff;
\r
1249 sh2->ea = sh2->gbr + disp * 2;
\r
1250 sh2->r[0] = (INT32)(INT16) RW( sh2->ea );
\r
1253 /* MOV.L @(disp8,GBR),R0 */
\r
1254 INLINE void MOVLLG(UINT32 d)
\r
1256 UINT32 disp = d & 0xff;
\r
1257 sh2->ea = sh2->gbr + disp * 4;
\r
1258 sh2->r[0] = RL( sh2->ea );
\r
1261 /* MOV.B R0,@(disp8,GBR) */
\r
1262 INLINE void MOVBSG(UINT32 d)
\r
1264 UINT32 disp = d & 0xff;
\r
1265 sh2->ea = sh2->gbr + disp;
\r
1266 WB( sh2->ea, sh2->r[0] & 0x000000ff );
\r
1269 /* MOV.W R0,@(disp8,GBR) */
\r
1270 INLINE void MOVWSG(UINT32 d)
\r
1272 UINT32 disp = d & 0xff;
\r
1273 sh2->ea = sh2->gbr + disp * 2;
\r
1274 WW( sh2->ea, sh2->r[0] & 0x0000ffff );
\r
1277 /* MOV.L R0,@(disp8,GBR) */
\r
1278 INLINE void MOVLSG(UINT32 d)
\r
1280 UINT32 disp = d & 0xff;
\r
1281 sh2->ea = sh2->gbr + disp * 4;
\r
1282 WL( sh2->ea, sh2->r[0] );
\r
1285 /* MOV.B R0,@(disp4,Rn) */
\r
1286 INLINE void MOVBS4(UINT32 d, UINT32 n)
\r
1288 UINT32 disp = d & 0x0f;
\r
1289 sh2->ea = sh2->r[n] + disp;
\r
1290 WB( sh2->ea, sh2->r[0] & 0x000000ff );
\r
1293 /* MOV.W R0,@(disp4,Rn) */
\r
1294 INLINE void MOVWS4(UINT32 d, UINT32 n)
\r
1296 UINT32 disp = d & 0x0f;
\r
1297 sh2->ea = sh2->r[n] + disp * 2;
\r
1298 WW( sh2->ea, sh2->r[0] & 0x0000ffff );
\r
1301 /* MOV.L Rm,@(disp4,Rn) */
\r
1302 INLINE void MOVLS4(UINT32 m, UINT32 d, UINT32 n)
\r
1304 UINT32 disp = d & 0x0f;
\r
1305 sh2->ea = sh2->r[n] + disp * 4;
\r
1306 WL( sh2->ea, sh2->r[m] );
\r
1309 /* MOV.B @(disp4,Rm),R0 */
\r
1310 INLINE void MOVBL4(UINT32 m, UINT32 d)
\r
1312 UINT32 disp = d & 0x0f;
\r
1313 sh2->ea = sh2->r[m] + disp;
\r
1314 sh2->r[0] = (UINT32)(INT32)(INT16)(INT8) RB( sh2->ea );
\r
1317 /* MOV.W @(disp4,Rm),R0 */
\r
1318 INLINE void MOVWL4(UINT32 m, UINT32 d)
\r
1320 UINT32 disp = d & 0x0f;
\r
1321 sh2->ea = sh2->r[m] + disp * 2;
\r
1322 sh2->r[0] = (UINT32)(INT32)(INT16) RW( sh2->ea );
\r
1325 /* MOV.L @(disp4,Rm),Rn */
\r
1326 INLINE void MOVLL4(UINT32 m, UINT32 d, UINT32 n)
\r
1328 UINT32 disp = d & 0x0f;
\r
1329 sh2->ea = sh2->r[m] + disp * 4;
\r
1330 sh2->r[n] = RL( sh2->ea );
\r
1333 /* MOVA @(disp8,PC),R0 */
\r
1334 INLINE void MOVA(UINT32 d)
\r
1336 UINT32 disp = d & 0xff;
\r
1337 sh2->ea = ((sh2->pc + 2) & ~3) + disp * 4;
\r
1338 sh2->r[0] = sh2->ea;
\r
1342 INLINE void MOVT(UINT32 n)
\r
1344 sh2->r[n] = sh2->sr & T;
\r
1348 INLINE void MULL(UINT32 m, UINT32 n)
\r
1350 sh2->macl = sh2->r[n] * sh2->r[m];
\r
1355 INLINE void MULS(UINT32 m, UINT32 n)
\r
1357 sh2->macl = (INT16) sh2->r[n] * (INT16) sh2->r[m];
\r
1361 INLINE void MULU(UINT32 m, UINT32 n)
\r
1363 sh2->macl = (UINT16) sh2->r[n] * (UINT16) sh2->r[m];
\r
1367 INLINE void NEG(UINT32 m, UINT32 n)
\r
1369 sh2->r[n] = 0 - sh2->r[m];
\r
1373 INLINE void NEGC(UINT32 m, UINT32 n)
\r
1378 sh2->r[n] = -temp - (sh2->sr & T);
\r
1379 if (temp || (sh2->sr & T))
\r
1386 INLINE void NOP(void)
\r
1391 INLINE void NOT(UINT32 m, UINT32 n)
\r
1393 sh2->r[n] = ~sh2->r[m];
\r
1397 INLINE void OR(UINT32 m, UINT32 n)
\r
1399 sh2->r[n] |= sh2->r[m];
\r
1403 INLINE void ORI(UINT32 i)
\r
1409 /* OR.B #imm,@(R0,GBR) */
\r
1410 INLINE void ORM(UINT32 i)
\r
1414 sh2->ea = sh2->gbr + sh2->r[0];
\r
1415 temp = RB( sh2->ea );
\r
1417 WB( sh2->ea, temp );
\r
1421 INLINE void ROTCL(UINT32 n)
\r
1425 temp = (sh2->r[n] >> 31) & T;
\r
1426 sh2->r[n] = (sh2->r[n] << 1) | (sh2->sr & T);
\r
1427 sh2->sr = (sh2->sr & ~T) | temp;
\r
1431 INLINE void ROTCR(UINT32 n)
\r
1434 temp = (sh2->sr & T) << 31;
\r
1435 if (sh2->r[n] & T)
\r
1439 sh2->r[n] = (sh2->r[n] >> 1) | temp;
\r
1443 INLINE void ROTL(UINT32 n)
\r
1445 sh2->sr = (sh2->sr & ~T) | ((sh2->r[n] >> 31) & T);
\r
1446 sh2->r[n] = (sh2->r[n] << 1) | (sh2->r[n] >> 31);
\r
1450 INLINE void ROTR(UINT32 n)
\r
1452 sh2->sr = (sh2->sr & ~T) | (sh2->r[n] & T);
\r
1453 sh2->r[n] = (sh2->r[n] >> 1) | (sh2->r[n] << 31);
\r
1457 INLINE void RTE(void)
\r
1459 sh2->ea = sh2->r[15];
\r
1460 sh2->delay = sh2->pc;
\r
1461 sh2->pc = RL( sh2->ea );
\r
1463 sh2->ea = sh2->r[15];
\r
1464 sh2->sr = RL( sh2->ea ) & FLAGS;
\r
1467 sh2->test_irq = 1;
\r
1471 INLINE void RTS(void)
\r
1473 sh2->delay = sh2->pc;
\r
1474 sh2->pc = sh2->ea = sh2->pr;
\r
1479 INLINE void SETT(void)
\r
1484 /* SHAL Rn (same as SHLL) */
\r
1485 INLINE void SHAL(UINT32 n)
\r
1487 sh2->sr = (sh2->sr & ~T) | ((sh2->r[n] >> 31) & T);
\r
1492 INLINE void SHAR(UINT32 n)
\r
1494 sh2->sr = (sh2->sr & ~T) | (sh2->r[n] & T);
\r
1495 sh2->r[n] = (UINT32)((INT32)sh2->r[n] >> 1);
\r
1498 /* SHLL Rn (same as SHAL) */
\r
1499 INLINE void SHLL(UINT32 n)
\r
1501 sh2->sr = (sh2->sr & ~T) | ((sh2->r[n] >> 31) & T);
\r
1506 INLINE void SHLL2(UINT32 n)
\r
1512 INLINE void SHLL8(UINT32 n)
\r
1518 INLINE void SHLL16(UINT32 n)
\r
1524 INLINE void SHLR(UINT32 n)
\r
1526 sh2->sr = (sh2->sr & ~T) | (sh2->r[n] & T);
\r
1531 INLINE void SHLR2(UINT32 n)
\r
1537 INLINE void SHLR8(UINT32 n)
\r
1543 INLINE void SHLR16(UINT32 n)
\r
1549 INLINE void SLEEP(void)
\r
1553 /* Wait_for_exception; */
\r
1557 INLINE void STCSR(UINT32 n)
\r
1559 sh2->r[n] = sh2->sr;
\r
1563 INLINE void STCGBR(UINT32 n)
\r
1565 sh2->r[n] = sh2->gbr;
\r
1569 INLINE void STCVBR(UINT32 n)
\r
1571 sh2->r[n] = sh2->vbr;
\r
1574 /* STC.L SR,@-Rn */
\r
1575 INLINE void STCMSR(UINT32 n)
\r
1578 sh2->ea = sh2->r[n];
\r
1579 WL( sh2->ea, sh2->sr );
\r
1583 /* STC.L GBR,@-Rn */
\r
1584 INLINE void STCMGBR(UINT32 n)
\r
1587 sh2->ea = sh2->r[n];
\r
1588 WL( sh2->ea, sh2->gbr );
\r
1592 /* STC.L VBR,@-Rn */
\r
1593 INLINE void STCMVBR(UINT32 n)
\r
1596 sh2->ea = sh2->r[n];
\r
1597 WL( sh2->ea, sh2->vbr );
\r
1602 INLINE void STSMACH(UINT32 n)
\r
1604 sh2->r[n] = sh2->mach;
\r
1608 INLINE void STSMACL(UINT32 n)
\r
1610 sh2->r[n] = sh2->macl;
\r
1614 INLINE void STSPR(UINT32 n)
\r
1616 sh2->r[n] = sh2->pr;
\r
1619 /* STS.L MACH,@-Rn */
\r
1620 INLINE void STSMMACH(UINT32 n)
\r
1623 sh2->ea = sh2->r[n];
\r
1624 WL( sh2->ea, sh2->mach );
\r
1627 /* STS.L MACL,@-Rn */
\r
1628 INLINE void STSMMACL(UINT32 n)
\r
1631 sh2->ea = sh2->r[n];
\r
1632 WL( sh2->ea, sh2->macl );
\r
1635 /* STS.L PR,@-Rn */
\r
1636 INLINE void STSMPR(UINT32 n)
\r
1639 sh2->ea = sh2->r[n];
\r
1640 WL( sh2->ea, sh2->pr );
\r
1644 INLINE void SUB(UINT32 m, UINT32 n)
\r
1646 sh2->r[n] -= sh2->r[m];
\r
1650 INLINE void SUBC(UINT32 m, UINT32 n)
\r
1652 UINT32 tmp0, tmp1;
\r
1654 tmp1 = sh2->r[n] - sh2->r[m];
\r
1656 sh2->r[n] = tmp1 - (sh2->sr & T);
\r
1661 if (tmp1 < sh2->r[n])
\r
1666 INLINE void SUBV(UINT32 m, UINT32 n)
\r
1668 INT32 dest, src, ans;
\r
1670 if ((INT32) sh2->r[n] >= 0)
\r
1674 if ((INT32) sh2->r[m] >= 0)
\r
1679 sh2->r[n] -= sh2->r[m];
\r
1680 if ((INT32) sh2->r[n] >= 0)
\r
1696 /* SWAP.B Rm,Rn */
\r
1697 INLINE void SWAPB(UINT32 m, UINT32 n)
\r
1699 UINT32 temp0, temp1;
\r
1701 temp0 = sh2->r[m] & 0xffff0000;
\r
1702 temp1 = (sh2->r[m] & 0x000000ff) << 8;
\r
1703 sh2->r[n] = (sh2->r[m] >> 8) & 0x000000ff;
\r
1704 sh2->r[n] = sh2->r[n] | temp1 | temp0;
\r
1707 /* SWAP.W Rm,Rn */
\r
1708 INLINE void SWAPW(UINT32 m, UINT32 n)
\r
1712 temp = (sh2->r[m] >> 16) & 0x0000ffff;
\r
1713 sh2->r[n] = (sh2->r[m] << 16) | temp;
\r
1717 INLINE void TAS(UINT32 n)
\r
1720 sh2->ea = sh2->r[n];
\r
1721 /* Bus Lock enable */
\r
1722 temp = RB( sh2->ea );
\r
1728 /* Bus Lock disable */
\r
1729 WB( sh2->ea, temp );
\r
1734 INLINE void TRAPA(UINT32 i)
\r
1736 UINT32 imm = i & 0xff;
\r
1738 sh2->ea = sh2->vbr + imm * 4;
\r
1741 WL( sh2->r[15], sh2->sr );
\r
1743 WL( sh2->r[15], sh2->pc );
\r
1745 sh2->pc = RL( sh2->ea );
\r
1751 INLINE void TST(UINT32 m, UINT32 n)
\r
1753 if ((sh2->r[n] & sh2->r[m]) == 0)
\r
1760 INLINE void TSTI(UINT32 i)
\r
1762 UINT32 imm = i & 0xff;
\r
1764 if ((imm & sh2->r[0]) == 0)
\r
1770 /* TST.B #imm,@(R0,GBR) */
\r
1771 INLINE void TSTM(UINT32 i)
\r
1773 UINT32 imm = i & 0xff;
\r
1775 sh2->ea = sh2->gbr + sh2->r[0];
\r
1776 if ((imm & RB( sh2->ea )) == 0)
\r
1784 INLINE void XOR(UINT32 m, UINT32 n)
\r
1786 sh2->r[n] ^= sh2->r[m];
\r
1790 INLINE void XORI(UINT32 i)
\r
1792 UINT32 imm = i & 0xff;
\r
1796 /* XOR.B #imm,@(R0,GBR) */
\r
1797 INLINE void XORM(UINT32 i)
\r
1799 UINT32 imm = i & 0xff;
\r
1802 sh2->ea = sh2->gbr + sh2->r[0];
\r
1803 temp = RB( sh2->ea );
\r
1805 WB( sh2->ea, temp );
\r
1810 INLINE void XTRCT(UINT32 m, UINT32 n)
\r
1814 temp = (sh2->r[m] << 16) & 0xffff0000;
\r
1815 sh2->r[n] = (sh2->r[n] >> 16) & 0x0000ffff;
\r
1816 sh2->r[n] |= temp;
\r
1819 /*****************************************************************************
\r
1820 * OPCODE DISPATCHERS
\r
1821 *****************************************************************************/
\r
1823 INLINE void op0000(UINT16 opcode)
\r
1825 switch (opcode & 0x3F)
\r
1827 case 0x00: NOP(); break;
\r
1828 case 0x01: NOP(); break;
\r
1829 case 0x02: STCSR(Rn); break;
\r
1830 case 0x03: BSRF(Rn); break;
\r
1831 case 0x04: MOVBS0(Rm, Rn); break;
\r
1832 case 0x05: MOVWS0(Rm, Rn); break;
\r
1833 case 0x06: MOVLS0(Rm, Rn); break;
\r
1834 case 0x07: MULL(Rm, Rn); break;
\r
1835 case 0x08: CLRT(); break;
\r
1836 case 0x09: NOP(); break;
\r
1837 case 0x0a: STSMACH(Rn); break;
\r
1838 case 0x0b: RTS(); break;
\r
1839 case 0x0c: MOVBL0(Rm, Rn); break;
\r
1840 case 0x0d: MOVWL0(Rm, Rn); break;
\r
1841 case 0x0e: MOVLL0(Rm, Rn); break;
\r
1842 case 0x0f: MAC_L(Rm, Rn); break;
\r
1844 case 0x10: NOP(); break;
\r
1845 case 0x11: NOP(); break;
\r
1846 case 0x12: STCGBR(Rn); break;
\r
1847 case 0x13: NOP(); break;
\r
1848 case 0x14: MOVBS0(Rm, Rn); break;
\r
1849 case 0x15: MOVWS0(Rm, Rn); break;
\r
1850 case 0x16: MOVLS0(Rm, Rn); break;
\r
1851 case 0x17: MULL(Rm, Rn); break;
\r
1852 case 0x18: SETT(); break;
\r
1853 case 0x19: DIV0U(); break;
\r
1854 case 0x1a: STSMACL(Rn); break;
\r
1855 case 0x1b: SLEEP(); break;
\r
1856 case 0x1c: MOVBL0(Rm, Rn); break;
\r
1857 case 0x1d: MOVWL0(Rm, Rn); break;
\r
1858 case 0x1e: MOVLL0(Rm, Rn); break;
\r
1859 case 0x1f: MAC_L(Rm, Rn); break;
\r
1861 case 0x20: NOP(); break;
\r
1862 case 0x21: NOP(); break;
\r
1863 case 0x22: STCVBR(Rn); break;
\r
1864 case 0x23: BRAF(Rn); break;
\r
1865 case 0x24: MOVBS0(Rm, Rn); break;
\r
1866 case 0x25: MOVWS0(Rm, Rn); break;
\r
1867 case 0x26: MOVLS0(Rm, Rn); break;
\r
1868 case 0x27: MULL(Rm, Rn); break;
\r
1869 case 0x28: CLRMAC(); break;
\r
1870 case 0x29: MOVT(Rn); break;
\r
1871 case 0x2a: STSPR(Rn); break;
\r
1872 case 0x2b: RTE(); break;
\r
1873 case 0x2c: MOVBL0(Rm, Rn); break;
\r
1874 case 0x2d: MOVWL0(Rm, Rn); break;
\r
1875 case 0x2e: MOVLL0(Rm, Rn); break;
\r
1876 case 0x2f: MAC_L(Rm, Rn); break;
\r
1878 case 0x30: NOP(); break;
\r
1879 case 0x31: NOP(); break;
\r
1880 case 0x32: NOP(); break;
\r
1881 case 0x33: NOP(); break;
\r
1882 case 0x34: MOVBS0(Rm, Rn); break;
\r
1883 case 0x35: MOVWS0(Rm, Rn); break;
\r
1884 case 0x36: MOVLS0(Rm, Rn); break;
\r
1885 case 0x37: MULL(Rm, Rn); break;
\r
1886 case 0x38: NOP(); break;
\r
1887 case 0x39: NOP(); break;
\r
1888 case 0x3c: MOVBL0(Rm, Rn); break;
\r
1889 case 0x3d: MOVWL0(Rm, Rn); break;
\r
1890 case 0x3e: MOVLL0(Rm, Rn); break;
\r
1891 case 0x3f: MAC_L(Rm, Rn); break;
\r
1892 case 0x3a: NOP(); break;
\r
1893 case 0x3b: NOP(); break;
\r
1900 INLINE void op0001(UINT16 opcode)
\r
1902 MOVLS4(Rm, opcode & 0x0f, Rn);
\r
1905 INLINE void op0010(UINT16 opcode)
\r
1907 switch (opcode & 15)
\r
1909 case 0: MOVBS(Rm, Rn); break;
\r
1910 case 1: MOVWS(Rm, Rn); break;
\r
1911 case 2: MOVLS(Rm, Rn); break;
\r
1912 case 3: NOP(); break;
\r
1913 case 4: MOVBM(Rm, Rn); break;
\r
1914 case 5: MOVWM(Rm, Rn); break;
\r
1915 case 6: MOVLM(Rm, Rn); break;
\r
1916 case 7: DIV0S(Rm, Rn); break;
\r
1917 case 8: TST(Rm, Rn); break;
\r
1918 case 9: AND(Rm, Rn); break;
\r
1919 case 10: XOR(Rm, Rn); break;
\r
1920 case 11: OR(Rm, Rn); break;
\r
1921 case 12: CMPSTR(Rm, Rn); break;
\r
1922 case 13: XTRCT(Rm, Rn); break;
\r
1923 case 14: MULU(Rm, Rn); break;
\r
1924 case 15: MULS(Rm, Rn); break;
\r
1928 INLINE void op0011(UINT16 opcode)
\r
1930 switch (opcode & 15)
\r
1932 case 0: CMPEQ(Rm, Rn); break;
\r
1933 case 1: NOP(); break;
\r
1934 case 2: CMPHS(Rm, Rn); break;
\r
1935 case 3: CMPGE(Rm, Rn); break;
\r
1936 case 4: DIV1(Rm, Rn); break;
\r
1937 case 5: DMULU(Rm, Rn); break;
\r
1938 case 6: CMPHI(Rm, Rn); break;
\r
1939 case 7: CMPGT(Rm, Rn); break;
\r
1940 case 8: SUB(Rm, Rn); break;
\r
1941 case 9: NOP(); break;
\r
1942 case 10: SUBC(Rm, Rn); break;
\r
1943 case 11: SUBV(Rm, Rn); break;
\r
1944 case 12: ADD(Rm, Rn); break;
\r
1945 case 13: DMULS(Rm, Rn); break;
\r
1946 case 14: ADDC(Rm, Rn); break;
\r
1947 case 15: ADDV(Rm, Rn); break;
\r
1951 INLINE void op0100(UINT16 opcode)
\r
1953 switch (opcode & 0x3F)
\r
1955 case 0x00: SHLL(Rn); break;
\r
1956 case 0x01: SHLR(Rn); break;
\r
1957 case 0x02: STSMMACH(Rn); break;
\r
1958 case 0x03: STCMSR(Rn); break;
\r
1959 case 0x04: ROTL(Rn); break;
\r
1960 case 0x05: ROTR(Rn); break;
\r
1961 case 0x06: LDSMMACH(Rn); break;
\r
1962 case 0x07: LDCMSR(Rn); break;
\r
1963 case 0x08: SHLL2(Rn); break;
\r
1964 case 0x09: SHLR2(Rn); break;
\r
1965 case 0x0a: LDSMACH(Rn); break;
\r
1966 case 0x0b: JSR(Rn); break;
\r
1967 case 0x0c: NOP(); break;
\r
1968 case 0x0d: NOP(); break;
\r
1969 case 0x0e: LDCSR(Rn); break;
\r
1970 case 0x0f: MAC_W(Rm, Rn); break;
\r
1972 case 0x10: DT(Rn); break;
\r
1973 case 0x11: CMPPZ(Rn); break;
\r
1974 case 0x12: STSMMACL(Rn); break;
\r
1975 case 0x13: STCMGBR(Rn); break;
\r
1976 case 0x14: NOP(); break;
\r
1977 case 0x15: CMPPL(Rn); break;
\r
1978 case 0x16: LDSMMACL(Rn); break;
\r
1979 case 0x17: LDCMGBR(Rn); break;
\r
1980 case 0x18: SHLL8(Rn); break;
\r
1981 case 0x19: SHLR8(Rn); break;
\r
1982 case 0x1a: LDSMACL(Rn); break;
\r
1983 case 0x1b: TAS(Rn); break;
\r
1984 case 0x1c: NOP(); break;
\r
1985 case 0x1d: NOP(); break;
\r
1986 case 0x1e: LDCGBR(Rn); break;
\r
1987 case 0x1f: MAC_W(Rm, Rn); break;
\r
1989 case 0x20: SHAL(Rn); break;
\r
1990 case 0x21: SHAR(Rn); break;
\r
1991 case 0x22: STSMPR(Rn); break;
\r
1992 case 0x23: STCMVBR(Rn); break;
\r
1993 case 0x24: ROTCL(Rn); break;
\r
1994 case 0x25: ROTCR(Rn); break;
\r
1995 case 0x26: LDSMPR(Rn); break;
\r
1996 case 0x27: LDCMVBR(Rn); break;
\r
1997 case 0x28: SHLL16(Rn); break;
\r
1998 case 0x29: SHLR16(Rn); break;
\r
1999 case 0x2a: LDSPR(Rn); break;
\r
2000 case 0x2b: JMP(Rn); break;
\r
2001 case 0x2c: NOP(); break;
\r
2002 case 0x2d: NOP(); break;
\r
2003 case 0x2e: LDCVBR(Rn); break;
\r
2004 case 0x2f: MAC_W(Rm, Rn); break;
\r
2006 case 0x30: NOP(); break;
\r
2007 case 0x31: NOP(); break;
\r
2008 case 0x32: NOP(); break;
\r
2009 case 0x33: NOP(); break;
\r
2010 case 0x34: NOP(); break;
\r
2011 case 0x35: NOP(); break;
\r
2012 case 0x36: NOP(); break;
\r
2013 case 0x37: NOP(); break;
\r
2014 case 0x38: NOP(); break;
\r
2015 case 0x39: NOP(); break;
\r
2016 case 0x3a: NOP(); break;
\r
2017 case 0x3b: NOP(); break;
\r
2018 case 0x3c: NOP(); break;
\r
2019 case 0x3d: NOP(); break;
\r
2020 case 0x3e: NOP(); break;
\r
2021 case 0x3f: MAC_W(Rm, Rn); break;
\r
2026 INLINE void op0101(UINT16 opcode)
\r
2028 MOVLL4(Rm, opcode & 0x0f, Rn);
\r
2031 INLINE void op0110(UINT16 opcode)
\r
2033 switch (opcode & 15)
\r
2035 case 0: MOVBL(Rm, Rn); break;
\r
2036 case 1: MOVWL(Rm, Rn); break;
\r
2037 case 2: MOVLL(Rm, Rn); break;
\r
2038 case 3: MOV(Rm, Rn); break;
\r
2039 case 4: MOVBP(Rm, Rn); break;
\r
2040 case 5: MOVWP(Rm, Rn); break;
\r
2041 case 6: MOVLP(Rm, Rn); break;
\r
2042 case 7: NOT(Rm, Rn); break;
\r
2043 case 8: SWAPB(Rm, Rn); break;
\r
2044 case 9: SWAPW(Rm, Rn); break;
\r
2045 case 10: NEGC(Rm, Rn); break;
\r
2046 case 11: NEG(Rm, Rn); break;
\r
2047 case 12: EXTUB(Rm, Rn); break;
\r
2048 case 13: EXTUW(Rm, Rn); break;
\r
2049 case 14: EXTSB(Rm, Rn); break;
\r
2050 case 15: EXTSW(Rm, Rn); break;
\r
2054 INLINE void op0111(UINT16 opcode)
\r
2056 ADDI(opcode & 0xff, Rn);
\r
2059 INLINE void op1000(UINT16 opcode)
\r
2061 switch ( opcode & (15<<8) )
\r
2063 case 0 << 8: MOVBS4(opcode & 0x0f, Rm); break;
\r
2064 case 1 << 8: MOVWS4(opcode & 0x0f, Rm); break;
\r
2065 case 2<< 8: NOP(); break;
\r
2066 case 3<< 8: NOP(); break;
\r
2067 case 4<< 8: MOVBL4(Rm, opcode & 0x0f); break;
\r
2068 case 5<< 8: MOVWL4(Rm, opcode & 0x0f); break;
\r
2069 case 6<< 8: NOP(); break;
\r
2070 case 7<< 8: NOP(); break;
\r
2071 case 8<< 8: CMPIM(opcode & 0xff); break;
\r
2072 case 9<< 8: BT(opcode & 0xff); break;
\r
2073 case 10<< 8: NOP(); break;
\r
2074 case 11<< 8: BF(opcode & 0xff); break;
\r
2075 case 12<< 8: NOP(); break;
\r
2076 case 13<< 8: BTS(opcode & 0xff); break;
\r
2077 case 14<< 8: NOP(); break;
\r
2078 case 15<< 8: BFS(opcode & 0xff); break;
\r
2083 INLINE void op1001(UINT16 opcode)
\r
2085 MOVWI(opcode & 0xff, Rn);
\r
2088 INLINE void op1010(UINT16 opcode)
\r
2090 BRA(opcode & 0xfff);
\r
2093 INLINE void op1011(UINT16 opcode)
\r
2095 BSR(opcode & 0xfff);
\r
2098 INLINE void op1100(UINT16 opcode)
\r
2100 switch (opcode & (15<<8))
\r
2102 case 0<<8: MOVBSG(opcode & 0xff); break;
\r
2103 case 1<<8: MOVWSG(opcode & 0xff); break;
\r
2104 case 2<<8: MOVLSG(opcode & 0xff); break;
\r
2105 case 3<<8: TRAPA(opcode & 0xff); break;
\r
2106 case 4<<8: MOVBLG(opcode & 0xff); break;
\r
2107 case 5<<8: MOVWLG(opcode & 0xff); break;
\r
2108 case 6<<8: MOVLLG(opcode & 0xff); break;
\r
2109 case 7<<8: MOVA(opcode & 0xff); break;
\r
2110 case 8<<8: TSTI(opcode & 0xff); break;
\r
2111 case 9<<8: ANDI(opcode & 0xff); break;
\r
2112 case 10<<8: XORI(opcode & 0xff); break;
\r
2113 case 11<<8: ORI(opcode & 0xff); break;
\r
2114 case 12<<8: TSTM(opcode & 0xff); break;
\r
2115 case 13<<8: ANDM(opcode & 0xff); break;
\r
2116 case 14<<8: XORM(opcode & 0xff); break;
\r
2117 case 15<<8: ORM(opcode & 0xff); break;
\r
2121 INLINE void op1101(UINT16 opcode)
\r
2123 MOVLI(opcode & 0xff, Rn);
\r
2126 INLINE void op1110(UINT16 opcode)
\r
2128 MOVI(opcode & 0xff, Rn);
\r
2131 INLINE void op1111(UINT16 opcode)
\r