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);
74 * @brief 汎用レジスタの番号からレジスタを表す文字列を返す
76 * @return 汎用レジスタを表す文字列。「GR0」「GR1」・・・「GR7」のいずれか
78 * @param word レジスタ番号[0-7]を表すWORD値
80 char *grstr(WORD word);
86 static CERR cerr_exec[] = {
87 { 201, "Program Register (PR) - memory overflow" },
88 { 202, "Stack Pointer (SP) - stack overflow" },
89 { 203, "Stack Pointer (SP) - stack underflow" },
90 { 204, "OP in word #1 - not command code" },
91 { 205, "r/r1 in word #1 - not GR" },
92 { 206, "x/r2 in word #1 - not GR" },
93 { 207, "address in word #2 - out of memory" },
94 { 208, "SVC input - memory overflow" },
95 { 209, "SVC output - memory overflow" },
99 * @brief アセンブル結果読み込みエラーの定義
101 static CERR cerr_load[] = {
102 { 210, "load - memory overflow" },
103 { 211, "object file not specified" },
107 * @brief 実行モード: trace, logical, dump, step
109 EXECMODE execmode = {false, false, false, false};
111 char *pr2str(WORD pr)
113 char *str = malloc_chk(CERRSTRSIZE + 1, "pr2str.pr");
115 sprintf(str, "PR:#%04X", pr);
122 char *buf = malloc_chk(INSIZE + 1, "svcin.buf");
124 if(fgets(buf, INSIZE, stdin) == NULL) {
125 sys->memory[sys->cpu->gr[1]] = sys->memory[sys->cpu->gr[2]] = 0x0;
128 for(i = 0; i < INSIZE; i++) {
129 if(*(buf + i) == '\0' || *(buf + i) == '\n') {
133 if(sys->cpu->gr[1] + i > execptr->end) {
134 setcerr(208, ""); /* SVC input - memory overflow */
137 sys->memory[sys->cpu->gr[1]+i] = *(buf + i);
139 sys->memory[sys->cpu->gr[2]] = i + 1;
148 for(i = 0; i < sys->memory[sys->cpu->gr[2]]; i++) {
149 if(sys->cpu->gr[1] + i > execptr->end) {
150 setcerr(209, ""); /* SVC output - memory overflow */
153 /* 「JIS X 0201ラテン文字・片仮名用8ビット符号で規定する文字の符号表」
154 に記載された文字と、改行(CR)/タブを表示 */
155 /* それ以外の文字は、「.」で表す */
156 if(((w = sys->memory[sys->cpu->gr[1]+i]) >= 0x20 && w <= 0x7E) || /* JIS X 0201ラテン文字 */
157 (w >= 0xA0 && w <= 0xFE) || /* JIS X 0201片仮名用8ビット符号 */
158 w == 0xA || w == '\t')
170 /* 第15ビットが1のとき、SFは1 */
171 if((adr & 0x8000) == 0x8000) {
180 WORD get_r_r1(WORD oprx)
185 if((r = ((oprx & 0x00F0) >>4)) > GRSIZE - 1) {
186 setcerr(205, s = pr2str(sys->cpu->pr)); /* r/r1 in word #1 - not GR */
193 WORD get_x_r2(WORD oprx)
198 if((x = (oprx & 0x000F)) > GRSIZE - 1) {
199 setcerr(206, s = pr2str(sys->cpu->pr)); /* r/r1 in word #1 - not GR */
206 WORD get_adr_x(WORD adr, WORD oprx)
209 if((x = get_x_r2(oprx)) > 0) {
210 a += sys->cpu->gr[x];
215 WORD get_val_adr_x(WORD adr, WORD oprx)
220 if((a = get_adr_x(adr, oprx)) >= sys->memsize) {
221 setcerr(207, s = pr2str(sys->cpu->pr + 1)); /* address in word #2 - out of memory */
225 return sys->memory[a];
228 /* exec.hで定義された関数群 */
229 void addcerrlist_load()
231 addcerrlist(ARRAYSIZE(cerr_load), cerr_load);
234 void addcerrlist_exec()
236 addcerrlist(ARRAYSIZE(cerr_exec), cerr_exec);
239 bool loadassemble(const char *file)
244 assert(file != NULL);
245 if((fp = fopen(file, "rb")) == NULL) {
249 execptr->end = execptr->start +
250 fread(sys->memory, sizeof(WORD), sys->memsize - execptr->start, fp);
251 if(execptr->end == sys->memsize) {
252 setcerr(210, file); /* load - memory overflow */
253 fprintf(stderr, "Load error - %d: %s\n", cerr->num, cerr->msg);
268 w[0] = sys->memory[sys->cpu->pr];
269 w[1] = sys->memory[sys->cpu->pr + 1];
270 setfr(sys->cpu->gr[get_r_r1(w[0])] = get_val_adr_x(w[1], w[0]));
277 w[0] = sys->memory[sys->cpu->pr];
278 setfr(sys->cpu->gr[get_r_r1(w[0])] = sys->cpu->gr[get_x_r2(w[0])]);
285 w[0] = sys->memory[sys->cpu->pr];
286 w[1] = sys->memory[sys->cpu->pr + 1];
287 sys->memory[get_adr_x(w[1], w[0])] = sys->cpu->gr[get_r_r1(w[0])];
294 w[0] = sys->memory[sys->cpu->pr];
295 w[1] = sys->memory[sys->cpu->pr + 1];
296 sys->cpu->gr[get_r_r1(w[0])] = get_adr_x(w[1], w[0]);
300 void adda(WORD r, WORD val)
305 /* 引数の値を16ビット符号付整数として加算し、オーバーフローをチェック */
306 assert(sizeof(short) * 8 == 16 && (short)0xFFFF == -1);
307 if((tmp = (short)(sys->cpu->gr[r]) + (short)val) > 32767 || tmp < -32768) {
310 /* 加算した結果を、WORD値に戻す */
311 sys->cpu->gr[r] = (WORD)(tmp & 0xFFFF);
312 if((sys->cpu->gr[r] & 0x8000) == 0x8000) {
314 } else if(sys->cpu->gr[r] == 0x0) {
322 w[0] = sys->memory[sys->cpu->pr];
323 w[1] = sys->memory[sys->cpu->pr + 1];
324 adda(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]));
331 w[0] = sys->memory[sys->cpu->pr];
332 adda(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])]);
339 w[0] = sys->memory[sys->cpu->pr];
340 w[1] = sys->memory[sys->cpu->pr + 1];
341 adda(get_r_r1(w[0]), ~(get_val_adr_x(w[1], w[0])) + 1);
348 w[0] = sys->memory[sys->cpu->pr];
349 adda(get_r_r1(w[0]), ~(sys->cpu->gr[get_x_r2(w[0])]) + 1);
353 void addl_gr(WORD r, WORD val, bool add)
358 sys->cpu->fr = 0x0; /* flag initialize */
374 sys->cpu->gr[r] = (WORD)s;
376 if((s & 0x8000) == 0x8000) {
387 w[0] = sys->memory[sys->cpu->pr];
388 w[1] = sys->memory[sys->cpu->pr + 1];
389 addl_gr(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]), true);
396 w[0] = sys->memory[sys->cpu->pr];
397 addl_gr(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])], true);
404 w[0] = sys->memory[sys->cpu->pr];
405 w[1] = sys->memory[sys->cpu->pr + 1];
406 addl_gr(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]), false);
413 w[0] = sys->memory[sys->cpu->pr];
414 addl_gr(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])], false);
421 w[0] = sys->memory[sys->cpu->pr];
422 w[1] = sys->memory[sys->cpu->pr + 1];
423 setfr(sys->cpu->gr[get_r_r1(w[0])] &= get_val_adr_x(w[1], w[0]));
430 w[0] = sys->memory[sys->cpu->pr];
431 setfr(sys->cpu->gr[get_r_r1(w[0])] &= sys->cpu->gr[get_x_r2(w[0])]);
438 w[0] = sys->memory[sys->cpu->pr];
439 w[1] = sys->memory[sys->cpu->pr + 1];
440 setfr(sys->cpu->gr[get_r_r1(w[0])] |= get_val_adr_x(w[1], w[0]));
447 w[0] = sys->memory[sys->cpu->pr];
448 setfr(sys->cpu->gr[get_r_r1(w[0])] |= sys->cpu->gr[get_x_r2(w[0])]);
455 w[0] = sys->memory[sys->cpu->pr];
456 w[1] = sys->memory[sys->cpu->pr + 1];
457 setfr(sys->cpu->gr[get_r_r1(w[0])] ^= get_val_adr_x(w[1], w[0]));
464 w[0] = sys->memory[sys->cpu->pr];
465 setfr(sys->cpu->gr[get_r_r1(w[0])] ^= sys->cpu->gr[get_x_r2(w[0])]);
469 void cpa(WORD r, WORD val)
472 if((short)sys->cpu->gr[r] < (short)val) {
474 } else if(sys->cpu->gr[r] == val) {
482 w[0] = sys->memory[sys->cpu->pr];
483 w[1] = sys->memory[sys->cpu->pr + 1];
484 cpa(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]));
491 w[0] = sys->memory[sys->cpu->pr];
492 cpa(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])]);
496 void cpl(WORD r, WORD val)
499 if(sys->cpu->gr[r] < val) {
501 } else if(sys->cpu->gr[r] == val) {
509 w[0] = sys->memory[sys->cpu->pr];
510 w[1] = sys->memory[sys->cpu->pr + 1];
511 cpl(get_r_r1(w[0]), get_val_adr_x(w[1], w[0]));
518 w[0] = sys->memory[sys->cpu->pr];
519 cpl(get_r_r1(w[0]), sys->cpu->gr[get_x_r2(w[0])]);
525 WORD w[2], sign, last = 0x0, r;
528 w[0] = sys->memory[sys->cpu->pr];
529 w[1] = sys->memory[sys->cpu->pr + 1];
531 sign = sys->cpu->gr[(r = get_r_r1(w[0]))] & 0x8000;
532 sys->cpu->gr[r] &= 0x7FFF;
533 for(i = 0; i < get_adr_x(w[1], w[0]); i++) {
534 last = sys->cpu->gr[r] & 0x4000;
535 sys->cpu->gr[r] <<= 1;
537 sys->cpu->gr[r] = sign | (sys->cpu->gr[r] & 0x7FFF);
538 /* OFに、レジスタから最後に送り出されたビットの値を設定 */
542 /* 符号(第15ビット)が1のとき、SFは1 */
547 if(sys->cpu->gr[r] == 0x0) {
555 WORD w[2], sign, last = 0x0, r;
558 w[0] = sys->memory[sys->cpu->pr];
559 w[1] = sys->memory[sys->cpu->pr + 1];
561 sign = sys->cpu->gr[(r = get_r_r1(w[0]))] & 0x8000;
562 sys->cpu->gr[r] &= 0x7FFF;
563 for(i = 0; i < get_adr_x(w[1], w[0]); i++) {
564 last = sys->cpu->gr[r] & 0x1;
565 sys->cpu->gr[r] >>= 1;
567 sys->cpu->gr[r] |= 0x4000;
570 sys->cpu->gr[r] = sign | sys->cpu->gr[r];
571 /* OFに、レジスタから最後に送り出されたビットの値を設定 */
575 /* 符号(第15ビット)が1のとき、SFは1 */
580 if(sys->cpu->gr[r] == 0x0) {
588 WORD w[2], last = 0x0, r;
591 w[0] = sys->memory[sys->cpu->pr];
592 w[1] = sys->memory[sys->cpu->pr + 1];
594 for(i = 0; i < get_adr_x(w[1], w[0]); i++) {
595 last = sys->cpu->gr[(r = get_r_r1(w[0]))] & 0x8000;
596 sys->cpu->gr[r] <<= 1;
598 /* OFに、レジスタから最後に送り出されたビットの値を設定 */
602 /* 第15ビットが1のとき、SFは1 */
603 if((sys->cpu->gr[r] & 0x8000) > 0x0) {
607 if(sys->cpu->gr[r] == 0x0) {
615 WORD w[2], last = 0x0, r;
618 w[0] = sys->memory[sys->cpu->pr];
619 w[1] = sys->memory[sys->cpu->pr + 1];
622 for(i = 0; i < get_adr_x(w[1], w[0]); i++) {
623 last = sys->cpu->gr[r] & 0x0001;
624 sys->cpu->gr[r] >>= 1;
626 /* OFに、レジスタから最後に送り出されたビットの値を設定 */
630 /* 第15ビットが1のとき、SFは1 */
631 if((sys->cpu->gr[r] & 0x8000) > 0x0) {
635 if(sys->cpu->gr[r] == 0x0) {
644 w[0] = sys->memory[sys->cpu->pr];
645 w[1] = sys->memory[sys->cpu->pr + 1];
646 if((sys->cpu->fr & (SF | ZF)) == 0) {
647 sys->cpu->pr = get_adr_x(w[1], w[0]);
656 w[0] = sys->memory[sys->cpu->pr];
657 w[1] = sys->memory[sys->cpu->pr + 1];
658 if((sys->cpu->fr & SF) > 0) {
659 sys->cpu->pr = get_adr_x(w[1], w[0]);
668 w[0] = sys->memory[sys->cpu->pr];
669 w[1] = sys->memory[sys->cpu->pr + 1];
670 if((sys->cpu->fr & ZF) == 0) {
671 sys->cpu->pr = get_adr_x(w[1], w[0]);
680 w[0] = sys->memory[sys->cpu->pr];
681 w[1] = sys->memory[sys->cpu->pr + 1];
682 if((sys->cpu->fr & ZF) > 0) {
683 sys->cpu->pr = get_adr_x(w[1], w[0]);
692 w[0] = sys->memory[sys->cpu->pr];
693 w[1] = sys->memory[sys->cpu->pr + 1];
694 if((sys->cpu->fr & OF) > 0) {
695 sys->cpu->pr = get_adr_x(w[1], w[0]);
704 w[0] = sys->memory[sys->cpu->pr];
705 w[1] = sys->memory[sys->cpu->pr + 1];
706 sys->cpu->pr = get_adr_x(w[1], w[0]);
711 assert(sys->cpu->sp > execptr->end && sys->cpu->sp <= sys->memsize);
714 w[0] = sys->memory[sys->cpu->pr];
715 w[1] = sys->memory[sys->cpu->pr + 1];
716 sys->memory[--(sys->cpu->sp)] = get_adr_x(w[1], w[0]);
722 assert(sys->cpu->sp > execptr->end);
726 if(sys->cpu->sp >= sys->memsize) {
727 setcerr(203, s = pr2str(sys->cpu->pr)); /* Stack Pointer (SP) - stack underflow */
730 w = sys->memory[sys->cpu->pr];
731 sys->cpu->gr[get_r_r1(w)] = sys->memory[(sys->cpu->sp)++];
738 assert(sys->cpu->sp > execptr->end && sys->cpu->sp <= sys->memsize);
740 w[0] = sys->memory[sys->cpu->pr];
741 w[1] = sys->memory[sys->cpu->pr + 1];
742 sys->memory[--(sys->cpu->sp)] = sys->cpu->pr + 1;
743 sys->cpu->pr = get_adr_x(w[1], w[0]);
748 assert(sys->cpu->sp <= sys->memsize);
749 if(sys->cpu->sp == sys->memsize) {
750 execptr->stop = true;
751 } else if(sys->cpu->sp < sys->memsize) {
752 sys->cpu->pr = sys->memory[(sys->cpu->sp)++] + 1;
759 w[0] = sys->memory[sys->cpu->pr];
760 w[1] = sys->memory[sys->cpu->pr + 1];
761 switch(get_adr_x(w[1], w[0]))
764 execptr->stop = true;
776 char *grstr(WORD word)
779 char *str = malloc_chk(3 + 1, "grstr.str");
780 sprintf(str, "GR%d", word);
786 clock_t clock_begin, clock_end;
790 create_code_cmdtype(); /* 命令のコードとタイプがキーのハッシュ表を作成 */
791 if(execmode.trace == true) {
792 fprintf(stdout, "\nExecuting machine codes\n");
795 for (sys->cpu->pr = execptr->start; ; ) {
796 clock_begin = clock(); /* クロック周波数設定のため、実行開始時間を格納 */
797 if(execmode.dump || execmode.trace) { /* traceまたはdumpオプション指定時、改行を出力 */
798 if(execmode.trace) { /* traceオプション指定時、レジスタを出力 */
799 fprintf(stdout, "#%04X: Register::::\n", sys->cpu->pr);
802 if(execmode.dump) { /* dumpオプション指定時、メモリを出力 */
803 fprintf(stdout, "#%04X: Memory::::\n", sys->cpu->pr);
806 fprintf(stdout, "\n");
808 /* デバッガーモードの場合、デバッガーを起動 */
809 if(execmode.step == true || getbps(sys->cpu->pr) == true) {
813 if(sys->cpu->pr >= sys->memsize) {
814 setcerr(201, s = pr2str(sys->cpu->pr)); /* Program Register (PR) - memory overflow */
819 if(sys->cpu->sp <= execptr->end) {
820 setcerr(202, s = pr2str(sys->cpu->pr)); /* Stack Pointer (SP) - stack overflow */
826 if((cmdptr = getcmdptr(sys->memory[sys->cpu->pr] & 0xFF00)) == NULL) {
827 setcerr(204, s = pr2str(sys->cpu->pr)); /* OP in word #1 - not command code */
837 /* 終了フラグがtrueの場合は、正常終了 */
838 if(execptr->stop == true) {
844 } while(clock_end - clock_begin < CLOCKS_PER_SEC / sys->clocks);
848 free_code_cmdtype(); /* 命令のコードとタイプがキーのハッシュ表を解放 */
850 fprintf(stderr, "Execute error - %d: %s\n", cerr->num, cerr->msg);
854 bool disassemble_file(const char *file)
858 WORD i = 0, w, cmd, x, adr;
860 char *cmdname, *g, *g1, *g2;
862 assert(file != NULL);
863 if((fp = fopen(file, "rb")) == NULL) {
868 create_code_cmdtype(); /* 命令のコードとタイプがキーのハッシュ表を作成 */
870 fprintf(stdout, "MAIN\tSTART\n");
872 fread(&w, sizeof(WORD), 1, fp);
877 cmdname = getcmdname(cmd);
878 cmdtype = getcmdtype(cmd);
879 if(cmd == 0xFF00 || (w != 0 && cmd == 0x0000)) {
880 fprintf(stdout, "\tDC\t%d\t\t\t\t; #%04X: #%04X :: ", w, i++, w);
881 print_dumpword(w, true);
882 } else if(cmdtype == R_ADR_X || cmdtype == ADR_X) {
883 fread(&adr, sizeof(WORD), 1, fp);
884 fprintf(stdout, "\t%s\t", cmdname);
885 if(cmdtype == R_ADR_X) {
886 g = grstr((w & 0x00F0) >> 4);
887 fprintf(stdout, "%s,", g);
890 fprintf(stdout, "#%04X", adr);
891 if((x = w & 0x000F) != 0) {
892 fprintf(stdout, ",%s", g = grstr(x));
895 fprintf(stdout, "\t\t\t\t; #%04X: #%04X #%04X", i, w, adr);
898 fprintf(stdout, "\t%s", cmdname);
899 if(cmdtype == R1_R2) {
900 g1 = grstr((w & 0x00F0) >> 4);
901 g2 = grstr(w & 0x000F);
902 fprintf(stdout, "\t%s,%s", g1, g2);
905 } else if(cmdtype == R_) {
906 g = grstr((w & 0x00F0) >> 4);
907 fprintf(stdout, "\t%s", g);
910 fprintf(stdout, "\t\t\t\t; #%04X: #%04X", i++, w);
912 fprintf(stdout, "\n");
914 fprintf(stdout, "\tEND\n");