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

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