From a77e8363f86dfc38838990a174486166b7c5cbf2 Mon Sep 17 00:00:00 2001 From: j8takagi Date: Fri, 22 Jun 2018 19:26:22 +0900 Subject: [PATCH] =?utf8?q?=E3=83=87=E3=83=90=E3=83=83=E3=82=AC=E3=83=BC?= =?utf8?q?=E6=A9=9F=E8=83=BD=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- VERSION | 2 +- include/exec.h | 21 +++- src/casl2.c | 7 +- src/casl2rev.c | 96 +----------------- src/comet2.c | 6 +- src/exec.c | 128 ++++++++++++++++++++++-- test/system/casl2_opt/opt_h/0.txt | 2 +- test/system/casl2_opt/opt_opterr/0.txt | 2 +- test/system/comet2_opt/opt_h/0.txt | 2 +- test/system/comet2_opt/opt_opterr/0.txt | 2 +- 10 files changed, 156 insertions(+), 112 deletions(-) diff --git a/VERSION b/VERSION index db52e0d..3f5326d 100644 --- a/VERSION +++ b/VERSION @@ -1,2 +1,2 @@ -v0.3p5 +v0.4p0 diff --git a/include/exec.h b/include/exec.h index 931f799..0794a91 100644 --- a/include/exec.h +++ b/include/exec.h @@ -11,17 +11,22 @@ enum { INSIZE = 256 /**]] [-M ] [-C ] FILE1[ FILE2 ...]\n"; + "Usage: %s [-slLaAtTdbvh] [-oO[]] [-M ] [-C ] FILE1[ FILE2 ...]\n"; cerr_init(); addcerrlist_casl2(); addcerrlist_assemble(); addcerrlist_exec(); /* オプションの処理 */ - while((opt = getopt_long(argc, argv, "tTdslLao::O::AM:C:vh", longopts, NULL)) != -1) { + while((opt = getopt_long(argc, argv, "tTdslLbao::O::AM:C:vh", longopts, NULL)) != -1) { switch(opt) { case 's': asmode.src = true; @@ -169,6 +169,9 @@ int main(int argc, char *argv[]) case 'd': execmode.dump = true; break; + case 'b': + execmode.debugger = true; + break; case 'M': memsize = atoi(optarg); break; diff --git a/src/casl2rev.c b/src/casl2rev.c index 36e58c9..11a2f5e 100644 --- a/src/casl2rev.c +++ b/src/casl2rev.c @@ -2,99 +2,7 @@ #include "exec.h" /** - * @brief 汎用レジスタの番号からレジスタを表す文字列を返す - * - * @return 汎用レジスタを表す文字列。「GR0」「GR1」・・・「GR7」のいずれか - * - * @param word レジスタ番号[0-7]を表すWORD値 - */ -char *grstr(WORD word); - -/** - * @brief CASL IIのオブジェクトファイルを逆アセンブルし、標準出力へ出力する - * - * @return 正常終了時は0、異常終了時は0以外 - * - * @param *file オブジェクトファイルのファイル名 - */ -bool disassemble(const char *file); - -char *grstr(WORD word) -{ - assert(word <= 7); - char *str = malloc_chk(3 + 1, "grstr.str"); - sprintf(str, "GR%d", word); - return str; -} - -bool disassemble(const char *file) -{ - bool stat = true; - FILE *fp; - WORD i = 0, w, cmd, r, x, r1, r2, adr; - CMDTYPE cmdtype = 0; - char *cmdname, *g1, *g2; - - assert(file != NULL); - if((fp = fopen(file, "rb")) == NULL) { - perror(file); - return false; - } - - create_code_cmdtype(); /* 命令のコードとタイプがキーのハッシュ表を作成 */ - - fprintf(stdout, "MAIN\tSTART\n"); - for(; ;) { - fread(&w, sizeof(WORD), 1, fp); - if(feof(fp)) { - break; - } - cmd = w & 0xFF00; - cmdname = getcmdname(cmd); - cmdtype = getcmdtype(cmd); - if(cmd == 0xFF00 || (w != 0 && cmd == 0x0000)) { - fprintf(stdout, "\tDC\t%d\t\t\t\t; #%04X: #%04X :: ", w, i++, w); - print_dumpword(w, true); - } else if(cmdtype == R_ADR_X || cmdtype == ADR_X) { - fread(&adr, sizeof(WORD), 1, fp); - fprintf(stdout, "\t%s\t", cmdname); - if(cmdtype == R_ADR_X) { - r = (w & 0x00F0) >> 4; - fprintf(stdout, "%s,", g1 = grstr(r)); - FREE(g1); - } - fprintf(stdout, "#%04X", adr); - if((x = w & 0x000F) != 0) { - fprintf(stdout, ",%s", g1 = grstr(x)); - FREE(g1); - } - fprintf(stdout, "\t\t\t\t; #%04X: #%04X #%04X", i, w, adr); - i += 2; - } else { - fprintf(stdout, "\t%s", cmdname); - if(cmdtype == R1_R2) { - r1 = (w & 0x00F0) >> 4; - r2 = w & 0x000F; - fprintf(stdout, "\t%s,%s", g1 = grstr(r1), g2 = grstr(r2)); - FREE(g1); - FREE(g2); - } else if(cmdtype == R_) { - r = (w & 0x00F0) >> 4; - fprintf(stdout, "\t%s", g1 = grstr(r)); - FREE(g1); - } - fprintf(stdout, "\t\t\t\t; #%04X: #%04X", i++, w); - } - fprintf(stdout, "\n"); - } - fprintf(stdout, "\tEND\n"); - free_code_cmdtype(); - fclose(fp); - return stat; -} - -/** - * disassembleコマンドのオプション + * @brief casl2revコマンドのオプション */ static struct option longopts[] = { {"version", no_argument, NULL, 'v' }, @@ -139,7 +47,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "disassemble error - %d: %s\n", cerr->num, cerr->msg); exit(1); } - disassemble(argv[optind]); /* プログラム実行 */ + disassemble_file(argv[optind]); /* プログラム実行 */ stat = (cerr->num == 0) ? 0 : 1; /* エラーの解放 */ freecerr(); diff --git a/src/comet2.c b/src/comet2.c index 1bef35e..73669a7 100644 --- a/src/comet2.c +++ b/src/comet2.c @@ -9,6 +9,7 @@ static struct option longopts[] = { {"tracearithmetic", no_argument, NULL, 't'}, {"tracelogical", no_argument, NULL, 'T'}, {"dump", no_argument, NULL, 'd'}, + {"debug", no_argument, NULL, 'b'}, {"memorysize", required_argument, NULL, 'M'}, {"clocks", required_argument, NULL, 'C'}, { "version", no_argument, NULL, 'v' }, @@ -29,7 +30,7 @@ int main(int argc, char *argv[]) int memsize = DEFAULT_MEMSIZE, clocks = DEFAULT_CLOCKS; int opt, stat = 0; const char *version = PACKAGE_VERSION, *cmdversion = "comet2 of YACASL2 version %s\n"; - const char *usage = "Usage: %s [-tTdvh] [-M ] [-C ] FILE\n"; + const char *usage = "Usage: %s [-btTdvh] [-M ] [-C ] FILE\n"; cerr_init(); addcerrlist_load(); @@ -48,6 +49,9 @@ int main(int argc, char *argv[]) case 'd': execmode.dump = true; break; + case 'b': + execmode.debugger = true; + break; case 'M': memsize = atoi(optarg); break; diff --git a/src/exec.c b/src/exec.c index aea3be7..718a936 100644 --- a/src/exec.c +++ b/src/exec.c @@ -75,6 +75,16 @@ WORD get_adr_x(WORD adr, WORD oprx); */ WORD get_val_adr_x(WORD adr, WORD oprx); +/** + * @brief 汎用レジスタの番号からレジスタを表す文字列を返す + * + * @return 汎用レジスタを表す文字列。「GR0」「GR1」・・・「GR7」のいずれか + * + * @param word レジスタ番号[0-7]を表すWORD値 + */ +char *grstr(WORD word); + + /** * @brief 実行エラーの定義 */ @@ -99,9 +109,9 @@ static CERR cerr_load[] = { }; /** - * @brief 実行モード: trace, logical, dump + * @brief 実行モード: trace, logical, dump, debugger */ -EXECMODE execmode = {false, false, false}; +EXECMODE execmode = {false, false, false, false}; char *pr2str(WORD pr) { @@ -114,14 +124,14 @@ char *pr2str(WORD pr) void svcin() { int i; - char *buffer = malloc_chk(INSIZE + 1, "svcin.buffer"); + char *buf = malloc_chk(INSIZE + 1, "svcin.buf"); - if(fgets(buffer, INSIZE, stdin) == NULL) { + if(fgets(buf, INSIZE, stdin) == NULL) { sys->memory[sys->cpu->gr[1]] = sys->memory[sys->cpu->gr[2]] = 0x0; return; } for(i = 0; i < INSIZE; i++) { - if(*(buffer + i) == '\0' || *(buffer + i) == '\n') { + if(*(buf + i) == '\0' || *(buf + i) == '\n') { --i; break; } @@ -129,10 +139,10 @@ void svcin() setcerr(208, ""); /* SVC input - memory overflow */ break; } - sys->memory[sys->cpu->gr[1]+i] = *(buffer + i); + sys->memory[sys->cpu->gr[1]+i] = *(buf + i); } sys->memory[sys->cpu->gr[2]] = i + 1; - FREE(buffer); + FREE(buf); } void svcout() @@ -768,6 +778,40 @@ void svc() sys->cpu->pr += 2; } +char *grstr(WORD word) +{ + assert(word <= 7); + char *str = malloc_chk(3 + 1, "grstr.str"); + sprintf(str, "GR%d", word); + return str; +} + +void debugger() +{ + char *buf = malloc_chk(DBINSIZE + 1, "debugger.buf"); + for( ; ;) { + fprintf(stdout, "COMET II (Type ? for help) > "); + fgets(buf, DBINSIZE, stdin); + if(*buf == 'r') { + execmode.debugger = false; + break; + } else if(*buf == 's') { + break; + } else if(*buf == 't') { + fprintf(stdout, "#%04X: Register::::\n", sys->cpu->pr); + dspregister(); + } else if(*buf == 'd') { + dumpmemory(); + } else if(*buf == '?') { + fprintf(stdout, "r -- Continue running your program.\n"); + fprintf(stdout, "s -- Continue running your program until next interaction.\n"); + fprintf(stdout, "t -- Display CPU register.\n"); + fprintf(stdout, "d -- Display memory dump.\n"); + break; + } + } +} + void exec() { clock_t clock_begin, clock_end; @@ -792,6 +836,10 @@ void exec() } fprintf(stdout, "\n"); } + /* デバッガーモードの場合、デバッガーを起動 */ + if(execmode.debugger == true) { + debugger(); + } /* プログラムレジスタをチェック */ if(sys->cpu->pr >= sys->memsize) { setcerr(201, s = pr2str(sys->cpu->pr)); /* Program Register (PR) - memory overflow */ @@ -832,3 +880,69 @@ execfin: fprintf(stderr, "Execute error - %d: %s\n", cerr->num, cerr->msg); } } + +bool disassemble_file(const char *file) +{ + bool stat = true; + FILE *fp; + WORD i = 0, w, cmd, x, adr; + CMDTYPE cmdtype = 0; + char *cmdname, *g, *g1, *g2; + + assert(file != NULL); + if((fp = fopen(file, "rb")) == NULL) { + perror(file); + return false; + } + + create_code_cmdtype(); /* 命令のコードとタイプがキーのハッシュ表を作成 */ + + fprintf(stdout, "MAIN\tSTART\n"); + for(; ;) { + fread(&w, sizeof(WORD), 1, fp); + if(feof(fp)) { + break; + } + cmd = w & 0xFF00; + cmdname = getcmdname(cmd); + cmdtype = getcmdtype(cmd); + if(cmd == 0xFF00 || (w != 0 && cmd == 0x0000)) { + fprintf(stdout, "\tDC\t%d\t\t\t\t; #%04X: #%04X :: ", w, i++, w); + print_dumpword(w, true); + } else if(cmdtype == R_ADR_X || cmdtype == ADR_X) { + fread(&adr, sizeof(WORD), 1, fp); + fprintf(stdout, "\t%s\t", cmdname); + if(cmdtype == R_ADR_X) { + g = grstr((w & 0x00F0) >> 4); + fprintf(stdout, "%s,", g); + FREE(g); + } + fprintf(stdout, "#%04X", adr); + if((x = w & 0x000F) != 0) { + fprintf(stdout, ",%s", g = grstr(x)); + FREE(g); + } + fprintf(stdout, "\t\t\t\t; #%04X: #%04X #%04X", i, w, adr); + i += 2; + } else { + fprintf(stdout, "\t%s", cmdname); + if(cmdtype == R1_R2) { + g1 = grstr((w & 0x00F0) >> 4); + g2 = grstr(w & 0x000F); + fprintf(stdout, "\t%s,%s", g1, g2); + FREE(g1); + FREE(g2); + } else if(cmdtype == R_) { + g = grstr((w & 0x00F0) >> 4); + fprintf(stdout, "\t%s", g); + FREE(g); + } + fprintf(stdout, "\t\t\t\t; #%04X: #%04X", i++, w); + } + fprintf(stdout, "\n"); + } + fprintf(stdout, "\tEND\n"); + free_code_cmdtype(); + fclose(fp); + return stat; +} diff --git a/test/system/casl2_opt/opt_h/0.txt b/test/system/casl2_opt/opt_h/0.txt index bf49402..72542f9 100644 --- a/test/system/casl2_opt/opt_h/0.txt +++ b/test/system/casl2_opt/opt_h/0.txt @@ -1 +1 @@ -Usage: ../../../../casl2 [-slLaAtTdvh] [-oO[]] [-M ] [-C ] FILE1[ FILE2 ...] +Usage: ../../../../casl2 [-slLaAtTdbvh] [-oO[]] [-M ] [-C ] FILE1[ FILE2 ...] diff --git a/test/system/casl2_opt/opt_opterr/0.txt b/test/system/casl2_opt/opt_opterr/0.txt index bf49402..72542f9 100644 --- a/test/system/casl2_opt/opt_opterr/0.txt +++ b/test/system/casl2_opt/opt_opterr/0.txt @@ -1 +1 @@ -Usage: ../../../../casl2 [-slLaAtTdvh] [-oO[]] [-M ] [-C ] FILE1[ FILE2 ...] +Usage: ../../../../casl2 [-slLaAtTdbvh] [-oO[]] [-M ] [-C ] FILE1[ FILE2 ...] diff --git a/test/system/comet2_opt/opt_h/0.txt b/test/system/comet2_opt/opt_h/0.txt index 9385315..3b0daf5 100644 --- a/test/system/comet2_opt/opt_h/0.txt +++ b/test/system/comet2_opt/opt_h/0.txt @@ -1 +1 @@ -Usage: ../../../../comet2 [-tTdvh] [-M ] [-C ] FILE +Usage: ../../../../comet2 [-btTdvh] [-M ] [-C ] FILE diff --git a/test/system/comet2_opt/opt_opterr/0.txt b/test/system/comet2_opt/opt_opterr/0.txt index 9385315..3b0daf5 100644 --- a/test/system/comet2_opt/opt_opterr/0.txt +++ b/test/system/comet2_opt/opt_opterr/0.txt @@ -1 +1 @@ -Usage: ../../../../comet2 [-tTdvh] [-M ] [-C ] FILE +Usage: ../../../../comet2 [-btTdvh] [-M ] [-C ] FILE -- 2.18.0