4 * @brief プログラムレジスタ(PR)を表すWORD値を文字列に変換
6 * @return 文字列「PR:XXXX」(Xは16進数の数字)
8 * @param pr プログラムレジスタ(PR)を表すWORD値
10 char *pr2str(WORD pr);
13 * @brief 標準入力から文字データを読込(SVC 1)
20 * @brief 標準出力へ文字データを書出(SVC 2)
27 * @brief ロード/論理積/論理和/排他的論理和のフラグ設定。OFは常に0
36 * @brief WORD値からr/r1を取得
38 * @return r/r1を表すWORD値
40 * @param oprx オペランドを表すWORD値
42 WORD get_r_r1(WORD oprx);
45 * @brief WORD値からx/r2を取得
47 * @return x/r2を表すWORD値
49 * @param oprx オペランドを表すWORD値
51 WORD get_x_r2(WORD oprx);
54 * @brief 2つのWORD値からadr[,x]を取得
56 * @return adr[,x]を表すWORD値
58 * @param adr アドレスを表すWORD値
59 * @param oprx オペランドを表すWORD値
61 WORD get_adr_x(WORD adr, WORD oprx);
64 * @brief 2つのWORD値からadr[,x]のアドレスに格納されている値を取得
66 * @return adr[,x]のアドレスに格納されている値を表すWORD値
68 * @param adr アドレスを表すWORD値
69 * @param oprx オペランドを表すWORD値
71 WORD get_val_adr_x(WORD adr, WORD oprx);
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" },
89 * @brief 実行モード: trace, logical, dump, dump_start, dump_end, monitor, step
91 EXECMODE execmode = {false, false, false, 0, 0xFFFF, false, false};
95 char *str = malloc_chk(CERRSTRSIZE + 1, "pr2str.pr");
97 sprintf(str, "PR:#%04X", pr);
104 char *buf = malloc_chk(INSIZE + 1, "svcin.buf");
106 if(fgets(buf, INSIZE, stdin) == NULL) {
107 sys->memory[sys->cpu->gr[1]] = sys->memory[sys->cpu->gr[2]] = 0x0;
110 for(i = 0; i < INSIZE; i++) {
111 if(!buf[i] || buf[i] == '\n') {
115 if(sys->cpu->gr[1] + i > execptr->end) {
116 setcerr(208, ""); /* SVC input - memory overflow */
119 sys->memory[sys->cpu->gr[1] + i] = buf[i];
121 sys->memory[sys->cpu->gr[2]] = i + 1;
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 */
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')
152 /* 第15ビットが1のとき、SFは1 */
153 if((adr & 0x8000) == 0x8000) {
162 WORD get_r_r1(WORD oprx)
167 if((r = ((oprx & 0x00F0) >>4)) > GRSIZE - 1) {
168 setcerr(205, s = pr2str(sys->cpu->pr)); /* r/r1 in word #1 - not GR */
175 WORD get_x_r2(WORD oprx)
180 if((x = (oprx & 0x000F)) > GRSIZE - 1) {
181 setcerr(206, s = pr2str(sys->cpu->pr)); /* r/r1 in word #1 - not GR */
188 WORD get_adr_x(WORD adr, WORD oprx)
191 WORD x = get_x_r2(oprx);
194 a += sys->cpu->gr[x];
199 WORD get_val_adr_x(WORD adr, WORD oprx)
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 */
209 return sys->memory[a];
212 /* exec.hで定義された関数群 */
213 void addcerrlist_exec()
215 addcerrlist(ARRAYSIZE(cerr_exec), cerr_exec);
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]));
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])]);
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])];
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]);
251 void adda(WORD r, WORD val)
256 /* 引数の値を16ビット符号付整数として加算し、オーバーフローをチェック */
257 assert(sizeof(short) * 8 == 16 && (short)0xFFFF == -1);
258 if((tmp = (short)(sys->cpu->gr[r]) + (short)val) > 32767 || tmp < -32768) {
261 /* 加算した結果を、WORD値に戻す */
262 sys->cpu->gr[r] = (WORD)(tmp & 0xFFFF);
263 if((sys->cpu->gr[r] & 0x8000) == 0x8000) {
265 } else if(sys->cpu->gr[r] == 0x0) {
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]));
279 WORD w[] = {sys->memory[sys->cpu->pr]};
280 adda(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])]);
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);
293 WORD w[] = {sys->memory[sys->cpu->pr]};
294 adda(get_r_r1(w[0]), ~(sys->cpu->gr[get_x_r2(w[0])]) + 1);
298 void addl_gr(WORD r, WORD val, bool add)
303 sys->cpu->fr = 0x0; /* flag initialize */
319 sys->cpu->gr[r] = (WORD)s;
321 if((s & 0x8000) == 0x8000) {
331 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
332 addl_gr(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]), true);
338 WORD w[] = {sys->memory[sys->cpu->pr]};
339 addl_gr(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])], true);
345 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
346 addl_gr(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]), false);
352 WORD w[] = {sys->memory[sys->cpu->pr]};
353 addl_gr(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])], false);
359 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
360 setfr(sys->cpu->gr[get_r_r1(w[0])] &= get_val_adr_x(w[1], w[0]));
366 WORD w[] = {sys->memory[sys->cpu->pr]};
367 setfr(sys->cpu->gr[get_r_r1(w[0])] &= sys->cpu->gr[get_x_r2(w[0])]);
373 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
374 setfr(sys->cpu->gr[get_r_r1(w[0])] |= get_val_adr_x(w[1], w[0]));
380 WORD w[] = {sys->memory[sys->cpu->pr]};
381 setfr(sys->cpu->gr[get_r_r1(w[0])] |= sys->cpu->gr[get_x_r2(w[0])]);
387 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
388 setfr(sys->cpu->gr[get_r_r1(w[0])] ^= get_val_adr_x(w[1], w[0]));
394 WORD w[] = {sys->memory[sys->cpu->pr]};
395 setfr(sys->cpu->gr[get_r_r1(w[0])] ^= sys->cpu->gr[get_x_r2(w[0])]);
399 void cpa(WORD r, WORD val)
402 if((short)sys->cpu->gr[r] < (short)val) {
404 } else if(sys->cpu->gr[r] == val) {
411 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
412 cpa(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]));
418 WORD w[] = {sys->memory[sys->cpu->pr]};
419 cpa(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])]);
423 void cpl(WORD r, WORD val)
426 if(sys->cpu->gr[r] < val) {
428 } else if(sys->cpu->gr[r] == val) {
435 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
436 cpl(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]));
442 WORD w[] = {sys->memory[sys->cpu->pr]};
443 cpl(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])]);
449 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
450 WORD r = get_r_r1(w[0]);
451 WORD sign = sys->cpu->gr[r] & 0x8000;
455 sys->cpu->gr[r] &= 0x7FFF;
456 for(int i = 0; i < get_adr_x(w[1], w[0]); i++) {
457 last = sys->cpu->gr[r] & 0x4000;
458 sys->cpu->gr[r] <<= 1;
460 sys->cpu->gr[r] = sign | (sys->cpu->gr[r] & 0x7FFF);
461 /* OFに、レジスタから最後に送り出されたビットの値を設定 */
465 /* 符号(第15ビット)が1のとき、SFは1 */
470 if(sys->cpu->gr[r] == 0x0) {
478 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
479 WORD r = get_r_r1(w[0]);
480 WORD sign = sys->cpu->gr[r] & 0x8000;
484 sys->cpu->gr[r] &= 0x7FFF;
485 for(int i = 0; i < get_adr_x(w[1], w[0]); i++) {
486 last = sys->cpu->gr[r] & 0x1;
487 sys->cpu->gr[r] >>= 1;
489 sys->cpu->gr[r] |= 0x4000;
492 sys->cpu->gr[r] = sign | sys->cpu->gr[r];
493 /* OFに、レジスタから最後に送り出されたビットの値を設定 */
497 /* 符号(第15ビット)が1のとき、SFは1 */
502 if(sys->cpu->gr[r] == 0x0) {
510 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
512 WORD r = get_r_r1(w[0]);
515 for(int i = 0; i < get_adr_x(w[1], w[0]); i++) {
516 last = sys->cpu->gr[r] & 0x8000;
517 sys->cpu->gr[r] <<= 1;
519 /* OFに、レジスタから最後に送り出されたビットの値を設定 */
523 /* 第15ビットが1のとき、SFは1 */
524 if((sys->cpu->gr[r] & 0x8000) > 0x0) {
528 if(sys->cpu->gr[r] == 0x0) {
536 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
538 WORD r = get_r_r1(w[0]);
541 for(int i = 0; i < get_adr_x(w[1], w[0]); i++) {
542 last = sys->cpu->gr[r] & 0x0001;
543 sys->cpu->gr[r] >>= 1;
545 /* OFに、レジスタから最後に送り出されたビットの値を設定 */
549 /* 第15ビットが1のとき、SFは1 */
550 if((sys->cpu->gr[r] & 0x8000) > 0x0) {
554 if(sys->cpu->gr[r] == 0x0) {
562 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
563 if((sys->cpu->fr & (SF | ZF)) == 0) {
564 sys->cpu->pr = get_adr_x(w[1], w[0]);
572 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
573 if((sys->cpu->fr & SF) > 0) {
574 sys->cpu->pr = get_adr_x(w[1], w[0]);
582 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
583 if((sys->cpu->fr & ZF) == 0) {
584 sys->cpu->pr = get_adr_x(w[1], w[0]);
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]);
602 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
603 if((sys->cpu->fr & OF) > 0) {
604 sys->cpu->pr = get_adr_x(w[1], w[0]);
612 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
613 sys->cpu->pr = get_adr_x(w[1], w[0]);
618 assert(sys->cpu->sp > execptr->end && sys->cpu->sp <= sys->memsize);
619 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
620 sys->memory[--(sys->cpu->sp)] = get_adr_x(w[1], w[0]);
626 assert(sys->cpu->sp > execptr->end);
627 WORD w[] = {sys->memory[sys->cpu->pr]};
630 if(sys->cpu->sp >= sys->memsize) {
631 setcerr(203, s = pr2str(sys->cpu->pr)); /* Stack Pointer (SP) - stack underflow */
634 sys->cpu->gr[get_r_r1(w[0])] = sys->memory[(sys->cpu->sp)++];
641 assert(sys->cpu->sp > execptr->end && sys->cpu->sp <= sys->memsize);
642 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
643 sys->memory[--(sys->cpu->sp)] = sys->cpu->pr + 1;
644 sys->cpu->pr = get_adr_x(w[1], w[0]);
649 assert(sys->cpu->sp <= sys->memsize);
650 if(sys->cpu->sp == sys->memsize) {
651 execptr->stop = true;
652 } else if(sys->cpu->sp < sys->memsize) {
653 sys->cpu->pr = sys->memory[(sys->cpu->sp)++] + 1;
659 WORD w[] = {sys->memory[sys->cpu->pr], sys->memory[sys->cpu->pr + 1]};
660 switch(get_adr_x(w[1], w[0]))
663 execptr->stop = true;
677 clock_t clock_begin = 0;
678 clock_t clock_end = 0;
679 void (*cmdptr)() = NULL;
681 const char *monmsg = "COMET II machine code monitor. Type ? for help.\n";
683 create_cmdtable(HASH_CODE); /* 命令のコードとタイプがキーのハッシュ表を作成 */
685 if(execmode.trace == true) {
686 fprintf(stdout, "\nExecuting machine codes\n");
689 for (sys->cpu->pr = execptr->start; ; ) {
690 clock_begin = clock(); /* クロック周波数設定のため、実行開始時間を格納 */
691 if(execmode.dump || execmode.trace) { /* traceまたはdumpオプション指定時、改行を出力 */
692 if(execmode.trace) { /* traceオプション指定時、レジスタを出力 */
693 fprintf(stdout, "#%04X: Register::::\n", sys->cpu->pr);
696 if(execmode.dump) { /* dumpオプション指定時、メモリを出力 */
697 fprintf(stdout, "#%04X: Memory::::\n", sys->cpu->pr);
698 dumpmemory(execmode.dump_start, execmode.dump_end);
700 fprintf(stdout, "\n");
702 /* ステップモードまたはブレークポイントの場合、モニターを起動 */
704 (execmode.monitor == true && sys->cpu->pr == execptr->start) ||
705 execmode.step == true || getbps(sys->cpu->pr) == true)
707 if(sys->cpu->pr == execptr->start) {
708 fprintf(stdout, "%s", monmsg);
713 if(sys->cpu->pr >= sys->memsize) {
714 setcerr(201, s = pr2str(sys->cpu->pr)); /* Program Register (PR) - memory overflow */
718 if(sys->cpu->sp <= execptr->end) {
719 setcerr(202, s = pr2str(sys->cpu->pr)); /* Stack Pointer (SP) - stack overflow */
724 if((cmdptr = getcmdptr(sys->memory[sys->cpu->pr] & 0xFF00)) == NULL) {
725 setcerr(204, s = pr2str(sys->cpu->pr)); /* OP in word #1 - not command code */
734 /* 終了フラグがtrueの場合は、モニターまたは正常終了 */
735 if(execptr->stop == true) {
736 if(execmode.monitor == true) {
737 fprintf(stdout, "Return to top.\n");
746 } while(clock_end - clock_begin < CLOCKS_PER_SEC / sys->clocks);
751 free_cmdtable(HASH_CODE); /* 命令のコードとタイプがキーのハッシュ表を解放 */
753 fprintf(stderr, "Execute error - %d: %s\n", cerr->num, cerr->msg);