root/src/exec.c

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

DEFINITIONS

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

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

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