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 アセンブル結果読み込みエラーの定義
91 static CERR cerr_load[] = {
92 { 210, "load - memory overflow" },
93 { 211, "object file not specified" },
97 * @brief 実行モード: trace, logical, dump, step
99 EXECMODE execmode = {false, false, false, false};
101 char *pr2str(WORD pr)
103 char *str = malloc_chk(CERRSTRSIZE + 1, "pr2str.pr");
105 sprintf(str, "PR:#%04X", pr);
112 char *buf = malloc_chk(INSIZE + 1, "svcin.buf");
114 if(fgets(buf, INSIZE, stdin) == NULL) {
115 sys->memory[sys->cpu->gr[1]] = sys->memory[sys->cpu->gr[2]] = 0x0;
118 for(i = 0; i < INSIZE; i++) {
119 if(*(buf + i) == '\0' || *(buf + i) == '\n') {
123 if(sys->cpu->gr[1] + i > execptr->end) {
124 setcerr(208, ""); /* SVC input - memory overflow */
127 sys->memory[sys->cpu->gr[1]+i] = *(buf + i);
129 sys->memory[sys->cpu->gr[2]] = i + 1;
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 */
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')
160 /* 第15ビットが1のとき、SFは1 */
161 if((adr & 0x8000) == 0x8000) {
170 WORD get_r_r1(WORD oprx)
175 if((r = ((oprx & 0x00F0) >>4)) > GRSIZE - 1) {
176 setcerr(205, s = pr2str(sys->cpu->pr)); /* r/r1 in word #1 - not GR */
183 WORD get_x_r2(WORD oprx)
188 if((x = (oprx & 0x000F)) > GRSIZE - 1) {
189 setcerr(206, s = pr2str(sys->cpu->pr)); /* r/r1 in word #1 - not GR */
196 WORD get_adr_x(WORD adr, WORD oprx)
199 if((x = get_x_r2(oprx)) > 0) {
200 a += sys->cpu->gr[x];
205 WORD get_val_adr_x(WORD adr, WORD oprx)
210 if((a = get_adr_x(adr, oprx)) >= sys->memsize) {
211 setcerr(207, s = pr2str(sys->cpu->pr + 1)); /* address in word #2 - out of memory */
215 return sys->memory[a];
218 /* exec.hで定義された関数群 */
219 void addcerrlist_load()
221 addcerrlist(ARRAYSIZE(cerr_load), cerr_load);
224 void addcerrlist_exec()
226 addcerrlist(ARRAYSIZE(cerr_exec), cerr_exec);
229 bool loadassemble(const char *file)
234 assert(file != NULL);
235 if((fp = fopen(file, "rb")) == NULL) {
239 execptr->end = execptr->start +
240 fread(sys->memory, sizeof(WORD), sys->memsize - execptr->start, fp);
241 if(execptr->end == sys->memsize) {
242 setcerr(210, file); /* load - memory overflow */
243 fprintf(stderr, "Load error - %d: %s\n", cerr->num, cerr->msg);
258 w[0] = sys->memory[sys->cpu->pr];
259 w[1] = sys->memory[sys->cpu->pr + 1];
260 setfr(sys->cpu->gr[get_r_r1(w[0])] = get_val_adr_x(w[1], w[0]));
267 w[0] = sys->memory[sys->cpu->pr];
268 setfr(sys->cpu->gr[get_r_r1(w[0])] = sys->cpu->gr[get_x_r2(w[0])]);
275 w[0] = sys->memory[sys->cpu->pr];
276 w[1] = sys->memory[sys->cpu->pr + 1];
277 sys->memory[get_adr_x(w[1], w[0])] = sys->cpu->gr[get_r_r1(w[0])];
284 w[0] = sys->memory[sys->cpu->pr];
285 w[1] = sys->memory[sys->cpu->pr + 1];
286 sys->cpu->gr[get_r_r1(w[0])] = get_adr_x(w[1], w[0]);
290 void adda(WORD r, WORD val)
295 /* 引数の値を16ビット符号付整数として加算し、オーバーフローをチェック */
296 assert(sizeof(short) * 8 == 16 && (short)0xFFFF == -1);
297 if((tmp = (short)(sys->cpu->gr[r]) + (short)val) > 32767 || tmp < -32768) {
300 /* 加算した結果を、WORD値に戻す */
301 sys->cpu->gr[r] = (WORD)(tmp & 0xFFFF);
302 if((sys->cpu->gr[r] & 0x8000) == 0x8000) {
304 } else if(sys->cpu->gr[r] == 0x0) {
312 w[0] = sys->memory[sys->cpu->pr];
313 w[1] = sys->memory[sys->cpu->pr + 1];
314 adda(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]));
321 w[0] = sys->memory[sys->cpu->pr];
322 adda(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])]);
329 w[0] = sys->memory[sys->cpu->pr];
330 w[1] = sys->memory[sys->cpu->pr + 1];
331 adda(get_r_r1(w[0]), ~(get_val_adr_x(w[1], w[0])) + 1);
338 w[0] = sys->memory[sys->cpu->pr];
339 adda(get_r_r1(w[0]), ~(sys->cpu->gr[get_x_r2(w[0])]) + 1);
343 void addl_gr(WORD r, WORD val, bool add)
348 sys->cpu->fr = 0x0; /* flag initialize */
364 sys->cpu->gr[r] = (WORD)s;
366 if((s & 0x8000) == 0x8000) {
377 w[0] = sys->memory[sys->cpu->pr];
378 w[1] = sys->memory[sys->cpu->pr + 1];
379 addl_gr(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]), true);
386 w[0] = sys->memory[sys->cpu->pr];
387 addl_gr(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])], true);
394 w[0] = sys->memory[sys->cpu->pr];
395 w[1] = sys->memory[sys->cpu->pr + 1];
396 addl_gr(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]), false);
403 w[0] = sys->memory[sys->cpu->pr];
404 addl_gr(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])], false);
411 w[0] = sys->memory[sys->cpu->pr];
412 w[1] = sys->memory[sys->cpu->pr + 1];
413 setfr(sys->cpu->gr[get_r_r1(w[0])] &= get_val_adr_x(w[1], w[0]));
420 w[0] = sys->memory[sys->cpu->pr];
421 setfr(sys->cpu->gr[get_r_r1(w[0])] &= sys->cpu->gr[get_x_r2(w[0])]);
428 w[0] = sys->memory[sys->cpu->pr];
429 w[1] = sys->memory[sys->cpu->pr + 1];
430 setfr(sys->cpu->gr[get_r_r1(w[0])] |= get_val_adr_x(w[1], w[0]));
437 w[0] = sys->memory[sys->cpu->pr];
438 setfr(sys->cpu->gr[get_r_r1(w[0])] |= sys->cpu->gr[get_x_r2(w[0])]);
445 w[0] = sys->memory[sys->cpu->pr];
446 w[1] = sys->memory[sys->cpu->pr + 1];
447 setfr(sys->cpu->gr[get_r_r1(w[0])] ^= get_val_adr_x(w[1], w[0]));
454 w[0] = sys->memory[sys->cpu->pr];
455 setfr(sys->cpu->gr[get_r_r1(w[0])] ^= sys->cpu->gr[get_x_r2(w[0])]);
459 void cpa(WORD r, WORD val)
462 if((short)sys->cpu->gr[r] < (short)val) {
464 } else if(sys->cpu->gr[r] == val) {
472 w[0] = sys->memory[sys->cpu->pr];
473 w[1] = sys->memory[sys->cpu->pr + 1];
474 cpa(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]));
481 w[0] = sys->memory[sys->cpu->pr];
482 cpa(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])]);
486 void cpl(WORD r, WORD val)
489 if(sys->cpu->gr[r] < val) {
491 } else if(sys->cpu->gr[r] == val) {
499 w[0] = sys->memory[sys->cpu->pr];
500 w[1] = sys->memory[sys->cpu->pr + 1];
501 cpl(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]));
508 w[0] = sys->memory[sys->cpu->pr];
509 cpl(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])]);
515 WORD w[2], sign, last = 0x0, r;
518 w[0] = sys->memory[sys->cpu->pr];
519 w[1] = sys->memory[sys->cpu->pr + 1];
521 sign = sys->cpu->gr[(r = get_r_r1(w[0]))] & 0x8000;
522 sys->cpu->gr[r] &= 0x7FFF;
523 for(i = 0; i < get_adr_x(w[1], w[0]); i++) {
524 last = sys->cpu->gr[r] & 0x4000;
525 sys->cpu->gr[r] <<= 1;
527 sys->cpu->gr[r] = sign | (sys->cpu->gr[r] & 0x7FFF);
528 /* OFに、レジスタから最後に送り出されたビットの値を設定 */
532 /* 符号(第15ビット)が1のとき、SFは1 */
537 if(sys->cpu->gr[r] == 0x0) {
545 WORD w[2], sign, last = 0x0, r;
548 w[0] = sys->memory[sys->cpu->pr];
549 w[1] = sys->memory[sys->cpu->pr + 1];
551 sign = sys->cpu->gr[(r = get_r_r1(w[0]))] & 0x8000;
552 sys->cpu->gr[r] &= 0x7FFF;
553 for(i = 0; i < get_adr_x(w[1], w[0]); i++) {
554 last = sys->cpu->gr[r] & 0x1;
555 sys->cpu->gr[r] >>= 1;
557 sys->cpu->gr[r] |= 0x4000;
560 sys->cpu->gr[r] = sign | sys->cpu->gr[r];
561 /* OFに、レジスタから最後に送り出されたビットの値を設定 */
565 /* 符号(第15ビット)が1のとき、SFは1 */
570 if(sys->cpu->gr[r] == 0x0) {
578 WORD w[2], last = 0x0, r;
581 w[0] = sys->memory[sys->cpu->pr];
582 w[1] = sys->memory[sys->cpu->pr + 1];
584 for(i = 0; i < get_adr_x(w[1], w[0]); i++) {
585 last = sys->cpu->gr[(r = get_r_r1(w[0]))] & 0x8000;
586 sys->cpu->gr[r] <<= 1;
588 /* OFに、レジスタから最後に送り出されたビットの値を設定 */
592 /* 第15ビットが1のとき、SFは1 */
593 if((sys->cpu->gr[r] & 0x8000) > 0x0) {
597 if(sys->cpu->gr[r] == 0x0) {
605 WORD w[2], last = 0x0, r;
608 w[0] = sys->memory[sys->cpu->pr];
609 w[1] = sys->memory[sys->cpu->pr + 1];
612 for(i = 0; i < get_adr_x(w[1], w[0]); i++) {
613 last = sys->cpu->gr[r] & 0x0001;
614 sys->cpu->gr[r] >>= 1;
616 /* OFに、レジスタから最後に送り出されたビットの値を設定 */
620 /* 第15ビットが1のとき、SFは1 */
621 if((sys->cpu->gr[r] & 0x8000) > 0x0) {
625 if(sys->cpu->gr[r] == 0x0) {
634 w[0] = sys->memory[sys->cpu->pr];
635 w[1] = sys->memory[sys->cpu->pr + 1];
636 if((sys->cpu->fr & (SF | ZF)) == 0) {
637 sys->cpu->pr = get_adr_x(w[1], w[0]);
646 w[0] = sys->memory[sys->cpu->pr];
647 w[1] = sys->memory[sys->cpu->pr + 1];
648 if((sys->cpu->fr & SF) > 0) {
649 sys->cpu->pr = get_adr_x(w[1], w[0]);
658 w[0] = sys->memory[sys->cpu->pr];
659 w[1] = sys->memory[sys->cpu->pr + 1];
660 if((sys->cpu->fr & ZF) == 0) {
661 sys->cpu->pr = get_adr_x(w[1], w[0]);
670 w[0] = sys->memory[sys->cpu->pr];
671 w[1] = sys->memory[sys->cpu->pr + 1];
672 if((sys->cpu->fr & ZF) > 0) {
673 sys->cpu->pr = get_adr_x(w[1], w[0]);
682 w[0] = sys->memory[sys->cpu->pr];
683 w[1] = sys->memory[sys->cpu->pr + 1];
684 if((sys->cpu->fr & OF) > 0) {
685 sys->cpu->pr = get_adr_x(w[1], w[0]);
694 w[0] = sys->memory[sys->cpu->pr];
695 w[1] = sys->memory[sys->cpu->pr + 1];
696 sys->cpu->pr = get_adr_x(w[1], w[0]);
701 assert(sys->cpu->sp > execptr->end && sys->cpu->sp <= sys->memsize);
704 w[0] = sys->memory[sys->cpu->pr];
705 w[1] = sys->memory[sys->cpu->pr + 1];
706 sys->memory[--(sys->cpu->sp)] = get_adr_x(w[1], w[0]);
712 assert(sys->cpu->sp > execptr->end);
716 if(sys->cpu->sp >= sys->memsize) {
717 setcerr(203, s = pr2str(sys->cpu->pr)); /* Stack Pointer (SP) - stack underflow */
720 w = sys->memory[sys->cpu->pr];
721 sys->cpu->gr[get_r_r1(w)] = sys->memory[(sys->cpu->sp)++];
728 assert(sys->cpu->sp > execptr->end && sys->cpu->sp <= sys->memsize);
730 w[0] = sys->memory[sys->cpu->pr];
731 w[1] = sys->memory[sys->cpu->pr + 1];
732 sys->memory[--(sys->cpu->sp)] = sys->cpu->pr + 1;
733 sys->cpu->pr = get_adr_x(w[1], w[0]);
738 assert(sys->cpu->sp <= sys->memsize);
739 if(sys->cpu->sp == sys->memsize) {
740 execptr->stop = true;
741 } else if(sys->cpu->sp < sys->memsize) {
742 sys->cpu->pr = sys->memory[(sys->cpu->sp)++] + 1;
749 w[0] = sys->memory[sys->cpu->pr];
750 w[1] = sys->memory[sys->cpu->pr + 1];
751 switch(get_adr_x(w[1], w[0]))
754 execptr->stop = true;
766 char *grstr(WORD word)
769 char *str = malloc_chk(3 + 1, "grstr.str");
770 sprintf(str, "GR%d", word);
776 clock_t clock_begin, clock_end;
780 create_code_cmdtype(); /* 命令のコードとタイプがキーのハッシュ表を作成 */
781 if(execmode.trace == true) {
782 fprintf(stdout, "\nExecuting machine codes\n");
785 for (sys->cpu->pr = execptr->start; ; ) {
786 clock_begin = clock(); /* クロック周波数設定のため、実行開始時間を格納 */
787 if(execmode.dump || execmode.trace) { /* traceまたはdumpオプション指定時、改行を出力 */
788 if(execmode.trace) { /* traceオプション指定時、レジスタを出力 */
789 fprintf(stdout, "#%04X: Register::::\n", sys->cpu->pr);
792 if(execmode.dump) { /* dumpオプション指定時、メモリを出力 */
793 fprintf(stdout, "#%04X: Memory::::\n", sys->cpu->pr);
794 dumpmemory(0x0, 0xFFFF);
796 fprintf(stdout, "\n");
798 /* デバッガーモードの場合、デバッガーを起動 */
799 if(execmode.step == true || getbps(sys->cpu->pr) == true) {
803 if(sys->cpu->pr >= sys->memsize) {
804 setcerr(201, s = pr2str(sys->cpu->pr)); /* Program Register (PR) - memory overflow */
809 if(sys->cpu->sp <= execptr->end) {
810 setcerr(202, s = pr2str(sys->cpu->pr)); /* Stack Pointer (SP) - stack overflow */
816 if((cmdptr = getcmdptr(sys->memory[sys->cpu->pr] & 0xFF00)) == NULL) {
817 setcerr(204, s = pr2str(sys->cpu->pr)); /* OP in word #1 - not command code */
827 /* 終了フラグがtrueの場合は、正常終了 */
828 if(execptr->stop == true) {
834 } while(clock_end - clock_begin < CLOCKS_PER_SEC / sys->clocks);
838 free_code_cmdtype(); /* 命令のコードとタイプがキーのハッシュ表を解放 */
840 fprintf(stderr, "Execute error - %d: %s\n", cerr->num, cerr->msg);