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

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