1 /* rl78.c --- opcode semantics for stand-alone RL78 simulator. 2 3 Copyright (C) 2008-2024 Free Software Foundation, Inc. 4 Contributed by Red Hat, Inc. 5 6 This file is part of the GNU simulators. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. 20 */ 21 22 /* This must come before any other includes. */ 23 #include "defs.h" 24 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <string.h> 28 #include <signal.h> 29 #include <setjmp.h> 30 #include <time.h> 31 32 #include "opcode/rl78.h" 33 #include "cpu.h" 34 #include "mem.h" 35 36 extern int skip_init; 37 static int opcode_pc = 0; 38 39 jmp_buf decode_jmp_buf; 40 #define DO_RETURN(x) longjmp (decode_jmp_buf, x) 41 42 #define tprintf if (trace) printf 43 44 #define WILD_JUMP_CHECK(new_pc) \ 45 do { \ 46 if (new_pc == 0 || new_pc > 0xfffff) \ 47 { \ 48 pc = opcode_pc; \ 49 fprintf (stderr, "Wild jump to 0x%x from 0x%x!\n", new_pc, pc); \ 50 DO_RETURN (RL78_MAKE_HIT_BREAK ()); \ 51 } \ 52 } while (0) 53 54 typedef struct { 55 unsigned long dpc; 56 } RL78_Data; 57 58 static int 59 rl78_get_byte (void *vdata) 60 { 61 RL78_Data *rl78_data = (RL78_Data *)vdata; 62 int rv = mem_get_pc (rl78_data->dpc); 63 rl78_data->dpc ++; 64 return rv; 65 } 66 67 static int 68 op_addr (const RL78_Opcode_Operand *o, int for_data) 69 { 70 int v = o->addend; 71 if (o->reg != RL78_Reg_None) 72 v += get_reg (o->reg); 73 if (o->reg2 != RL78_Reg_None) 74 v += get_reg (o->reg2); 75 if (o->use_es) 76 v |= (get_reg (RL78_Reg_ES) & 0xf) << 16; 77 else if (for_data) 78 v |= 0xf0000; 79 v &= 0xfffff; 80 return v; 81 } 82 83 static int 84 get_op (const RL78_Opcode_Decoded *rd, int i, int for_data) 85 { 86 int v, r; 87 const RL78_Opcode_Operand *o = rd->op + i; 88 89 switch (o->type) 90 { 91 case RL78_Operand_None: 92 /* condition code does this. */ 93 v = 0; 94 break; 95 96 case RL78_Operand_Immediate: 97 tprintf (" #"); 98 v = o->addend; 99 break; 100 101 case RL78_Operand_Register: 102 tprintf (" %s=", reg_names[o->reg]); 103 v = get_reg (o->reg); 104 break; 105 106 case RL78_Operand_Bit: 107 tprintf (" %s.%d=", reg_names[o->reg], o->bit_number); 108 v = get_reg (o->reg); 109 v = (v & (1 << o->bit_number)) ? 1 : 0; 110 break; 111 112 case RL78_Operand_Indirect: 113 v = op_addr (o, for_data); 114 tprintf (" [0x%x]=", v); 115 if (rd->size == RL78_Word) 116 v = mem_get_hi (v); 117 else 118 v = mem_get_qi (v); 119 break; 120 121 case RL78_Operand_BitIndirect: 122 v = op_addr (o, for_data); 123 tprintf (" [0x%x].%d=", v, o->bit_number); 124 v = (mem_get_qi (v) & (1 << o->bit_number)) ? 1 : 0; 125 break; 126 127 case RL78_Operand_PreDec: 128 r = get_reg (o->reg); 129 tprintf (" [--%s]", reg_names[o->reg]); 130 if (rd->size == RL78_Word) 131 { 132 r -= 2; 133 v = mem_get_hi (r | 0xf0000); 134 } 135 else 136 { 137 r -= 1; 138 v = mem_get_qi (r | 0xf0000); 139 } 140 set_reg (o->reg, r); 141 break; 142 143 case RL78_Operand_PostInc: 144 tprintf (" [%s++]", reg_names[o->reg]); 145 r = get_reg (o->reg); 146 if (rd->size == RL78_Word) 147 { 148 v = mem_get_hi (r | 0xf0000); 149 r += 2; 150 } 151 else 152 { 153 v = mem_get_qi (r | 0xf0000); 154 r += 1; 155 } 156 set_reg (o->reg, r); 157 break; 158 159 default: 160 abort (); 161 } 162 tprintf ("%d", v); 163 return v; 164 } 165 166 static void 167 put_op (const RL78_Opcode_Decoded *rd, int i, int for_data, int v) 168 { 169 int r, a; 170 const RL78_Opcode_Operand *o = rd->op + i; 171 172 tprintf (" -> "); 173 174 switch (o->type) 175 { 176 case RL78_Operand_Register: 177 tprintf ("%s", reg_names[o->reg]); 178 set_reg (o->reg, v); 179 break; 180 181 case RL78_Operand_Bit: 182 tprintf ("%s.%d", reg_names[o->reg], o->bit_number); 183 r = get_reg (o->reg); 184 if (v) 185 r |= (1 << o->bit_number); 186 else 187 r &= ~(1 << o->bit_number); 188 set_reg (o->reg, r); 189 break; 190 191 case RL78_Operand_Indirect: 192 r = op_addr (o, for_data); 193 tprintf ("[0x%x]", r); 194 if (rd->size == RL78_Word) 195 mem_put_hi (r, v); 196 else 197 mem_put_qi (r, v); 198 break; 199 200 case RL78_Operand_BitIndirect: 201 a = op_addr (o, for_data); 202 tprintf ("[0x%x].%d", a, o->bit_number); 203 r = mem_get_qi (a); 204 if (v) 205 r |= (1 << o->bit_number); 206 else 207 r &= ~(1 << o->bit_number); 208 mem_put_qi (a, r); 209 break; 210 211 case RL78_Operand_PreDec: 212 r = get_reg (o->reg); 213 tprintf ("[--%s]", reg_names[o->reg]); 214 if (rd->size == RL78_Word) 215 { 216 r -= 2; 217 set_reg (o->reg, r); 218 mem_put_hi (r | 0xf0000, v); 219 } 220 else 221 { 222 r -= 1; 223 set_reg (o->reg, r); 224 mem_put_qi (r | 0xf0000, v); 225 } 226 break; 227 228 case RL78_Operand_PostInc: 229 tprintf ("[%s++]", reg_names[o->reg]); 230 r = get_reg (o->reg); 231 if (rd->size == RL78_Word) 232 { 233 mem_put_hi (r | 0xf0000, v); 234 r += 2; 235 } 236 else 237 { 238 mem_put_qi (r | 0xf0000, v); 239 r += 1; 240 } 241 set_reg (o->reg, r); 242 break; 243 244 default: 245 abort (); 246 } 247 tprintf ("\n"); 248 } 249 250 static void 251 op_flags (int before, int after, int mask, RL78_Size size) 252 { 253 int vmask, cmask, amask, avmask; 254 int psw; 255 256 if (size == RL78_Word) 257 { 258 cmask = 0x10000; 259 vmask = 0xffff; 260 amask = 0x100; 261 avmask = 0x0ff; 262 } 263 else 264 { 265 cmask = 0x100; 266 vmask = 0xff; 267 amask = 0x10; 268 avmask = 0x0f; 269 } 270 271 psw = get_reg (RL78_Reg_PSW); 272 psw &= ~mask; 273 274 if (mask & RL78_PSW_CY) 275 { 276 if ((after & cmask) != (before & cmask)) 277 psw |= RL78_PSW_CY; 278 } 279 if (mask & RL78_PSW_AC) 280 { 281 if ((after & amask) != (before & amask) 282 && (after & avmask) < (before & avmask)) 283 psw |= RL78_PSW_AC; 284 } 285 if (mask & RL78_PSW_Z) 286 { 287 if (! (after & vmask)) 288 psw |= RL78_PSW_Z; 289 } 290 291 set_reg (RL78_Reg_PSW, psw); 292 } 293 294 #define FLAGS(before,after) if (opcode.flags) op_flags (before, after, opcode.flags, opcode.size) 295 296 #define PD(x) put_op (&opcode, 0, 1, x) 297 #define PS(x) put_op (&opcode, 1, 1, x) 298 #define GD() get_op (&opcode, 0, 1) 299 #define GS() get_op (&opcode, 1, 1) 300 301 #define GPC() gpc (&opcode, 0) 302 static int 303 gpc (RL78_Opcode_Decoded *opcode, int idx) 304 { 305 int a = get_op (opcode, 0, 1); 306 if (opcode->op[idx].type == RL78_Operand_Register) 307 a =(a & 0x0ffff) | ((get_reg (RL78_Reg_CS) & 0x0f) << 16); 308 else 309 a &= 0xfffff; 310 return a; 311 } 312 313 static int 314 get_carry (void) 315 { 316 return (get_reg (RL78_Reg_PSW) & RL78_PSW_CY) ? 1 : 0; 317 } 318 319 static void 320 set_carry (int c) 321 { 322 int p = get_reg (RL78_Reg_PSW); 323 tprintf ("set_carry (%d)\n", c ? 1 : 0); 324 if (c) 325 p |= RL78_PSW_CY; 326 else 327 p &= ~RL78_PSW_CY; 328 set_reg (RL78_Reg_PSW, p); 329 } 330 331 /* We simulate timer TM00 in interval mode, no clearing, with 332 interrupts. I.e. it's a cycle counter. */ 333 334 unsigned int counts_per_insn[0x100000]; 335 336 int pending_clocks = 0; 337 long long total_clocks = 0; 338 339 #define TCR0 0xf0180 340 #define MK1 0xfffe6 341 static void 342 process_clock_tick (void) 343 { 344 unsigned short cnt; 345 unsigned short ivect; 346 unsigned short mask; 347 unsigned char psw; 348 int save_trace; 349 350 save_trace = trace; 351 trace = 0; 352 353 pending_clocks ++; 354 355 counts_per_insn[opcode_pc] += pending_clocks; 356 total_clocks += pending_clocks; 357 358 while (pending_clocks) 359 { 360 pending_clocks --; 361 cnt = mem_get_hi (TCR0); 362 cnt --; 363 mem_put_hi (TCR0, cnt); 364 if (cnt != 0xffff) 365 continue; 366 367 /* overflow. */ 368 psw = get_reg (RL78_Reg_PSW); 369 ivect = mem_get_hi (0x0002c); 370 mask = mem_get_hi (MK1); 371 372 if ((psw & RL78_PSW_IE) 373 && (ivect != 0) 374 && !(mask & 0x0010)) 375 { 376 unsigned short sp = get_reg (RL78_Reg_SP); 377 set_reg (RL78_Reg_SP, sp - 4); 378 sp --; 379 mem_put_qi (sp | 0xf0000, psw); 380 sp -= 3; 381 mem_put_psi (sp | 0xf0000, pc); 382 psw &= ~RL78_PSW_IE; 383 set_reg (RL78_Reg_PSW, psw); 384 pc = ivect; 385 /* Spec says 9-14 clocks */ 386 pending_clocks += 9; 387 } 388 } 389 390 trace = save_trace; 391 } 392 393 void 394 dump_counts_per_insn (const char * filename) 395 { 396 int i; 397 FILE *f; 398 f = fopen (filename, "w"); 399 if (!f) 400 { 401 perror (filename); 402 return; 403 } 404 for (i = 0; i < 0x100000; i ++) 405 { 406 if (counts_per_insn[i]) 407 fprintf (f, "%05x %d\n", i, counts_per_insn[i]); 408 } 409 fclose (f); 410 } 411 412 static void 413 CLOCKS (int n) 414 { 415 pending_clocks += n - 1; 416 } 417 418 int 419 decode_opcode (void) 420 { 421 RL78_Data rl78_data; 422 RL78_Opcode_Decoded opcode; 423 int opcode_size; 424 int a, b, v, v2; 425 unsigned int u, u2; 426 int obits; 427 RL78_Dis_Isa isa; 428 429 isa = (rl78_g10_mode ? RL78_ISA_G10 430 : g14_multiply ? RL78_ISA_G14 431 : g13_multiply ? RL78_ISA_G13 432 : RL78_ISA_DEFAULT); 433 434 rl78_data.dpc = pc; 435 opcode_size = rl78_decode_opcode (pc, &opcode, 436 rl78_get_byte, &rl78_data, isa); 437 438 opcode_pc = pc; 439 pc += opcode_size; 440 441 trace_register_words = opcode.size == RL78_Word ? 1 : 0; 442 443 /* Used by shfit/rotate instructions */ 444 obits = opcode.size == RL78_Word ? 16 : 8; 445 446 switch (opcode.id) 447 { 448 case RLO_add: 449 tprintf ("ADD: "); 450 a = GS (); 451 b = GD (); 452 v = a + b; 453 FLAGS (b, v); 454 PD (v); 455 if (opcode.op[0].type == RL78_Operand_Indirect) 456 CLOCKS (2); 457 break; 458 459 case RLO_addc: 460 tprintf ("ADDC: "); 461 a = GS (); 462 b = GD (); 463 v = a + b + get_carry (); 464 FLAGS (b, v); 465 PD (v); 466 if (opcode.op[0].type == RL78_Operand_Indirect) 467 CLOCKS (2); 468 break; 469 470 case RLO_and: 471 tprintf ("AND: "); 472 a = GS (); 473 b = GD (); 474 v = a & b; 475 FLAGS (b, v); 476 PD (v); 477 if (opcode.op[0].type == RL78_Operand_Indirect) 478 CLOCKS (2); 479 break; 480 481 case RLO_branch_cond: 482 case RLO_branch_cond_clear: 483 tprintf ("BRANCH_COND: "); 484 if (!condition_true (opcode.op[1].condition, GS ())) 485 { 486 tprintf (" false\n"); 487 if (opcode.op[1].condition == RL78_Condition_T 488 || opcode.op[1].condition == RL78_Condition_F) 489 CLOCKS (3); 490 else 491 CLOCKS (2); 492 break; 493 } 494 if (opcode.id == RLO_branch_cond_clear) 495 PS (0); 496 tprintf (" "); 497 if (opcode.op[1].condition == RL78_Condition_T 498 || opcode.op[1].condition == RL78_Condition_F) 499 CLOCKS (3); /* note: adds two clocks, total 5 clocks */ 500 else 501 CLOCKS (2); /* note: adds one clock, total 4 clocks */ 502 ATTRIBUTE_FALLTHROUGH; 503 case RLO_branch: 504 tprintf ("BRANCH: "); 505 v = GPC (); 506 WILD_JUMP_CHECK (v); 507 pc = v; 508 tprintf (" => 0x%05x\n", pc); 509 CLOCKS (3); 510 break; 511 512 case RLO_break: 513 tprintf ("BRK: "); 514 CLOCKS (5); 515 if (rl78_in_gdb) 516 DO_RETURN (RL78_MAKE_HIT_BREAK ()); 517 else 518 DO_RETURN (RL78_MAKE_EXITED (1)); 519 break; 520 521 case RLO_call: 522 tprintf ("CALL: "); 523 a = get_reg (RL78_Reg_SP); 524 set_reg (RL78_Reg_SP, a - 4); 525 mem_put_psi ((a - 4) | 0xf0000, pc); 526 v = GPC (); 527 WILD_JUMP_CHECK (v); 528 pc = v; 529 #if 0 530 /* Enable this code to dump the arguments for each call. */ 531 if (trace) 532 { 533 int i; 534 skip_init ++; 535 for (i = 0; i < 8; i ++) 536 printf (" %02x", mem_get_qi (0xf0000 | (a + i)) & 0xff); 537 skip_init --; 538 } 539 #endif 540 tprintf ("\n"); 541 CLOCKS (3); 542 break; 543 544 case RLO_cmp: 545 tprintf ("CMP: "); 546 a = GD (); 547 b = GS (); 548 v = a - b; 549 FLAGS (b, v); 550 tprintf (" (%d)\n", v); 551 break; 552 553 case RLO_divhu: 554 a = get_reg (RL78_Reg_AX); 555 b = get_reg (RL78_Reg_DE); 556 tprintf (" %d / %d = ", a, b); 557 if (b == 0) 558 { 559 tprintf ("%d rem %d\n", 0xffff, a); 560 set_reg (RL78_Reg_AX, 0xffff); 561 set_reg (RL78_Reg_DE, a); 562 } 563 else 564 { 565 v = a / b; 566 a = a % b; 567 tprintf ("%d rem %d\n", v, a); 568 set_reg (RL78_Reg_AX, v); 569 set_reg (RL78_Reg_DE, a); 570 } 571 CLOCKS (9); 572 break; 573 574 case RLO_divwu: 575 { 576 unsigned long bcax, hlde, quot, rem; 577 bcax = get_reg (RL78_Reg_AX) + 65536 * get_reg (RL78_Reg_BC); 578 hlde = get_reg (RL78_Reg_DE) + 65536 * get_reg (RL78_Reg_HL); 579 580 tprintf (" %lu / %lu = ", bcax, hlde); 581 if (hlde == 0) 582 { 583 tprintf ("%lu rem %lu\n", 0xffffLU, bcax); 584 set_reg (RL78_Reg_AX, 0xffffLU); 585 set_reg (RL78_Reg_BC, 0xffffLU); 586 set_reg (RL78_Reg_DE, bcax); 587 set_reg (RL78_Reg_HL, bcax >> 16); 588 } 589 else 590 { 591 quot = bcax / hlde; 592 rem = bcax % hlde; 593 tprintf ("%lu rem %lu\n", quot, rem); 594 set_reg (RL78_Reg_AX, quot); 595 set_reg (RL78_Reg_BC, quot >> 16); 596 set_reg (RL78_Reg_DE, rem); 597 set_reg (RL78_Reg_HL, rem >> 16); 598 } 599 } 600 CLOCKS (17); 601 break; 602 603 case RLO_halt: 604 tprintf ("HALT.\n"); 605 DO_RETURN (RL78_MAKE_EXITED (get_reg (RL78_Reg_A))); 606 607 case RLO_mov: 608 tprintf ("MOV: "); 609 a = GS (); 610 FLAGS (a, a); 611 PD (a); 612 break; 613 614 #define MACR 0xffff0 615 case RLO_mach: 616 tprintf ("MACH:"); 617 a = sign_ext (get_reg (RL78_Reg_AX), 16); 618 b = sign_ext (get_reg (RL78_Reg_BC), 16); 619 v = sign_ext (mem_get_si (MACR), 32); 620 tprintf ("%08x %d + %d * %d = ", v, v, a, b); 621 v2 = sign_ext (v + a * b, 32); 622 tprintf ("%08x %d\n", v2, v2); 623 mem_put_si (MACR, v2); 624 a = get_reg (RL78_Reg_PSW); 625 v ^= v2; 626 if (v & (1<<31)) 627 a |= RL78_PSW_CY; 628 else 629 a &= ~RL78_PSW_CY; 630 if (v2 & (1 << 31)) 631 a |= RL78_PSW_AC; 632 else 633 a &= ~RL78_PSW_AC; 634 set_reg (RL78_Reg_PSW, a); 635 CLOCKS (3); 636 break; 637 638 case RLO_machu: 639 tprintf ("MACHU:"); 640 a = get_reg (RL78_Reg_AX); 641 b = get_reg (RL78_Reg_BC); 642 u = mem_get_si (MACR); 643 tprintf ("%08x %u + %u * %u = ", u, u, a, b); 644 u2 = (u + (unsigned)a * (unsigned)b) & 0xffffffffUL; 645 tprintf ("%08x %u\n", u2, u2); 646 mem_put_si (MACR, u2); 647 a = get_reg (RL78_Reg_PSW); 648 if (u2 < u) 649 a |= RL78_PSW_CY; 650 else 651 a &= ~RL78_PSW_CY; 652 a &= ~RL78_PSW_AC; 653 set_reg (RL78_Reg_PSW, a); 654 CLOCKS (3); 655 break; 656 657 case RLO_mulu: 658 tprintf ("MULU:"); 659 a = get_reg (RL78_Reg_A); 660 b = get_reg (RL78_Reg_X); 661 v = a * b; 662 tprintf (" %d * %d = %d\n", a, b, v); 663 set_reg (RL78_Reg_AX, v); 664 break; 665 666 case RLO_mulh: 667 tprintf ("MUL:"); 668 a = sign_ext (get_reg (RL78_Reg_AX), 16); 669 b = sign_ext (get_reg (RL78_Reg_BC), 16); 670 v = a * b; 671 tprintf (" %d * %d = %d\n", a, b, v); 672 set_reg (RL78_Reg_BC, v >> 16); 673 set_reg (RL78_Reg_AX, v); 674 CLOCKS (2); 675 break; 676 677 case RLO_mulhu: 678 tprintf ("MULHU:"); 679 a = get_reg (RL78_Reg_AX); 680 b = get_reg (RL78_Reg_BC); 681 v = a * b; 682 tprintf (" %d * %d = %d\n", a, b, v); 683 set_reg (RL78_Reg_BC, v >> 16); 684 set_reg (RL78_Reg_AX, v); 685 CLOCKS (2); 686 break; 687 688 case RLO_nop: 689 tprintf ("NOP.\n"); 690 break; 691 692 case RLO_or: 693 tprintf ("OR:"); 694 a = GS (); 695 b = GD (); 696 v = a | b; 697 FLAGS (b, v); 698 PD (v); 699 if (opcode.op[0].type == RL78_Operand_Indirect) 700 CLOCKS (2); 701 break; 702 703 case RLO_ret: 704 tprintf ("RET: "); 705 a = get_reg (RL78_Reg_SP); 706 v = mem_get_psi (a | 0xf0000); 707 WILD_JUMP_CHECK (v); 708 pc = v; 709 set_reg (RL78_Reg_SP, a + 4); 710 #if 0 711 /* Enable this code to dump the return values for each return. */ 712 if (trace) 713 { 714 int i; 715 skip_init ++; 716 for (i = 0; i < 8; i ++) 717 printf (" %02x", mem_get_qi (0xffef0 + i) & 0xff); 718 skip_init --; 719 } 720 #endif 721 tprintf ("\n"); 722 CLOCKS (6); 723 break; 724 725 case RLO_reti: 726 tprintf ("RETI: "); 727 a = get_reg (RL78_Reg_SP); 728 v = mem_get_psi (a | 0xf0000); 729 WILD_JUMP_CHECK (v); 730 pc = v; 731 b = mem_get_qi ((a + 3) | 0xf0000); 732 set_reg (RL78_Reg_PSW, b); 733 set_reg (RL78_Reg_SP, a + 4); 734 tprintf ("\n"); 735 break; 736 737 case RLO_rol: 738 tprintf ("ROL:"); /* d <<= s */ 739 a = GS (); 740 b = GD (); 741 v = b; 742 while (a --) 743 { 744 v = b << 1; 745 v |= (b >> (obits - 1)) & 1; 746 set_carry ((b >> (obits - 1)) & 1); 747 b = v; 748 } 749 PD (v); 750 break; 751 752 case RLO_rolc: 753 tprintf ("ROLC:"); /* d <<= s */ 754 a = GS (); 755 b = GD (); 756 v = b; 757 while (a --) 758 { 759 v = b << 1; 760 v |= get_carry (); 761 set_carry ((b >> (obits - 1)) & 1); 762 b = v; 763 } 764 PD (v); 765 break; 766 767 case RLO_ror: 768 tprintf ("ROR:"); /* d >>= s */ 769 a = GS (); 770 b = GD (); 771 v = b; 772 while (a --) 773 { 774 v = b >> 1; 775 v |= (b & 1) << (obits - 1); 776 set_carry (b & 1); 777 b = v; 778 } 779 PD (v); 780 break; 781 782 case RLO_rorc: 783 tprintf ("RORC:"); /* d >>= s */ 784 a = GS (); 785 b = GD (); 786 v = b; 787 while (a --) 788 { 789 v = b >> 1; 790 v |= (get_carry () << (obits - 1)); 791 set_carry (b & 1); 792 b = v; 793 } 794 PD (v); 795 break; 796 797 case RLO_sar: 798 tprintf ("SAR:"); /* d >>= s */ 799 a = GS (); 800 b = GD (); 801 v = b; 802 while (a --) 803 { 804 v = b >> 1; 805 v |= b & (1 << (obits - 1)); 806 set_carry (b & 1); 807 b = v; 808 } 809 PD (v); 810 break; 811 812 case RLO_sel: 813 tprintf ("SEL:"); 814 a = GS (); 815 b = get_reg (RL78_Reg_PSW); 816 b &= ~(RL78_PSW_RBS1 | RL78_PSW_RBS0); 817 if (a & 1) 818 b |= RL78_PSW_RBS0; 819 if (a & 2) 820 b |= RL78_PSW_RBS1; 821 set_reg (RL78_Reg_PSW, b); 822 tprintf ("\n"); 823 break; 824 825 case RLO_shl: 826 tprintf ("SHL%d:", obits); /* d <<= s */ 827 a = GS (); 828 b = GD (); 829 v = b; 830 while (a --) 831 { 832 v = b << 1; 833 tprintf ("b = 0x%x & 0x%x\n", b, 1<<(obits - 1)); 834 set_carry (b & (1<<(obits - 1))); 835 b = v; 836 } 837 PD (v); 838 break; 839 840 case RLO_shr: 841 tprintf ("SHR:"); /* d >>= s */ 842 a = GS (); 843 b = GD (); 844 v = b; 845 while (a --) 846 { 847 v = b >> 1; 848 set_carry (b & 1); 849 b = v; 850 } 851 PD (v); 852 break; 853 854 case RLO_skip: 855 tprintf ("SKIP: "); 856 if (!condition_true (opcode.op[1].condition, GS ())) 857 { 858 tprintf (" false\n"); 859 break; 860 } 861 862 rl78_data.dpc = pc; 863 opcode_size = rl78_decode_opcode (pc, &opcode, 864 rl78_get_byte, &rl78_data, isa); 865 pc += opcode_size; 866 tprintf (" skipped: %s\n", opcode.syntax); 867 break; 868 869 case RLO_stop: 870 tprintf ("STOP.\n"); 871 DO_RETURN (RL78_MAKE_EXITED (get_reg (RL78_Reg_A))); 872 DO_RETURN (RL78_MAKE_HIT_BREAK ()); 873 874 case RLO_sub: 875 tprintf ("SUB: "); 876 a = GS (); 877 b = GD (); 878 v = b - a; 879 FLAGS (b, v); 880 PD (v); 881 tprintf ("%d (0x%x) - %d (0x%x) = %d (0x%x)\n", b, b, a, a, v, v); 882 if (opcode.op[0].type == RL78_Operand_Indirect) 883 CLOCKS (2); 884 break; 885 886 case RLO_subc: 887 tprintf ("SUBC: "); 888 a = GS (); 889 b = GD (); 890 v = b - a - get_carry (); 891 FLAGS (b, v); 892 PD (v); 893 if (opcode.op[0].type == RL78_Operand_Indirect) 894 CLOCKS (2); 895 break; 896 897 case RLO_xch: 898 tprintf ("XCH: "); 899 a = GS (); 900 b = GD (); 901 PD (a); 902 PS (b); 903 break; 904 905 case RLO_xor: 906 tprintf ("XOR:"); 907 a = GS (); 908 b = GD (); 909 v = a ^ b; 910 FLAGS (b, v); 911 PD (v); 912 if (opcode.op[0].type == RL78_Operand_Indirect) 913 CLOCKS (2); 914 break; 915 916 default: 917 tprintf ("Unknown opcode?\n"); 918 DO_RETURN (RL78_MAKE_HIT_BREAK ()); 919 } 920 921 if (timer_enabled) 922 process_clock_tick (); 923 924 return RL78_MAKE_STEPPED (); 925 } 926