root/src/exec.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pr2str
  2. svcin
  3. svcout
  4. setfr
  5. get_r_r1
  6. get_x_r2
  7. get_adr_x
  8. get_val_adr_x
  9. addcerrlist_exec
  10. nop
  11. ld_r_adr_x
  12. ld_r1_r2
  13. st
  14. lad
  15. adda
  16. adda_r_adr_x
  17. adda_r1_r2
  18. suba_r_adr_x
  19. suba_r1_r2
  20. addl_gr
  21. addl_r_adr_x
  22. addl_r1_r2
  23. subl_r_adr_x
  24. subl_r1_r2
  25. and_r_adr_x
  26. and_r1_r2
  27. or_r_adr_x
  28. or_r1_r2
  29. xor_r_adr_x
  30. xor_r1_r2
  31. cpa
  32. cpa_r_adr_x
  33. cpa_r1_r2
  34. cpl
  35. cpl_r_adr_x
  36. cpl_r1_r2
  37. sla
  38. sra
  39. sll
  40. srl
  41. jpl
  42. jmi
  43. jnz
  44. jze
  45. jov
  46. jump
  47. push
  48. pop
  49. call
  50. ret
  51. svc
  52. exec

   1 #include "exec.h"
   2 
   3 /**
   4  * @brief プログラムレジスタ(PR)を表すWORD値を文字列に変換
   5  *
   6  * @return 文字列「PR:XXXX」(Xは16進数の数字)
   7  *
   8  * @param pr プログラムレジスタ(PR)を表すWORD値
   9  */
  10 char *pr2str(WORD pr);
  11 
  12 /**
  13  * @brief 標準入力から文字データを読込(SVC 1)
  14  *
  15  * @return なし
  16  */
  17 void svcin();
  18 
  19 /**
  20  * @brief 標準出力へ文字データを書出(SVC 2)
  21  *
  22  * @return なし
  23  */
  24 void svcout();
  25 
  26 /**
  27  * @brief ロード/論理積/論理和/排他的論理和のフラグ設定。OFは常に0
  28  *
  29  * @return なし
  30  *
  31  * @param adr アドレス
  32  */
  33 void setfr(WORD adr);
  34 
  35 /**
  36  * @brief WORD値からr/r1を取得
  37  *
  38  * @return r/r1を表すWORD値
  39  *
  40  * @param oprx オペランドを表すWORD値
  41  */
  42 WORD get_r_r1(WORD oprx);
  43 
  44 /**
  45  * @brief WORD値からx/r2を取得
  46  *
  47  * @return x/r2を表すWORD値
  48  *
  49  * @param oprx オペランドを表すWORD値
  50  */
  51 WORD get_x_r2(WORD oprx);
  52 
  53 /**
  54  * @brief 2つのWORD値からadr[,x]を取得
  55  *
  56  * @return adr[,x]を表すWORD値
  57  *
  58  * @param adr アドレスを表すWORD値
  59  * @param oprx オペランドを表すWORD値
  60  */
  61 WORD get_adr_x(WORD adr, WORD oprx);
  62 
  63 /**
  64  * @brief 2つのWORD値からadr[,x]のアドレスに格納されている値を取得
  65  *
  66  * @return adr[,x]のアドレスに格納されている値を表すWORD値
  67  *
  68  * @param adr アドレスを表すWORD値
  69  * @param oprx オペランドを表すWORD値
  70  */
  71 WORD get_val_adr_x(WORD adr, WORD oprx);
  72 
  73 /**
  74  * @brief 実行エラーの定義
  75  */
  76 static CERR cerr_exec[] = {
  77     { 201, "Program Register (PR) - memory overflow" },
  78     { 202, "Stack Pointer (SP) - stack overflow" },
  79     { 203, "Stack Pointer (SP) - stack underflow" },
  80     { 204, "OP in word #1 - not command code" },
  81     { 205, "r/r1 in word #1 - not GR" },
  82     { 206, "x/r2 in word #1 - not GR" },
  83     { 207, "address in word #2 - out of memory" },
  84     { 208, "SVC input - memory overflow" },
  85     { 209, "SVC output - memory overflow" },
  86 };
  87 
  88 /**
  89  * @brief 実行モード: trace, logical, dump, dump_start, dump_end,  monitor, step
  90  */
  91 EXECMODE execmode = {false, false, false, 0, 0xFFFF, false, false};
  92 
  93 char *pr2str(WORD pr)
  94 {
  95     char *str = malloc_chk(CERRSTRSIZE + 1, "pr2str.pr");
  96 
  97     sprintf(str, "PR:#%04X", pr);
  98     return str;
  99 }
 100 
 101 void svcin()
 102 {
 103     int i;
 104     char *buf = malloc_chk(INSIZE + 1, "svcin.buf");
 105 
 106     if(fgets(buf, INSIZE, stdin) == NULL) {
 107         sys->memory[sys->cpu->gr[1]] = sys->memory[sys->cpu->gr[2]] = 0x0;
 108         return;
 109     }
 110     for(i = 0; i < INSIZE; i++) {
 111         if(!buf[i] || buf[i] == '\n') {
 112             --i;
 113             break;
 114         }
 115         if(sys->cpu->gr[1] + i > execptr->end) {
 116             setcerr(208, "");    /* SVC input - memory overflow */
 117             break;
 118         }
 119         sys->memory[sys->cpu->gr[1] + i] = buf[i];
 120     }
 121     sys->memory[sys->cpu->gr[2]] = i + 1;
 122     FREE(buf);
 123 }
 124 
 125 void svcout()
 126 {
 127     int i;
 128     WORD w;
 129 
 130     for(i = 0; i < sys->memory[sys->cpu->gr[2]]; i++) {
 131         if(sys->cpu->gr[1] + i > execptr->end) {
 132             setcerr(209, "");    /* SVC output - memory overflow */
 133             return;
 134         }
 135         /* 「JIS X 0201ラテン文字・片仮名用8ビット符号で規定する文字の符号表」
 136            に記載された文字と、改行(CR)/タブを表示 */
 137         /* それ以外の文字は、「.」で表す */
 138         if(((w = sys->memory[sys->cpu->gr[1]+i]) >= 0x20 && w <= 0x7E) ||    /* JIS X 0201ラテン文字 */
 139            (w >= 0xA0 && w <= 0xFE) ||                                       /* JIS X 0201片仮名用8ビット符号 */
 140            w == 0xA || w == '\t')
 141         {
 142             putchar((char)w);
 143         } else {
 144             putchar('.');
 145         }
 146     }
 147 }
 148 
 149 void setfr(WORD adr)
 150 {
 151     sys->cpu->fr = 0x0;
 152     /* 第15ビットが1のとき、SFは1 */
 153     if((adr & 0x8000) == 0x8000) {
 154         sys->cpu->fr += SF;
 155     }
 156     /* 演算結果が0のとき、ZFは1 */
 157     if(adr == 0x0) {
 158         sys->cpu->fr += ZF;
 159     }
 160 }
 161 
 162 WORD get_r_r1(WORD oprx)
 163 {
 164     WORD r = 0;
 165     char *s = NULL;
 166 
 167     if((r = ((oprx & 0x00F0) >>4)) > GRSIZE - 1) {
 168         setcerr(205, s = pr2str(sys->cpu->pr));    /* r/r1 in word #1 - not GR */
 169         FREE(s);
 170         return 0x0;
 171     }
 172     return r;
 173 }
 174 
 175 WORD get_x_r2(WORD oprx)
 176 {
 177     WORD x = 0;
 178     char *s = NULL;
 179 
 180     if((x = (oprx & 0x000F)) > GRSIZE - 1) {
 181         setcerr(206, s = pr2str(sys->cpu->pr));    /* r/r1 in word #1 - not GR */
 182         FREE(s);
 183         return 0x0;
 184     }
 185     return x;
 186 }
 187 
 188 WORD get_adr_x(WORD adr, WORD oprx)
 189 {
 190     WORD a = adr;
 191     WORD x = get_x_r2(oprx);
 192 
 193     if(x > 0) {
 194         a += sys->cpu->gr[x];
 195     }
 196     return a;
 197 }
 198 
 199 WORD get_val_adr_x(WORD adr, WORD oprx)
 200 {
 201     WORD a = 0;
 202     char *s = NULL;
 203 
 204     if((a = get_adr_x(adr, oprx)) >= sys->memsize) {
 205         setcerr(207, s = pr2str(sys->cpu->pr + 1));    /* address in word #2 - out of memory */
 206         FREE(s);
 207         return 0x0;
 208     }
 209     return sys->memory[a];
 210 }
 211 
 212 /* exec.hで定義された関数群 */
 213 void addcerrlist_exec()
 214 {
 215     addcerrlist(ARRAYSIZE(cerr_exec), cerr_exec);
 216 }
 217 
 218 void nop()
 219 {
 220     sys->cpu->pr += 1;
 221 }
 222 
 223 void ld_r_adr_x()
 224 {
 225     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 226     setfr(sys->cpu->gr[get_r_r1(w[0])] = get_val_adr_x(w[1], w[0]));
 227     sys->cpu->pr += 2;
 228 }
 229 
 230 void ld_r1_r2()
 231 {
 232     WORD w[] = {sys->memory[sys->cpu->pr]};
 233     setfr(sys->cpu->gr[get_r_r1(w[0])] = sys->cpu->gr[get_x_r2(w[0])]);
 234     sys->cpu->pr += 1;
 235 }
 236 
 237 void st()
 238 {
 239     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 240     sys->memory[get_adr_x(w[1], w[0])] = sys->cpu->gr[get_r_r1(w[0])];
 241     sys->cpu->pr += 2;
 242 }
 243 
 244 void lad()
 245 {
 246     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 247     sys->cpu->gr[get_r_r1(w[0])] = get_adr_x(w[1], w[0]);
 248     sys->cpu->pr += 2;
 249 }
 250 
 251 void adda(WORD r, WORD val)
 252 {
 253     long tmp;
 254 
 255     sys->cpu->fr = 0x0;
 256     /* 引数の値を16ビット符号付整数として加算し、オーバーフローをチェック */
 257     assert(sizeof(short) * 8 == 16 && (short)0xFFFF == -1);
 258     if((tmp = (short)(sys->cpu->gr[r]) + (short)val) > 32767 || tmp < -32768) {
 259         sys->cpu->fr += OF;
 260     }
 261     /* 加算した結果を、WORD値に戻す */
 262     sys->cpu->gr[r] = (WORD)(tmp & 0xFFFF);
 263     if((sys->cpu->gr[r] & 0x8000) == 0x8000) {
 264         sys->cpu->fr += SF;
 265     } else if(sys->cpu->gr[r] == 0x0) {
 266         sys->cpu->fr += ZF;
 267     }
 268 }
 269 
 270 void adda_r_adr_x()
 271 {
 272     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 273     adda(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]));
 274     sys->cpu->pr += 2;
 275 }
 276 
 277 void adda_r1_r2()
 278 {
 279     WORD w[] = {sys->memory[sys->cpu->pr]};
 280     adda(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])]);
 281     sys->cpu->pr += 1;
 282 }
 283 
 284 void suba_r_adr_x()
 285 {
 286     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 287     adda(get_r_r1(w[0]), ~(get_val_adr_x(w[1], w[0])) + 1);
 288     sys->cpu->pr += 2;
 289 }
 290 
 291 void suba_r1_r2()
 292 {
 293     WORD w[] = {sys->memory[sys->cpu->pr]};
 294     adda(get_r_r1(w[0]), ~(sys->cpu->gr[get_x_r2(w[0])]) + 1);
 295     sys->cpu->pr += 1;
 296 }
 297 
 298 void addl_gr(WORD r, WORD val, bool add)
 299 {
 300     unsigned long o = 0;
 301     unsigned long s = 0;
 302 
 303     o = sys->cpu->gr[r];
 304     sys->cpu->fr = 0;    /* flag initialize */
 305 
 306     if(add == true) {
 307         s = o + val;
 308         if(s > 0xFFFF) {
 309             sys->cpu->fr += OF;
 310         }
 311     } else {
 312         if(o < val) {
 313             sys->cpu->fr += OF;
 314         }
 315         s = o + (~val + 1);
 316         if(s > 0xFFFF) {
 317             s &= 0xFFFF;
 318         }
 319     }
 320     sys->cpu->gr[r] = (WORD)s;
 321 
 322     if((s & 0x8000) == 0x8000) {
 323         sys->cpu->fr += SF;
 324     }
 325     else if(s == 0x0) {
 326         sys->cpu->fr += ZF;
 327     }
 328 }
 329 
 330 void addl_r_adr_x()
 331 {
 332     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 333     addl_gr(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]), true);
 334     sys->cpu->pr += 2;
 335 }
 336 
 337 void addl_r1_r2()
 338 {
 339     WORD w[] = {sys->memory[sys->cpu->pr]};
 340     addl_gr(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])], true);
 341     sys->cpu->pr += 1;
 342 }
 343 
 344 void subl_r_adr_x()
 345 {
 346     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 347     addl_gr(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]), false);
 348     sys->cpu->pr += 2;
 349 }
 350 
 351 void subl_r1_r2()
 352 {
 353     WORD w[] = {sys->memory[sys->cpu->pr]};
 354     addl_gr(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])], false);
 355     sys->cpu->pr += 1;
 356 }
 357 
 358 void and_r_adr_x()
 359 {
 360     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 361     setfr(sys->cpu->gr[get_r_r1(w[0])] &= get_val_adr_x(w[1], w[0]));
 362     sys->cpu->pr += 2;
 363 }
 364 
 365 void and_r1_r2()
 366 {
 367     WORD w[] = {sys->memory[sys->cpu->pr]};
 368     setfr(sys->cpu->gr[get_r_r1(w[0])] &= sys->cpu->gr[get_x_r2(w[0])]);
 369     sys->cpu->pr += 1;
 370 }
 371 
 372 void or_r_adr_x()
 373 {
 374     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 375     setfr(sys->cpu->gr[get_r_r1(w[0])] |= get_val_adr_x(w[1], w[0]));
 376     sys->cpu->pr += 2;
 377 }
 378 
 379 void or_r1_r2()
 380 {
 381     WORD w[] = {sys->memory[sys->cpu->pr]};
 382     setfr(sys->cpu->gr[get_r_r1(w[0])] |= sys->cpu->gr[get_x_r2(w[0])]);
 383     sys->cpu->pr += 1;
 384 }
 385 
 386 void xor_r_adr_x()
 387 {
 388     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 389     setfr(sys->cpu->gr[get_r_r1(w[0])] ^= get_val_adr_x(w[1], w[0]));
 390     sys->cpu->pr += 2;
 391 }
 392 
 393 void xor_r1_r2()
 394 {
 395     WORD w[] = {sys->memory[sys->cpu->pr]};
 396     setfr(sys->cpu->gr[get_r_r1(w[0])] ^= sys->cpu->gr[get_x_r2(w[0])]);
 397     sys->cpu->pr += 1;
 398 }
 399 
 400 void cpa(WORD r, WORD val)
 401 {
 402     sys->cpu->fr = 0;
 403     if((short)sys->cpu->gr[r] < (short)val) {
 404         sys->cpu->fr = SF;
 405     } else if(sys->cpu->gr[r] == val) {
 406         sys->cpu->fr = ZF;
 407     }
 408 }
 409 
 410 void cpa_r_adr_x()
 411 {
 412     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 413     cpa(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]));
 414     sys->cpu->pr += 2;
 415 }
 416 
 417 void cpa_r1_r2()
 418 {
 419     WORD w[] = {sys->memory[sys->cpu->pr]};
 420     cpa(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])]);
 421     sys->cpu->pr += 1;
 422 }
 423 
 424 void cpl(WORD r, WORD val)
 425 {
 426     sys->cpu->fr = 0x0;
 427     if(sys->cpu->gr[r] < val) {
 428         sys->cpu->fr = SF;
 429     } else if(sys->cpu->gr[r] == val) {
 430         sys->cpu->fr = ZF;
 431     }
 432 }
 433 
 434 void cpl_r_adr_x()
 435 {
 436     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 437     cpl(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]));
 438     sys->cpu->pr += 2;
 439 }
 440 
 441 void cpl_r1_r2()
 442 {
 443     WORD w[] = {sys->memory[sys->cpu->pr]};
 444     cpl(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])]);
 445     sys->cpu->pr += 1;
 446 }
 447 
 448 void sla()
 449 {
 450     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 451     WORD r = get_r_r1(w[0]);
 452     WORD sign = sys->cpu->gr[r] & 0x8000;
 453     WORD last = 0;
 454 
 455     sys->cpu->fr = 0;
 456     sys->cpu->gr[r] &= 0x7FFF;
 457     for(int i = 0; i < get_adr_x(w[1], w[0]); i++) {
 458         last = sys->cpu->gr[r] & 0x4000;
 459         sys->cpu->gr[r] <<= 1;
 460     }
 461     sys->cpu->gr[r] = sign | (sys->cpu->gr[r] & 0x7FFF);
 462     /* OFに、レジスタから最後に送り出されたビットの値を設定 */
 463     if(last > 0x0) {
 464         sys->cpu->fr += OF;
 465     }
 466     /* 符号(第15ビット)が1のとき、SFは1 */
 467     if(sign > 0x0) {
 468         sys->cpu->fr += SF;
 469     }
 470     /* 演算結果が0のとき、ZFは1 */
 471     if(sys->cpu->gr[r] == 0x0) {
 472         sys->cpu->fr += ZF;
 473     }
 474     sys->cpu->pr += 2;
 475 }
 476 
 477 void sra()
 478 {
 479     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 480     WORD r = get_r_r1(w[0]);
 481     WORD sign = sys->cpu->gr[r] & 0x8000;
 482     WORD last = 0;
 483 
 484     sys->cpu->fr = 0;
 485     sys->cpu->gr[r] &= 0x7FFF;
 486     for(int i = 0; i < get_adr_x(w[1], w[0]); i++) {
 487         last = sys->cpu->gr[r] & 0x1;
 488         sys->cpu->gr[r] >>= 1;
 489         if(sign > 0) {
 490             sys->cpu->gr[r] |= 0x4000;
 491         }
 492     }
 493     sys->cpu->gr[r] = sign | sys->cpu->gr[r];
 494     /* OFに、レジスタから最後に送り出されたビットの値を設定 */
 495     if(last > 0x0) {
 496         sys->cpu->fr += OF;
 497     }
 498     /* 符号(第15ビット)が1のとき、SFは1 */
 499     if(sign > 0x0) {
 500         sys->cpu->fr += SF;
 501     }
 502     /* 演算結果が0のとき、ZFは1 */
 503     if(sys->cpu->gr[r] == 0x0) {
 504         sys->cpu->fr += ZF;
 505     }
 506     sys->cpu->pr += 2;
 507 }
 508 
 509 void sll()
 510 {
 511     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 512     WORD last = 0;
 513     WORD r = get_r_r1(w[0]);
 514 
 515     sys->cpu->fr = 0x0;
 516     for(int i = 0; i < get_adr_x(w[1], w[0]); i++) {
 517         last = sys->cpu->gr[r] & 0x8000;
 518         sys->cpu->gr[r] <<= 1;
 519     }
 520     /* OFに、レジスタから最後に送り出されたビットの値を設定 */
 521     if(last > 0x0) {
 522         sys->cpu->fr += OF;
 523     }
 524     /* 第15ビットが1のとき、SFは1 */
 525     if((sys->cpu->gr[r] & 0x8000) > 0x0) {
 526         sys->cpu->fr += SF;
 527     }
 528     /* 演算結果が0のとき、ZFは1 */
 529     if(sys->cpu->gr[r] == 0x0) {
 530         sys->cpu->fr += ZF;
 531     }
 532     sys->cpu->pr += 2;
 533 }
 534 
 535 void srl()
 536 {
 537     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 538     WORD last = 0;
 539     WORD r = get_r_r1(w[0]);
 540 
 541     sys->cpu->fr = 0x0;
 542     for(int i = 0; i < get_adr_x(w[1], w[0]); i++) {
 543         last = sys->cpu->gr[r] & 0x0001;
 544         sys->cpu->gr[r] >>= 1;
 545     }
 546     /* OFに、レジスタから最後に送り出されたビットの値を設定 */
 547     if(last > 0x0) {
 548         sys->cpu->fr += OF;
 549     }
 550     /* 第15ビットが1のとき、SFは1 */
 551     if((sys->cpu->gr[r] & 0x8000) > 0x0) {
 552         sys->cpu->fr += SF;
 553     }
 554     /* 演算結果が0のとき、ZFは1 */
 555     if(sys->cpu->gr[r] == 0x0) {
 556         sys->cpu->fr += ZF;
 557     }
 558     sys->cpu->pr += 2;
 559 }
 560 
 561 void jpl()
 562 {
 563     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 564     if((sys->cpu->fr & (SF | ZF)) == 0) {
 565         sys->cpu->pr = get_adr_x(w[1], w[0]);
 566     } else {
 567         sys->cpu->pr += 2;
 568     }
 569 }
 570 
 571 void jmi()
 572 {
 573     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 574     if((sys->cpu->fr & SF) > 0) {
 575         sys->cpu->pr = get_adr_x(w[1], w[0]);
 576     } else {
 577         sys->cpu->pr += 2;
 578     }
 579 }
 580 
 581 void jnz()
 582 {
 583     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 584     if((sys->cpu->fr & ZF) == 0) {
 585         sys->cpu->pr = get_adr_x(w[1], w[0]);
 586     } else {
 587         sys->cpu->pr += 2;
 588     }
 589 }
 590 
 591 void jze()
 592 {
 593     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 594     if((sys->cpu->fr & ZF) > 0) {
 595         sys->cpu->pr = get_adr_x(w[1], w[0]);
 596     } else {
 597         sys->cpu->pr += 2;
 598     }
 599 }
 600 
 601 void jov()
 602 {
 603     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 604     if((sys->cpu->fr & OF) > 0) {
 605         sys->cpu->pr = get_adr_x(w[1], w[0]);
 606     } else {
 607         sys->cpu->pr += 2;
 608     }
 609 }
 610 
 611 void jump()
 612 {
 613     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 614     sys->cpu->pr = get_adr_x(w[1], w[0]);
 615 }
 616 
 617 void push()
 618 {
 619     assert(sys->cpu->sp > execptr->end && sys->cpu->sp <= sys->memsize);
 620     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 621     sys->memory[--(sys->cpu->sp)] = get_adr_x(w[1], w[0]);
 622     sys->cpu->pr += 2;
 623 }
 624 
 625 void pop()
 626 {
 627     assert(sys->cpu->sp > execptr->end);
 628     WORD w[] = {sys->memory[sys->cpu->pr]};
 629     char *s = NULL;
 630 
 631     if(sys->cpu->sp >= sys->memsize) {
 632         setcerr(203, s = pr2str(sys->cpu->pr));        /* Stack Pointer (SP) - stack underflow */
 633         FREE(s);
 634     } else {
 635         sys->cpu->gr[get_r_r1(w[0])] = sys->memory[(sys->cpu->sp)++];
 636         sys->cpu->pr += 1;
 637     }
 638 }
 639 
 640 void call()
 641 {
 642     assert(sys->cpu->sp > execptr->end && sys->cpu->sp <= sys->memsize);
 643     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 644     sys->memory[--(sys->cpu->sp)] = sys->cpu->pr + 1;
 645     sys->cpu->pr = get_adr_x(w[1], w[0]);
 646 }
 647 
 648 void ret()
 649 {
 650     assert(sys->cpu->sp <= sys->memsize);
 651     if(sys->cpu->sp == sys->memsize) {
 652         execptr->stop = true;
 653     } else if(sys->cpu->sp < sys->memsize) {
 654         sys->cpu->pr = sys->memory[(sys->cpu->sp)++] + 1;
 655     }
 656 }
 657 
 658 void svc()
 659 {
 660     WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
 661     switch(get_adr_x(w[1], w[0]))
 662     {
 663     case 0x0:                   /* STOP */
 664         execptr->stop = true;
 665         break;
 666     case 0x1:                   /* IN */
 667         svcin();
 668         break;
 669     case 0x2:                   /* OUT */
 670         svcout();
 671         break;
 672     }
 673     sys->cpu->pr += 2;
 674 }
 675 
 676 void exec()
 677 {
 678     clock_t clock_begin = 0;
 679     clock_t clock_end = 0;
 680     void (*cmdptr)() = NULL;
 681     char *s = NULL;
 682     const char *monmsg = "COMET II machine code monitor. Type ? for help.\n";
 683 
 684     create_cmdtable(HASH_CODE);                 /* 命令のコードとタイプがキーのハッシュ表を作成 */
 685 
 686     if(execmode.trace == true) {
 687         fprintf(stdout, "\nExecuting machine codes\n");
 688     }
 689     /* 機械語の実行 */
 690     for (sys->cpu->pr = execptr->start; ; ) {
 691         clock_begin = clock();                     /* クロック周波数設定のため、実行開始時間を格納 */
 692         if(execmode.dump || execmode.trace) {      /* traceまたはdumpオプション指定時、改行を出力 */
 693             if(execmode.trace) {                   /* traceオプション指定時、レジスタを出力 */
 694                 fprintf(stdout, "#%04X: Register::::\n", sys->cpu->pr);
 695                 dspregister();
 696             }
 697             if(execmode.dump) {                    /* dumpオプション指定時、メモリを出力 */
 698                 fprintf(stdout, "#%04X: Memory::::\n", sys->cpu->pr);
 699                 dumpmemory(execmode.dump_start, execmode.dump_end);
 700             }
 701             fprintf(stdout, "\n");
 702         }
 703         /* ステップモードまたはブレークポイントの場合、モニターを起動 */
 704         if(
 705             (execmode.monitor == true && sys->cpu->pr == execptr->start) ||
 706             execmode.step == true || getbps(sys->cpu->pr) == true)
 707         {
 708             if(sys->cpu->pr == execptr->start) {
 709                 fprintf(stdout, "%s", monmsg);
 710             }
 711             monitor();
 712         }
 713         /* プログラムレジスタをチェック */
 714         if(sys->cpu->pr >= sys->memsize) {
 715             setcerr(201, s = pr2str(sys->cpu->pr));        /* Program Register (PR) - memory overflow */
 716             goto execfin;
 717         }
 718         /* スタックポインタをチェック */
 719         if(sys->cpu->sp <= execptr->end) {
 720             setcerr(202, s = pr2str(sys->cpu->pr));        /* Stack Pointer (SP) - stack overflow */
 721             goto execfin;
 722         }
 723         /* コードから命令を取得 */
 724         /* 取得できない場合はエラー終了 */
 725         if((cmdptr = getcmdptr(sys->memory[sys->cpu->pr] & 0xFF00)) == NULL) {
 726             setcerr(204, s = pr2str(sys->cpu->pr));            /* OP in word #1 - not command code */
 727             goto execfin;
 728         }
 729         /* 命令の実行 */
 730         (*cmdptr)();
 731         /* エラー発生時はエラー終了 */
 732         if(cerr->num > 0) {
 733             goto execfin;
 734         }
 735         /* 終了フラグがtrueの場合は、モニターまたは正常終了 */
 736         if(execptr->stop == true) {
 737             if(execmode.monitor == true) {
 738                 fprintf(stdout, "Return to top.\n");
 739                 monitor();
 740             } else {
 741                 break;
 742             }
 743         }
 744         /* クロック周波数の設定 */
 745         do {
 746             clock_end = clock();
 747         } while(clock_end - clock_begin < CLOCKS_PER_SEC / sys->clocks);
 748     }
 749 execfin:
 750     FREE(s);
 751     freebps();
 752     free_cmdtable(HASH_CODE);              /* 命令のコードとタイプがキーのハッシュ表を解放 */
 753     if(cerr->num > 0) {
 754         fprintf(stderr, "Execute error - %d: %s\n", cerr->num, cerr->msg);
 755     }
 756 }

/* [<][>][^][v][top][bottom][index][help] */