32x: add base of SH2 emu from MAME
authornotaz <notasas@gmail.com>
Thu, 17 Sep 2009 20:31:30 +0000 (20:31 +0000)
committernotaz <notasas@gmail.com>
Thu, 17 Sep 2009 20:31:30 +0000 (20:31 +0000)
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@781 be3aeb3a-fb24-0410-a615-afba39da0efa

cpu/sh2mame/sh2.c [new file with mode: 0644]
cpu/sh2mame/sh2.h [new file with mode: 0644]
cpu/sh2mame/sh2pico.c [new file with mode: 0644]

diff --git a/cpu/sh2mame/sh2.c b/cpu/sh2mame/sh2.c
new file mode 100644 (file)
index 0000000..acd6a61
--- /dev/null
@@ -0,0 +1,2136 @@
+/*****************************************************************************\r
+ *\r
+ *   sh2.c\r
+ *   Portable Hitachi SH-2 (SH7600 family) emulator\r
+ *\r
+ *   Copyright Juergen Buchmueller <pullmoll@t-online.de>,\r
+ *   all rights reserved.\r
+ *\r
+ *   - This source code is released as freeware for non-commercial purposes.\r
+ *   - You are free to use and redistribute this code in modified or\r
+ *     unmodified form, provided you list me in the credits.\r
+ *   - If you modify this source code, you must add a notice to each modified\r
+ *     source file that it has been changed.  If you're a nice person, you\r
+ *     will clearly mark each change too.  :)\r
+ *   - If you wish to use this for commercial purposes, please contact me at\r
+ *     pullmoll@t-online.de\r
+ *   - The author of this copywritten work reserves the right to change the\r
+ *     terms of its usage and license at any time, including retroactively\r
+ *   - This entire notice must remain in the source code.\r
+ *\r
+ *  This work is based on <tiraniddo@hotmail.com> C/C++ implementation of\r
+ *  the SH-2 CPU core and was adapted to the MAME CPU core requirements.\r
+ *  Thanks also go to Chuck Mason <chukjr@sundail.net> and Olivier Galibert\r
+ *  <galibert@pobox.com> for letting me peek into their SEMU code :-)\r
+ *\r
+ *****************************************************************************/\r
+\r
+/*****************************************************************************\r
+    Changes\r
+    20051129 Mariusz Wojcieszek\r
+    - introduced memory_decrypted_read_word() for opcode fetching\r
+\r
+    20050813 Mariusz Wojcieszek\r
+    - fixed 64 bit / 32 bit division in division unit\r
+\r
+    20031015 O. Galibert\r
+    - dma fixes, thanks to sthief\r
+\r
+    20031013 O. Galibert, A. Giles\r
+    - timer fixes\r
+    - multi-cpu simplifications\r
+\r
+    20030915 O. Galibert\r
+    - fix DMA1 irq vector\r
+    - ignore writes to DRCRx\r
+    - fix cpu number issues\r
+    - fix slave/master recognition\r
+    - fix wrong-cpu-in-context problem with the timers\r
+\r
+    20021020 O. Galibert\r
+    - DMA implementation, lightly tested\r
+    - delay slot in debugger fixed\r
+    - add divide box mirrors\r
+    - Nicola-ify the indentation\r
+    - Uncrapify sh2_internal_*\r
+    - Put back nmi support that had been lost somehow\r
+\r
+    20020914 R. Belmont\r
+    - Initial SH2 internal timers implementation, based on code by O. Galibert.\r
+      Makes music work in galspanic4/s/s2, panic street, cyvern, other SKNS games.\r
+    - Fix to external division, thanks to "spice" on the E2J board.\r
+      Corrects behavior of s1945ii turret boss.\r
+\r
+    20020302 Olivier Galibert (galibert@mame.net)\r
+    - Fixed interrupt in delay slot\r
+    - Fixed rotcr\r
+    - Fixed div1\r
+    - Fixed mulu\r
+    - Fixed negc\r
+\r
+    20020301 R. Belmont\r
+    - Fixed external division\r
+\r
+    20020225 Olivier Galibert (galibert@mame.net)\r
+    - Fixed interrupt handling\r
+\r
+    20010207 Sylvain Glaize (mokona@puupuu.org)\r
+\r
+    - Bug fix in INLINE void MOVBM(UINT32 m, UINT32 n) (see comment)\r
+    - Support of full 32 bit addressing (RB, RW, RL and WB, WW, WL functions)\r
+        reason : when the two high bits of the address are set, access is\r
+        done directly in the cache data array. The SUPER KANEKO NOVA SYSTEM\r
+        sets the stack pointer here, using these addresses as usual RAM access.\r
+\r
+        No real cache support has been added.\r
+    - Read/Write memory format correction (_bew to _bedw) (see also SH2\r
+        definition in cpuintrf.c and DasmSH2(..) in sh2dasm.c )\r
+\r
+    20010623 James Forshaw (TyRaNiD@totalise.net)\r
+\r
+    - Modified operation of sh2_exception. Done cause mame irq system is stupid, and\r
+      doesnt really seem designed for any more than 8 interrupt lines.\r
+\r
+    20010701 James Forshaw (TyRaNiD@totalise.net)\r
+\r
+    - Fixed DIV1 operation. Q bit now correctly generated\r
+\r
+    20020218 Added save states (mokona@puupuu.org)\r
+\r
+ *****************************************************************************/\r
+\r
+//#include "debugger.h"\r
+#include "sh2.h"\r
+//#include "sh2comn.h"\r
+#define INLINE static\r
+\r
+//CPU_DISASSEMBLE( sh2 );\r
+\r
+#ifndef USE_SH2DRC\r
+\r
+/* speed up delay loops, bail out of tight loops */\r
+#define BUSY_LOOP_HACKS        1\r
+\r
+#define VERBOSE 0\r
+\r
+#define LOG(x) do { if (VERBOSE) logerror x; } while (0)\r
+\r
+static int sh2_icount;\r
+SH2 *sh2;\r
+\r
+#if 0\r
+INLINE UINT8 RB(offs_t A)\r
+{\r
+       if (A >= 0xe0000000)\r
+               return sh2_internal_r(sh2->internal, (A & 0x1fc)>>2, 0xff << (((~A) & 3)*8)) >> (((~A) & 3)*8);\r
+\r
+       if (A >= 0xc0000000)\r
+               return memory_read_byte_32be(sh2->program, A);\r
+\r
+       if (A >= 0x40000000)\r
+               return 0xa5;\r
+\r
+       return memory_read_byte_32be(sh2->program, A & AM);\r
+}\r
+\r
+INLINE UINT16 RW(offs_t A)\r
+{\r
+       if (A >= 0xe0000000)\r
+               return sh2_internal_r(sh2->internal, (A & 0x1fc)>>2, 0xffff << (((~A) & 2)*8)) >> (((~A) & 2)*8);\r
+\r
+       if (A >= 0xc0000000)\r
+               return memory_read_word_32be(sh2->program, A);\r
+\r
+       if (A >= 0x40000000)\r
+               return 0xa5a5;\r
+\r
+       return memory_read_word_32be(sh2->program, A & AM);\r
+}\r
+\r
+INLINE UINT32 RL(offs_t A)\r
+{\r
+       if (A >= 0xe0000000)\r
+               return sh2_internal_r(sh2->internal, (A & 0x1fc)>>2, 0xffffffff);\r
+\r
+       if (A >= 0xc0000000)\r
+               return memory_read_dword_32be(sh2->program, A);\r
+\r
+       if (A >= 0x40000000)\r
+               return 0xa5a5a5a5;\r
+\r
+  return memory_read_dword_32be(sh2->program, A & AM);\r
+}\r
+\r
+INLINE void WB(offs_t A, UINT8 V)\r
+{\r
+\r
+       if (A >= 0xe0000000)\r
+       {\r
+               sh2_internal_w(sh2->internal, (A & 0x1fc)>>2, V << (((~A) & 3)*8), 0xff << (((~A) & 3)*8));\r
+               return;\r
+       }\r
+\r
+       if (A >= 0xc0000000)\r
+       {\r
+               memory_write_byte_32be(sh2->program, A,V);\r
+               return;\r
+       }\r
+\r
+       if (A >= 0x40000000)\r
+               return;\r
+\r
+       memory_write_byte_32be(sh2->program, A & AM,V);\r
+}\r
+\r
+INLINE void WW(offs_t A, UINT16 V)\r
+{\r
+       if (A >= 0xe0000000)\r
+       {\r
+               sh2_internal_w(sh2->internal, (A & 0x1fc)>>2, V << (((~A) & 2)*8), 0xffff << (((~A) & 2)*8));\r
+               return;\r
+       }\r
+\r
+       if (A >= 0xc0000000)\r
+       {\r
+               memory_write_word_32be(sh2->program, A,V);\r
+               return;\r
+       }\r
+\r
+       if (A >= 0x40000000)\r
+               return;\r
+\r
+       memory_write_word_32be(sh2->program, A & AM,V);\r
+}\r
+\r
+INLINE void WL(offs_t A, UINT32 V)\r
+{\r
+       if (A >= 0xe0000000)\r
+       {\r
+               sh2_internal_w(sh2->internal, (A & 0x1fc)>>2, V, 0xffffffff);\r
+               return;\r
+       }\r
+\r
+       if (A >= 0xc0000000)\r
+       {\r
+               memory_write_dword_32be(sh2->program, A,V);\r
+               return;\r
+       }\r
+\r
+       if (A >= 0x40000000)\r
+               return;\r
+\r
+       memory_write_dword_32be(sh2->program, A & AM,V);\r
+}\r
+#endif\r
+\r
+/*  code                 cycles  t-bit\r
+ *  0011 nnnn mmmm 1100  1       -\r
+ *  ADD     Rm,Rn\r
+ */\r
+INLINE void ADD(UINT32 m, UINT32 n)\r
+{\r
+       sh2->r[n] += sh2->r[m];\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  0111 nnnn iiii iiii  1       -\r
+ *  ADD     #imm,Rn\r
+ */\r
+INLINE void ADDI(UINT32 i, UINT32 n)\r
+{\r
+       sh2->r[n] += (INT32)(INT16)(INT8)i;\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  0011 nnnn mmmm 1110  1       carry\r
+ *  ADDC    Rm,Rn\r
+ */\r
+INLINE void ADDC(UINT32 m, UINT32 n)\r
+{\r
+       UINT32 tmp0, tmp1;\r
+\r
+       tmp1 = sh2->r[n] + sh2->r[m];\r
+       tmp0 = sh2->r[n];\r
+       sh2->r[n] = tmp1 + (sh2->sr & T);\r
+       if (tmp0 > tmp1)\r
+               sh2->sr |= T;\r
+       else\r
+               sh2->sr &= ~T;\r
+       if (tmp1 > sh2->r[n])\r
+               sh2->sr |= T;\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  0011 nnnn mmmm 1111  1       overflow\r
+ *  ADDV    Rm,Rn\r
+ */\r
+INLINE void ADDV(UINT32 m, UINT32 n)\r
+{\r
+       INT32 dest, src, ans;\r
+\r
+       if ((INT32) sh2->r[n] >= 0)\r
+               dest = 0;\r
+       else\r
+               dest = 1;\r
+       if ((INT32) sh2->r[m] >= 0)\r
+               src = 0;\r
+       else\r
+               src = 1;\r
+       src += dest;\r
+       sh2->r[n] += sh2->r[m];\r
+       if ((INT32) sh2->r[n] >= 0)\r
+               ans = 0;\r
+       else\r
+               ans = 1;\r
+       ans += dest;\r
+       if (src == 0 || src == 2)\r
+       {\r
+               if (ans == 1)\r
+                       sh2->sr |= T;\r
+               else\r
+                       sh2->sr &= ~T;\r
+       }\r
+       else\r
+               sh2->sr &= ~T;\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  0010 nnnn mmmm 1001  1       -\r
+ *  AND     Rm,Rn\r
+ */\r
+INLINE void AND(UINT32 m, UINT32 n)\r
+{\r
+       sh2->r[n] &= sh2->r[m];\r
+}\r
+\r
+\r
+/*  code                 cycles  t-bit\r
+ *  1100 1001 iiii iiii  1       -\r
+ *  AND     #imm,R0\r
+ */\r
+INLINE void ANDI(UINT32 i)\r
+{\r
+       sh2->r[0] &= i;\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  1100 1101 iiii iiii  1       -\r
+ *  AND.B   #imm,@(R0,GBR)\r
+ */\r
+INLINE void ANDM(UINT32 i)\r
+{\r
+       UINT32 temp;\r
+\r
+       sh2->ea = sh2->gbr + sh2->r[0];\r
+       temp = i & RB( sh2->ea );\r
+       WB( sh2->ea, temp );\r
+       sh2_icount -= 2;\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  1000 1011 dddd dddd  3/1     -\r
+ *  BF      disp8\r
+ */\r
+INLINE void BF(UINT32 d)\r
+{\r
+       if ((sh2->sr & T) == 0)\r
+       {\r
+               INT32 disp = ((INT32)d << 24) >> 24;\r
+               sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;\r
+               sh2_icount -= 2;\r
+       }\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  1000 1111 dddd dddd  3/1     -\r
+ *  BFS     disp8\r
+ */\r
+INLINE void BFS(UINT32 d)\r
+{\r
+       if ((sh2->sr & T) == 0)\r
+       {\r
+               INT32 disp = ((INT32)d << 24) >> 24;\r
+               sh2->delay = sh2->pc;\r
+               sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;\r
+               sh2_icount--;\r
+       }\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  1010 dddd dddd dddd  2       -\r
+ *  BRA     disp12\r
+ */\r
+INLINE void BRA(UINT32 d)\r
+{\r
+       INT32 disp = ((INT32)d << 20) >> 20;\r
+\r
+#if BUSY_LOOP_HACKS\r
+       if (disp == -2)\r
+       {\r
+               UINT32 next_opcode = RW(sh2->ppc & AM);\r
+               /* BRA  $\r
+         * NOP\r
+         */\r
+               if (next_opcode == 0x0009)\r
+                       sh2_icount %= 3;        /* cycles for BRA $ and NOP taken (3) */\r
+       }\r
+#endif\r
+       sh2->delay = sh2->pc;\r
+       sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;\r
+       sh2_icount--;\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  0000 mmmm 0010 0011  2       -\r
+ *  BRAF    Rm\r
+ */\r
+INLINE void BRAF(UINT32 m)\r
+{\r
+       sh2->delay = sh2->pc;\r
+       sh2->pc += sh2->r[m] + 2;\r
+       sh2_icount--;\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  1011 dddd dddd dddd  2       -\r
+ *  BSR     disp12\r
+ */\r
+INLINE void BSR(UINT32 d)\r
+{\r
+       INT32 disp = ((INT32)d << 20) >> 20;\r
+\r
+       sh2->pr = sh2->pc + 2;\r
+       sh2->delay = sh2->pc;\r
+       sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;\r
+       sh2_icount--;\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  0000 mmmm 0000 0011  2       -\r
+ *  BSRF    Rm\r
+ */\r
+INLINE void BSRF(UINT32 m)\r
+{\r
+       sh2->pr = sh2->pc + 2;\r
+       sh2->delay = sh2->pc;\r
+       sh2->pc += sh2->r[m] + 2;\r
+       sh2_icount--;\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  1000 1001 dddd dddd  3/1     -\r
+ *  BT      disp8\r
+ */\r
+INLINE void BT(UINT32 d)\r
+{\r
+       if ((sh2->sr & T) != 0)\r
+       {\r
+               INT32 disp = ((INT32)d << 24) >> 24;\r
+               sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;\r
+               sh2_icount -= 2;\r
+       }\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  1000 1101 dddd dddd  2/1     -\r
+ *  BTS     disp8\r
+ */\r
+INLINE void BTS(UINT32 d)\r
+{\r
+       if ((sh2->sr & T) != 0)\r
+       {\r
+               INT32 disp = ((INT32)d << 24) >> 24;\r
+               sh2->delay = sh2->pc;\r
+               sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;\r
+               sh2_icount--;\r
+       }\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  0000 0000 0010 1000  1       -\r
+ *  CLRMAC\r
+ */\r
+INLINE void CLRMAC(void)\r
+{\r
+       sh2->mach = 0;\r
+       sh2->macl = 0;\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  0000 0000 0000 1000  1       -\r
+ *  CLRT\r
+ */\r
+INLINE void CLRT(void)\r
+{\r
+       sh2->sr &= ~T;\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  0011 nnnn mmmm 0000  1       comparison result\r
+ *  CMP_EQ  Rm,Rn\r
+ */\r
+INLINE void CMPEQ(UINT32 m, UINT32 n)\r
+{\r
+       if (sh2->r[n] == sh2->r[m])\r
+               sh2->sr |= T;\r
+       else\r
+               sh2->sr &= ~T;\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  0011 nnnn mmmm 0011  1       comparison result\r
+ *  CMP_GE  Rm,Rn\r
+ */\r
+INLINE void CMPGE(UINT32 m, UINT32 n)\r
+{\r
+       if ((INT32) sh2->r[n] >= (INT32) sh2->r[m])\r
+               sh2->sr |= T;\r
+       else\r
+               sh2->sr &= ~T;\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  0011 nnnn mmmm 0111  1       comparison result\r
+ *  CMP_GT  Rm,Rn\r
+ */\r
+INLINE void CMPGT(UINT32 m, UINT32 n)\r
+{\r
+       if ((INT32) sh2->r[n] > (INT32) sh2->r[m])\r
+               sh2->sr |= T;\r
+       else\r
+               sh2->sr &= ~T;\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  0011 nnnn mmmm 0110  1       comparison result\r
+ *  CMP_HI  Rm,Rn\r
+ */\r
+INLINE void CMPHI(UINT32 m, UINT32 n)\r
+{\r
+       if ((UINT32) sh2->r[n] > (UINT32) sh2->r[m])\r
+               sh2->sr |= T;\r
+       else\r
+               sh2->sr &= ~T;\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  0011 nnnn mmmm 0010  1       comparison result\r
+ *  CMP_HS  Rm,Rn\r
+ */\r
+INLINE void CMPHS(UINT32 m, UINT32 n)\r
+{\r
+       if ((UINT32) sh2->r[n] >= (UINT32) sh2->r[m])\r
+               sh2->sr |= T;\r
+       else\r
+               sh2->sr &= ~T;\r
+}\r
+\r
+\r
+/*  code                 cycles  t-bit\r
+ *  0100 nnnn 0001 0101  1       comparison result\r
+ *  CMP_PL  Rn\r
+ */\r
+INLINE void CMPPL(UINT32 n)\r
+{\r
+       if ((INT32) sh2->r[n] > 0)\r
+               sh2->sr |= T;\r
+       else\r
+               sh2->sr &= ~T;\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  0100 nnnn 0001 0001  1       comparison result\r
+ *  CMP_PZ  Rn\r
+ */\r
+INLINE void CMPPZ(UINT32 n)\r
+{\r
+       if ((INT32) sh2->r[n] >= 0)\r
+               sh2->sr |= T;\r
+       else\r
+               sh2->sr &= ~T;\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  0010 nnnn mmmm 1100  1       comparison result\r
+ * CMP_STR  Rm,Rn\r
+ */\r
+INLINE void CMPSTR(UINT32 m, UINT32 n)\r
+ {\r
+  UINT32 temp;\r
+  INT32 HH, HL, LH, LL;\r
+  temp = sh2->r[n] ^ sh2->r[m];\r
+  HH = (temp >> 24) & 0xff;\r
+  HL = (temp >> 16) & 0xff;\r
+  LH = (temp >> 8) & 0xff;\r
+  LL = temp & 0xff;\r
+  if (HH && HL && LH && LL)\r
+   sh2->sr &= ~T;\r
+  else\r
+   sh2->sr |= T;\r
+ }\r
+\r
+\r
+/*  code                 cycles  t-bit\r
+ *  1000 1000 iiii iiii  1       comparison result\r
+ *  CMP/EQ #imm,R0\r
+ */\r
+INLINE void CMPIM(UINT32 i)\r
+{\r
+       UINT32 imm = (UINT32)(INT32)(INT16)(INT8)i;\r
+\r
+       if (sh2->r[0] == imm)\r
+               sh2->sr |= T;\r
+       else\r
+               sh2->sr &= ~T;\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  0010 nnnn mmmm 0111  1       calculation result\r
+ *  DIV0S   Rm,Rn\r
+ */\r
+INLINE void DIV0S(UINT32 m, UINT32 n)\r
+{\r
+       if ((sh2->r[n] & 0x80000000) == 0)\r
+               sh2->sr &= ~Q;\r
+       else\r
+               sh2->sr |= Q;\r
+       if ((sh2->r[m] & 0x80000000) == 0)\r
+               sh2->sr &= ~M;\r
+       else\r
+               sh2->sr |= M;\r
+       if ((sh2->r[m] ^ sh2->r[n]) & 0x80000000)\r
+               sh2->sr |= T;\r
+       else\r
+               sh2->sr &= ~T;\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  0000 0000 0001 1001  1       0\r
+ *  DIV0U\r
+ */\r
+INLINE void DIV0U(void)\r
+{\r
+       sh2->sr &= ~(M | Q | T);\r
+}\r
+\r
+/*  code                 cycles  t-bit\r
+ *  0011 nnnn mmmm 0100  1       calculation result\r
+ *  DIV1 Rm,Rn\r
+ */\r
+INLINE void DIV1(UINT32 m, UINT32 n)\r
+{\r
+       UINT32 tmp0;\r
+       UINT32 old_q;\r
+\r
+       old_q = sh2->sr & Q;\r
+       if (0x80000000 & sh2->r[n])\r
+               sh2->sr |= Q;\r
+       else\r
+               sh2->sr &= ~Q;\r
+\r
+       sh2->r[n] = (sh2->r[n] << 1) | (sh2->sr & T);\r
+\r
+       if (!old_q)\r
+       {\r
+               if (!(sh2->sr & M))\r
+               {\r
+                       tmp0 = sh2->r[n];\r
+                       sh2->r[n] -= sh2->r[m];\r
+                       if(!(sh2->sr & Q))\r
+                               if(sh2->r[n] > tmp0)\r
+                                       sh2->sr |= Q;\r
+                               else\r
+                                       sh2->sr &= ~Q;\r
+                       else\r
+                               if(sh2->r[n] > tmp0)\r
+                                       sh2->sr &= ~Q;\r
+                               else\r
+                                       sh2->sr |= Q;\r
+               }\r
+               else\r
+               {\r
+                       tmp0 = sh2->r[n];\r
+                       sh2->r[n] += sh2->r[m];\r
+                       if(!(sh2->sr & Q))\r
+                       {\r
+                               if(sh2->r[n] < tmp0)\r
+                                       sh2->sr &= ~Q;\r
+                               else\r
+                                       sh2->sr |= Q;\r
+                       }\r
+                       else\r
+                       {\r
+                               if(sh2->r[n] < tmp0)\r
+                                       sh2->sr |= Q;\r
+                               else\r
+                                       sh2->sr &= ~Q;\r
+                       }\r
+               }\r
+       }\r
+       else\r
+       {\r
+               if (!(sh2->sr & M))\r
+               {\r
+                       tmp0 = sh2->r[n];\r
+                       sh2->r[n] += sh2->r[m];\r
+                       if(!(sh2->sr & Q))\r
+                               if(sh2->r[n] < tmp0)\r
+                                       sh2->sr |= Q;\r
+                               else\r
+                                       sh2->sr &= ~Q;\r
+                       else\r
+                               if(sh2->r[n] < tmp0)\r
+                                       sh2->sr &= ~Q;\r
+                               else\r
+                                       sh2->sr |= Q;\r
+               }\r
+               else\r
+               {\r
+                       tmp0 = sh2->r[n];\r
+                       sh2->r[n] -= sh2->r[m];\r
+                       if(!(sh2->sr & Q))\r
+                               if(sh2->r[n] > tmp0)\r
+                                       sh2->sr &= ~Q;\r
+                               else\r
+                                       sh2->sr |= Q;\r
+                       else\r
+                               if(sh2->r[n] > tmp0)\r
+                                       sh2->sr |= Q;\r
+                               else\r
+                                       sh2->sr &= ~Q;\r
+               }\r
+       }\r
+\r
+       tmp0 = (sh2->sr & (Q | M));\r
+       if((!tmp0) || (tmp0 == 0x300)) /* if Q == M set T else clear T */\r
+               sh2->sr |= T;\r
+       else\r
+               sh2->sr &= ~T;\r
+}\r
+\r
+/*  DMULS.L Rm,Rn */\r
+INLINE void DMULS(UINT32 m, UINT32 n)\r
+{\r
+       UINT32 RnL, RnH, RmL, RmH, Res0, Res1, Res2;\r
+       UINT32 temp0, temp1, temp2, temp3;\r
+       INT32 tempm, tempn, fnLmL;\r
+\r
+       tempn = (INT32) sh2->r[n];\r
+       tempm = (INT32) sh2->r[m];\r
+       if (tempn < 0)\r
+               tempn = 0 - tempn;\r
+       if (tempm < 0)\r
+               tempm = 0 - tempm;\r
+       if ((INT32) (sh2->r[n] ^ sh2->r[m]) < 0)\r
+               fnLmL = -1;\r
+       else\r
+               fnLmL = 0;\r
+       temp1 = (UINT32) tempn;\r
+       temp2 = (UINT32) tempm;\r
+       RnL = temp1 & 0x0000ffff;\r
+       RnH = (temp1 >> 16) & 0x0000ffff;\r
+       RmL = temp2 & 0x0000ffff;\r
+       RmH = (temp2 >> 16) & 0x0000ffff;\r
+       temp0 = RmL * RnL;\r
+       temp1 = RmH * RnL;\r
+       temp2 = RmL * RnH;\r
+       temp3 = RmH * RnH;\r
+       Res2 = 0;\r
+       Res1 = temp1 + temp2;\r
+       if (Res1 < temp1)\r
+               Res2 += 0x00010000;\r
+       temp1 = (Res1 << 16) & 0xffff0000;\r
+       Res0 = temp0 + temp1;\r
+       if (Res0 < temp0)\r
+               Res2++;\r
+       Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;\r
+       if (fnLmL < 0)\r
+       {\r
+               Res2 = ~Res2;\r
+               if (Res0 == 0)\r
+                       Res2++;\r
+               else\r
+                       Res0 = (~Res0) + 1;\r
+       }\r
+       sh2->mach = Res2;\r
+       sh2->macl = Res0;\r
+       sh2_icount--;\r
+}\r
+\r
+/*  DMULU.L Rm,Rn */\r
+INLINE void DMULU(UINT32 m, UINT32 n)\r
+{\r
+       UINT32 RnL, RnH, RmL, RmH, Res0, Res1, Res2;\r
+       UINT32 temp0, temp1, temp2, temp3;\r
+\r
+       RnL = sh2->r[n] & 0x0000ffff;\r
+       RnH = (sh2->r[n] >> 16) & 0x0000ffff;\r
+       RmL = sh2->r[m] & 0x0000ffff;\r
+       RmH = (sh2->r[m] >> 16) & 0x0000ffff;\r
+       temp0 = RmL * RnL;\r
+       temp1 = RmH * RnL;\r
+       temp2 = RmL * RnH;\r
+       temp3 = RmH * RnH;\r
+       Res2 = 0;\r
+       Res1 = temp1 + temp2;\r
+       if (Res1 < temp1)\r
+               Res2 += 0x00010000;\r
+       temp1 = (Res1 << 16) & 0xffff0000;\r
+       Res0 = temp0 + temp1;\r
+       if (Res0 < temp0)\r
+               Res2++;\r
+       Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;\r
+       sh2->mach = Res2;\r
+       sh2->macl = Res0;\r
+       sh2_icount--;\r
+}\r
+\r
+/*  DT      Rn */\r
+INLINE void DT(UINT32 n)\r
+{\r
+       sh2->r[n]--;\r
+       if (sh2->r[n] == 0)\r
+               sh2->sr |= T;\r
+       else\r
+               sh2->sr &= ~T;\r
+#if BUSY_LOOP_HACKS\r
+       {\r
+               UINT32 next_opcode = RW(sh2->ppc & AM);\r
+               /* DT   Rn\r
+         * BF   $-2\r
+         */\r
+               if (next_opcode == 0x8bfd)\r
+               {\r
+                       while (sh2->r[n] > 1 && sh2_icount > 4)\r
+                       {\r
+                               sh2->r[n]--;\r
+                               sh2_icount -= 4;        /* cycles for DT (1) and BF taken (3) */\r
+                       }\r
+               }\r
+       }\r
+#endif\r
+}\r
+\r
+/*  EXTS.B  Rm,Rn */\r
+INLINE void EXTSB(UINT32 m, UINT32 n)\r
+{\r
+       sh2->r[n] = ((INT32)sh2->r[m] << 24) >> 24;\r
+}\r
+\r
+/*  EXTS.W  Rm,Rn */\r
+INLINE void EXTSW(UINT32 m, UINT32 n)\r
+{\r
+       sh2->r[n] = ((INT32)sh2->r[m] << 16) >> 16;\r
+}\r
+\r
+/*  EXTU.B  Rm,Rn */\r
+INLINE void EXTUB(UINT32 m, UINT32 n)\r
+{\r
+       sh2->r[n] = sh2->r[m] & 0x000000ff;\r
+}\r
+\r
+/*  EXTU.W  Rm,Rn */\r
+INLINE void EXTUW(UINT32 m, UINT32 n)\r
+{\r
+       sh2->r[n] = sh2->r[m] & 0x0000ffff;\r
+}\r
+\r
+/*  JMP     @Rm */\r
+INLINE void JMP(UINT32 m)\r
+{\r
+       sh2->delay = sh2->pc;\r
+       sh2->pc = sh2->ea = sh2->r[m];\r
+}\r
+\r
+/*  JSR     @Rm */\r
+INLINE void JSR(UINT32 m)\r
+{\r
+       sh2->delay = sh2->pc;\r
+       sh2->pr = sh2->pc + 2;\r
+       sh2->pc = sh2->ea = sh2->r[m];\r
+       sh2_icount--;\r
+}\r
+\r
+\r
+/*  LDC     Rm,SR */\r
+INLINE void LDCSR(UINT32 m)\r
+{\r
+       sh2->sr = sh2->r[m] & FLAGS;\r
+       sh2->test_irq = 1;\r
+}\r
+\r
+/*  LDC     Rm,GBR */\r
+INLINE void LDCGBR(UINT32 m)\r
+{\r
+       sh2->gbr = sh2->r[m];\r
+}\r
+\r
+/*  LDC     Rm,VBR */\r
+INLINE void LDCVBR(UINT32 m)\r
+{\r
+       sh2->vbr = sh2->r[m];\r
+}\r
+\r
+/*  LDC.L   @Rm+,SR */\r
+INLINE void LDCMSR(UINT32 m)\r
+{\r
+       sh2->ea = sh2->r[m];\r
+       sh2->sr = RL( sh2->ea ) & FLAGS;\r
+       sh2->r[m] += 4;\r
+       sh2_icount -= 2;\r
+       sh2->test_irq = 1;\r
+}\r
+\r
+/*  LDC.L   @Rm+,GBR */\r
+INLINE void LDCMGBR(UINT32 m)\r
+{\r
+       sh2->ea = sh2->r[m];\r
+       sh2->gbr = RL( sh2->ea );\r
+       sh2->r[m] += 4;\r
+       sh2_icount -= 2;\r
+}\r
+\r
+/*  LDC.L   @Rm+,VBR */\r
+INLINE void LDCMVBR(UINT32 m)\r
+{\r
+       sh2->ea = sh2->r[m];\r
+       sh2->vbr = RL( sh2->ea );\r
+       sh2->r[m] += 4;\r
+       sh2_icount -= 2;\r
+}\r
+\r
+/*  LDS     Rm,MACH */\r
+INLINE void LDSMACH(UINT32 m)\r
+{\r
+       sh2->mach = sh2->r[m];\r
+}\r
+\r
+/*  LDS     Rm,MACL */\r
+INLINE void LDSMACL(UINT32 m)\r
+{\r
+       sh2->macl = sh2->r[m];\r
+}\r
+\r
+/*  LDS     Rm,PR */\r
+INLINE void LDSPR(UINT32 m)\r
+{\r
+       sh2->pr = sh2->r[m];\r
+}\r
+\r
+/*  LDS.L   @Rm+,MACH */\r
+INLINE void LDSMMACH(UINT32 m)\r
+{\r
+       sh2->ea = sh2->r[m];\r
+       sh2->mach = RL( sh2->ea );\r
+       sh2->r[m] += 4;\r
+}\r
+\r
+/*  LDS.L   @Rm+,MACL */\r
+INLINE void LDSMMACL(UINT32 m)\r
+{\r
+       sh2->ea = sh2->r[m];\r
+       sh2->macl = RL( sh2->ea );\r
+       sh2->r[m] += 4;\r
+}\r
+\r
+/*  LDS.L   @Rm+,PR */\r
+INLINE void LDSMPR(UINT32 m)\r
+{\r
+       sh2->ea = sh2->r[m];\r
+       sh2->pr = RL( sh2->ea );\r
+       sh2->r[m] += 4;\r
+}\r
+\r
+/*  MAC.L   @Rm+,@Rn+ */\r
+INLINE void MAC_L(UINT32 m, UINT32 n)\r
+{\r
+       UINT32 RnL, RnH, RmL, RmH, Res0, Res1, Res2;\r
+       UINT32 temp0, temp1, temp2, temp3;\r
+       INT32 tempm, tempn, fnLmL;\r
+\r
+       tempn = (INT32) RL( sh2->r[n] );\r
+       sh2->r[n] += 4;\r
+       tempm = (INT32) RL( sh2->r[m] );\r
+       sh2->r[m] += 4;\r
+       if ((INT32) (tempn ^ tempm) < 0)\r
+               fnLmL = -1;\r
+       else\r
+               fnLmL = 0;\r
+       if (tempn < 0)\r
+               tempn = 0 - tempn;\r
+       if (tempm < 0)\r
+               tempm = 0 - tempm;\r
+       temp1 = (UINT32) tempn;\r
+       temp2 = (UINT32) tempm;\r
+       RnL = temp1 & 0x0000ffff;\r
+       RnH = (temp1 >> 16) & 0x0000ffff;\r
+       RmL = temp2 & 0x0000ffff;\r
+       RmH = (temp2 >> 16) & 0x0000ffff;\r
+       temp0 = RmL * RnL;\r
+       temp1 = RmH * RnL;\r
+       temp2 = RmL * RnH;\r
+       temp3 = RmH * RnH;\r
+       Res2 = 0;\r
+       Res1 = temp1 + temp2;\r
+       if (Res1 < temp1)\r
+               Res2 += 0x00010000;\r
+       temp1 = (Res1 << 16) & 0xffff0000;\r
+       Res0 = temp0 + temp1;\r
+       if (Res0 < temp0)\r
+               Res2++;\r
+       Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;\r
+       if (fnLmL < 0)\r
+       {\r
+               Res2 = ~Res2;\r
+               if (Res0 == 0)\r
+                       Res2++;\r
+               else\r
+                       Res0 = (~Res0) + 1;\r
+       }\r
+       if (sh2->sr & S)\r
+       {\r
+               Res0 = sh2->macl + Res0;\r
+               if (sh2->macl > Res0)\r
+                       Res2++;\r
+               Res2 += (sh2->mach & 0x0000ffff);\r
+               if (((INT32) Res2 < 0) && (Res2 < 0xffff8000))\r
+               {\r
+                       Res2 = 0x00008000;\r
+                       Res0 = 0x00000000;\r
+               }\r
+               else if (((INT32) Res2 > 0) && (Res2 > 0x00007fff))\r
+               {\r
+                       Res2 = 0x00007fff;\r
+                       Res0 = 0xffffffff;\r
+               }\r
+               sh2->mach = Res2;\r
+               sh2->macl = Res0;\r
+       }\r
+       else\r
+       {\r
+               Res0 = sh2->macl + Res0;\r
+               if (sh2->macl > Res0)\r
+                       Res2++;\r
+               Res2 += sh2->mach;\r
+               sh2->mach = Res2;\r
+               sh2->macl = Res0;\r
+       }\r
+       sh2_icount -= 2;\r
+}\r
+\r
+/*  MAC.W   @Rm+,@Rn+ */\r
+INLINE void MAC_W(UINT32 m, UINT32 n)\r
+{\r
+       INT32 tempm, tempn, dest, src, ans;\r
+       UINT32 templ;\r
+\r
+       tempn = (INT32) RW( sh2->r[n] );\r
+       sh2->r[n] += 2;\r
+       tempm = (INT32) RW( sh2->r[m] );\r
+       sh2->r[m] += 2;\r
+       templ = sh2->macl;\r
+       tempm = ((INT32) (short) tempn * (INT32) (short) tempm);\r
+       if ((INT32) sh2->macl >= 0)\r
+               dest = 0;\r
+       else\r
+               dest = 1;\r
+       if ((INT32) tempm >= 0)\r
+       {\r
+               src = 0;\r
+               tempn = 0;\r
+       }\r
+       else\r
+       {\r
+               src = 1;\r
+               tempn = 0xffffffff;\r
+       }\r
+       src += dest;\r
+       sh2->macl += tempm;\r
+       if ((INT32) sh2->macl >= 0)\r
+               ans = 0;\r
+       else\r
+               ans = 1;\r
+       ans += dest;\r
+       if (sh2->sr & S)\r
+       {\r
+               if (ans == 1)\r
+                       {\r
+                               if (src == 0)\r
+                                       sh2->macl = 0x7fffffff;\r
+                               if (src == 2)\r
+                                       sh2->macl = 0x80000000;\r
+                       }\r
+       }\r
+       else\r
+       {\r
+               sh2->mach += tempn;\r
+               if (templ > sh2->macl)\r
+                       sh2->mach += 1;\r
+               }\r
+       sh2_icount -= 2;\r
+}\r
+\r
+/*  MOV     Rm,Rn */\r
+INLINE void MOV(UINT32 m, UINT32 n)\r
+{\r
+       sh2->r[n] = sh2->r[m];\r
+}\r
+\r
+/*  MOV.B   Rm,@Rn */\r
+INLINE void MOVBS(UINT32 m, UINT32 n)\r
+{\r
+       sh2->ea = sh2->r[n];\r
+       WB( sh2->ea, sh2->r[m] & 0x000000ff);\r
+}\r
+\r
+/*  MOV.W   Rm,@Rn */\r
+INLINE void MOVWS(UINT32 m, UINT32 n)\r
+{\r
+       sh2->ea = sh2->r[n];\r
+       WW( sh2->ea, sh2->r[m] & 0x0000ffff);\r
+}\r
+\r
+/*  MOV.L   Rm,@Rn */\r
+INLINE void MOVLS(UINT32 m, UINT32 n)\r
+{\r
+       sh2->ea = sh2->r[n];\r
+       WL( sh2->ea, sh2->r[m] );\r
+}\r
+\r
+/*  MOV.B   @Rm,Rn */\r
+INLINE void MOVBL(UINT32 m, UINT32 n)\r
+{\r
+       sh2->ea = sh2->r[m];\r
+       sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) RB( sh2->ea );\r
+}\r
+\r
+/*  MOV.W   @Rm,Rn */\r
+INLINE void MOVWL(UINT32 m, UINT32 n)\r
+{\r
+       sh2->ea = sh2->r[m];\r
+       sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2->ea );\r
+}\r
+\r
+/*  MOV.L   @Rm,Rn */\r
+INLINE void MOVLL(UINT32 m, UINT32 n)\r
+{\r
+       sh2->ea = sh2->r[m];\r
+       sh2->r[n] = RL( sh2->ea );\r
+}\r
+\r
+/*  MOV.B   Rm,@-Rn */\r
+INLINE void MOVBM(UINT32 m, UINT32 n)\r
+{\r
+       /* SMG : bug fix, was reading sh2->r[n] */\r
+       UINT32 data = sh2->r[m] & 0x000000ff;\r
+\r
+       sh2->r[n] -= 1;\r
+       WB( sh2->r[n], data );\r
+}\r
+\r
+/*  MOV.W   Rm,@-Rn */\r
+INLINE void MOVWM(UINT32 m, UINT32 n)\r
+{\r
+       UINT32 data = sh2->r[m] & 0x0000ffff;\r
+\r
+       sh2->r[n] -= 2;\r
+       WW( sh2->r[n], data );\r
+}\r
+\r
+/*  MOV.L   Rm,@-Rn */\r
+INLINE void MOVLM(UINT32 m, UINT32 n)\r
+{\r
+       UINT32 data = sh2->r[m];\r
+\r
+       sh2->r[n] -= 4;\r
+       WL( sh2->r[n], data );\r
+}\r
+\r
+/*  MOV.B   @Rm+,Rn */\r
+INLINE void MOVBP(UINT32 m, UINT32 n)\r
+{\r
+       sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) RB( sh2->r[m] );\r
+       if (n != m)\r
+               sh2->r[m] += 1;\r
+}\r
+\r
+/*  MOV.W   @Rm+,Rn */\r
+INLINE void MOVWP(UINT32 m, UINT32 n)\r
+{\r
+       sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2->r[m] );\r
+       if (n != m)\r
+               sh2->r[m] += 2;\r
+}\r
+\r
+/*  MOV.L   @Rm+,Rn */\r
+INLINE void MOVLP(UINT32 m, UINT32 n)\r
+{\r
+       sh2->r[n] = RL( sh2->r[m] );\r
+       if (n != m)\r
+               sh2->r[m] += 4;\r
+}\r
+\r
+/*  MOV.B   Rm,@(R0,Rn) */\r
+INLINE void MOVBS0(UINT32 m, UINT32 n)\r
+{\r
+       sh2->ea = sh2->r[n] + sh2->r[0];\r
+       WB( sh2->ea, sh2->r[m] & 0x000000ff );\r
+}\r
+\r
+/*  MOV.W   Rm,@(R0,Rn) */\r
+INLINE void MOVWS0(UINT32 m, UINT32 n)\r
+{\r
+       sh2->ea = sh2->r[n] + sh2->r[0];\r
+       WW( sh2->ea, sh2->r[m] & 0x0000ffff );\r
+}\r
+\r
+/*  MOV.L   Rm,@(R0,Rn) */\r
+INLINE void MOVLS0(UINT32 m, UINT32 n)\r
+{\r
+       sh2->ea = sh2->r[n] + sh2->r[0];\r
+       WL( sh2->ea, sh2->r[m] );\r
+}\r
+\r
+/*  MOV.B   @(R0,Rm),Rn */\r
+INLINE void MOVBL0(UINT32 m, UINT32 n)\r
+{\r
+       sh2->ea = sh2->r[m] + sh2->r[0];\r
+       sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) RB( sh2->ea );\r
+}\r
+\r
+/*  MOV.W   @(R0,Rm),Rn */\r
+INLINE void MOVWL0(UINT32 m, UINT32 n)\r
+{\r
+       sh2->ea = sh2->r[m] + sh2->r[0];\r
+       sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2->ea );\r
+}\r
+\r
+/*  MOV.L   @(R0,Rm),Rn */\r
+INLINE void MOVLL0(UINT32 m, UINT32 n)\r
+{\r
+       sh2->ea = sh2->r[m] + sh2->r[0];\r
+       sh2->r[n] = RL( sh2->ea );\r
+}\r
+\r
+/*  MOV     #imm,Rn */\r
+INLINE void MOVI(UINT32 i, UINT32 n)\r
+{\r
+       sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) i;\r
+}\r
+\r
+/*  MOV.W   @(disp8,PC),Rn */\r
+INLINE void MOVWI(UINT32 d, UINT32 n)\r
+{\r
+       UINT32 disp = d & 0xff;\r
+       sh2->ea = sh2->pc + disp * 2 + 2;\r
+       sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2->ea );\r
+}\r
+\r
+/*  MOV.L   @(disp8,PC),Rn */\r
+INLINE void MOVLI(UINT32 d, UINT32 n)\r
+{\r
+       UINT32 disp = d & 0xff;\r
+       sh2->ea = ((sh2->pc + 2) & ~3) + disp * 4;\r
+       sh2->r[n] = RL( sh2->ea );\r
+}\r
+\r
+/*  MOV.B   @(disp8,GBR),R0 */\r
+INLINE void MOVBLG(UINT32 d)\r
+{\r
+       UINT32 disp = d & 0xff;\r
+       sh2->ea = sh2->gbr + disp;\r
+       sh2->r[0] = (UINT32)(INT32)(INT16)(INT8) RB( sh2->ea );\r
+}\r
+\r
+/*  MOV.W   @(disp8,GBR),R0 */\r
+INLINE void MOVWLG(UINT32 d)\r
+{\r
+       UINT32 disp = d & 0xff;\r
+       sh2->ea = sh2->gbr + disp * 2;\r
+       sh2->r[0] = (INT32)(INT16) RW( sh2->ea );\r
+}\r
+\r
+/*  MOV.L   @(disp8,GBR),R0 */\r
+INLINE void MOVLLG(UINT32 d)\r
+{\r
+       UINT32 disp = d & 0xff;\r
+       sh2->ea = sh2->gbr + disp * 4;\r
+       sh2->r[0] = RL( sh2->ea );\r
+}\r
+\r
+/*  MOV.B   R0,@(disp8,GBR) */\r
+INLINE void MOVBSG(UINT32 d)\r
+{\r
+       UINT32 disp = d & 0xff;\r
+       sh2->ea = sh2->gbr + disp;\r
+       WB( sh2->ea, sh2->r[0] & 0x000000ff );\r
+}\r
+\r
+/*  MOV.W   R0,@(disp8,GBR) */\r
+INLINE void MOVWSG(UINT32 d)\r
+{\r
+       UINT32 disp = d & 0xff;\r
+       sh2->ea = sh2->gbr + disp * 2;\r
+       WW( sh2->ea, sh2->r[0] & 0x0000ffff );\r
+}\r
+\r
+/*  MOV.L   R0,@(disp8,GBR) */\r
+INLINE void MOVLSG(UINT32 d)\r
+{\r
+       UINT32 disp = d & 0xff;\r
+       sh2->ea = sh2->gbr + disp * 4;\r
+       WL( sh2->ea, sh2->r[0] );\r
+}\r
+\r
+/*  MOV.B   R0,@(disp4,Rn) */\r
+INLINE void MOVBS4(UINT32 d, UINT32 n)\r
+{\r
+       UINT32 disp = d & 0x0f;\r
+       sh2->ea = sh2->r[n] + disp;\r
+       WB( sh2->ea, sh2->r[0] & 0x000000ff );\r
+}\r
+\r
+/*  MOV.W   R0,@(disp4,Rn) */\r
+INLINE void MOVWS4(UINT32 d, UINT32 n)\r
+{\r
+       UINT32 disp = d & 0x0f;\r
+       sh2->ea = sh2->r[n] + disp * 2;\r
+       WW( sh2->ea, sh2->r[0] & 0x0000ffff );\r
+}\r
+\r
+/* MOV.L Rm,@(disp4,Rn) */\r
+INLINE void MOVLS4(UINT32 m, UINT32 d, UINT32 n)\r
+{\r
+       UINT32 disp = d & 0x0f;\r
+       sh2->ea = sh2->r[n] + disp * 4;\r
+       WL( sh2->ea, sh2->r[m] );\r
+}\r
+\r
+/*  MOV.B   @(disp4,Rm),R0 */\r
+INLINE void MOVBL4(UINT32 m, UINT32 d)\r
+{\r
+       UINT32 disp = d & 0x0f;\r
+       sh2->ea = sh2->r[m] + disp;\r
+       sh2->r[0] = (UINT32)(INT32)(INT16)(INT8) RB( sh2->ea );\r
+}\r
+\r
+/*  MOV.W   @(disp4,Rm),R0 */\r
+INLINE void MOVWL4(UINT32 m, UINT32 d)\r
+{\r
+       UINT32 disp = d & 0x0f;\r
+       sh2->ea = sh2->r[m] + disp * 2;\r
+       sh2->r[0] = (UINT32)(INT32)(INT16) RW( sh2->ea );\r
+}\r
+\r
+/*  MOV.L   @(disp4,Rm),Rn */\r
+INLINE void MOVLL4(UINT32 m, UINT32 d, UINT32 n)\r
+{\r
+       UINT32 disp = d & 0x0f;\r
+       sh2->ea = sh2->r[m] + disp * 4;\r
+       sh2->r[n] = RL( sh2->ea );\r
+}\r
+\r
+/*  MOVA    @(disp8,PC),R0 */\r
+INLINE void MOVA(UINT32 d)\r
+{\r
+       UINT32 disp = d & 0xff;\r
+       sh2->ea = ((sh2->pc + 2) & ~3) + disp * 4;\r
+       sh2->r[0] = sh2->ea;\r
+}\r
+\r
+/*  MOVT    Rn */\r
+INLINE void MOVT(UINT32 n)\r
+{\r
+       sh2->r[n] = sh2->sr & T;\r
+}\r
+\r
+/*  MUL.L   Rm,Rn */\r
+INLINE void MULL(UINT32 m, UINT32 n)\r
+{\r
+       sh2->macl = sh2->r[n] * sh2->r[m];\r
+       sh2_icount--;\r
+}\r
+\r
+/*  MULS    Rm,Rn */\r
+INLINE void MULS(UINT32 m, UINT32 n)\r
+{\r
+       sh2->macl = (INT16) sh2->r[n] * (INT16) sh2->r[m];\r
+}\r
+\r
+/*  MULU    Rm,Rn */\r
+INLINE void MULU(UINT32 m, UINT32 n)\r
+{\r
+       sh2->macl = (UINT16) sh2->r[n] * (UINT16) sh2->r[m];\r
+}\r
+\r
+/*  NEG     Rm,Rn */\r
+INLINE void NEG(UINT32 m, UINT32 n)\r
+{\r
+       sh2->r[n] = 0 - sh2->r[m];\r
+}\r
+\r
+/*  NEGC    Rm,Rn */\r
+INLINE void NEGC(UINT32 m, UINT32 n)\r
+{\r
+       UINT32 temp;\r
+\r
+       temp = sh2->r[m];\r
+       sh2->r[n] = -temp - (sh2->sr & T);\r
+       if (temp || (sh2->sr & T))\r
+               sh2->sr |= T;\r
+       else\r
+               sh2->sr &= ~T;\r
+}\r
+\r
+/*  NOP */\r
+INLINE void NOP(void)\r
+{\r
+}\r
+\r
+/*  NOT     Rm,Rn */\r
+INLINE void NOT(UINT32 m, UINT32 n)\r
+{\r
+       sh2->r[n] = ~sh2->r[m];\r
+}\r
+\r
+/*  OR      Rm,Rn */\r
+INLINE void OR(UINT32 m, UINT32 n)\r
+{\r
+       sh2->r[n] |= sh2->r[m];\r
+}\r
+\r
+/*  OR      #imm,R0 */\r
+INLINE void ORI(UINT32 i)\r
+{\r
+       sh2->r[0] |= i;\r
+       sh2_icount -= 2;\r
+}\r
+\r
+/*  OR.B    #imm,@(R0,GBR) */\r
+INLINE void ORM(UINT32 i)\r
+{\r
+       UINT32 temp;\r
+\r
+       sh2->ea = sh2->gbr + sh2->r[0];\r
+       temp = RB( sh2->ea );\r
+       temp |= i;\r
+       WB( sh2->ea, temp );\r
+}\r
+\r
+/*  ROTCL   Rn */\r
+INLINE void ROTCL(UINT32 n)\r
+{\r
+       UINT32 temp;\r
+\r
+       temp = (sh2->r[n] >> 31) & T;\r
+       sh2->r[n] = (sh2->r[n] << 1) | (sh2->sr & T);\r
+       sh2->sr = (sh2->sr & ~T) | temp;\r
+}\r
+\r
+/*  ROTCR   Rn */\r
+INLINE void ROTCR(UINT32 n)\r
+{\r
+       UINT32 temp;\r
+       temp = (sh2->sr & T) << 31;\r
+       if (sh2->r[n] & T)\r
+               sh2->sr |= T;\r
+       else\r
+               sh2->sr &= ~T;\r
+       sh2->r[n] = (sh2->r[n] >> 1) | temp;\r
+}\r
+\r
+/*  ROTL    Rn */\r
+INLINE void ROTL(UINT32 n)\r
+{\r
+       sh2->sr = (sh2->sr & ~T) | ((sh2->r[n] >> 31) & T);\r
+       sh2->r[n] = (sh2->r[n] << 1) | (sh2->r[n] >> 31);\r
+}\r
+\r
+/*  ROTR    Rn */\r
+INLINE void ROTR(UINT32 n)\r
+{\r
+       sh2->sr = (sh2->sr & ~T) | (sh2->r[n] & T);\r
+       sh2->r[n] = (sh2->r[n] >> 1) | (sh2->r[n] << 31);\r
+}\r
+\r
+/*  RTE */\r
+INLINE void RTE(void)\r
+{\r
+       sh2->ea = sh2->r[15];\r
+       sh2->delay = sh2->pc;\r
+       sh2->pc = RL( sh2->ea );\r
+       sh2->r[15] += 4;\r
+       sh2->ea = sh2->r[15];\r
+       sh2->sr = RL( sh2->ea ) & FLAGS;\r
+       sh2->r[15] += 4;\r
+       sh2_icount -= 3;\r
+       sh2->test_irq = 1;\r
+}\r
+\r
+/*  RTS */\r
+INLINE void RTS(void)\r
+{\r
+       sh2->delay = sh2->pc;\r
+       sh2->pc = sh2->ea = sh2->pr;\r
+       sh2_icount--;\r
+}\r
+\r
+/*  SETT */\r
+INLINE void SETT(void)\r
+{\r
+       sh2->sr |= T;\r
+}\r
+\r
+/*  SHAL    Rn      (same as SHLL) */\r
+INLINE void SHAL(UINT32 n)\r
+{\r
+       sh2->sr = (sh2->sr & ~T) | ((sh2->r[n] >> 31) & T);\r
+       sh2->r[n] <<= 1;\r
+}\r
+\r
+/*  SHAR    Rn */\r
+INLINE void SHAR(UINT32 n)\r
+{\r
+       sh2->sr = (sh2->sr & ~T) | (sh2->r[n] & T);\r
+       sh2->r[n] = (UINT32)((INT32)sh2->r[n] >> 1);\r
+}\r
+\r
+/*  SHLL    Rn      (same as SHAL) */\r
+INLINE void SHLL(UINT32 n)\r
+{\r
+       sh2->sr = (sh2->sr & ~T) | ((sh2->r[n] >> 31) & T);\r
+       sh2->r[n] <<= 1;\r
+}\r
+\r
+/*  SHLL2   Rn */\r
+INLINE void SHLL2(UINT32 n)\r
+{\r
+       sh2->r[n] <<= 2;\r
+}\r
+\r
+/*  SHLL8   Rn */\r
+INLINE void SHLL8(UINT32 n)\r
+{\r
+       sh2->r[n] <<= 8;\r
+}\r
+\r
+/*  SHLL16  Rn */\r
+INLINE void SHLL16(UINT32 n)\r
+{\r
+       sh2->r[n] <<= 16;\r
+}\r
+\r
+/*  SHLR    Rn */\r
+INLINE void SHLR(UINT32 n)\r
+{\r
+       sh2->sr = (sh2->sr & ~T) | (sh2->r[n] & T);\r
+       sh2->r[n] >>= 1;\r
+}\r
+\r
+/*  SHLR2   Rn */\r
+INLINE void SHLR2(UINT32 n)\r
+{\r
+       sh2->r[n] >>= 2;\r
+}\r
+\r
+/*  SHLR8   Rn */\r
+INLINE void SHLR8(UINT32 n)\r
+{\r
+       sh2->r[n] >>= 8;\r
+}\r
+\r
+/*  SHLR16  Rn */\r
+INLINE void SHLR16(UINT32 n)\r
+{\r
+       sh2->r[n] >>= 16;\r
+}\r
+\r
+/*  SLEEP */\r
+INLINE void SLEEP(void)\r
+{\r
+       sh2->pc -= 2;\r
+       sh2_icount -= 2;\r
+       /* Wait_for_exception; */\r
+}\r
+\r
+/*  STC     SR,Rn */\r
+INLINE void STCSR(UINT32 n)\r
+{\r
+       sh2->r[n] = sh2->sr;\r
+}\r
+\r
+/*  STC     GBR,Rn */\r
+INLINE void STCGBR(UINT32 n)\r
+{\r
+       sh2->r[n] = sh2->gbr;\r
+}\r
+\r
+/*  STC     VBR,Rn */\r
+INLINE void STCVBR(UINT32 n)\r
+{\r
+       sh2->r[n] = sh2->vbr;\r
+}\r
+\r
+/*  STC.L   SR,@-Rn */\r
+INLINE void STCMSR(UINT32 n)\r
+{\r
+       sh2->r[n] -= 4;\r
+       sh2->ea = sh2->r[n];\r
+       WL( sh2->ea, sh2->sr );\r
+       sh2_icount--;\r
+}\r
+\r
+/*  STC.L   GBR,@-Rn */\r
+INLINE void STCMGBR(UINT32 n)\r
+{\r
+       sh2->r[n] -= 4;\r
+       sh2->ea = sh2->r[n];\r
+       WL( sh2->ea, sh2->gbr );\r
+       sh2_icount--;\r
+}\r
+\r
+/*  STC.L   VBR,@-Rn */\r
+INLINE void STCMVBR(UINT32 n)\r
+{\r
+       sh2->r[n] -= 4;\r
+       sh2->ea = sh2->r[n];\r
+       WL( sh2->ea, sh2->vbr );\r
+       sh2_icount--;\r
+}\r
+\r
+/*  STS     MACH,Rn */\r
+INLINE void STSMACH(UINT32 n)\r
+{\r
+       sh2->r[n] = sh2->mach;\r
+}\r
+\r
+/*  STS     MACL,Rn */\r
+INLINE void STSMACL(UINT32 n)\r
+{\r
+       sh2->r[n] = sh2->macl;\r
+}\r
+\r
+/*  STS     PR,Rn */\r
+INLINE void STSPR(UINT32 n)\r
+{\r
+       sh2->r[n] = sh2->pr;\r
+}\r
+\r
+/*  STS.L   MACH,@-Rn */\r
+INLINE void STSMMACH(UINT32 n)\r
+{\r
+       sh2->r[n] -= 4;\r
+       sh2->ea = sh2->r[n];\r
+       WL( sh2->ea, sh2->mach );\r
+}\r
+\r
+/*  STS.L   MACL,@-Rn */\r
+INLINE void STSMMACL(UINT32 n)\r
+{\r
+       sh2->r[n] -= 4;\r
+       sh2->ea = sh2->r[n];\r
+       WL( sh2->ea, sh2->macl );\r
+}\r
+\r
+/*  STS.L   PR,@-Rn */\r
+INLINE void STSMPR(UINT32 n)\r
+{\r
+       sh2->r[n] -= 4;\r
+       sh2->ea = sh2->r[n];\r
+       WL( sh2->ea, sh2->pr );\r
+}\r
+\r
+/*  SUB     Rm,Rn */\r
+INLINE void SUB(UINT32 m, UINT32 n)\r
+{\r
+       sh2->r[n] -= sh2->r[m];\r
+}\r
+\r
+/*  SUBC    Rm,Rn */\r
+INLINE void SUBC(UINT32 m, UINT32 n)\r
+{\r
+       UINT32 tmp0, tmp1;\r
+\r
+       tmp1 = sh2->r[n] - sh2->r[m];\r
+       tmp0 = sh2->r[n];\r
+       sh2->r[n] = tmp1 - (sh2->sr & T);\r
+       if (tmp0 < tmp1)\r
+               sh2->sr |= T;\r
+       else\r
+               sh2->sr &= ~T;\r
+       if (tmp1 < sh2->r[n])\r
+               sh2->sr |= T;\r
+}\r
+\r
+/*  SUBV    Rm,Rn */\r
+INLINE void SUBV(UINT32 m, UINT32 n)\r
+{\r
+       INT32 dest, src, ans;\r
+\r
+       if ((INT32) sh2->r[n] >= 0)\r
+               dest = 0;\r
+       else\r
+               dest = 1;\r
+       if ((INT32) sh2->r[m] >= 0)\r
+               src = 0;\r
+       else\r
+               src = 1;\r
+       src += dest;\r
+       sh2->r[n] -= sh2->r[m];\r
+       if ((INT32) sh2->r[n] >= 0)\r
+               ans = 0;\r
+       else\r
+               ans = 1;\r
+       ans += dest;\r
+       if (src == 1)\r
+       {\r
+               if (ans == 1)\r
+                       sh2->sr |= T;\r
+               else\r
+                       sh2->sr &= ~T;\r
+       }\r
+       else\r
+               sh2->sr &= ~T;\r
+}\r
+\r
+/*  SWAP.B  Rm,Rn */\r
+INLINE void SWAPB(UINT32 m, UINT32 n)\r
+{\r
+       UINT32 temp0, temp1;\r
+\r
+       temp0 = sh2->r[m] & 0xffff0000;\r
+       temp1 = (sh2->r[m] & 0x000000ff) << 8;\r
+       sh2->r[n] = (sh2->r[m] >> 8) & 0x000000ff;\r
+       sh2->r[n] = sh2->r[n] | temp1 | temp0;\r
+}\r
+\r
+/*  SWAP.W  Rm,Rn */\r
+INLINE void SWAPW(UINT32 m, UINT32 n)\r
+{\r
+       UINT32 temp;\r
+\r
+       temp = (sh2->r[m] >> 16) & 0x0000ffff;\r
+       sh2->r[n] = (sh2->r[m] << 16) | temp;\r
+}\r
+\r
+/*  TAS.B   @Rn */\r
+INLINE void TAS(UINT32 n)\r
+{\r
+       UINT32 temp;\r
+       sh2->ea = sh2->r[n];\r
+       /* Bus Lock enable */\r
+       temp = RB( sh2->ea );\r
+       if (temp == 0)\r
+               sh2->sr |= T;\r
+       else\r
+               sh2->sr &= ~T;\r
+       temp |= 0x80;\r
+       /* Bus Lock disable */\r
+       WB( sh2->ea, temp );\r
+       sh2_icount -= 3;\r
+}\r
+\r
+/*  TRAPA   #imm */\r
+INLINE void TRAPA(UINT32 i)\r
+{\r
+       UINT32 imm = i & 0xff;\r
+\r
+       sh2->ea = sh2->vbr + imm * 4;\r
+\r
+       sh2->r[15] -= 4;\r
+       WL( sh2->r[15], sh2->sr );\r
+       sh2->r[15] -= 4;\r
+       WL( sh2->r[15], sh2->pc );\r
+\r
+       sh2->pc = RL( sh2->ea );\r
+\r
+       sh2_icount -= 7;\r
+}\r
+\r
+/*  TST     Rm,Rn */\r
+INLINE void TST(UINT32 m, UINT32 n)\r
+{\r
+       if ((sh2->r[n] & sh2->r[m]) == 0)\r
+               sh2->sr |= T;\r
+       else\r
+               sh2->sr &= ~T;\r
+}\r
+\r
+/*  TST     #imm,R0 */\r
+INLINE void TSTI(UINT32 i)\r
+{\r
+       UINT32 imm = i & 0xff;\r
+\r
+       if ((imm & sh2->r[0]) == 0)\r
+               sh2->sr |= T;\r
+       else\r
+               sh2->sr &= ~T;\r
+}\r
+\r
+/*  TST.B   #imm,@(R0,GBR) */\r
+INLINE void TSTM(UINT32 i)\r
+{\r
+       UINT32 imm = i & 0xff;\r
+\r
+       sh2->ea = sh2->gbr + sh2->r[0];\r
+       if ((imm & RB( sh2->ea )) == 0)\r
+               sh2->sr |= T;\r
+       else\r
+               sh2->sr &= ~T;\r
+       sh2_icount -= 2;\r
+}\r
+\r
+/*  XOR     Rm,Rn */\r
+INLINE void XOR(UINT32 m, UINT32 n)\r
+{\r
+       sh2->r[n] ^= sh2->r[m];\r
+}\r
+\r
+/*  XOR     #imm,R0 */\r
+INLINE void XORI(UINT32 i)\r
+{\r
+       UINT32 imm = i & 0xff;\r
+       sh2->r[0] ^= imm;\r
+}\r
+\r
+/*  XOR.B   #imm,@(R0,GBR) */\r
+INLINE void XORM(UINT32 i)\r
+{\r
+       UINT32 imm = i & 0xff;\r
+       UINT32 temp;\r
+\r
+       sh2->ea = sh2->gbr + sh2->r[0];\r
+       temp = RB( sh2->ea );\r
+       temp ^= imm;\r
+       WB( sh2->ea, temp );\r
+       sh2_icount -= 2;\r
+}\r
+\r
+/*  XTRCT   Rm,Rn */\r
+INLINE void XTRCT(UINT32 m, UINT32 n)\r
+{\r
+       UINT32 temp;\r
+\r
+       temp = (sh2->r[m] << 16) & 0xffff0000;\r
+       sh2->r[n] = (sh2->r[n] >> 16) & 0x0000ffff;\r
+       sh2->r[n] |= temp;\r
+}\r
+\r
+/*****************************************************************************\r
+ *  OPCODE DISPATCHERS\r
+ *****************************************************************************/\r
+\r
+INLINE void op0000(UINT16 opcode)\r
+{\r
+       switch (opcode & 0x3F)\r
+       {\r
+       case 0x00: NOP();                                               break;\r
+       case 0x01: NOP();                                               break;\r
+       case 0x02: STCSR(Rn);                                   break;\r
+       case 0x03: BSRF(Rn);                                    break;\r
+       case 0x04: MOVBS0(Rm, Rn);                              break;\r
+       case 0x05: MOVWS0(Rm, Rn);                              break;\r
+       case 0x06: MOVLS0(Rm, Rn);                              break;\r
+       case 0x07: MULL(Rm, Rn);                                break;\r
+       case 0x08: CLRT();                                              break;\r
+       case 0x09: NOP();                                               break;\r
+       case 0x0a: STSMACH(Rn);                                 break;\r
+       case 0x0b: RTS();                                               break;\r
+       case 0x0c: MOVBL0(Rm, Rn);                              break;\r
+       case 0x0d: MOVWL0(Rm, Rn);                              break;\r
+       case 0x0e: MOVLL0(Rm, Rn);                              break;\r
+       case 0x0f: MAC_L(Rm, Rn);                               break;\r
+\r
+       case 0x10: NOP();                                               break;\r
+       case 0x11: NOP();                                               break;\r
+       case 0x12: STCGBR(Rn);                                  break;\r
+       case 0x13: NOP();                                               break;\r
+       case 0x14: MOVBS0(Rm, Rn);                              break;\r
+       case 0x15: MOVWS0(Rm, Rn);                              break;\r
+       case 0x16: MOVLS0(Rm, Rn);                              break;\r
+       case 0x17: MULL(Rm, Rn);                                break;\r
+       case 0x18: SETT();                                              break;\r
+       case 0x19: DIV0U();                                     break;\r
+       case 0x1a: STSMACL(Rn);                                 break;\r
+       case 0x1b: SLEEP();                                     break;\r
+       case 0x1c: MOVBL0(Rm, Rn);                              break;\r
+       case 0x1d: MOVWL0(Rm, Rn);                              break;\r
+       case 0x1e: MOVLL0(Rm, Rn);                              break;\r
+       case 0x1f: MAC_L(Rm, Rn);                               break;\r
+\r
+       case 0x20: NOP();                                               break;\r
+       case 0x21: NOP();                                               break;\r
+       case 0x22: STCVBR(Rn);                                  break;\r
+       case 0x23: BRAF(Rn);                                    break;\r
+       case 0x24: MOVBS0(Rm, Rn);                              break;\r
+       case 0x25: MOVWS0(Rm, Rn);                              break;\r
+       case 0x26: MOVLS0(Rm, Rn);                              break;\r
+       case 0x27: MULL(Rm, Rn);                                break;\r
+       case 0x28: CLRMAC();                                    break;\r
+       case 0x29: MOVT(Rn);                                    break;\r
+       case 0x2a: STSPR(Rn);                                   break;\r
+       case 0x2b: RTE();                                               break;\r
+       case 0x2c: MOVBL0(Rm, Rn);                              break;\r
+       case 0x2d: MOVWL0(Rm, Rn);                              break;\r
+       case 0x2e: MOVLL0(Rm, Rn);                              break;\r
+       case 0x2f: MAC_L(Rm, Rn);                               break;\r
+\r
+       case 0x30: NOP();                                               break;\r
+       case 0x31: NOP();                                               break;\r
+       case 0x32: NOP();                                               break;\r
+       case 0x33: NOP();                                               break;\r
+       case 0x34: MOVBS0(Rm, Rn);                              break;\r
+       case 0x35: MOVWS0(Rm, Rn);                              break;\r
+       case 0x36: MOVLS0(Rm, Rn);                              break;\r
+       case 0x37: MULL(Rm, Rn);                                break;\r
+       case 0x38: NOP();                                               break;\r
+       case 0x39: NOP();                                               break;\r
+       case 0x3c: MOVBL0(Rm, Rn);                              break;\r
+       case 0x3d: MOVWL0(Rm, Rn);                              break;\r
+       case 0x3e: MOVLL0(Rm, Rn);                              break;\r
+       case 0x3f: MAC_L(Rm, Rn);                               break;\r
+       case 0x3a: NOP();                                               break;\r
+       case 0x3b: NOP();                                               break;\r
+\r
+\r
+\r
+       }\r
+}\r
+\r
+INLINE void op0001(UINT16 opcode)\r
+{\r
+       MOVLS4(Rm, opcode & 0x0f, Rn);\r
+}\r
+\r
+INLINE void op0010(UINT16 opcode)\r
+{\r
+       switch (opcode & 15)\r
+       {\r
+       case  0: MOVBS(Rm, Rn);                                 break;\r
+       case  1: MOVWS(Rm, Rn);                                 break;\r
+       case  2: MOVLS(Rm, Rn);                                 break;\r
+       case  3: NOP();                                                 break;\r
+       case  4: MOVBM(Rm, Rn);                                 break;\r
+       case  5: MOVWM(Rm, Rn);                                 break;\r
+       case  6: MOVLM(Rm, Rn);                                 break;\r
+       case  7: DIV0S(Rm, Rn);                                 break;\r
+       case  8: TST(Rm, Rn);                                   break;\r
+       case  9: AND(Rm, Rn);                                   break;\r
+       case 10: XOR(Rm, Rn);                                   break;\r
+       case 11: OR(Rm, Rn);                                    break;\r
+       case 12: CMPSTR(Rm, Rn);                                break;\r
+       case 13: XTRCT(Rm, Rn);                                 break;\r
+       case 14: MULU(Rm, Rn);                                  break;\r
+       case 15: MULS(Rm, Rn);                                  break;\r
+       }\r
+}\r
+\r
+INLINE void op0011(UINT16 opcode)\r
+{\r
+       switch (opcode & 15)\r
+       {\r
+       case  0: CMPEQ(Rm, Rn);                                 break;\r
+       case  1: NOP();                                                 break;\r
+       case  2: CMPHS(Rm, Rn);                                 break;\r
+       case  3: CMPGE(Rm, Rn);                                 break;\r
+       case  4: DIV1(Rm, Rn);                                  break;\r
+       case  5: DMULU(Rm, Rn);                                 break;\r
+       case  6: CMPHI(Rm, Rn);                                 break;\r
+       case  7: CMPGT(Rm, Rn);                                 break;\r
+       case  8: SUB(Rm, Rn);                                   break;\r
+       case  9: NOP();                                                 break;\r
+       case 10: SUBC(Rm, Rn);                                  break;\r
+       case 11: SUBV(Rm, Rn);                                  break;\r
+       case 12: ADD(Rm, Rn);                                   break;\r
+       case 13: DMULS(Rm, Rn);                                 break;\r
+       case 14: ADDC(Rm, Rn);                                  break;\r
+       case 15: ADDV(Rm, Rn);                                  break;\r
+       }\r
+}\r
+\r
+INLINE void op0100(UINT16 opcode)\r
+{\r
+       switch (opcode & 0x3F)\r
+       {\r
+       case 0x00: SHLL(Rn);                                    break;\r
+       case 0x01: SHLR(Rn);                                    break;\r
+       case 0x02: STSMMACH(Rn);                                break;\r
+       case 0x03: STCMSR(Rn);                                  break;\r
+       case 0x04: ROTL(Rn);                                    break;\r
+       case 0x05: ROTR(Rn);                                    break;\r
+       case 0x06: LDSMMACH(Rn);                                break;\r
+       case 0x07: LDCMSR(Rn);                                  break;\r
+       case 0x08: SHLL2(Rn);                                   break;\r
+       case 0x09: SHLR2(Rn);                                   break;\r
+       case 0x0a: LDSMACH(Rn);                                 break;\r
+       case 0x0b: JSR(Rn);                                     break;\r
+       case 0x0c: NOP();                                               break;\r
+       case 0x0d: NOP();                                               break;\r
+       case 0x0e: LDCSR(Rn);                                   break;\r
+       case 0x0f: MAC_W(Rm, Rn);                               break;\r
+\r
+       case 0x10: DT(Rn);                                              break;\r
+       case 0x11: CMPPZ(Rn);                                   break;\r
+       case 0x12: STSMMACL(Rn);                                break;\r
+       case 0x13: STCMGBR(Rn);                                 break;\r
+       case 0x14: NOP();                                               break;\r
+       case 0x15: CMPPL(Rn);                                   break;\r
+       case 0x16: LDSMMACL(Rn);                                break;\r
+       case 0x17: LDCMGBR(Rn);                                 break;\r
+       case 0x18: SHLL8(Rn);                                   break;\r
+       case 0x19: SHLR8(Rn);                                   break;\r
+       case 0x1a: LDSMACL(Rn);                                 break;\r
+       case 0x1b: TAS(Rn);                                     break;\r
+       case 0x1c: NOP();                                               break;\r
+       case 0x1d: NOP();                                               break;\r
+       case 0x1e: LDCGBR(Rn);                                  break;\r
+       case 0x1f: MAC_W(Rm, Rn);                               break;\r
+\r
+       case 0x20: SHAL(Rn);                                    break;\r
+       case 0x21: SHAR(Rn);                                    break;\r
+       case 0x22: STSMPR(Rn);                                  break;\r
+       case 0x23: STCMVBR(Rn);                                 break;\r
+       case 0x24: ROTCL(Rn);                                   break;\r
+       case 0x25: ROTCR(Rn);                                   break;\r
+       case 0x26: LDSMPR(Rn);                                  break;\r
+       case 0x27: LDCMVBR(Rn);                                 break;\r
+       case 0x28: SHLL16(Rn);                                  break;\r
+       case 0x29: SHLR16(Rn);                                  break;\r
+       case 0x2a: LDSPR(Rn);                                   break;\r
+       case 0x2b: JMP(Rn);                                     break;\r
+       case 0x2c: NOP();                                               break;\r
+       case 0x2d: NOP();                                               break;\r
+       case 0x2e: LDCVBR(Rn);                                  break;\r
+       case 0x2f: MAC_W(Rm, Rn);                               break;\r
+\r
+       case 0x30: NOP();                                               break;\r
+       case 0x31: NOP();                                               break;\r
+       case 0x32: NOP();                                               break;\r
+       case 0x33: NOP();                                               break;\r
+       case 0x34: NOP();                                               break;\r
+       case 0x35: NOP();                                               break;\r
+       case 0x36: NOP();                                               break;\r
+       case 0x37: NOP();                                               break;\r
+       case 0x38: NOP();                                               break;\r
+       case 0x39: NOP();                                               break;\r
+       case 0x3a: NOP();                                               break;\r
+       case 0x3b: NOP();                                               break;\r
+       case 0x3c: NOP();                                               break;\r
+       case 0x3d: NOP();                                               break;\r
+       case 0x3e: NOP();                                               break;\r
+       case 0x3f: MAC_W(Rm, Rn);                               break;\r
+\r
+       }\r
+}\r
+\r
+INLINE void op0101(UINT16 opcode)\r
+{\r
+       MOVLL4(Rm, opcode & 0x0f, Rn);\r
+}\r
+\r
+INLINE void op0110(UINT16 opcode)\r
+{\r
+       switch (opcode & 15)\r
+       {\r
+       case  0: MOVBL(Rm, Rn);                                 break;\r
+       case  1: MOVWL(Rm, Rn);                                 break;\r
+       case  2: MOVLL(Rm, Rn);                                 break;\r
+       case  3: MOV(Rm, Rn);                                   break;\r
+       case  4: MOVBP(Rm, Rn);                                 break;\r
+       case  5: MOVWP(Rm, Rn);                                 break;\r
+       case  6: MOVLP(Rm, Rn);                                 break;\r
+       case  7: NOT(Rm, Rn);                                   break;\r
+       case  8: SWAPB(Rm, Rn);                                 break;\r
+       case  9: SWAPW(Rm, Rn);                                 break;\r
+       case 10: NEGC(Rm, Rn);                                  break;\r
+       case 11: NEG(Rm, Rn);                                   break;\r
+       case 12: EXTUB(Rm, Rn);                                 break;\r
+       case 13: EXTUW(Rm, Rn);                                 break;\r
+       case 14: EXTSB(Rm, Rn);                                 break;\r
+       case 15: EXTSW(Rm, Rn);                                 break;\r
+       }\r
+}\r
+\r
+INLINE void op0111(UINT16 opcode)\r
+{\r
+       ADDI(opcode & 0xff, Rn);\r
+}\r
+\r
+INLINE void op1000(UINT16 opcode)\r
+{\r
+       switch ( opcode  & (15<<8) )\r
+       {\r
+       case  0 << 8: MOVBS4(opcode & 0x0f, Rm);        break;\r
+       case  1 << 8: MOVWS4(opcode & 0x0f, Rm);        break;\r
+       case  2<< 8: NOP();                             break;\r
+       case  3<< 8: NOP();                             break;\r
+       case  4<< 8: MOVBL4(Rm, opcode & 0x0f);         break;\r
+       case  5<< 8: MOVWL4(Rm, opcode & 0x0f);         break;\r
+       case  6<< 8: NOP();                             break;\r
+       case  7<< 8: NOP();                             break;\r
+       case  8<< 8: CMPIM(opcode & 0xff);              break;\r
+       case  9<< 8: BT(opcode & 0xff);                 break;\r
+       case 10<< 8: NOP();                             break;\r
+       case 11<< 8: BF(opcode & 0xff);                 break;\r
+       case 12<< 8: NOP();                             break;\r
+       case 13<< 8: BTS(opcode & 0xff);                break;\r
+       case 14<< 8: NOP();                             break;\r
+       case 15<< 8: BFS(opcode & 0xff);                break;\r
+       }\r
+}\r
+\r
+\r
+INLINE void op1001(UINT16 opcode)\r
+{\r
+       MOVWI(opcode & 0xff, Rn);\r
+}\r
+\r
+INLINE void op1010(UINT16 opcode)\r
+{\r
+       BRA(opcode & 0xfff);\r
+}\r
+\r
+INLINE void op1011(UINT16 opcode)\r
+{\r
+       BSR(opcode & 0xfff);\r
+}\r
+\r
+INLINE void op1100(UINT16 opcode)\r
+{\r
+       switch (opcode & (15<<8))\r
+       {\r
+       case  0<<8: MOVBSG(opcode & 0xff);              break;\r
+       case  1<<8: MOVWSG(opcode & 0xff);              break;\r
+       case  2<<8: MOVLSG(opcode & 0xff);              break;\r
+       case  3<<8: TRAPA(opcode & 0xff);               break;\r
+       case  4<<8: MOVBLG(opcode & 0xff);              break;\r
+       case  5<<8: MOVWLG(opcode & 0xff);              break;\r
+       case  6<<8: MOVLLG(opcode & 0xff);              break;\r
+       case  7<<8: MOVA(opcode & 0xff);                break;\r
+       case  8<<8: TSTI(opcode & 0xff);                break;\r
+       case  9<<8: ANDI(opcode & 0xff);                break;\r
+       case 10<<8: XORI(opcode & 0xff);                break;\r
+       case 11<<8: ORI(opcode & 0xff);                 break;\r
+       case 12<<8: TSTM(opcode & 0xff);                break;\r
+       case 13<<8: ANDM(opcode & 0xff);                break;\r
+       case 14<<8: XORM(opcode & 0xff);                break;\r
+       case 15<<8: ORM(opcode & 0xff);                 break;\r
+       }\r
+}\r
+\r
+INLINE void op1101(UINT16 opcode)\r
+{\r
+       MOVLI(opcode & 0xff, Rn);\r
+}\r
+\r
+INLINE void op1110(UINT16 opcode)\r
+{\r
+       MOVI(opcode & 0xff, Rn);\r
+}\r
+\r
+INLINE void op1111(UINT16 opcode)\r
+{\r
+       NOP();\r
+}\r
+\r
+#endif\r
diff --git a/cpu/sh2mame/sh2.h b/cpu/sh2mame/sh2.h
new file mode 100644 (file)
index 0000000..cdcdecf
--- /dev/null
@@ -0,0 +1,57 @@
+/*****************************************************************************\r
+ *\r
+ *   sh2.h\r
+ *   Portable Hitachi SH-2 (SH7600 family) emulator interface\r
+ *\r
+ *   Copyright Juergen Buchmueller <pullmoll@t-online.de>,\r
+ *   all rights reserved.\r
+ *\r
+ *   - This source code is released as freeware for non-commercial purposes.\r
+ *   - You are free to use and redistribute this code in modified or\r
+ *     unmodified form, provided you list me in the credits.\r
+ *   - If you modify this source code, you must add a notice to each modified\r
+ *     source file that it has been changed.  If you're a nice person, you\r
+ *     will clearly mark each change too.  :)\r
+ *   - If you wish to use this for commercial purposes, please contact me at\r
+ *     pullmoll@t-online.de\r
+ *   - The author of this copywritten work reserves the right to change the\r
+ *     terms of its usage and license at any time, including retroactively\r
+ *   - This entire notice must remain in the source code.\r
+ *\r
+ *  This work is based on <tiraniddo@hotmail.com> C/C++ implementation of\r
+ *  the SH-2 CPU core and was heavily changed to the MAME CPU requirements.\r
+ *  Thanks also go to Chuck Mason <chukjr@sundail.net> and Olivier Galibert\r
+ *  <galibert@pobox.com> for letting me peek into their SEMU code :-)\r
+ *\r
+ *****************************************************************************/\r
+\r
+#pragma once\r
+\r
+#ifndef __SH2_H__\r
+#define __SH2_H__\r
+\r
+typedef struct\r
+{\r
+       UINT32  r[16];\r
+       UINT32  ppc;\r
+       UINT32  pc;\r
+       UINT32  pr;\r
+       UINT32  sr;\r
+       UINT32  gbr, vbr;\r
+       UINT32  mach, macl;\r
+       UINT32  ea;\r
+       UINT32  delay;\r
+       UINT32  test_irq;\r
+\r
+       // XXX: unused, will we ever use?\r
+       void  (*irq_callback)(void);\r
+       int   nmi_line_state;\r
+       int   internal_irq_level;\r
+       int   is_slave;\r
+} SH2;\r
+\r
+void sh2_init(SH2 *sh2);\r
+void sh2_reset(SH2 *sh2);\r
+int sh2_execute(SH2 *sh2_, int cycles);\r
+\r
+#endif /* __SH2_H__ */\r
diff --git a/cpu/sh2mame/sh2pico.c b/cpu/sh2mame/sh2pico.c
new file mode 100644 (file)
index 0000000..c6f87ea
--- /dev/null
@@ -0,0 +1,115 @@
+#include <string.h>
+
+// MAME types
+typedef signed char  INT8;
+typedef signed short INT16;
+typedef signed int   INT32;
+typedef unsigned int   UINT32;
+typedef unsigned short UINT16;
+typedef unsigned char  UINT8;
+
+// pico memhandlers
+unsigned int pico32x_read8(unsigned int a);
+unsigned int pico32x_read16(unsigned int a);
+unsigned int pico32x_read32(unsigned int a);
+void pico32x_write8(unsigned int a, unsigned int d);
+void pico32x_write16(unsigned int a, unsigned int d);
+void pico32x_write32(unsigned int a, unsigned int d);
+
+#define RB pico32x_read8
+#define RW pico32x_read16
+#define RL pico32x_read32
+#define WB pico32x_write8
+#define WW pico32x_write16
+#define WL pico32x_write32
+
+// some stuff from sh2comn.h
+#define T      0x00000001
+#define S      0x00000002
+#define I      0x000000f0
+#define Q      0x00000100
+#define M      0x00000200
+
+#define AM     0xc7ffffff
+
+#define FLAGS  (M|Q|I|S|T)
+
+#define Rn     ((opcode>>8)&15)
+#define Rm     ((opcode>>4)&15)
+
+#include "sh2.c"
+
+void sh2_reset(SH2 *sh2)
+{
+       int save_is_slave;
+//     cpu_irq_callback save_irqcallback;
+
+//     save_irqcallback = sh2->irq_callback;
+       save_is_slave = sh2->is_slave;
+
+       memset(sh2, 0, sizeof(SH2));
+
+       sh2->is_slave = save_is_slave;
+//     sh2->irq_callback = save_irqcallback;
+
+       sh2->pc = RL(0);
+       sh2->r[15] = RL(4);
+       sh2->sr = I;
+
+       sh2->internal_irq_level = -1;
+}
+
+/* Execute cycles - returns number of cycles actually run */
+int sh2_execute(SH2 *sh2_, int cycles)
+{
+       sh2 = sh2_;
+       sh2_icount = cycles;
+
+       do
+       {
+               UINT32 opcode;
+
+               opcode = RW(sh2->pc);
+
+               sh2->delay = 0;
+               sh2->pc += 2;
+               sh2->ppc = sh2->pc;
+
+               switch (opcode & ( 15 << 12))
+               {
+               case  0<<12: op0000(opcode); break;
+               case  1<<12: op0001(opcode); break;
+               case  2<<12: op0010(opcode); break;
+               case  3<<12: op0011(opcode); break;
+               case  4<<12: op0100(opcode); break;
+               case  5<<12: op0101(opcode); break;
+               case  6<<12: op0110(opcode); break;
+               case  7<<12: op0111(opcode); break;
+               case  8<<12: op1000(opcode); break;
+               case  9<<12: op1001(opcode); break;
+               case 10<<12: op1010(opcode); break;
+               case 11<<12: op1011(opcode); break;
+               case 12<<12: op1100(opcode); break;
+               case 13<<12: op1101(opcode); break;
+               case 14<<12: op1110(opcode); break;
+               default: op1111(opcode); break;
+               }
+
+               if (sh2->test_irq && !sh2->delay)
+               {
+//                     CHECK_PENDING_IRQ("mame_sh2_execute");
+                       sh2->test_irq = 0;
+               }
+               sh2_icount--;
+       }
+       while (sh2_icount > 0);
+
+       return cycles - sh2_icount;
+}
+
+void sh2_init(SH2 *sh2)
+{
+       memset(sh2, 0, sizeof(*sh2));
+}
+
+