| 1 | /*****************************************************************************\r |
| 2 | *\r |
| 3 | * sh2.c\r |
| 4 | * Portable Hitachi SH-2 (SH7600 family) emulator\r |
| 5 | *\r |
| 6 | * Copyright Juergen Buchmueller <pullmoll@t-online.de>,\r |
| 7 | * all rights reserved.\r |
| 8 | *\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 |
| 20 | *\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 |
| 25 | *\r |
| 26 | *****************************************************************************/\r |
| 27 | \r |
| 28 | /*****************************************************************************\r |
| 29 | Changes\r |
| 30 | 20130129 Angelo Salese\r |
| 31 | - added illegal opcode exception handling, side effect of some Saturn games\r |
| 32 | on loading like Feda or Falcom Classics Vol. 1\r |
| 33 | (i.e. Master CPU Incautiously transfers memory from CD to work RAM H, and\r |
| 34 | wipes out Slave CPU program code too while at it).\r |
| 35 | \r |
| 36 | 20051129 Mariusz Wojcieszek\r |
| 37 | - introduced memory_decrypted_read_word() for opcode fetching\r |
| 38 | \r |
| 39 | 20050813 Mariusz Wojcieszek\r |
| 40 | - fixed 64 bit / 32 bit division in division unit\r |
| 41 | \r |
| 42 | 20031015 O. Galibert\r |
| 43 | - dma fixes, thanks to sthief\r |
| 44 | \r |
| 45 | 20031013 O. Galibert, A. Giles\r |
| 46 | - timer fixes\r |
| 47 | - multi-cpu simplifications\r |
| 48 | \r |
| 49 | 20030915 O. Galibert\r |
| 50 | - fix DMA1 irq vector\r |
| 51 | - ignore writes to DRCRx\r |
| 52 | - fix cpu number issues\r |
| 53 | - fix slave/master recognition\r |
| 54 | - fix wrong-cpu-in-context problem with the timers\r |
| 55 | \r |
| 56 | 20021020 O. Galibert\r |
| 57 | - DMA implementation, lightly tested\r |
| 58 | - delay slot in debugger fixed\r |
| 59 | - add divide box mirrors\r |
| 60 | - Nicola-ify the indentation\r |
| 61 | - Uncrapify sh2_internal_*\r |
| 62 | - Put back nmi support that had been lost somehow\r |
| 63 | \r |
| 64 | 20020914 R. Belmont\r |
| 65 | - Initial SH2 internal timers implementation, based on code by O. Galibert.\r |
| 66 | Makes music work in galspanic4/s/s2, panic street, cyvern, other SKNS games.\r |
| 67 | - Fix to external division, thanks to "spice" on the E2J board.\r |
| 68 | Corrects behavior of s1945ii turret boss.\r |
| 69 | \r |
| 70 | 20020302 Olivier Galibert (galibert@mame.net)\r |
| 71 | - Fixed interrupt in delay slot\r |
| 72 | - Fixed rotcr\r |
| 73 | - Fixed div1\r |
| 74 | - Fixed mulu\r |
| 75 | - Fixed negc\r |
| 76 | \r |
| 77 | 20020301 R. Belmont\r |
| 78 | - Fixed external division\r |
| 79 | \r |
| 80 | 20020225 Olivier Galibert (galibert@mame.net)\r |
| 81 | - Fixed interrupt handling\r |
| 82 | \r |
| 83 | 20010207 Sylvain Glaize (mokona@puupuu.org)\r |
| 84 | \r |
| 85 | - Bug fix in INLINE void MOVBM(UINT32 m, UINT32 n) (see comment)\r |
| 86 | - Support of full 32 bit addressing (RB, RW, RL and WB, WW, WL functions)\r |
| 87 | reason : when the two high bits of the address are set, access is\r |
| 88 | done directly in the cache data array. The SUPER KANEKO NOVA SYSTEM\r |
| 89 | sets the stack pointer here, using these addresses as usual RAM access.\r |
| 90 | \r |
| 91 | No real cache support has been added.\r |
| 92 | - Read/Write memory format correction (_bew to _bedw) (see also SH2\r |
| 93 | definition in cpuintrf.c and DasmSH2(..) in sh2dasm.c )\r |
| 94 | \r |
| 95 | 20010623 James Forshaw (TyRaNiD@totalise.net)\r |
| 96 | \r |
| 97 | - Modified operation of sh2_exception. Done cause mame irq system is stupid, and\r |
| 98 | doesnt really seem designed for any more than 8 interrupt lines.\r |
| 99 | \r |
| 100 | 20010701 James Forshaw (TyRaNiD@totalise.net)\r |
| 101 | \r |
| 102 | - Fixed DIV1 operation. Q bit now correctly generated\r |
| 103 | \r |
| 104 | 20020218 Added save states (mokona@puupuu.org)\r |
| 105 | \r |
| 106 | *****************************************************************************/\r |
| 107 | \r |
| 108 | //#include "debugger.h"\r |
| 109 | //#include "sh2.h"\r |
| 110 | //#include "sh2comn.h"\r |
| 111 | #undef INLINE\r |
| 112 | #define INLINE static\r |
| 113 | \r |
| 114 | //CPU_DISASSEMBLE( sh2 );\r |
| 115 | \r |
| 116 | #ifndef USE_SH2DRC\r |
| 117 | \r |
| 118 | /* speed up delay loops, bail out of tight loops */\r |
| 119 | //#define BUSY_LOOP_HACKS 1\r |
| 120 | \r |
| 121 | #define VERBOSE 0\r |
| 122 | \r |
| 123 | #define LOG(x) do { if (VERBOSE) logerror x; } while (0)\r |
| 124 | \r |
| 125 | #if 0\r |
| 126 | INLINE UINT8 RB(sh2_state *sh2, offs_t A)\r |
| 127 | {\r |
| 128 | if (A >= 0xe0000000)\r |
| 129 | return sh2_internal_r(*sh2->internal, (A & 0x1fc)>>2, 0xff << (((~A) & 3)*8)) >> (((~A) & 3)*8);\r |
| 130 | \r |
| 131 | if (A >= 0xc0000000)\r |
| 132 | return sh2->program->read_byte(A);\r |
| 133 | \r |
| 134 | if (A >= 0x40000000)\r |
| 135 | return 0xa5;\r |
| 136 | \r |
| 137 | return sh2->program->read_byte(A & AM);\r |
| 138 | }\r |
| 139 | \r |
| 140 | INLINE UINT16 RW(sh2_state *sh2, offs_t A)\r |
| 141 | {\r |
| 142 | if (A >= 0xe0000000)\r |
| 143 | return sh2_internal_r(*sh2->internal, (A & 0x1fc)>>2, 0xffff << (((~A) & 2)*8)) >> (((~A) & 2)*8);\r |
| 144 | \r |
| 145 | if (A >= 0xc0000000)\r |
| 146 | return sh2->program->read_word(A);\r |
| 147 | \r |
| 148 | if (A >= 0x40000000)\r |
| 149 | return 0xa5a5;\r |
| 150 | \r |
| 151 | return sh2->program->read_word(A & AM);\r |
| 152 | }\r |
| 153 | \r |
| 154 | INLINE UINT32 RL(sh2_state *sh2, offs_t A)\r |
| 155 | {\r |
| 156 | if (A >= 0xe0000000)\r |
| 157 | return sh2_internal_r(*sh2->internal, (A & 0x1fc)>>2, 0xffffffff);\r |
| 158 | \r |
| 159 | if (A >= 0xc0000000)\r |
| 160 | return sh2->program->read_dword(A);\r |
| 161 | \r |
| 162 | if (A >= 0x40000000)\r |
| 163 | return 0xa5a5a5a5;\r |
| 164 | \r |
| 165 | return sh2->program->read_dword(A & AM);\r |
| 166 | }\r |
| 167 | \r |
| 168 | INLINE void WB(sh2_state *sh2, offs_t A, UINT8 V)\r |
| 169 | {\r |
| 170 | if (A >= 0xe0000000)\r |
| 171 | {\r |
| 172 | sh2_internal_w(*sh2->internal, (A & 0x1fc)>>2, V << (((~A) & 3)*8), 0xff << (((~A) & 3)*8));\r |
| 173 | return;\r |
| 174 | }\r |
| 175 | \r |
| 176 | if (A >= 0xc0000000)\r |
| 177 | {\r |
| 178 | sh2->program->write_byte(A,V);\r |
| 179 | return;\r |
| 180 | }\r |
| 181 | \r |
| 182 | if (A >= 0x40000000)\r |
| 183 | return;\r |
| 184 | \r |
| 185 | sh2->program->write_byte(A & AM,V);\r |
| 186 | }\r |
| 187 | \r |
| 188 | INLINE void WW(sh2_state *sh2, offs_t A, UINT16 V)\r |
| 189 | {\r |
| 190 | if (A >= 0xe0000000)\r |
| 191 | {\r |
| 192 | sh2_internal_w(*sh2->internal, (A & 0x1fc)>>2, V << (((~A) & 2)*8), 0xffff << (((~A) & 2)*8));\r |
| 193 | return;\r |
| 194 | }\r |
| 195 | \r |
| 196 | if (A >= 0xc0000000)\r |
| 197 | {\r |
| 198 | sh2->program->write_word(A,V);\r |
| 199 | return;\r |
| 200 | }\r |
| 201 | \r |
| 202 | if (A >= 0x40000000)\r |
| 203 | return;\r |
| 204 | \r |
| 205 | sh2->program->write_word(A & AM,V);\r |
| 206 | }\r |
| 207 | \r |
| 208 | INLINE void WL(sh2_state *sh2, offs_t A, UINT32 V)\r |
| 209 | {\r |
| 210 | if (A >= 0xe0000000)\r |
| 211 | {\r |
| 212 | sh2_internal_w(*sh2->internal, (A & 0x1fc)>>2, V, 0xffffffff);\r |
| 213 | return;\r |
| 214 | }\r |
| 215 | \r |
| 216 | if (A >= 0xc0000000)\r |
| 217 | {\r |
| 218 | sh2->program->write_dword(A,V);\r |
| 219 | return;\r |
| 220 | }\r |
| 221 | \r |
| 222 | if (A >= 0x40000000)\r |
| 223 | return;\r |
| 224 | \r |
| 225 | sh2->program->write_dword(A & AM,V);\r |
| 226 | }\r |
| 227 | #endif\r |
| 228 | \r |
| 229 | /* code cycles t-bit\r |
| 230 | * 0011 nnnn mmmm 1100 1 -\r |
| 231 | * ADD Rm,Rn\r |
| 232 | */\r |
| 233 | INLINE void ADD(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 234 | {\r |
| 235 | sh2->r[n] += sh2->r[m];\r |
| 236 | }\r |
| 237 | \r |
| 238 | /* code cycles t-bit\r |
| 239 | * 0111 nnnn iiii iiii 1 -\r |
| 240 | * ADD #imm,Rn\r |
| 241 | */\r |
| 242 | INLINE void ADDI(sh2_state *sh2, UINT32 i, UINT32 n)\r |
| 243 | {\r |
| 244 | sh2->r[n] += (INT32)(INT16)(INT8)i;\r |
| 245 | }\r |
| 246 | \r |
| 247 | /* code cycles t-bit\r |
| 248 | * 0011 nnnn mmmm 1110 1 carry\r |
| 249 | * ADDC Rm,Rn\r |
| 250 | */\r |
| 251 | INLINE void ADDC(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 252 | {\r |
| 253 | UINT32 tmp0, tmp1;\r |
| 254 | \r |
| 255 | tmp1 = sh2->r[n] + sh2->r[m];\r |
| 256 | tmp0 = sh2->r[n];\r |
| 257 | sh2->r[n] = tmp1 + (sh2->sr & T);\r |
| 258 | if (tmp0 > tmp1)\r |
| 259 | sh2->sr |= T;\r |
| 260 | else\r |
| 261 | sh2->sr &= ~T;\r |
| 262 | if (tmp1 > sh2->r[n])\r |
| 263 | sh2->sr |= T;\r |
| 264 | }\r |
| 265 | \r |
| 266 | /* code cycles t-bit\r |
| 267 | * 0011 nnnn mmmm 1111 1 overflow\r |
| 268 | * ADDV Rm,Rn\r |
| 269 | */\r |
| 270 | INLINE void ADDV(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 271 | {\r |
| 272 | INT32 dest, src, ans;\r |
| 273 | \r |
| 274 | if ((INT32) sh2->r[n] >= 0)\r |
| 275 | dest = 0;\r |
| 276 | else\r |
| 277 | dest = 1;\r |
| 278 | if ((INT32) sh2->r[m] >= 0)\r |
| 279 | src = 0;\r |
| 280 | else\r |
| 281 | src = 1;\r |
| 282 | src += dest;\r |
| 283 | sh2->r[n] += sh2->r[m];\r |
| 284 | if ((INT32) sh2->r[n] >= 0)\r |
| 285 | ans = 0;\r |
| 286 | else\r |
| 287 | ans = 1;\r |
| 288 | ans += dest;\r |
| 289 | if (src == 0 || src == 2)\r |
| 290 | {\r |
| 291 | if (ans == 1)\r |
| 292 | sh2->sr |= T;\r |
| 293 | else\r |
| 294 | sh2->sr &= ~T;\r |
| 295 | }\r |
| 296 | else\r |
| 297 | sh2->sr &= ~T;\r |
| 298 | }\r |
| 299 | \r |
| 300 | /* code cycles t-bit\r |
| 301 | * 0010 nnnn mmmm 1001 1 -\r |
| 302 | * AND Rm,Rn\r |
| 303 | */\r |
| 304 | INLINE void AND(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 305 | {\r |
| 306 | sh2->r[n] &= sh2->r[m];\r |
| 307 | }\r |
| 308 | \r |
| 309 | \r |
| 310 | /* code cycles t-bit\r |
| 311 | * 1100 1001 iiii iiii 1 -\r |
| 312 | * AND #imm,R0\r |
| 313 | */\r |
| 314 | INLINE void ANDI(sh2_state *sh2, UINT32 i)\r |
| 315 | {\r |
| 316 | sh2->r[0] &= i;\r |
| 317 | }\r |
| 318 | \r |
| 319 | /* code cycles t-bit\r |
| 320 | * 1100 1101 iiii iiii 1 -\r |
| 321 | * AND.B #imm,@(R0,GBR)\r |
| 322 | */\r |
| 323 | INLINE void ANDM(sh2_state *sh2, UINT32 i)\r |
| 324 | {\r |
| 325 | UINT32 temp;\r |
| 326 | \r |
| 327 | sh2->ea = sh2->gbr + sh2->r[0];\r |
| 328 | temp = i & RB( sh2, sh2->ea );\r |
| 329 | WB( sh2, sh2->ea, temp );\r |
| 330 | sh2->icount -= 2;\r |
| 331 | }\r |
| 332 | \r |
| 333 | /* code cycles t-bit\r |
| 334 | * 1000 1011 dddd dddd 3/1 -\r |
| 335 | * BF disp8\r |
| 336 | */\r |
| 337 | INLINE void BF(sh2_state *sh2, UINT32 d)\r |
| 338 | {\r |
| 339 | if ((sh2->sr & T) == 0)\r |
| 340 | {\r |
| 341 | INT32 disp = ((INT32)d << 24) >> 24;\r |
| 342 | sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;\r |
| 343 | sh2->icount -= 2;\r |
| 344 | }\r |
| 345 | }\r |
| 346 | \r |
| 347 | /* code cycles t-bit\r |
| 348 | * 1000 1111 dddd dddd 3/1 -\r |
| 349 | * BFS disp8\r |
| 350 | */\r |
| 351 | INLINE void BFS(sh2_state *sh2, UINT32 d)\r |
| 352 | {\r |
| 353 | sh2->delay = sh2->pc;\r |
| 354 | sh2->pc += 2;\r |
| 355 | \r |
| 356 | if ((sh2->sr & T) == 0)\r |
| 357 | {\r |
| 358 | INT32 disp = ((INT32)d << 24) >> 24;\r |
| 359 | sh2->pc = sh2->ea = sh2->pc + disp * 2;\r |
| 360 | sh2->icount--;\r |
| 361 | }\r |
| 362 | }\r |
| 363 | \r |
| 364 | /* code cycles t-bit\r |
| 365 | * 1010 dddd dddd dddd 2 -\r |
| 366 | * BRA disp12\r |
| 367 | */\r |
| 368 | INLINE void BRA(sh2_state *sh2, UINT32 d)\r |
| 369 | {\r |
| 370 | INT32 disp = ((INT32)d << 20) >> 20;\r |
| 371 | \r |
| 372 | #if BUSY_LOOP_HACKS\r |
| 373 | if (disp == -2)\r |
| 374 | {\r |
| 375 | UINT32 next_opcode = (UINT32)(UINT16)RW( sh2, sh2->ppc & AM );\r |
| 376 | /* BRA $\r |
| 377 | * NOP\r |
| 378 | */\r |
| 379 | if (next_opcode == 0x0009)\r |
| 380 | sh2->icount %= 3; /* cycles for BRA $ and NOP taken (3) */\r |
| 381 | }\r |
| 382 | #endif\r |
| 383 | sh2->delay = sh2->pc;\r |
| 384 | sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;\r |
| 385 | sh2->icount--;\r |
| 386 | }\r |
| 387 | \r |
| 388 | /* code cycles t-bit\r |
| 389 | * 0000 mmmm 0010 0011 2 -\r |
| 390 | * BRAF Rm\r |
| 391 | */\r |
| 392 | INLINE void BRAF(sh2_state *sh2, UINT32 m)\r |
| 393 | {\r |
| 394 | sh2->delay = sh2->pc;\r |
| 395 | sh2->pc += sh2->r[m] + 2;\r |
| 396 | sh2->icount--;\r |
| 397 | }\r |
| 398 | \r |
| 399 | /* code cycles t-bit\r |
| 400 | * 1011 dddd dddd dddd 2 -\r |
| 401 | * BSR disp12\r |
| 402 | */\r |
| 403 | INLINE void BSR(sh2_state *sh2, UINT32 d)\r |
| 404 | {\r |
| 405 | INT32 disp = ((INT32)d << 20) >> 20;\r |
| 406 | \r |
| 407 | sh2->pr = sh2->pc + 2;\r |
| 408 | sh2->delay = sh2->pc;\r |
| 409 | sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;\r |
| 410 | sh2->icount--;\r |
| 411 | }\r |
| 412 | \r |
| 413 | /* code cycles t-bit\r |
| 414 | * 0000 mmmm 0000 0011 2 -\r |
| 415 | * BSRF Rm\r |
| 416 | */\r |
| 417 | INLINE void BSRF(sh2_state *sh2, UINT32 m)\r |
| 418 | {\r |
| 419 | sh2->pr = sh2->pc + 2;\r |
| 420 | sh2->delay = sh2->pc;\r |
| 421 | sh2->pc += sh2->r[m] + 2;\r |
| 422 | sh2->icount--;\r |
| 423 | }\r |
| 424 | \r |
| 425 | /* code cycles t-bit\r |
| 426 | * 1000 1001 dddd dddd 3/1 -\r |
| 427 | * BT disp8\r |
| 428 | */\r |
| 429 | INLINE void BT(sh2_state *sh2, UINT32 d)\r |
| 430 | {\r |
| 431 | if ((sh2->sr & T) != 0)\r |
| 432 | {\r |
| 433 | INT32 disp = ((INT32)d << 24) >> 24;\r |
| 434 | sh2->pc = sh2->ea = sh2->pc + disp * 2 + 2;\r |
| 435 | sh2->icount -= 2;\r |
| 436 | }\r |
| 437 | }\r |
| 438 | \r |
| 439 | /* code cycles t-bit\r |
| 440 | * 1000 1101 dddd dddd 2/1 -\r |
| 441 | * BTS disp8\r |
| 442 | */\r |
| 443 | INLINE void BTS(sh2_state *sh2, UINT32 d)\r |
| 444 | {\r |
| 445 | sh2->delay = sh2->pc;\r |
| 446 | sh2->pc += 2;\r |
| 447 | \r |
| 448 | if ((sh2->sr & T) != 0)\r |
| 449 | {\r |
| 450 | INT32 disp = ((INT32)d << 24) >> 24;\r |
| 451 | sh2->pc = sh2->ea = sh2->pc + disp * 2;\r |
| 452 | sh2->icount--;\r |
| 453 | }\r |
| 454 | }\r |
| 455 | \r |
| 456 | /* code cycles t-bit\r |
| 457 | * 0000 0000 0010 1000 1 -\r |
| 458 | * CLRMAC\r |
| 459 | */\r |
| 460 | INLINE void CLRMAC(sh2_state *sh2)\r |
| 461 | {\r |
| 462 | sh2->mach = 0;\r |
| 463 | sh2->macl = 0;\r |
| 464 | }\r |
| 465 | \r |
| 466 | /* code cycles t-bit\r |
| 467 | * 0000 0000 0000 1000 1 -\r |
| 468 | * CLRT\r |
| 469 | */\r |
| 470 | INLINE void CLRT(sh2_state *sh2)\r |
| 471 | {\r |
| 472 | sh2->sr &= ~T;\r |
| 473 | }\r |
| 474 | \r |
| 475 | /* code cycles t-bit\r |
| 476 | * 0011 nnnn mmmm 0000 1 comparison result\r |
| 477 | * CMP_EQ Rm,Rn\r |
| 478 | */\r |
| 479 | INLINE void CMPEQ(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 480 | {\r |
| 481 | if (sh2->r[n] == sh2->r[m])\r |
| 482 | sh2->sr |= T;\r |
| 483 | else\r |
| 484 | sh2->sr &= ~T;\r |
| 485 | }\r |
| 486 | \r |
| 487 | /* code cycles t-bit\r |
| 488 | * 0011 nnnn mmmm 0011 1 comparison result\r |
| 489 | * CMP_GE Rm,Rn\r |
| 490 | */\r |
| 491 | INLINE void CMPGE(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 492 | {\r |
| 493 | if ((INT32) sh2->r[n] >= (INT32) sh2->r[m])\r |
| 494 | sh2->sr |= T;\r |
| 495 | else\r |
| 496 | sh2->sr &= ~T;\r |
| 497 | }\r |
| 498 | \r |
| 499 | /* code cycles t-bit\r |
| 500 | * 0011 nnnn mmmm 0111 1 comparison result\r |
| 501 | * CMP_GT Rm,Rn\r |
| 502 | */\r |
| 503 | INLINE void CMPGT(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 504 | {\r |
| 505 | if ((INT32) sh2->r[n] > (INT32) sh2->r[m])\r |
| 506 | sh2->sr |= T;\r |
| 507 | else\r |
| 508 | sh2->sr &= ~T;\r |
| 509 | }\r |
| 510 | \r |
| 511 | /* code cycles t-bit\r |
| 512 | * 0011 nnnn mmmm 0110 1 comparison result\r |
| 513 | * CMP_HI Rm,Rn\r |
| 514 | */\r |
| 515 | INLINE void CMPHI(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 516 | {\r |
| 517 | if ((UINT32) sh2->r[n] > (UINT32) sh2->r[m])\r |
| 518 | sh2->sr |= T;\r |
| 519 | else\r |
| 520 | sh2->sr &= ~T;\r |
| 521 | }\r |
| 522 | \r |
| 523 | /* code cycles t-bit\r |
| 524 | * 0011 nnnn mmmm 0010 1 comparison result\r |
| 525 | * CMP_HS Rm,Rn\r |
| 526 | */\r |
| 527 | INLINE void CMPHS(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 528 | {\r |
| 529 | if ((UINT32) sh2->r[n] >= (UINT32) sh2->r[m])\r |
| 530 | sh2->sr |= T;\r |
| 531 | else\r |
| 532 | sh2->sr &= ~T;\r |
| 533 | }\r |
| 534 | \r |
| 535 | \r |
| 536 | /* code cycles t-bit\r |
| 537 | * 0100 nnnn 0001 0101 1 comparison result\r |
| 538 | * CMP_PL Rn\r |
| 539 | */\r |
| 540 | INLINE void CMPPL(sh2_state *sh2, UINT32 n)\r |
| 541 | {\r |
| 542 | if ((INT32) sh2->r[n] > 0)\r |
| 543 | sh2->sr |= T;\r |
| 544 | else\r |
| 545 | sh2->sr &= ~T;\r |
| 546 | }\r |
| 547 | \r |
| 548 | /* code cycles t-bit\r |
| 549 | * 0100 nnnn 0001 0001 1 comparison result\r |
| 550 | * CMP_PZ Rn\r |
| 551 | */\r |
| 552 | INLINE void CMPPZ(sh2_state *sh2, UINT32 n)\r |
| 553 | {\r |
| 554 | if ((INT32) sh2->r[n] >= 0)\r |
| 555 | sh2->sr |= T;\r |
| 556 | else\r |
| 557 | sh2->sr &= ~T;\r |
| 558 | }\r |
| 559 | \r |
| 560 | /* code cycles t-bit\r |
| 561 | * 0010 nnnn mmmm 1100 1 comparison result\r |
| 562 | * CMP_STR Rm,Rn\r |
| 563 | */\r |
| 564 | INLINE void CMPSTR(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 565 | {\r |
| 566 | UINT32 temp;\r |
| 567 | INT32 HH, HL, LH, LL;\r |
| 568 | temp = sh2->r[n] ^ sh2->r[m];\r |
| 569 | HH = (temp >> 24) & 0xff;\r |
| 570 | HL = (temp >> 16) & 0xff;\r |
| 571 | LH = (temp >> 8) & 0xff;\r |
| 572 | LL = temp & 0xff;\r |
| 573 | if (HH && HL && LH && LL)\r |
| 574 | sh2->sr &= ~T;\r |
| 575 | else\r |
| 576 | sh2->sr |= T;\r |
| 577 | }\r |
| 578 | \r |
| 579 | \r |
| 580 | /* code cycles t-bit\r |
| 581 | * 1000 1000 iiii iiii 1 comparison result\r |
| 582 | * CMP/EQ #imm,R0\r |
| 583 | */\r |
| 584 | INLINE void CMPIM(sh2_state *sh2, UINT32 i)\r |
| 585 | {\r |
| 586 | UINT32 imm = (UINT32)(INT32)(INT16)(INT8)i;\r |
| 587 | \r |
| 588 | if (sh2->r[0] == imm)\r |
| 589 | sh2->sr |= T;\r |
| 590 | else\r |
| 591 | sh2->sr &= ~T;\r |
| 592 | }\r |
| 593 | \r |
| 594 | /* code cycles t-bit\r |
| 595 | * 0010 nnnn mmmm 0111 1 calculation result\r |
| 596 | * DIV0S Rm,Rn\r |
| 597 | */\r |
| 598 | INLINE void DIV0S(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 599 | {\r |
| 600 | if ((sh2->r[n] & 0x80000000) == 0)\r |
| 601 | sh2->sr &= ~Q;\r |
| 602 | else\r |
| 603 | sh2->sr |= Q;\r |
| 604 | if ((sh2->r[m] & 0x80000000) == 0)\r |
| 605 | sh2->sr &= ~M;\r |
| 606 | else\r |
| 607 | sh2->sr |= M;\r |
| 608 | if ((sh2->r[m] ^ sh2->r[n]) & 0x80000000)\r |
| 609 | sh2->sr |= T;\r |
| 610 | else\r |
| 611 | sh2->sr &= ~T;\r |
| 612 | }\r |
| 613 | \r |
| 614 | /* code cycles t-bit\r |
| 615 | * 0000 0000 0001 1001 1 0\r |
| 616 | * DIV0U\r |
| 617 | */\r |
| 618 | INLINE void DIV0U(sh2_state *sh2)\r |
| 619 | {\r |
| 620 | sh2->sr &= ~(M | Q | T);\r |
| 621 | }\r |
| 622 | \r |
| 623 | /* code cycles t-bit\r |
| 624 | * 0011 nnnn mmmm 0100 1 calculation result\r |
| 625 | * DIV1 Rm,Rn\r |
| 626 | */\r |
| 627 | INLINE void DIV1(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 628 | {\r |
| 629 | UINT32 tmp0;\r |
| 630 | UINT32 old_q;\r |
| 631 | \r |
| 632 | old_q = sh2->sr & Q;\r |
| 633 | if (0x80000000 & sh2->r[n])\r |
| 634 | sh2->sr |= Q;\r |
| 635 | else\r |
| 636 | sh2->sr &= ~Q;\r |
| 637 | \r |
| 638 | sh2->r[n] = (sh2->r[n] << 1) | (sh2->sr & T);\r |
| 639 | \r |
| 640 | if (!old_q)\r |
| 641 | {\r |
| 642 | if (!(sh2->sr & M))\r |
| 643 | {\r |
| 644 | tmp0 = sh2->r[n];\r |
| 645 | sh2->r[n] -= sh2->r[m];\r |
| 646 | if(!(sh2->sr & Q))\r |
| 647 | if(sh2->r[n] > tmp0)\r |
| 648 | sh2->sr |= Q;\r |
| 649 | else\r |
| 650 | sh2->sr &= ~Q;\r |
| 651 | else\r |
| 652 | if(sh2->r[n] > tmp0)\r |
| 653 | sh2->sr &= ~Q;\r |
| 654 | else\r |
| 655 | sh2->sr |= Q;\r |
| 656 | }\r |
| 657 | else\r |
| 658 | {\r |
| 659 | tmp0 = sh2->r[n];\r |
| 660 | sh2->r[n] += sh2->r[m];\r |
| 661 | if(!(sh2->sr & Q))\r |
| 662 | {\r |
| 663 | if(sh2->r[n] < tmp0)\r |
| 664 | sh2->sr &= ~Q;\r |
| 665 | else\r |
| 666 | sh2->sr |= Q;\r |
| 667 | }\r |
| 668 | else\r |
| 669 | {\r |
| 670 | if(sh2->r[n] < tmp0)\r |
| 671 | sh2->sr |= Q;\r |
| 672 | else\r |
| 673 | sh2->sr &= ~Q;\r |
| 674 | }\r |
| 675 | }\r |
| 676 | }\r |
| 677 | else\r |
| 678 | {\r |
| 679 | if (!(sh2->sr & M))\r |
| 680 | {\r |
| 681 | tmp0 = sh2->r[n];\r |
| 682 | sh2->r[n] += sh2->r[m];\r |
| 683 | if(!(sh2->sr & Q))\r |
| 684 | if(sh2->r[n] < tmp0)\r |
| 685 | sh2->sr |= Q;\r |
| 686 | else\r |
| 687 | sh2->sr &= ~Q;\r |
| 688 | else\r |
| 689 | if(sh2->r[n] < tmp0)\r |
| 690 | sh2->sr &= ~Q;\r |
| 691 | else\r |
| 692 | sh2->sr |= Q;\r |
| 693 | }\r |
| 694 | else\r |
| 695 | {\r |
| 696 | tmp0 = sh2->r[n];\r |
| 697 | sh2->r[n] -= sh2->r[m];\r |
| 698 | if(!(sh2->sr & Q))\r |
| 699 | if(sh2->r[n] > tmp0)\r |
| 700 | sh2->sr &= ~Q;\r |
| 701 | else\r |
| 702 | sh2->sr |= Q;\r |
| 703 | else\r |
| 704 | if(sh2->r[n] > tmp0)\r |
| 705 | sh2->sr |= Q;\r |
| 706 | else\r |
| 707 | sh2->sr &= ~Q;\r |
| 708 | }\r |
| 709 | }\r |
| 710 | \r |
| 711 | tmp0 = (sh2->sr & (Q | M));\r |
| 712 | if((!tmp0) || (tmp0 == 0x300)) /* if Q == M set T else clear T */\r |
| 713 | sh2->sr |= T;\r |
| 714 | else\r |
| 715 | sh2->sr &= ~T;\r |
| 716 | }\r |
| 717 | \r |
| 718 | /* DMULS.L Rm,Rn */\r |
| 719 | INLINE void DMULS(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 720 | {\r |
| 721 | UINT32 RnL, RnH, RmL, RmH, Res0, Res1, Res2;\r |
| 722 | UINT32 temp0, temp1, temp2, temp3;\r |
| 723 | INT32 tempm, tempn, fnLmL;\r |
| 724 | \r |
| 725 | tempn = (INT32) sh2->r[n];\r |
| 726 | tempm = (INT32) sh2->r[m];\r |
| 727 | if (tempn < 0)\r |
| 728 | tempn = 0 - tempn;\r |
| 729 | if (tempm < 0)\r |
| 730 | tempm = 0 - tempm;\r |
| 731 | if ((INT32) (sh2->r[n] ^ sh2->r[m]) < 0)\r |
| 732 | fnLmL = -1;\r |
| 733 | else\r |
| 734 | fnLmL = 0;\r |
| 735 | temp1 = (UINT32) tempn;\r |
| 736 | temp2 = (UINT32) tempm;\r |
| 737 | RnL = temp1 & 0x0000ffff;\r |
| 738 | RnH = (temp1 >> 16) & 0x0000ffff;\r |
| 739 | RmL = temp2 & 0x0000ffff;\r |
| 740 | RmH = (temp2 >> 16) & 0x0000ffff;\r |
| 741 | temp0 = RmL * RnL;\r |
| 742 | temp1 = RmH * RnL;\r |
| 743 | temp2 = RmL * RnH;\r |
| 744 | temp3 = RmH * RnH;\r |
| 745 | Res2 = 0;\r |
| 746 | Res1 = temp1 + temp2;\r |
| 747 | if (Res1 < temp1)\r |
| 748 | Res2 += 0x00010000;\r |
| 749 | temp1 = (Res1 << 16) & 0xffff0000;\r |
| 750 | Res0 = temp0 + temp1;\r |
| 751 | if (Res0 < temp0)\r |
| 752 | Res2++;\r |
| 753 | Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;\r |
| 754 | if (fnLmL < 0)\r |
| 755 | {\r |
| 756 | Res2 = ~Res2;\r |
| 757 | if (Res0 == 0)\r |
| 758 | Res2++;\r |
| 759 | else\r |
| 760 | Res0 = (~Res0) + 1;\r |
| 761 | }\r |
| 762 | sh2->mach = Res2;\r |
| 763 | sh2->macl = Res0;\r |
| 764 | sh2->icount--;\r |
| 765 | }\r |
| 766 | \r |
| 767 | /* DMULU.L Rm,Rn */\r |
| 768 | INLINE void DMULU(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 769 | {\r |
| 770 | UINT32 RnL, RnH, RmL, RmH, Res0, Res1, Res2;\r |
| 771 | UINT32 temp0, temp1, temp2, temp3;\r |
| 772 | \r |
| 773 | RnL = sh2->r[n] & 0x0000ffff;\r |
| 774 | RnH = (sh2->r[n] >> 16) & 0x0000ffff;\r |
| 775 | RmL = sh2->r[m] & 0x0000ffff;\r |
| 776 | RmH = (sh2->r[m] >> 16) & 0x0000ffff;\r |
| 777 | temp0 = RmL * RnL;\r |
| 778 | temp1 = RmH * RnL;\r |
| 779 | temp2 = RmL * RnH;\r |
| 780 | temp3 = RmH * RnH;\r |
| 781 | Res2 = 0;\r |
| 782 | Res1 = temp1 + temp2;\r |
| 783 | if (Res1 < temp1)\r |
| 784 | Res2 += 0x00010000;\r |
| 785 | temp1 = (Res1 << 16) & 0xffff0000;\r |
| 786 | Res0 = temp0 + temp1;\r |
| 787 | if (Res0 < temp0)\r |
| 788 | Res2++;\r |
| 789 | Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;\r |
| 790 | sh2->mach = Res2;\r |
| 791 | sh2->macl = Res0;\r |
| 792 | sh2->icount--;\r |
| 793 | }\r |
| 794 | \r |
| 795 | /* DT Rn */\r |
| 796 | INLINE void DT(sh2_state *sh2, UINT32 n)\r |
| 797 | {\r |
| 798 | sh2->r[n]--;\r |
| 799 | if (sh2->r[n] == 0)\r |
| 800 | sh2->sr |= T;\r |
| 801 | else\r |
| 802 | sh2->sr &= ~T;\r |
| 803 | sh2->no_polling = SH2_NO_POLLING;\r |
| 804 | #if BUSY_LOOP_HACKS\r |
| 805 | {\r |
| 806 | UINT32 next_opcode = (UINT32)(UINT16)RW( sh2, sh2->ppc & AM );\r |
| 807 | /* DT Rn\r |
| 808 | * BF $-2\r |
| 809 | */\r |
| 810 | if (next_opcode == 0x8bfd)\r |
| 811 | {\r |
| 812 | while (sh2->r[n] > 1 && sh2->icount > 4)\r |
| 813 | {\r |
| 814 | sh2->r[n]--;\r |
| 815 | sh2->icount -= 4; /* cycles for DT (1) and BF taken (3) */\r |
| 816 | }\r |
| 817 | }\r |
| 818 | }\r |
| 819 | #endif\r |
| 820 | }\r |
| 821 | \r |
| 822 | /* EXTS.B Rm,Rn */\r |
| 823 | INLINE void EXTSB(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 824 | {\r |
| 825 | sh2->r[n] = ((INT32)sh2->r[m] << 24) >> 24;\r |
| 826 | }\r |
| 827 | \r |
| 828 | /* EXTS.W Rm,Rn */\r |
| 829 | INLINE void EXTSW(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 830 | {\r |
| 831 | sh2->r[n] = ((INT32)sh2->r[m] << 16) >> 16;\r |
| 832 | }\r |
| 833 | \r |
| 834 | /* EXTU.B Rm,Rn */\r |
| 835 | INLINE void EXTUB(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 836 | {\r |
| 837 | sh2->r[n] = sh2->r[m] & 0x000000ff;\r |
| 838 | }\r |
| 839 | \r |
| 840 | /* EXTU.W Rm,Rn */\r |
| 841 | INLINE void EXTUW(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 842 | {\r |
| 843 | sh2->r[n] = sh2->r[m] & 0x0000ffff;\r |
| 844 | }\r |
| 845 | \r |
| 846 | /* ILLEGAL */\r |
| 847 | INLINE void ILLEGAL(sh2_state *sh2)\r |
| 848 | {\r |
| 849 | logerror("SH2: Illegal opcode at %08x\n", sh2->pc - 2);\r |
| 850 | sh2->r[15] -= 4;\r |
| 851 | WL( sh2, sh2->r[15], sh2->sr ); /* push SR onto stack */\r |
| 852 | sh2->r[15] -= 4;\r |
| 853 | WL( sh2, sh2->r[15], sh2->pc - 2 ); /* push PC onto stack */\r |
| 854 | \r |
| 855 | /* fetch PC */\r |
| 856 | sh2->pc = RL( sh2, sh2->vbr + 4 * 4 );\r |
| 857 | \r |
| 858 | /* TODO: timing is a guess */\r |
| 859 | sh2->icount -= 5;\r |
| 860 | }\r |
| 861 | \r |
| 862 | \r |
| 863 | /* JMP @Rm */\r |
| 864 | INLINE void JMP(sh2_state *sh2, UINT32 m)\r |
| 865 | {\r |
| 866 | sh2->delay = sh2->pc;\r |
| 867 | sh2->pc = sh2->ea = sh2->r[m];\r |
| 868 | sh2->icount--;\r |
| 869 | }\r |
| 870 | \r |
| 871 | /* JSR @Rm */\r |
| 872 | INLINE void JSR(sh2_state *sh2, UINT32 m)\r |
| 873 | {\r |
| 874 | sh2->delay = sh2->pc;\r |
| 875 | sh2->pr = sh2->pc + 2;\r |
| 876 | sh2->pc = sh2->ea = sh2->r[m];\r |
| 877 | sh2->icount--;\r |
| 878 | }\r |
| 879 | \r |
| 880 | \r |
| 881 | /* LDC Rm,SR */\r |
| 882 | INLINE void LDCSR(sh2_state *sh2, UINT32 m)\r |
| 883 | {\r |
| 884 | sh2->sr = sh2->r[m] & FLAGS;\r |
| 885 | sh2->test_irq = 1;\r |
| 886 | }\r |
| 887 | \r |
| 888 | /* LDC Rm,GBR */\r |
| 889 | INLINE void LDCGBR(sh2_state *sh2, UINT32 m)\r |
| 890 | {\r |
| 891 | sh2->gbr = sh2->r[m];\r |
| 892 | }\r |
| 893 | \r |
| 894 | /* LDC Rm,VBR */\r |
| 895 | INLINE void LDCVBR(sh2_state *sh2, UINT32 m)\r |
| 896 | {\r |
| 897 | sh2->vbr = sh2->r[m];\r |
| 898 | }\r |
| 899 | \r |
| 900 | /* LDC.L @Rm+,SR */\r |
| 901 | INLINE void LDCMSR(sh2_state *sh2, UINT32 m)\r |
| 902 | {\r |
| 903 | sh2->ea = sh2->r[m];\r |
| 904 | sh2->sr = RL( sh2, sh2->ea ) & FLAGS;\r |
| 905 | sh2->r[m] += 4;\r |
| 906 | sh2->icount -= 2;\r |
| 907 | sh2->test_irq = 1;\r |
| 908 | }\r |
| 909 | \r |
| 910 | /* LDC.L @Rm+,GBR */\r |
| 911 | INLINE void LDCMGBR(sh2_state *sh2, UINT32 m)\r |
| 912 | {\r |
| 913 | sh2->ea = sh2->r[m];\r |
| 914 | sh2->gbr = RL( sh2, sh2->ea );\r |
| 915 | sh2->r[m] += 4;\r |
| 916 | sh2->icount -= 2;\r |
| 917 | }\r |
| 918 | \r |
| 919 | /* LDC.L @Rm+,VBR */\r |
| 920 | INLINE void LDCMVBR(sh2_state *sh2, UINT32 m)\r |
| 921 | {\r |
| 922 | sh2->ea = sh2->r[m];\r |
| 923 | sh2->vbr = RL( sh2, sh2->ea );\r |
| 924 | sh2->r[m] += 4;\r |
| 925 | sh2->icount -= 2;\r |
| 926 | }\r |
| 927 | \r |
| 928 | /* LDS Rm,MACH */\r |
| 929 | INLINE void LDSMACH(sh2_state *sh2, UINT32 m)\r |
| 930 | {\r |
| 931 | sh2->mach = sh2->r[m];\r |
| 932 | }\r |
| 933 | \r |
| 934 | /* LDS Rm,MACL */\r |
| 935 | INLINE void LDSMACL(sh2_state *sh2, UINT32 m)\r |
| 936 | {\r |
| 937 | sh2->macl = sh2->r[m];\r |
| 938 | }\r |
| 939 | \r |
| 940 | /* LDS Rm,PR */\r |
| 941 | INLINE void LDSPR(sh2_state *sh2, UINT32 m)\r |
| 942 | {\r |
| 943 | sh2->pr = sh2->r[m];\r |
| 944 | }\r |
| 945 | \r |
| 946 | /* LDS.L @Rm+,MACH */\r |
| 947 | INLINE void LDSMMACH(sh2_state *sh2, UINT32 m)\r |
| 948 | {\r |
| 949 | sh2->ea = sh2->r[m];\r |
| 950 | sh2->mach = RL( sh2, sh2->ea );\r |
| 951 | sh2->r[m] += 4;\r |
| 952 | }\r |
| 953 | \r |
| 954 | /* LDS.L @Rm+,MACL */\r |
| 955 | INLINE void LDSMMACL(sh2_state *sh2, UINT32 m)\r |
| 956 | {\r |
| 957 | sh2->ea = sh2->r[m];\r |
| 958 | sh2->macl = RL( sh2, sh2->ea );\r |
| 959 | sh2->r[m] += 4;\r |
| 960 | }\r |
| 961 | \r |
| 962 | /* LDS.L @Rm+,PR */\r |
| 963 | INLINE void LDSMPR(sh2_state *sh2, UINT32 m)\r |
| 964 | {\r |
| 965 | sh2->ea = sh2->r[m];\r |
| 966 | sh2->pr = RL( sh2, sh2->ea );\r |
| 967 | sh2->r[m] += 4;\r |
| 968 | }\r |
| 969 | \r |
| 970 | /* MAC.L @Rm+,@Rn+ */\r |
| 971 | INLINE void MAC_L(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 972 | {\r |
| 973 | UINT32 RnL, RnH, RmL, RmH, Res0, Res1, Res2;\r |
| 974 | UINT32 temp0, temp1, temp2, temp3;\r |
| 975 | INT32 tempm, tempn, fnLmL;\r |
| 976 | \r |
| 977 | tempn = (INT32) RL( sh2, sh2->r[n] );\r |
| 978 | sh2->r[n] += 4;\r |
| 979 | tempm = (INT32) RL( sh2, sh2->r[m] );\r |
| 980 | sh2->r[m] += 4;\r |
| 981 | if ((INT32) (tempn ^ tempm) < 0)\r |
| 982 | fnLmL = -1;\r |
| 983 | else\r |
| 984 | fnLmL = 0;\r |
| 985 | if (tempn < 0)\r |
| 986 | tempn = 0 - tempn;\r |
| 987 | if (tempm < 0)\r |
| 988 | tempm = 0 - tempm;\r |
| 989 | temp1 = (UINT32) tempn;\r |
| 990 | temp2 = (UINT32) tempm;\r |
| 991 | RnL = temp1 & 0x0000ffff;\r |
| 992 | RnH = (temp1 >> 16) & 0x0000ffff;\r |
| 993 | RmL = temp2 & 0x0000ffff;\r |
| 994 | RmH = (temp2 >> 16) & 0x0000ffff;\r |
| 995 | temp0 = RmL * RnL;\r |
| 996 | temp1 = RmH * RnL;\r |
| 997 | temp2 = RmL * RnH;\r |
| 998 | temp3 = RmH * RnH;\r |
| 999 | Res2 = 0;\r |
| 1000 | Res1 = temp1 + temp2;\r |
| 1001 | if (Res1 < temp1)\r |
| 1002 | Res2 += 0x00010000;\r |
| 1003 | temp1 = (Res1 << 16) & 0xffff0000;\r |
| 1004 | Res0 = temp0 + temp1;\r |
| 1005 | if (Res0 < temp0)\r |
| 1006 | Res2++;\r |
| 1007 | Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;\r |
| 1008 | if (fnLmL < 0)\r |
| 1009 | {\r |
| 1010 | Res2 = ~Res2;\r |
| 1011 | if (Res0 == 0)\r |
| 1012 | Res2++;\r |
| 1013 | else\r |
| 1014 | Res0 = (~Res0) + 1;\r |
| 1015 | }\r |
| 1016 | if (sh2->sr & S)\r |
| 1017 | {\r |
| 1018 | Res0 = sh2->macl + Res0;\r |
| 1019 | if (sh2->macl > Res0)\r |
| 1020 | Res2++;\r |
| 1021 | Res2 += (sh2->mach & 0x0000ffff);\r |
| 1022 | if (((INT32) Res2 < 0) && (Res2 < 0xffff8000))\r |
| 1023 | {\r |
| 1024 | Res2 = 0x00008000;\r |
| 1025 | Res0 = 0x00000000;\r |
| 1026 | }\r |
| 1027 | else if (((INT32) Res2 > 0) && (Res2 > 0x00007fff))\r |
| 1028 | {\r |
| 1029 | Res2 = 0x00007fff;\r |
| 1030 | Res0 = 0xffffffff;\r |
| 1031 | }\r |
| 1032 | sh2->mach = Res2;\r |
| 1033 | sh2->macl = Res0;\r |
| 1034 | }\r |
| 1035 | else\r |
| 1036 | {\r |
| 1037 | Res0 = sh2->macl + Res0;\r |
| 1038 | if (sh2->macl > Res0)\r |
| 1039 | Res2++;\r |
| 1040 | Res2 += sh2->mach;\r |
| 1041 | sh2->mach = Res2;\r |
| 1042 | sh2->macl = Res0;\r |
| 1043 | }\r |
| 1044 | sh2->icount -= 2;\r |
| 1045 | }\r |
| 1046 | \r |
| 1047 | /* MAC.W @Rm+,@Rn+ */\r |
| 1048 | INLINE void MAC_W(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1049 | {\r |
| 1050 | INT32 tempm, tempn, dest, src, ans;\r |
| 1051 | UINT32 templ;\r |
| 1052 | \r |
| 1053 | tempn = (INT32)(INT16) RW( sh2, sh2->r[n] );\r |
| 1054 | sh2->r[n] += 2;\r |
| 1055 | tempm = (INT32)(INT16) RW( sh2, sh2->r[m] );\r |
| 1056 | sh2->r[m] += 2;\r |
| 1057 | templ = sh2->macl;\r |
| 1058 | tempm = (tempn * tempm);\r |
| 1059 | if ((INT32) sh2->macl >= 0)\r |
| 1060 | dest = 0;\r |
| 1061 | else\r |
| 1062 | dest = 1;\r |
| 1063 | if ((INT32) tempm >= 0)\r |
| 1064 | {\r |
| 1065 | src = 0;\r |
| 1066 | tempn = 0;\r |
| 1067 | }\r |
| 1068 | else\r |
| 1069 | {\r |
| 1070 | src = 1;\r |
| 1071 | tempn = 0xffffffff;\r |
| 1072 | }\r |
| 1073 | src += dest;\r |
| 1074 | sh2->macl += tempm;\r |
| 1075 | if ((INT32) sh2->macl >= 0)\r |
| 1076 | ans = 0;\r |
| 1077 | else\r |
| 1078 | ans = 1;\r |
| 1079 | ans += dest;\r |
| 1080 | if (sh2->sr & S)\r |
| 1081 | {\r |
| 1082 | if (ans == 1)\r |
| 1083 | {\r |
| 1084 | if (src == 0)\r |
| 1085 | sh2->macl = 0x7fffffff;\r |
| 1086 | if (src == 2)\r |
| 1087 | sh2->macl = 0x80000000;\r |
| 1088 | }\r |
| 1089 | }\r |
| 1090 | else\r |
| 1091 | {\r |
| 1092 | sh2->mach += tempn;\r |
| 1093 | if (templ > sh2->macl)\r |
| 1094 | sh2->mach += 1;\r |
| 1095 | }\r |
| 1096 | sh2->icount -= 2;\r |
| 1097 | }\r |
| 1098 | \r |
| 1099 | /* MOV Rm,Rn */\r |
| 1100 | INLINE void MOV(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1101 | {\r |
| 1102 | sh2->r[n] = sh2->r[m];\r |
| 1103 | }\r |
| 1104 | \r |
| 1105 | /* MOV.B Rm,@Rn */\r |
| 1106 | INLINE void MOVBS(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1107 | {\r |
| 1108 | sh2->ea = sh2->r[n];\r |
| 1109 | WB( sh2, sh2->ea, sh2->r[m] & 0x000000ff);\r |
| 1110 | }\r |
| 1111 | \r |
| 1112 | /* MOV.W Rm,@Rn */\r |
| 1113 | INLINE void MOVWS(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1114 | {\r |
| 1115 | sh2->ea = sh2->r[n];\r |
| 1116 | WW( sh2, sh2->ea, sh2->r[m] & 0x0000ffff);\r |
| 1117 | }\r |
| 1118 | \r |
| 1119 | /* MOV.L Rm,@Rn */\r |
| 1120 | INLINE void MOVLS(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1121 | {\r |
| 1122 | sh2->ea = sh2->r[n];\r |
| 1123 | WL( sh2, sh2->ea, sh2->r[m] );\r |
| 1124 | }\r |
| 1125 | \r |
| 1126 | /* MOV.B @Rm,Rn */\r |
| 1127 | INLINE void MOVBL(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1128 | {\r |
| 1129 | sh2->ea = sh2->r[m];\r |
| 1130 | sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->ea );\r |
| 1131 | }\r |
| 1132 | \r |
| 1133 | /* MOV.W @Rm,Rn */\r |
| 1134 | INLINE void MOVWL(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1135 | {\r |
| 1136 | sh2->ea = sh2->r[m];\r |
| 1137 | sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2, sh2->ea );\r |
| 1138 | }\r |
| 1139 | \r |
| 1140 | /* MOV.L @Rm,Rn */\r |
| 1141 | INLINE void MOVLL(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1142 | {\r |
| 1143 | sh2->ea = sh2->r[m];\r |
| 1144 | sh2->r[n] = RL( sh2, sh2->ea );\r |
| 1145 | }\r |
| 1146 | \r |
| 1147 | /* MOV.B Rm,@-Rn */\r |
| 1148 | INLINE void MOVBM(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1149 | {\r |
| 1150 | /* SMG : bug fix, was reading sh2->r[n] */\r |
| 1151 | UINT32 data = sh2->r[m] & 0x000000ff;\r |
| 1152 | \r |
| 1153 | sh2->r[n] -= 1;\r |
| 1154 | WB( sh2, sh2->r[n], data );\r |
| 1155 | }\r |
| 1156 | \r |
| 1157 | /* MOV.W Rm,@-Rn */\r |
| 1158 | INLINE void MOVWM(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1159 | {\r |
| 1160 | UINT32 data = sh2->r[m] & 0x0000ffff;\r |
| 1161 | \r |
| 1162 | sh2->r[n] -= 2;\r |
| 1163 | WW( sh2, sh2->r[n], data );\r |
| 1164 | }\r |
| 1165 | \r |
| 1166 | /* MOV.L Rm,@-Rn */\r |
| 1167 | INLINE void MOVLM(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1168 | {\r |
| 1169 | UINT32 data = sh2->r[m];\r |
| 1170 | \r |
| 1171 | sh2->r[n] -= 4;\r |
| 1172 | WL( sh2, sh2->r[n], data );\r |
| 1173 | }\r |
| 1174 | \r |
| 1175 | /* MOV.B @Rm+,Rn */\r |
| 1176 | INLINE void MOVBP(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1177 | {\r |
| 1178 | sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->r[m] );\r |
| 1179 | if (n != m)\r |
| 1180 | sh2->r[m] += 1;\r |
| 1181 | }\r |
| 1182 | \r |
| 1183 | /* MOV.W @Rm+,Rn */\r |
| 1184 | INLINE void MOVWP(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1185 | {\r |
| 1186 | sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2, sh2->r[m] );\r |
| 1187 | if (n != m)\r |
| 1188 | sh2->r[m] += 2;\r |
| 1189 | }\r |
| 1190 | \r |
| 1191 | /* MOV.L @Rm+,Rn */\r |
| 1192 | INLINE void MOVLP(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1193 | {\r |
| 1194 | sh2->r[n] = RL( sh2, sh2->r[m] );\r |
| 1195 | if (n != m)\r |
| 1196 | sh2->r[m] += 4;\r |
| 1197 | }\r |
| 1198 | \r |
| 1199 | /* MOV.B Rm,@(R0,Rn) */\r |
| 1200 | INLINE void MOVBS0(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1201 | {\r |
| 1202 | sh2->ea = sh2->r[n] + sh2->r[0];\r |
| 1203 | WB( sh2, sh2->ea, sh2->r[m] & 0x000000ff );\r |
| 1204 | }\r |
| 1205 | \r |
| 1206 | /* MOV.W Rm,@(R0,Rn) */\r |
| 1207 | INLINE void MOVWS0(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1208 | {\r |
| 1209 | sh2->ea = sh2->r[n] + sh2->r[0];\r |
| 1210 | WW( sh2, sh2->ea, sh2->r[m] & 0x0000ffff );\r |
| 1211 | }\r |
| 1212 | \r |
| 1213 | /* MOV.L Rm,@(R0,Rn) */\r |
| 1214 | INLINE void MOVLS0(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1215 | {\r |
| 1216 | sh2->ea = sh2->r[n] + sh2->r[0];\r |
| 1217 | WL( sh2, sh2->ea, sh2->r[m] );\r |
| 1218 | }\r |
| 1219 | \r |
| 1220 | /* MOV.B @(R0,Rm),Rn */\r |
| 1221 | INLINE void MOVBL0(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1222 | {\r |
| 1223 | sh2->ea = sh2->r[m] + sh2->r[0];\r |
| 1224 | sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->ea );\r |
| 1225 | }\r |
| 1226 | \r |
| 1227 | /* MOV.W @(R0,Rm),Rn */\r |
| 1228 | INLINE void MOVWL0(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1229 | {\r |
| 1230 | sh2->ea = sh2->r[m] + sh2->r[0];\r |
| 1231 | sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2, sh2->ea );\r |
| 1232 | }\r |
| 1233 | \r |
| 1234 | /* MOV.L @(R0,Rm),Rn */\r |
| 1235 | INLINE void MOVLL0(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1236 | {\r |
| 1237 | sh2->ea = sh2->r[m] + sh2->r[0];\r |
| 1238 | sh2->r[n] = RL( sh2, sh2->ea );\r |
| 1239 | }\r |
| 1240 | \r |
| 1241 | /* MOV #imm,Rn */\r |
| 1242 | INLINE void MOVI(sh2_state *sh2, UINT32 i, UINT32 n)\r |
| 1243 | {\r |
| 1244 | sh2->r[n] = (UINT32)(INT32)(INT16)(INT8) i;\r |
| 1245 | }\r |
| 1246 | \r |
| 1247 | /* MOV.W @(disp8,PC),Rn */\r |
| 1248 | INLINE void MOVWI(sh2_state *sh2, UINT32 d, UINT32 n)\r |
| 1249 | {\r |
| 1250 | UINT32 disp = d & 0xff;\r |
| 1251 | sh2->ea = sh2->pc + disp * 2 + 2;\r |
| 1252 | sh2->r[n] = (UINT32)(INT32)(INT16) RW( sh2, sh2->ea );\r |
| 1253 | }\r |
| 1254 | \r |
| 1255 | /* MOV.L @(disp8,PC),Rn */\r |
| 1256 | INLINE void MOVLI(sh2_state *sh2, UINT32 d, UINT32 n)\r |
| 1257 | {\r |
| 1258 | UINT32 disp = d & 0xff;\r |
| 1259 | sh2->ea = ((sh2->pc + 2) & ~3) + disp * 4;\r |
| 1260 | sh2->r[n] = RL( sh2, sh2->ea );\r |
| 1261 | }\r |
| 1262 | \r |
| 1263 | /* MOV.B @(disp8,GBR),R0 */\r |
| 1264 | INLINE void MOVBLG(sh2_state *sh2, UINT32 d)\r |
| 1265 | {\r |
| 1266 | UINT32 disp = d & 0xff;\r |
| 1267 | sh2->ea = sh2->gbr + disp;\r |
| 1268 | sh2->r[0] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->ea );\r |
| 1269 | }\r |
| 1270 | \r |
| 1271 | /* MOV.W @(disp8,GBR),R0 */\r |
| 1272 | INLINE void MOVWLG(sh2_state *sh2, UINT32 d)\r |
| 1273 | {\r |
| 1274 | UINT32 disp = d & 0xff;\r |
| 1275 | sh2->ea = sh2->gbr + disp * 2;\r |
| 1276 | sh2->r[0] = (INT32)(INT16) RW( sh2, sh2->ea );\r |
| 1277 | }\r |
| 1278 | \r |
| 1279 | /* MOV.L @(disp8,GBR),R0 */\r |
| 1280 | INLINE void MOVLLG(sh2_state *sh2, UINT32 d)\r |
| 1281 | {\r |
| 1282 | UINT32 disp = d & 0xff;\r |
| 1283 | sh2->ea = sh2->gbr + disp * 4;\r |
| 1284 | sh2->r[0] = RL( sh2, sh2->ea );\r |
| 1285 | }\r |
| 1286 | \r |
| 1287 | /* MOV.B R0,@(disp8,GBR) */\r |
| 1288 | INLINE void MOVBSG(sh2_state *sh2, UINT32 d)\r |
| 1289 | {\r |
| 1290 | UINT32 disp = d & 0xff;\r |
| 1291 | sh2->ea = sh2->gbr + disp;\r |
| 1292 | WB( sh2, sh2->ea, sh2->r[0] & 0x000000ff );\r |
| 1293 | }\r |
| 1294 | \r |
| 1295 | /* MOV.W R0,@(disp8,GBR) */\r |
| 1296 | INLINE void MOVWSG(sh2_state *sh2, UINT32 d)\r |
| 1297 | {\r |
| 1298 | UINT32 disp = d & 0xff;\r |
| 1299 | sh2->ea = sh2->gbr + disp * 2;\r |
| 1300 | WW( sh2, sh2->ea, sh2->r[0] & 0x0000ffff );\r |
| 1301 | }\r |
| 1302 | \r |
| 1303 | /* MOV.L R0,@(disp8,GBR) */\r |
| 1304 | INLINE void MOVLSG(sh2_state *sh2, UINT32 d)\r |
| 1305 | {\r |
| 1306 | UINT32 disp = d & 0xff;\r |
| 1307 | sh2->ea = sh2->gbr + disp * 4;\r |
| 1308 | WL( sh2, sh2->ea, sh2->r[0] );\r |
| 1309 | }\r |
| 1310 | \r |
| 1311 | /* MOV.B R0,@(disp4,Rn) */\r |
| 1312 | INLINE void MOVBS4(sh2_state *sh2, UINT32 d, UINT32 n)\r |
| 1313 | {\r |
| 1314 | UINT32 disp = d & 0x0f;\r |
| 1315 | sh2->ea = sh2->r[n] + disp;\r |
| 1316 | WB( sh2, sh2->ea, sh2->r[0] & 0x000000ff );\r |
| 1317 | }\r |
| 1318 | \r |
| 1319 | /* MOV.W R0,@(disp4,Rn) */\r |
| 1320 | INLINE void MOVWS4(sh2_state *sh2, UINT32 d, UINT32 n)\r |
| 1321 | {\r |
| 1322 | UINT32 disp = d & 0x0f;\r |
| 1323 | sh2->ea = sh2->r[n] + disp * 2;\r |
| 1324 | WW( sh2, sh2->ea, sh2->r[0] & 0x0000ffff );\r |
| 1325 | }\r |
| 1326 | \r |
| 1327 | /* MOV.L Rm,@(disp4,Rn) */\r |
| 1328 | INLINE void MOVLS4(sh2_state *sh2, UINT32 m, UINT32 d, UINT32 n)\r |
| 1329 | {\r |
| 1330 | UINT32 disp = d & 0x0f;\r |
| 1331 | sh2->ea = sh2->r[n] + disp * 4;\r |
| 1332 | WL( sh2, sh2->ea, sh2->r[m] );\r |
| 1333 | }\r |
| 1334 | \r |
| 1335 | /* MOV.B @(disp4,Rm),R0 */\r |
| 1336 | INLINE void MOVBL4(sh2_state *sh2, UINT32 m, UINT32 d)\r |
| 1337 | {\r |
| 1338 | UINT32 disp = d & 0x0f;\r |
| 1339 | sh2->ea = sh2->r[m] + disp;\r |
| 1340 | sh2->r[0] = (UINT32)(INT32)(INT16)(INT8) RB( sh2, sh2->ea );\r |
| 1341 | }\r |
| 1342 | \r |
| 1343 | /* MOV.W @(disp4,Rm),R0 */\r |
| 1344 | INLINE void MOVWL4(sh2_state *sh2, UINT32 m, UINT32 d)\r |
| 1345 | {\r |
| 1346 | UINT32 disp = d & 0x0f;\r |
| 1347 | sh2->ea = sh2->r[m] + disp * 2;\r |
| 1348 | sh2->r[0] = (UINT32)(INT32)(INT16) RW( sh2, sh2->ea );\r |
| 1349 | }\r |
| 1350 | \r |
| 1351 | /* MOV.L @(disp4,Rm),Rn */\r |
| 1352 | INLINE void MOVLL4(sh2_state *sh2, UINT32 m, UINT32 d, UINT32 n)\r |
| 1353 | {\r |
| 1354 | UINT32 disp = d & 0x0f;\r |
| 1355 | sh2->ea = sh2->r[m] + disp * 4;\r |
| 1356 | sh2->r[n] = RL( sh2, sh2->ea );\r |
| 1357 | }\r |
| 1358 | \r |
| 1359 | /* MOVA @(disp8,PC),R0 */\r |
| 1360 | INLINE void MOVA(sh2_state *sh2, UINT32 d)\r |
| 1361 | {\r |
| 1362 | UINT32 disp = d & 0xff;\r |
| 1363 | sh2->ea = ((sh2->pc + 2) & ~3) + disp * 4;\r |
| 1364 | sh2->r[0] = sh2->ea;\r |
| 1365 | }\r |
| 1366 | \r |
| 1367 | /* MOVT Rn */\r |
| 1368 | INLINE void MOVT(sh2_state *sh2, UINT32 n)\r |
| 1369 | {\r |
| 1370 | sh2->r[n] = sh2->sr & T;\r |
| 1371 | }\r |
| 1372 | \r |
| 1373 | /* MUL.L Rm,Rn */\r |
| 1374 | INLINE void MULL(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1375 | {\r |
| 1376 | sh2->macl = sh2->r[n] * sh2->r[m];\r |
| 1377 | sh2->icount--;\r |
| 1378 | }\r |
| 1379 | \r |
| 1380 | /* MULS Rm,Rn */\r |
| 1381 | INLINE void MULS(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1382 | {\r |
| 1383 | sh2->macl = (INT16) sh2->r[n] * (INT16) sh2->r[m];\r |
| 1384 | }\r |
| 1385 | \r |
| 1386 | /* MULU Rm,Rn */\r |
| 1387 | INLINE void MULU(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1388 | {\r |
| 1389 | sh2->macl = (UINT16) sh2->r[n] * (UINT16) sh2->r[m];\r |
| 1390 | }\r |
| 1391 | \r |
| 1392 | /* NEG Rm,Rn */\r |
| 1393 | INLINE void NEG(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1394 | {\r |
| 1395 | sh2->r[n] = 0 - sh2->r[m];\r |
| 1396 | }\r |
| 1397 | \r |
| 1398 | /* NEGC Rm,Rn */\r |
| 1399 | INLINE void NEGC(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1400 | {\r |
| 1401 | UINT32 temp;\r |
| 1402 | \r |
| 1403 | temp = sh2->r[m];\r |
| 1404 | sh2->r[n] = -temp - (sh2->sr & T);\r |
| 1405 | if (temp || (sh2->sr & T))\r |
| 1406 | sh2->sr |= T;\r |
| 1407 | else\r |
| 1408 | sh2->sr &= ~T;\r |
| 1409 | }\r |
| 1410 | \r |
| 1411 | /* NOP */\r |
| 1412 | INLINE void NOP(void)\r |
| 1413 | {\r |
| 1414 | }\r |
| 1415 | \r |
| 1416 | /* NOT Rm,Rn */\r |
| 1417 | INLINE void NOT(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1418 | {\r |
| 1419 | sh2->r[n] = ~sh2->r[m];\r |
| 1420 | }\r |
| 1421 | \r |
| 1422 | /* OR Rm,Rn */\r |
| 1423 | INLINE void OR(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1424 | {\r |
| 1425 | sh2->r[n] |= sh2->r[m];\r |
| 1426 | }\r |
| 1427 | \r |
| 1428 | /* OR #imm,R0 */\r |
| 1429 | INLINE void ORI(sh2_state *sh2, UINT32 i)\r |
| 1430 | {\r |
| 1431 | sh2->r[0] |= i;\r |
| 1432 | }\r |
| 1433 | \r |
| 1434 | /* OR.B #imm,@(R0,GBR) */\r |
| 1435 | INLINE void ORM(sh2_state *sh2, UINT32 i)\r |
| 1436 | {\r |
| 1437 | UINT32 temp;\r |
| 1438 | \r |
| 1439 | sh2->ea = sh2->gbr + sh2->r[0];\r |
| 1440 | temp = RB( sh2, sh2->ea );\r |
| 1441 | temp |= i;\r |
| 1442 | WB( sh2, sh2->ea, temp );\r |
| 1443 | sh2->icount -= 2;\r |
| 1444 | }\r |
| 1445 | \r |
| 1446 | /* ROTCL Rn */\r |
| 1447 | INLINE void ROTCL(sh2_state *sh2, UINT32 n)\r |
| 1448 | {\r |
| 1449 | UINT32 temp;\r |
| 1450 | \r |
| 1451 | temp = (sh2->r[n] >> 31) & T;\r |
| 1452 | sh2->r[n] = (sh2->r[n] << 1) | (sh2->sr & T);\r |
| 1453 | sh2->sr = (sh2->sr & ~T) | temp;\r |
| 1454 | }\r |
| 1455 | \r |
| 1456 | /* ROTCR Rn */\r |
| 1457 | INLINE void ROTCR(sh2_state *sh2, UINT32 n)\r |
| 1458 | {\r |
| 1459 | UINT32 temp;\r |
| 1460 | temp = (sh2->sr & T) << 31;\r |
| 1461 | if (sh2->r[n] & T)\r |
| 1462 | sh2->sr |= T;\r |
| 1463 | else\r |
| 1464 | sh2->sr &= ~T;\r |
| 1465 | sh2->r[n] = (sh2->r[n] >> 1) | temp;\r |
| 1466 | }\r |
| 1467 | \r |
| 1468 | /* ROTL Rn */\r |
| 1469 | INLINE void ROTL(sh2_state *sh2, UINT32 n)\r |
| 1470 | {\r |
| 1471 | sh2->sr = (sh2->sr & ~T) | ((sh2->r[n] >> 31) & T);\r |
| 1472 | sh2->r[n] = (sh2->r[n] << 1) | (sh2->r[n] >> 31);\r |
| 1473 | }\r |
| 1474 | \r |
| 1475 | /* ROTR Rn */\r |
| 1476 | INLINE void ROTR(sh2_state *sh2, UINT32 n)\r |
| 1477 | {\r |
| 1478 | sh2->sr = (sh2->sr & ~T) | (sh2->r[n] & T);\r |
| 1479 | sh2->r[n] = (sh2->r[n] >> 1) | (sh2->r[n] << 31);\r |
| 1480 | }\r |
| 1481 | \r |
| 1482 | /* RTE */\r |
| 1483 | INLINE void RTE(sh2_state *sh2)\r |
| 1484 | {\r |
| 1485 | sh2->ea = sh2->r[15];\r |
| 1486 | sh2->delay = sh2->pc;\r |
| 1487 | sh2->pc = RL( sh2, sh2->ea );\r |
| 1488 | sh2->r[15] += 4;\r |
| 1489 | sh2->ea = sh2->r[15];\r |
| 1490 | sh2->sr = RL( sh2, sh2->ea ) & FLAGS;\r |
| 1491 | sh2->r[15] += 4;\r |
| 1492 | sh2->icount -= 3;\r |
| 1493 | sh2->test_irq = 1;\r |
| 1494 | }\r |
| 1495 | \r |
| 1496 | /* RTS */\r |
| 1497 | INLINE void RTS(sh2_state *sh2)\r |
| 1498 | {\r |
| 1499 | sh2->delay = sh2->pc;\r |
| 1500 | sh2->pc = sh2->ea = sh2->pr;\r |
| 1501 | sh2->icount--;\r |
| 1502 | }\r |
| 1503 | \r |
| 1504 | /* SETT */\r |
| 1505 | INLINE void SETT(sh2_state *sh2)\r |
| 1506 | {\r |
| 1507 | sh2->sr |= T;\r |
| 1508 | }\r |
| 1509 | \r |
| 1510 | /* SHAL Rn (same as SHLL) */\r |
| 1511 | INLINE void SHAL(sh2_state *sh2, UINT32 n)\r |
| 1512 | {\r |
| 1513 | sh2->sr = (sh2->sr & ~T) | ((sh2->r[n] >> 31) & T);\r |
| 1514 | sh2->r[n] <<= 1;\r |
| 1515 | }\r |
| 1516 | \r |
| 1517 | /* SHAR Rn */\r |
| 1518 | INLINE void SHAR(sh2_state *sh2, UINT32 n)\r |
| 1519 | {\r |
| 1520 | sh2->sr = (sh2->sr & ~T) | (sh2->r[n] & T);\r |
| 1521 | sh2->r[n] = (UINT32)((INT32)sh2->r[n] >> 1);\r |
| 1522 | }\r |
| 1523 | \r |
| 1524 | /* SHLL Rn (same as SHAL) */\r |
| 1525 | INLINE void SHLL(sh2_state *sh2, UINT32 n)\r |
| 1526 | {\r |
| 1527 | sh2->sr = (sh2->sr & ~T) | ((sh2->r[n] >> 31) & T);\r |
| 1528 | sh2->r[n] <<= 1;\r |
| 1529 | }\r |
| 1530 | \r |
| 1531 | /* SHLL2 Rn */\r |
| 1532 | INLINE void SHLL2(sh2_state *sh2, UINT32 n)\r |
| 1533 | {\r |
| 1534 | sh2->r[n] <<= 2;\r |
| 1535 | }\r |
| 1536 | \r |
| 1537 | /* SHLL8 Rn */\r |
| 1538 | INLINE void SHLL8(sh2_state *sh2, UINT32 n)\r |
| 1539 | {\r |
| 1540 | sh2->r[n] <<= 8;\r |
| 1541 | }\r |
| 1542 | \r |
| 1543 | /* SHLL16 Rn */\r |
| 1544 | INLINE void SHLL16(sh2_state *sh2, UINT32 n)\r |
| 1545 | {\r |
| 1546 | sh2->r[n] <<= 16;\r |
| 1547 | }\r |
| 1548 | \r |
| 1549 | /* SHLR Rn */\r |
| 1550 | INLINE void SHLR(sh2_state *sh2, UINT32 n)\r |
| 1551 | {\r |
| 1552 | sh2->sr = (sh2->sr & ~T) | (sh2->r[n] & T);\r |
| 1553 | sh2->r[n] >>= 1;\r |
| 1554 | }\r |
| 1555 | \r |
| 1556 | /* SHLR2 Rn */\r |
| 1557 | INLINE void SHLR2(sh2_state *sh2, UINT32 n)\r |
| 1558 | {\r |
| 1559 | sh2->r[n] >>= 2;\r |
| 1560 | }\r |
| 1561 | \r |
| 1562 | /* SHLR8 Rn */\r |
| 1563 | INLINE void SHLR8(sh2_state *sh2, UINT32 n)\r |
| 1564 | {\r |
| 1565 | sh2->r[n] >>= 8;\r |
| 1566 | }\r |
| 1567 | \r |
| 1568 | /* SHLR16 Rn */\r |
| 1569 | INLINE void SHLR16(sh2_state *sh2, UINT32 n)\r |
| 1570 | {\r |
| 1571 | sh2->r[n] >>= 16;\r |
| 1572 | }\r |
| 1573 | \r |
| 1574 | /* SLEEP */\r |
| 1575 | INLINE void SLEEP(sh2_state *sh2)\r |
| 1576 | {\r |
| 1577 | //if(sh2->sleep_mode != 2)\r |
| 1578 | sh2->pc -= 2;\r |
| 1579 | sh2->icount -= 2;\r |
| 1580 | /* Wait_for_exception; */\r |
| 1581 | /*if(sh2->sleep_mode == 0)\r |
| 1582 | sh2->sleep_mode = 1;\r |
| 1583 | else if(sh2->sleep_mode == 2)\r |
| 1584 | sh2->sleep_mode = 0;*/\r |
| 1585 | }\r |
| 1586 | \r |
| 1587 | /* STC SR,Rn */\r |
| 1588 | INLINE void STCSR(sh2_state *sh2, UINT32 n)\r |
| 1589 | {\r |
| 1590 | sh2->r[n] = sh2->sr;\r |
| 1591 | }\r |
| 1592 | \r |
| 1593 | /* STC GBR,Rn */\r |
| 1594 | INLINE void STCGBR(sh2_state *sh2, UINT32 n)\r |
| 1595 | {\r |
| 1596 | sh2->r[n] = sh2->gbr;\r |
| 1597 | }\r |
| 1598 | \r |
| 1599 | /* STC VBR,Rn */\r |
| 1600 | INLINE void STCVBR(sh2_state *sh2, UINT32 n)\r |
| 1601 | {\r |
| 1602 | sh2->r[n] = sh2->vbr;\r |
| 1603 | }\r |
| 1604 | \r |
| 1605 | /* STC.L SR,@-Rn */\r |
| 1606 | INLINE void STCMSR(sh2_state *sh2, UINT32 n)\r |
| 1607 | {\r |
| 1608 | sh2->r[n] -= 4;\r |
| 1609 | sh2->ea = sh2->r[n];\r |
| 1610 | WL( sh2, sh2->ea, sh2->sr );\r |
| 1611 | sh2->icount--;\r |
| 1612 | }\r |
| 1613 | \r |
| 1614 | /* STC.L GBR,@-Rn */\r |
| 1615 | INLINE void STCMGBR(sh2_state *sh2, UINT32 n)\r |
| 1616 | {\r |
| 1617 | sh2->r[n] -= 4;\r |
| 1618 | sh2->ea = sh2->r[n];\r |
| 1619 | WL( sh2, sh2->ea, sh2->gbr );\r |
| 1620 | sh2->icount--;\r |
| 1621 | }\r |
| 1622 | \r |
| 1623 | /* STC.L VBR,@-Rn */\r |
| 1624 | INLINE void STCMVBR(sh2_state *sh2, UINT32 n)\r |
| 1625 | {\r |
| 1626 | sh2->r[n] -= 4;\r |
| 1627 | sh2->ea = sh2->r[n];\r |
| 1628 | WL( sh2, sh2->ea, sh2->vbr );\r |
| 1629 | sh2->icount--;\r |
| 1630 | }\r |
| 1631 | \r |
| 1632 | /* STS MACH,Rn */\r |
| 1633 | INLINE void STSMACH(sh2_state *sh2, UINT32 n)\r |
| 1634 | {\r |
| 1635 | sh2->r[n] = sh2->mach;\r |
| 1636 | }\r |
| 1637 | \r |
| 1638 | /* STS MACL,Rn */\r |
| 1639 | INLINE void STSMACL(sh2_state *sh2, UINT32 n)\r |
| 1640 | {\r |
| 1641 | sh2->r[n] = sh2->macl;\r |
| 1642 | }\r |
| 1643 | \r |
| 1644 | /* STS PR,Rn */\r |
| 1645 | INLINE void STSPR(sh2_state *sh2, UINT32 n)\r |
| 1646 | {\r |
| 1647 | sh2->r[n] = sh2->pr;\r |
| 1648 | }\r |
| 1649 | \r |
| 1650 | /* STS.L MACH,@-Rn */\r |
| 1651 | INLINE void STSMMACH(sh2_state *sh2, UINT32 n)\r |
| 1652 | {\r |
| 1653 | sh2->r[n] -= 4;\r |
| 1654 | sh2->ea = sh2->r[n];\r |
| 1655 | WL( sh2, sh2->ea, sh2->mach );\r |
| 1656 | }\r |
| 1657 | \r |
| 1658 | /* STS.L MACL,@-Rn */\r |
| 1659 | INLINE void STSMMACL(sh2_state *sh2, UINT32 n)\r |
| 1660 | {\r |
| 1661 | sh2->r[n] -= 4;\r |
| 1662 | sh2->ea = sh2->r[n];\r |
| 1663 | WL( sh2, sh2->ea, sh2->macl );\r |
| 1664 | }\r |
| 1665 | \r |
| 1666 | /* STS.L PR,@-Rn */\r |
| 1667 | INLINE void STSMPR(sh2_state *sh2, UINT32 n)\r |
| 1668 | {\r |
| 1669 | sh2->r[n] -= 4;\r |
| 1670 | sh2->ea = sh2->r[n];\r |
| 1671 | WL( sh2, sh2->ea, sh2->pr );\r |
| 1672 | }\r |
| 1673 | \r |
| 1674 | /* SUB Rm,Rn */\r |
| 1675 | INLINE void SUB(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1676 | {\r |
| 1677 | sh2->r[n] -= sh2->r[m];\r |
| 1678 | }\r |
| 1679 | \r |
| 1680 | /* SUBC Rm,Rn */\r |
| 1681 | INLINE void SUBC(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1682 | {\r |
| 1683 | UINT32 tmp0, tmp1;\r |
| 1684 | \r |
| 1685 | tmp1 = sh2->r[n] - sh2->r[m];\r |
| 1686 | tmp0 = sh2->r[n];\r |
| 1687 | sh2->r[n] = tmp1 - (sh2->sr & T);\r |
| 1688 | if (tmp0 < tmp1)\r |
| 1689 | sh2->sr |= T;\r |
| 1690 | else\r |
| 1691 | sh2->sr &= ~T;\r |
| 1692 | if (tmp1 < sh2->r[n])\r |
| 1693 | sh2->sr |= T;\r |
| 1694 | }\r |
| 1695 | \r |
| 1696 | /* SUBV Rm,Rn */\r |
| 1697 | INLINE void SUBV(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1698 | {\r |
| 1699 | INT32 dest, src, ans;\r |
| 1700 | \r |
| 1701 | if ((INT32) sh2->r[n] >= 0)\r |
| 1702 | dest = 0;\r |
| 1703 | else\r |
| 1704 | dest = 1;\r |
| 1705 | if ((INT32) sh2->r[m] >= 0)\r |
| 1706 | src = 0;\r |
| 1707 | else\r |
| 1708 | src = 1;\r |
| 1709 | src += dest;\r |
| 1710 | sh2->r[n] -= sh2->r[m];\r |
| 1711 | if ((INT32) sh2->r[n] >= 0)\r |
| 1712 | ans = 0;\r |
| 1713 | else\r |
| 1714 | ans = 1;\r |
| 1715 | ans += dest;\r |
| 1716 | if (src == 1)\r |
| 1717 | {\r |
| 1718 | if (ans == 1)\r |
| 1719 | sh2->sr |= T;\r |
| 1720 | else\r |
| 1721 | sh2->sr &= ~T;\r |
| 1722 | }\r |
| 1723 | else\r |
| 1724 | sh2->sr &= ~T;\r |
| 1725 | }\r |
| 1726 | \r |
| 1727 | /* SWAP.B Rm,Rn */\r |
| 1728 | INLINE void SWAPB(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1729 | {\r |
| 1730 | UINT32 temp0, temp1;\r |
| 1731 | \r |
| 1732 | temp0 = sh2->r[m] & 0xffff0000;\r |
| 1733 | temp1 = (sh2->r[m] & 0x000000ff) << 8;\r |
| 1734 | sh2->r[n] = (sh2->r[m] >> 8) & 0x000000ff;\r |
| 1735 | sh2->r[n] = sh2->r[n] | temp1 | temp0;\r |
| 1736 | }\r |
| 1737 | \r |
| 1738 | /* SWAP.W Rm,Rn */\r |
| 1739 | INLINE void SWAPW(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1740 | {\r |
| 1741 | UINT32 temp;\r |
| 1742 | \r |
| 1743 | temp = (sh2->r[m] >> 16) & 0x0000ffff;\r |
| 1744 | sh2->r[n] = (sh2->r[m] << 16) | temp;\r |
| 1745 | }\r |
| 1746 | \r |
| 1747 | /* TAS.B @Rn */\r |
| 1748 | INLINE void TAS(sh2_state *sh2, UINT32 n)\r |
| 1749 | {\r |
| 1750 | UINT32 temp;\r |
| 1751 | sh2->ea = sh2->r[n];\r |
| 1752 | /* Bus Lock enable */\r |
| 1753 | temp = RB( sh2, sh2->ea );\r |
| 1754 | if (temp == 0)\r |
| 1755 | sh2->sr |= T;\r |
| 1756 | else\r |
| 1757 | sh2->sr &= ~T;\r |
| 1758 | temp |= 0x80;\r |
| 1759 | /* Bus Lock disable */\r |
| 1760 | WB( sh2, sh2->ea, temp );\r |
| 1761 | sh2->icount -= 3;\r |
| 1762 | }\r |
| 1763 | \r |
| 1764 | /* TRAPA #imm */\r |
| 1765 | INLINE void TRAPA(sh2_state *sh2, UINT32 i)\r |
| 1766 | {\r |
| 1767 | UINT32 imm = i & 0xff;\r |
| 1768 | \r |
| 1769 | sh2->ea = sh2->vbr + imm * 4;\r |
| 1770 | \r |
| 1771 | sh2->r[15] -= 4;\r |
| 1772 | WL( sh2, sh2->r[15], sh2->sr );\r |
| 1773 | sh2->r[15] -= 4;\r |
| 1774 | WL( sh2, sh2->r[15], sh2->pc );\r |
| 1775 | \r |
| 1776 | sh2->pc = RL( sh2, sh2->ea );\r |
| 1777 | \r |
| 1778 | sh2->icount -= 7;\r |
| 1779 | }\r |
| 1780 | \r |
| 1781 | /* TST Rm,Rn */\r |
| 1782 | INLINE void TST(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1783 | {\r |
| 1784 | if ((sh2->r[n] & sh2->r[m]) == 0)\r |
| 1785 | sh2->sr |= T;\r |
| 1786 | else\r |
| 1787 | sh2->sr &= ~T;\r |
| 1788 | }\r |
| 1789 | \r |
| 1790 | /* TST #imm,R0 */\r |
| 1791 | INLINE void TSTI(sh2_state *sh2, UINT32 i)\r |
| 1792 | {\r |
| 1793 | UINT32 imm = i & 0xff;\r |
| 1794 | \r |
| 1795 | if ((imm & sh2->r[0]) == 0)\r |
| 1796 | sh2->sr |= T;\r |
| 1797 | else\r |
| 1798 | sh2->sr &= ~T;\r |
| 1799 | }\r |
| 1800 | \r |
| 1801 | /* TST.B #imm,@(R0,GBR) */\r |
| 1802 | INLINE void TSTM(sh2_state *sh2, UINT32 i)\r |
| 1803 | {\r |
| 1804 | UINT32 imm = i & 0xff;\r |
| 1805 | \r |
| 1806 | sh2->ea = sh2->gbr + sh2->r[0];\r |
| 1807 | if ((imm & RB( sh2, sh2->ea )) == 0)\r |
| 1808 | sh2->sr |= T;\r |
| 1809 | else\r |
| 1810 | sh2->sr &= ~T;\r |
| 1811 | sh2->icount -= 2;\r |
| 1812 | }\r |
| 1813 | \r |
| 1814 | /* XOR Rm,Rn */\r |
| 1815 | INLINE void XOR(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1816 | {\r |
| 1817 | sh2->r[n] ^= sh2->r[m];\r |
| 1818 | }\r |
| 1819 | \r |
| 1820 | /* XOR #imm,R0 */\r |
| 1821 | INLINE void XORI(sh2_state *sh2, UINT32 i)\r |
| 1822 | {\r |
| 1823 | UINT32 imm = i & 0xff;\r |
| 1824 | sh2->r[0] ^= imm;\r |
| 1825 | }\r |
| 1826 | \r |
| 1827 | /* XOR.B #imm,@(R0,GBR) */\r |
| 1828 | INLINE void XORM(sh2_state *sh2, UINT32 i)\r |
| 1829 | {\r |
| 1830 | UINT32 imm = i & 0xff;\r |
| 1831 | UINT32 temp;\r |
| 1832 | \r |
| 1833 | sh2->ea = sh2->gbr + sh2->r[0];\r |
| 1834 | temp = RB( sh2, sh2->ea );\r |
| 1835 | temp ^= imm;\r |
| 1836 | WB( sh2, sh2->ea, temp );\r |
| 1837 | sh2->icount -= 2;\r |
| 1838 | }\r |
| 1839 | \r |
| 1840 | /* XTRCT Rm,Rn */\r |
| 1841 | INLINE void XTRCT(sh2_state *sh2, UINT32 m, UINT32 n)\r |
| 1842 | {\r |
| 1843 | UINT32 temp;\r |
| 1844 | \r |
| 1845 | temp = (sh2->r[m] << 16) & 0xffff0000;\r |
| 1846 | sh2->r[n] = (sh2->r[n] >> 16) & 0x0000ffff;\r |
| 1847 | sh2->r[n] |= temp;\r |
| 1848 | }\r |
| 1849 | \r |
| 1850 | /*****************************************************************************\r |
| 1851 | * OPCODE DISPATCHERS\r |
| 1852 | *****************************************************************************/\r |
| 1853 | \r |
| 1854 | INLINE void op0000(sh2_state *sh2, UINT16 opcode)\r |
| 1855 | {\r |
| 1856 | switch (opcode & 0x3F)\r |
| 1857 | {\r |
| 1858 | case 0x00: ILLEGAL(sh2); rlog(0); break;\r |
| 1859 | case 0x01: ILLEGAL(sh2); rlog(0); break;\r |
| 1860 | case 0x02: STCSR(sh2, Rn); rlog(LRN); break;\r |
| 1861 | case 0x03: BSRF(sh2, Rn); rlog(LRN); break;\r |
| 1862 | case 0x04: MOVBS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r |
| 1863 | case 0x05: MOVWS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r |
| 1864 | case 0x06: MOVLS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r |
| 1865 | case 0x07: MULL(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;\r |
| 1866 | case 0x08: CLRT(sh2); rlog(0); break;\r |
| 1867 | case 0x09: NOP(); rlog(0); break;\r |
| 1868 | case 0x0a: STSMACH(sh2, Rn); rlog(LRN); rlog1(SHR_MACH); break;\r |
| 1869 | case 0x0b: RTS(sh2); rlog(0); rlog1(SHR_PR); break;\r |
| 1870 | case 0x0c: MOVBL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r |
| 1871 | case 0x0d: MOVWL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r |
| 1872 | case 0x0e: MOVLL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r |
| 1873 | case 0x0f: MAC_L(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;\r |
| 1874 | \r |
| 1875 | case 0x10: ILLEGAL(sh2); rlog(0); break;\r |
| 1876 | case 0x11: ILLEGAL(sh2); rlog(0); break;\r |
| 1877 | case 0x12: STCGBR(sh2, Rn); rlog(LRN); rlog1(SHR_GBR); break;\r |
| 1878 | case 0x13: ILLEGAL(sh2); rlog(0); break;\r |
| 1879 | case 0x14: MOVBS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r |
| 1880 | case 0x15: MOVWS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r |
| 1881 | case 0x16: MOVLS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r |
| 1882 | case 0x17: MULL(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;\r |
| 1883 | case 0x18: SETT(sh2); rlog(0); break;\r |
| 1884 | case 0x19: DIV0U(sh2); rlog(0); break;\r |
| 1885 | case 0x1a: STSMACL(sh2, Rn); rlog(LRN); rlog1(SHR_MACL); break;\r |
| 1886 | case 0x1b: SLEEP(sh2); rlog(0); break;\r |
| 1887 | case 0x1c: MOVBL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r |
| 1888 | case 0x1d: MOVWL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r |
| 1889 | case 0x1e: MOVLL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r |
| 1890 | case 0x1f: MAC_L(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;\r |
| 1891 | \r |
| 1892 | case 0x20: ILLEGAL(sh2); rlog(0); break;\r |
| 1893 | case 0x21: ILLEGAL(sh2); rlog(0); break;\r |
| 1894 | case 0x22: STCVBR(sh2, Rn); rlog(LRN); rlog1(SHR_VBR); break;\r |
| 1895 | case 0x23: BRAF(sh2, Rn); rlog(LRN); break;\r |
| 1896 | case 0x24: MOVBS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r |
| 1897 | case 0x25: MOVWS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r |
| 1898 | case 0x26: MOVLS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r |
| 1899 | case 0x27: MULL(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;\r |
| 1900 | case 0x28: CLRMAC(sh2); rlog(0); rlog2(SHR_MACL,SHR_MACH); break;\r |
| 1901 | case 0x29: MOVT(sh2, Rn); rlog(LRN); break;\r |
| 1902 | case 0x2a: STSPR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;\r |
| 1903 | case 0x2b: RTE(sh2); rlog(0); break;\r |
| 1904 | case 0x2c: MOVBL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r |
| 1905 | case 0x2d: MOVWL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r |
| 1906 | case 0x2e: MOVLL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r |
| 1907 | case 0x2f: MAC_L(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;\r |
| 1908 | \r |
| 1909 | case 0x30: ILLEGAL(sh2); rlog(0); break;\r |
| 1910 | case 0x31: ILLEGAL(sh2); rlog(0); break;\r |
| 1911 | case 0x32: ILLEGAL(sh2); rlog(0); break;\r |
| 1912 | case 0x33: ILLEGAL(sh2); rlog(0); break;\r |
| 1913 | case 0x34: MOVBS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r |
| 1914 | case 0x35: MOVWS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r |
| 1915 | case 0x36: MOVLS0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r |
| 1916 | case 0x37: MULL(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;\r |
| 1917 | case 0x38: ILLEGAL(sh2); rlog(0); break;\r |
| 1918 | case 0x39: ILLEGAL(sh2); rlog(0); break;\r |
| 1919 | case 0x3c: MOVBL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r |
| 1920 | case 0x3d: MOVWL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r |
| 1921 | case 0x3e: MOVLL0(sh2, Rm, Rn); rlog(LRNM); rlog1(0); break;\r |
| 1922 | case 0x3f: MAC_L(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;\r |
| 1923 | case 0x3a: ILLEGAL(sh2); rlog(0); break;\r |
| 1924 | case 0x3b: ILLEGAL(sh2); rlog(0); break;\r |
| 1925 | }\r |
| 1926 | }\r |
| 1927 | \r |
| 1928 | INLINE void op0001(sh2_state *sh2, UINT16 opcode)\r |
| 1929 | {\r |
| 1930 | MOVLS4(sh2, Rm, opcode & 0x0f, Rn);\r |
| 1931 | rlog(LRNM);\r |
| 1932 | }\r |
| 1933 | \r |
| 1934 | INLINE void op0010(sh2_state *sh2, UINT16 opcode)\r |
| 1935 | {\r |
| 1936 | switch (opcode & 15)\r |
| 1937 | {\r |
| 1938 | case 0: MOVBS(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1939 | case 1: MOVWS(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1940 | case 2: MOVLS(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1941 | case 3: ILLEGAL(sh2); rlog(0); break;\r |
| 1942 | case 4: MOVBM(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1943 | case 5: MOVWM(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1944 | case 6: MOVLM(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1945 | case 7: DIV0S(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1946 | case 8: TST(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1947 | case 9: AND(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1948 | case 10: XOR(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1949 | case 11: OR(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1950 | case 12: CMPSTR(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1951 | case 13: XTRCT(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1952 | case 14: MULU(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;\r |
| 1953 | case 15: MULS(sh2, Rm, Rn); rlog(LRNM); rlog1(SHR_MACL); break;\r |
| 1954 | }\r |
| 1955 | }\r |
| 1956 | \r |
| 1957 | INLINE void op0011(sh2_state *sh2, UINT16 opcode)\r |
| 1958 | {\r |
| 1959 | switch (opcode & 15)\r |
| 1960 | {\r |
| 1961 | case 0: CMPEQ(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1962 | case 1: ILLEGAL(sh2); rlog(0); break;\r |
| 1963 | case 2: CMPHS(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1964 | case 3: CMPGE(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1965 | case 4: DIV1(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1966 | case 5: DMULU(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;\r |
| 1967 | case 6: CMPHI(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1968 | case 7: CMPGT(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1969 | case 8: SUB(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1970 | case 9: ILLEGAL(sh2); rlog(0); break;\r |
| 1971 | case 10: SUBC(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1972 | case 11: SUBV(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1973 | case 12: ADD(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1974 | case 13: DMULS(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;\r |
| 1975 | case 14: ADDC(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1976 | case 15: ADDV(sh2, Rm, Rn); rlog(LRNM); break;\r |
| 1977 | }\r |
| 1978 | }\r |
| 1979 | \r |
| 1980 | INLINE void op0100(sh2_state *sh2, UINT16 opcode)\r |
| 1981 | {\r |
| 1982 | switch (opcode & 0x3F)\r |
| 1983 | {\r |
| 1984 | case 0x00: SHLL(sh2, Rn); rlog(LRN); break;\r |
| 1985 | case 0x01: SHLR(sh2, Rn); rlog(LRN); break;\r |
| 1986 | case 0x02: STSMMACH(sh2, Rn); rlog(LRN); rlog1(SHR_MACH); break;\r |
| 1987 | case 0x03: STCMSR(sh2, Rn); rlog(LRN); break;\r |
| 1988 | case 0x04: ROTL(sh2, Rn); rlog(LRN); break;\r |
| 1989 | case 0x05: ROTR(sh2, Rn); rlog(LRN); break;\r |
| 1990 | case 0x06: LDSMMACH(sh2, Rn); rlog(LRN); rlog1(SHR_MACH); break;\r |
| 1991 | case 0x07: LDCMSR(sh2, Rn); rlog(LRN); break;\r |
| 1992 | case 0x08: SHLL2(sh2, Rn); rlog(LRN); break;\r |
| 1993 | case 0x09: SHLR2(sh2, Rn); rlog(LRN); break;\r |
| 1994 | case 0x0a: LDSMACH(sh2, Rn); rlog(LRN); rlog1(SHR_MACH); break;\r |
| 1995 | case 0x0b: JSR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;\r |
| 1996 | case 0x0c: ILLEGAL(sh2); rlog(0); break;\r |
| 1997 | case 0x0d: ILLEGAL(sh2); rlog(0); break;\r |
| 1998 | case 0x0e: LDCSR(sh2, Rn); rlog(LRN); break;\r |
| 1999 | case 0x0f: MAC_W(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;\r |
| 2000 | \r |
| 2001 | case 0x10: DT(sh2, Rn); rlog(LRN); break;\r |
| 2002 | case 0x11: CMPPZ(sh2, Rn); rlog(LRN); break;\r |
| 2003 | case 0x12: STSMMACL(sh2, Rn); rlog(LRN); rlog1(SHR_MACL); break;\r |
| 2004 | case 0x13: STCMGBR(sh2, Rn); rlog(LRN); rlog1(SHR_GBR); break;\r |
| 2005 | case 0x14: ILLEGAL(sh2); rlog(0); break;\r |
| 2006 | case 0x15: CMPPL(sh2, Rn); rlog(LRN); break;\r |
| 2007 | case 0x16: LDSMMACL(sh2, Rn); rlog(LRN); rlog1(SHR_MACL); break;\r |
| 2008 | case 0x17: LDCMGBR(sh2, Rn); rlog(LRN); rlog1(SHR_GBR); break;\r |
| 2009 | case 0x18: SHLL8(sh2, Rn); rlog(LRN); break;\r |
| 2010 | case 0x19: SHLR8(sh2, Rn); rlog(LRN); break;\r |
| 2011 | case 0x1a: LDSMACL(sh2, Rn); rlog(LRN); rlog1(SHR_MACL); break;\r |
| 2012 | case 0x1b: TAS(sh2, Rn); rlog(LRN); break;\r |
| 2013 | case 0x1c: ILLEGAL(sh2); rlog(0); break;\r |
| 2014 | case 0x1d: ILLEGAL(sh2); rlog(0); break;\r |
| 2015 | case 0x1e: LDCGBR(sh2, Rn); rlog(LRN); rlog1(SHR_GBR); break;\r |
| 2016 | case 0x1f: MAC_W(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;\r |
| 2017 | \r |
| 2018 | case 0x20: SHAL(sh2, Rn); rlog(LRN); break;\r |
| 2019 | case 0x21: SHAR(sh2, Rn); rlog(LRN); break;\r |
| 2020 | case 0x22: STSMPR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;\r |
| 2021 | case 0x23: STCMVBR(sh2, Rn); rlog(LRN); rlog1(SHR_VBR); break;\r |
| 2022 | case 0x24: ROTCL(sh2, Rn); rlog(LRN); break;\r |
| 2023 | case 0x25: ROTCR(sh2, Rn); rlog(LRN); break;\r |
| 2024 | case 0x26: LDSMPR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;\r |
| 2025 | case 0x27: LDCMVBR(sh2, Rn); rlog(LRN); rlog1(SHR_VBR); break;\r |
| 2026 | case 0x28: SHLL16(sh2, Rn); rlog(LRN); break;\r |
| 2027 | case 0x29: SHLR16(sh2, Rn); rlog(LRN); break;\r |
| 2028 | case 0x2a: LDSPR(sh2, Rn); rlog(LRN); rlog1(SHR_PR); break;\r |
| 2029 | case 0x2b: JMP(sh2, Rn); rlog(LRN); break;\r |
| 2030 | case 0x2c: ILLEGAL(sh2); rlog(0); break;\r |
| 2031 | case 0x2d: ILLEGAL(sh2); rlog(0); break;\r |
| 2032 | case 0x2e: LDCVBR(sh2, Rn); rlog(LRN); rlog1(SHR_VBR); break;\r |
| 2033 | case 0x2f: MAC_W(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;\r |
| 2034 | \r |
| 2035 | case 0x30:\r |
| 2036 | case 0x31:\r |
| 2037 | case 0x32:\r |
| 2038 | case 0x33:\r |
| 2039 | case 0x34:\r |
| 2040 | case 0x35:\r |
| 2041 | case 0x36:\r |
| 2042 | case 0x37:\r |
| 2043 | case 0x38:\r |
| 2044 | case 0x39:\r |
| 2045 | case 0x3a:\r |
| 2046 | case 0x3b:\r |
| 2047 | case 0x3c:\r |
| 2048 | case 0x3d:\r |
| 2049 | case 0x3e: ILLEGAL(sh2); rlog(0); break;\r |
| 2050 | case 0x3f: MAC_W(sh2, Rm, Rn); rlog(LRNM); rlog2(SHR_MACL,SHR_MACH); break;\r |
| 2051 | }\r |
| 2052 | }\r |
| 2053 | \r |
| 2054 | INLINE void op0101(sh2_state *sh2, UINT16 opcode)\r |
| 2055 | {\r |
| 2056 | MOVLL4(sh2, Rm, opcode & 0x0f, Rn);\r |
| 2057 | rlog(LRNM);\r |
| 2058 | }\r |
| 2059 | \r |
| 2060 | INLINE void op0110(sh2_state *sh2, UINT16 opcode)\r |
| 2061 | {\r |
| 2062 | switch (opcode & 15)\r |
| 2063 | {\r |
| 2064 | case 0: MOVBL(sh2, Rm, Rn); break;\r |
| 2065 | case 1: MOVWL(sh2, Rm, Rn); break;\r |
| 2066 | case 2: MOVLL(sh2, Rm, Rn); break;\r |
| 2067 | case 3: MOV(sh2, Rm, Rn); break;\r |
| 2068 | case 4: MOVBP(sh2, Rm, Rn); break;\r |
| 2069 | case 5: MOVWP(sh2, Rm, Rn); break;\r |
| 2070 | case 6: MOVLP(sh2, Rm, Rn); break;\r |
| 2071 | case 7: NOT(sh2, Rm, Rn); break;\r |
| 2072 | case 8: SWAPB(sh2, Rm, Rn); break;\r |
| 2073 | case 9: SWAPW(sh2, Rm, Rn); break;\r |
| 2074 | case 10: NEGC(sh2, Rm, Rn); break;\r |
| 2075 | case 11: NEG(sh2, Rm, Rn); break;\r |
| 2076 | case 12: EXTUB(sh2, Rm, Rn); break;\r |
| 2077 | case 13: EXTUW(sh2, Rm, Rn); break;\r |
| 2078 | case 14: EXTSB(sh2, Rm, Rn); break;\r |
| 2079 | case 15: EXTSW(sh2, Rm, Rn); break;\r |
| 2080 | }\r |
| 2081 | rlog(LRNM);\r |
| 2082 | }\r |
| 2083 | \r |
| 2084 | INLINE void op0111(sh2_state *sh2, UINT16 opcode)\r |
| 2085 | {\r |
| 2086 | ADDI(sh2, opcode & 0xff, Rn);\r |
| 2087 | rlog(LRN);\r |
| 2088 | }\r |
| 2089 | \r |
| 2090 | INLINE void op1000(sh2_state *sh2, UINT16 opcode)\r |
| 2091 | {\r |
| 2092 | switch ( opcode & (15<<8) )\r |
| 2093 | {\r |
| 2094 | case 0<< 8: MOVBS4(sh2, opcode & 0x0f, Rm); rlog(LRM); rlog1(0); break;\r |
| 2095 | case 1<< 8: MOVWS4(sh2, opcode & 0x0f, Rm); rlog(LRM); rlog1(0); break;\r |
| 2096 | case 2<< 8: ILLEGAL(sh2); rlog(0); break;\r |
| 2097 | case 3<< 8: ILLEGAL(sh2); rlog(0); break;\r |
| 2098 | case 4<< 8: MOVBL4(sh2, Rm, opcode & 0x0f); rlog(LRM); rlog1(0); break;\r |
| 2099 | case 5<< 8: MOVWL4(sh2, Rm, opcode & 0x0f); rlog(LRM); rlog1(0); break;\r |
| 2100 | case 6<< 8: ILLEGAL(sh2); rlog(0); break;\r |
| 2101 | case 7<< 8: ILLEGAL(sh2); rlog(0); break;\r |
| 2102 | case 8<< 8: CMPIM(sh2, opcode & 0xff); rlog(0); rlog1(0); break;\r |
| 2103 | case 9<< 8: BT(sh2, opcode & 0xff); rlog(0); break;\r |
| 2104 | case 10<< 8: ILLEGAL(sh2); rlog(0); break;\r |
| 2105 | case 11<< 8: BF(sh2, opcode & 0xff); rlog(0); break;\r |
| 2106 | case 12<< 8: ILLEGAL(sh2); rlog(0); break;\r |
| 2107 | case 13<< 8: BTS(sh2, opcode & 0xff); rlog(0); break;\r |
| 2108 | case 14<< 8: ILLEGAL(sh2); rlog(0); break;\r |
| 2109 | case 15<< 8: BFS(sh2, opcode & 0xff); rlog(0); break;\r |
| 2110 | }\r |
| 2111 | }\r |
| 2112 | \r |
| 2113 | \r |
| 2114 | INLINE void op1001(sh2_state *sh2, UINT16 opcode)\r |
| 2115 | {\r |
| 2116 | MOVWI(sh2, opcode & 0xff, Rn);\r |
| 2117 | rlog(LRN);\r |
| 2118 | }\r |
| 2119 | \r |
| 2120 | INLINE void op1010(sh2_state *sh2, UINT16 opcode)\r |
| 2121 | {\r |
| 2122 | BRA(sh2, opcode & 0xfff);\r |
| 2123 | rlog(0);\r |
| 2124 | }\r |
| 2125 | \r |
| 2126 | INLINE void op1011(sh2_state *sh2, UINT16 opcode)\r |
| 2127 | {\r |
| 2128 | BSR(sh2, opcode & 0xfff);\r |
| 2129 | rlog(0);\r |
| 2130 | rlog1(SHR_PR);\r |
| 2131 | }\r |
| 2132 | \r |
| 2133 | INLINE void op1100(sh2_state *sh2, UINT16 opcode)\r |
| 2134 | {\r |
| 2135 | switch (opcode & (15<<8))\r |
| 2136 | {\r |
| 2137 | case 0<<8: MOVBSG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;\r |
| 2138 | case 1<<8: MOVWSG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;\r |
| 2139 | case 2<<8: MOVLSG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;\r |
| 2140 | case 3<<8: TRAPA(sh2, opcode & 0xff); rlog1(SHR_VBR); break;\r |
| 2141 | case 4<<8: MOVBLG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;\r |
| 2142 | case 5<<8: MOVWLG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;\r |
| 2143 | case 6<<8: MOVLLG(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;\r |
| 2144 | case 7<<8: MOVA(sh2, opcode & 0xff); rlog1(0); break;\r |
| 2145 | case 8<<8: TSTI(sh2, opcode & 0xff); rlog1(0); break;\r |
| 2146 | case 9<<8: ANDI(sh2, opcode & 0xff); rlog1(0); break;\r |
| 2147 | case 10<<8: XORI(sh2, opcode & 0xff); rlog1(0); break;\r |
| 2148 | case 11<<8: ORI(sh2, opcode & 0xff); rlog1(0); break;\r |
| 2149 | case 12<<8: TSTM(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;\r |
| 2150 | case 13<<8: ANDM(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;\r |
| 2151 | case 14<<8: XORM(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;\r |
| 2152 | case 15<<8: ORM(sh2, opcode & 0xff); rlog2(0, SHR_GBR); break;\r |
| 2153 | }\r |
| 2154 | rlog(0);\r |
| 2155 | }\r |
| 2156 | \r |
| 2157 | INLINE void op1101(sh2_state *sh2, UINT16 opcode)\r |
| 2158 | {\r |
| 2159 | MOVLI(sh2, opcode & 0xff, Rn);\r |
| 2160 | rlog(LRN);\r |
| 2161 | }\r |
| 2162 | \r |
| 2163 | INLINE void op1110(sh2_state *sh2, UINT16 opcode)\r |
| 2164 | {\r |
| 2165 | MOVI(sh2, opcode & 0xff, Rn);\r |
| 2166 | rlog(LRN);\r |
| 2167 | }\r |
| 2168 | \r |
| 2169 | INLINE void op1111(sh2_state *sh2, UINT16 opcode)\r |
| 2170 | {\r |
| 2171 | ILLEGAL(sh2);\r |
| 2172 | rlog(0);\r |
| 2173 | }\r |
| 2174 | \r |
| 2175 | #endif\r |