rl78.c 19 KB

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