From: j8takagi Date: Tue, 10 Jul 2018 14:46:05 +0000 (+0900) Subject: comet2monitorの追加と、モニター機能作成 X-Git-Tag: v0.5p1~7 X-Git-Url: https://j8takagi.net/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2f0b91ab1a54973a084e1609b46a1432c8b8e334;p=YACASL2.git comet2monitorの追加と、モニター機能作成 --- diff --git a/.gitignore b/.gitignore index a78ba84..f72eba1 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ /comet2 /dumpword /casl2rev +/comet2monitor *.o *.o.casl !as/sample/hello.o diff --git a/Makefile b/Makefile index 29e29f1..bff31db 100644 --- a/Makefile +++ b/Makefile @@ -34,13 +34,13 @@ VERSIONFILES := include/version.h \ test/system/comet2_opt/opt_v/0.txt \ test/system/dumpword/opt_v/0.txt -CMDFILES := casl2 comet2 dumpword casl2rev +CMDFILES := casl2 comet2 dumpword casl2rev comet2monitor all: build INSTALL gtags build: $(MAKE) -C src all - @(for f in $(CMDFILES); do if test src/$$f -nt $$f; then $(CP) src/$$f $$f; fi; done) + @(for f in $(CMDFILES); do if test ! -e $$f -o src/$$f -nt $$f; then $(CP) src/$$f $$f; fi; done) gtags: $(if $(strip $(shell $(WHICH) $(GTAGS))),$(GTAGS),@$(ECHO) '$(GTAGS): not found') diff --git a/doc/manual.texi b/doc/manual.texi index 1c27aa2..69ff038 100644 --- a/doc/manual.texi +++ b/doc/manual.texi @@ -93,9 +93,8 @@ YACASL2の動作はCASL IIの仕様に準拠しているため、情報処理試 また、本パッケージ中にCASL IIのサンプルプログラムが多数収録されています。 YACASL2は、「ふつうの処理系」として動作します。 -ほかの多くのCASL IIエミュレータと違い、デバッガとして動作したり、 -コンピュータ内部の模式図を表示したりすることはありません。 -そのかわり、YACASL2は、次のような動作内容をすべてテキストで出力します。 +YACASL2の操作は、端末上のコマンドラインインターフェイス(CLI)で操作します。 +YACASL2は、次のような動作内容をすべてテキストで出力します。 @itemize @bullet @@ -112,10 +111,12 @@ YACASL2は、「ふつうの処理系」として動作します。 実行時のメモリの内容 @end itemize -出力された動作内容は、GNU/Linuxのさまざまなコマンド、 +YACASL2では、機械コードモニターを使い、動作中のCPUやメモリーを調べたりデバッグしたりすることもできます。 + +また、出力された動作内容は、GNU/Linuxのさまざまなコマンド、 たとえば、@command{cat}、@command{less}、@command{grep}、@command{wc}などを使って解析できます。 -YACASL2の操作は、端末上のコマンドラインインターフェイスで行います。 + @node Sample usage, casl2 invocation, Overview, Top @chapter YACASL2の使用例 @@ -821,7 +822,7 @@ $ @kbd{dumpword '#0048'} #0048: 72 = #0048 = 0000000001001000 = 'H' @end example -@unnumberedsubsec オプション +@unnumberedsec オプション @command{dumpword}は、次のオプションを指定できます。 diff --git a/doc_inner/Makefile b/doc_inner/Makefile index cdea34f..e57591f 100644 --- a/doc_inner/Makefile +++ b/doc_inner/Makefile @@ -35,7 +35,7 @@ $(DOXYGEN_DIR): $(DOXYSRCDIR)/Doxyfile ../src ../include $(CD) $(DOXYSRCDIR) && $(DOXYGEN) $(DOXYSRCDIR)/Doxyfile: Doxyfile - $(CP) -f Doxyfile $(DOXYSRCDIR)/ + @$(CP) -vf Doxyfile $(DOXYSRCDIR)/ # htagsのHTMLドキュメント作成先は、 # 引数DIRで指定されたディレクトリーの下のHTMLディレクトリー diff --git a/include/assemble.h b/include/assemble.h index 468f082..78f5b8a 100644 --- a/include/assemble.h +++ b/include/assemble.h @@ -10,6 +10,7 @@ #include #include "cerr.h" #include "cmem.h" +#include "exec.h" #include "hash.h" #include "struct.h" #include "word.h" @@ -186,6 +187,17 @@ void addcerrlist_assemble(); */ bool assemblefile(const char *file, PASS pass); +/** + * @brief 指定された1つまたは複数のファイルを2回アセンブル + * + * @return なし + * + * @param filec アセンブルするファイルの数 + * @param filev アセンブルするファイル名の配列 + * @param adr アセンブル結果を格納するアドレス + */ +void assemble(int filec, char *filev[], WORD adr); + /** * @brief ファイルにアセンブル結果を書き込む * diff --git a/include/disassemble.h b/include/disassemble.h index 345e727..4a56df6 100644 --- a/include/disassemble.h +++ b/include/disassemble.h @@ -1,7 +1,7 @@ #ifndef DISASSEMBLE_INCLUDE #define DISASSEMBLE_INCLUDE -#include "exec.h" +#include "struct.h" /** * @brief CASL IIのオブジェクトファイルを逆アセンブルし、標準出力へ出力する diff --git a/include/exec.h b/include/exec.h index 432d3fd..7940829 100644 --- a/include/exec.h +++ b/include/exec.h @@ -23,11 +23,12 @@ typedef struct { bool trace; /**<レジストリの内容をステップごとに表示する場合はtrue */ bool logical; /**<レジストリの内容を論理値(0から65535)で表示する場合はtrue */ bool dump; /**<メモリの内容をステップごとに表示する場合はtrue */ - bool step; /**<ステップ実行の場合はtrue */ + bool monitor; /**<モニターモードの場合はtrue */ + bool step; /**<ステップ実行の場合はtrue */ } EXECMODE; /** - * @brief 実行モード: trace, logical, dump, step + * @brief 実行モード: trace, logical, dump, monitor, step */ extern EXECMODE execmode; @@ -43,17 +44,13 @@ void addcerrlist_load(); /** * @brief 指定されたファイルからアセンブル結果を読み込む - */ -bool loadassemble(const char *file); - -/** - * @brief 汎用レジスタの番号からレジスタを表す文字列を返す * - * @return 汎用レジスタを表す文字列。「GR0」「GR1」・・・「GR7」のいずれか + * @return 読み込み終了アドレス。読み込めなかった場合は、0 * - * @param word レジスタ番号[0-7]を表すWORD値 + * @param file 読み込むファイル名 + * @param start 読み込み開始アドレス */ -char *grstr(WORD word); +WORD loadassemble(const char *file, WORD start); /** * @class Exec diff --git a/include/monitor.h b/include/monitor.h index 9a83f88..b2f648e 100644 --- a/include/monitor.h +++ b/include/monitor.h @@ -4,6 +4,7 @@ #include #include #include +#include "assemble.h" #include "hash.h" #include "cmem.h" #include "cerr.h" diff --git a/include/struct.h b/include/struct.h index d4d87d2..e36c13f 100644 --- a/include/struct.h +++ b/include/struct.h @@ -125,6 +125,15 @@ typedef struct { extern EXECPTR *execptr; +/** + * @brief 汎用レジスタの番号からレジスタを表す文字列を返す + * + * @return 汎用レジスタを表す文字列。「GR0」「GR1」・・・「GR7」のいずれか + * + * @param word レジスタ番号[0-7]を表すWORD値 + */ +char *grstr(WORD word); + /** * COMET II仮想マシンのリセット */ diff --git a/src/.gitignore b/src/.gitignore index b9840fb..344654b 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -5,4 +5,5 @@ tags casl2 comet2 dumpword -casl2rev \ No newline at end of file +casl2rev +comet2monitor diff --git a/src/Makefile b/src/Makefile index 59749cc..fbc5ad5 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,9 +1,9 @@ # ソースファイル。グループに分類 -CMDOBJ := casl2 comet2 dumpword casl2rev +CMDOBJ := casl2 comet2 dumpword casl2rev comet2monitor COMMONOBJ := word cmem cerr -CASL2OBJ := struct hash +STRUCTOBJ := struct hash ASOBJ := assemble token label -EXECOBJ := exec dump disassemble monitor +EXECOBJ := exec dump monitor disassemble # ヘッダファイル INCLUDEDIR := ../include @@ -21,22 +21,24 @@ WHICH := which all: build tag -# casl2、comet2、dumpwordのビルド +# casl2、comet2、dumpword、casl2rev、comet2monitorのビルド build: $(CMDOBJ) -casl2: $(addsuffix .o,casl2 $(COMMONOBJ) $(CASL2OBJ) $(ASOBJ) $(EXECOBJ)) +casl2: $(addsuffix .o,casl2 $(COMMONOBJ) $(STRUCTOBJ) $(ASOBJ) $(EXECOBJ)) -comet2: $(addsuffix .o,comet2 $(COMMONOBJ) $(CASL2OBJ) $(EXECOBJ)) +comet2: $(addsuffix .o,comet2 $(COMMONOBJ) $(STRUCTOBJ) $(ASOBJ) $(EXECOBJ)) dumpword: $(addsuffix .o,dumpword $(COMMONOBJ)) -casl2rev:$(addsuffix .o,casl2rev $(COMMONOBJ) $(CASL2OBJ) $(EXECOBJ)) +casl2rev:$(addsuffix .o,casl2rev $(COMMONOBJ) $(STRUCTOBJ) $(ASOBJ) $(EXECOBJ)) + +comet2monitor:$(addsuffix .o,comet2monitor $(COMMONOBJ) $(STRUCTOBJ) $(ASOBJ) $(EXECOBJ)) # .dファイルからヘッダファイルの依存関係を取得する # tags、check、clean、.d で終わるターゲットの場合は除く NODEP := %tags %check %clean %.d ifeq ($(filter $(NODEP),$(MAKECMDGOALS)),) - -include $(addsuffix .d,$(CMDOBJ) $(COMMONOBJ) $(CASL2OBJ) $(ASOBJ) $(EXECOBJ)) + -include $(addsuffix .d,$(CMDOBJ) $(COMMONOBJ) $(STRUCTOBJ) $(ASOBJ) $(EXECOBJ)) endif # tagファイル作成 - ctags & etags diff --git a/src/assemble.c b/src/assemble.c index 8318d18..ecfe900 100644 --- a/src/assemble.c +++ b/src/assemble.c @@ -749,6 +749,50 @@ bool assemblefile(const char *file, PASS pass) return (cerr->num == 0) ? true : false; } +void assemble(int filec, char *filev[], WORD adr) +{ + int i; + PASS pass; + WORD bp[filec]; + + create_cmdtype_code(); /* 命令の名前とタイプがキーのハッシュ表を作成 */ + asptr = malloc_chk(sizeof(ASPTR), "asptr"); /* アセンブル時のプロパティ用の領域確保 */ + asptr->prog = malloc_chk(LABELSIZE + 1, "asptr.prog"); + asptr->ptr = adr; + /* アセンブル。ラベル表作成のため、2回行う */ + for(pass = FIRST; pass <= SECOND; pass++) { + for(i = 0; i < filec; i++) { + /* データの格納開始位置 */ + if(pass == FIRST) { + bp[i] = asptr->ptr; + } else if(pass == SECOND) { + asptr->ptr = bp[i]; + } + if(execmode.trace == true || execmode.dump == true || + asmode.src == true || asmode.label == true || asmode.asdetail == true) + { + fprintf(stdout, "\nAssemble %s (%d)\n", filev[i], pass); + } + /* ファイルをアセンブル */ + if(assemblefile(filev[i], pass) == false) { + goto asfin; + } + } + if(pass == FIRST && asmode.label == true) { + fprintf(stdout, "\nLabel::::\n"); + printlabel(); + if(asmode.onlylabel == true) { + break; + } + } + } +asfin: + freelabel(); /* ラベルハッシュ表を解放 */ + free_cmdtype_code(); /* 命令の名前とタイプがキーのハッシュ表を解放 */ + FREE(asptr->prog); /* アセンブル時のプロパティを解放 */ + FREE(asptr); +} + /* assemble.hで定義された関数群 */ void addcerrlist_assemble() { diff --git a/src/casl2.c b/src/casl2.c index a54adb8..fb4290a 100644 --- a/src/casl2.c +++ b/src/casl2.c @@ -1,6 +1,5 @@ #include "package.h" #include "assemble.h" -#include "exec.h" /** * @brief CASL IIのエラーをエラーリストに追加 @@ -18,16 +17,6 @@ void addcerrlist_casl2(); */ const char *objfile_name(const char *str); -/** - * @brief 指定された1つまたは複数のファイルを2回アセンブル - * - * @return なし - * - * @param filec アセンブルするファイルの数 - * @param filev アセンブルするファイル名の配列 - */ -void assemble(int filec, char *filev[]); - /** * @brief casl2コマンドのオプション */ @@ -69,50 +58,6 @@ const char *objfile_name(const char *str) return (str == NULL) ? default_name : str; } -void assemble(int filec, char *filev[]) -{ - int i; - PASS pass; - WORD bp[filec]; - - create_cmdtype_code(); /* 命令の名前とタイプがキーのハッシュ表を作成 */ - asptr = malloc_chk(sizeof(ASPTR), "asptr"); /* アセンブル時のプロパティ用の領域確保 */ - asptr->prog = malloc_chk(LABELSIZE + 1, "asptr.prog"); - asptr->ptr = 0; - /* アセンブル。ラベル表作成のため、2回行う */ - for(pass = FIRST; pass <= SECOND; pass++) { - for(i = 0; i < filec; i++) { - /* データの格納開始位置 */ - if(pass == FIRST) { - bp[i] = asptr->ptr; - } else if(pass == SECOND) { - asptr->ptr = bp[i]; - } - if(execmode.trace == true || execmode.dump == true || - asmode.src == true || asmode.label == true || asmode.asdetail == true) - { - fprintf(stdout, "\nAssemble %s (%d)\n", filev[i], pass); - } - /* ファイルをアセンブル */ - if(assemblefile(filev[i], pass) == false) { - goto asfin; - } - } - if(pass == FIRST && asmode.label == true) { - fprintf(stdout, "\nLabel::::\n"); - printlabel(); - if(asmode.onlylabel == true) { - break; - } - } - } -asfin: - freelabel(); /* ラベルハッシュ表を解放 */ - free_cmdtype_code(); /* 命令の名前とタイプがキーのハッシュ表を解放 */ - FREE(asptr->prog); /* アセンブル時のプロパティを解放 */ - FREE(asptr); -} - /** * @brief casl2コマンドのメイン * @@ -204,7 +149,7 @@ int main(int argc, char *argv[]) for(i = 0; i < argc - optind; i++) { /* 引数からファイル名配列を取得 */ af[i] = argv[optind + i]; } - assemble(i, af); /* アセンブル */ + assemble(i, af, 0); /* アセンブル */ if(asmode.onlylabel == true || cerr->num > 0) { goto casl2fin; } diff --git a/src/comet2.c b/src/comet2.c index a3d6ee1..55bab75 100644 --- a/src/comet2.c +++ b/src/comet2.c @@ -46,7 +46,7 @@ int main(int argc, char *argv[]) execmode.dump = true; break; case 'm': - execmode.step = true; + execmode.monitor = true; break; case 'M': memsize = atoi(optarg); @@ -73,18 +73,15 @@ int main(int argc, char *argv[]) if(argv[optind] == NULL) { setcerr(211, ""); /* object file not specified */ fprintf(stderr, "comet2 error - %d: %s\n", cerr->num, cerr->msg); - freecerr(); /* エラーの解放 */ - exit(1); + goto fin; } - - /* COMET II仮想マシンのリセット */ - reset(memsize, clocks); + reset(memsize, clocks); /* COMET II仮想マシンのリセット */ execptr->start = 0; - if(loadassemble(argv[optind]) == true) { - exec(); /* プログラム実行 */ + if((execptr->end = loadassemble(argv[optind], execptr->start)) > 0 && cerr->num == 0) { + exec(); /* プログラム実行 */ } - /* COMET II仮想マシンのシャットダウン */ - shutdown(); + shutdown(); /* COMET II仮想マシンのシャットダウン */ +fin: stat = (cerr->num == 0) ? 0 : 1; freecerr(); /* エラーの解放 */ return stat; diff --git a/src/comet2monitor.c b/src/comet2monitor.c index d6fcbea..65f4241 100644 --- a/src/comet2monitor.c +++ b/src/comet2monitor.c @@ -24,7 +24,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 *version = PACKAGE_VERSION, *cmdversion = "comet2monitor: COMET II machine code monitor of YACASL2 version %s\n"; const char *usage = "Usage: %s [-vh] [-M ] [-C ]\n"; /* オプションの処理 */ @@ -55,8 +55,8 @@ int main(int argc, char *argv[]) /* COMET II仮想マシンのリセット */ reset(memsize, clocks); execptr->start = 0; - execmode.step = true; - exec(); /* プログラム実行 */ + execmode.monitor = true; + exec(); /* プログラム実行 */ shutdown(); stat = (cerr->num == 0) ? 0 : 1; freecerr(); /* エラーの解放 */ diff --git a/src/disassemble.c b/src/disassemble.c index ff24e3c..8f3c9d7 100644 --- a/src/disassemble.c +++ b/src/disassemble.c @@ -74,10 +74,7 @@ void disassemble_cmd_r(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD pra * * @return なし * - * @param cmdtype コマンドの種類 - * @param *cmdname コマンドの名前 * @param word ワード値 - * @param adr アドレス値 * @param pradr 次に実行すべき命令語の先頭アドレス */ void disassemble_dc(WORD word, WORD pradr); diff --git a/src/exec.c b/src/exec.c index b22fbf4..c7c125e 100644 --- a/src/exec.c +++ b/src/exec.c @@ -94,9 +94,9 @@ static CERR cerr_load[] = { }; /** - * @brief 実行モード: trace, logical, dump, step + * @brief 実行モード: trace, logical, dump, monitor, step */ -EXECMODE execmode = {false, false, false, false}; +EXECMODE execmode = {false, false, false, false, false}; char *pr2str(WORD pr) { @@ -226,25 +226,23 @@ void addcerrlist_exec() addcerrlist(ARRAYSIZE(cerr_exec), cerr_exec); } -bool loadassemble(const char *file) +WORD loadassemble(const char *file, WORD start) { FILE *fp; - bool stat = true; + WORD end; assert(file != NULL); if((fp = fopen(file, "rb")) == NULL) { perror(file); - return false; + return 0; } - execptr->end = execptr->start + - fread(sys->memory, sizeof(WORD), sys->memsize - execptr->start, fp); - if(execptr->end == sys->memsize) { + end = start + fread(sys->memory + start, sizeof(WORD), sys->memsize - start, fp); + if(end == sys->memsize) { setcerr(210, file); /* load - memory overflow */ fprintf(stderr, "Load error - %d: %s\n", cerr->num, cerr->msg); - stat = false; } fclose(fp); - return stat; + return end; } void nop() @@ -763,19 +761,12 @@ 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 exec() { clock_t clock_begin, clock_end; void (*cmdptr)(); char *s; + const char *monmsg = "COMET II machine code monitor. Type ? for help.\n"; create_code_cmdtype(); /* 命令のコードとタイプがキーのハッシュ表を作成 */ if(execmode.trace == true) { @@ -795,8 +786,14 @@ void exec() } fprintf(stdout, "\n"); } - /* デバッガーモードの場合、デバッガーを起動 */ - if(execmode.step == true || getbps(sys->cpu->pr) == true) { + /* ステップモードまたはブレークポイントの場合、モニターを起動 */ + if( + (execmode.monitor == true && sys->cpu->pr == execptr->start) || + execmode.step == true || getbps(sys->cpu->pr) == true) + { + if(sys->cpu->pr == execptr->start) { + fprintf(stdout, "%s", monmsg); + } monitor(); } /* プログラムレジスタをチェック */ @@ -824,9 +821,14 @@ void exec() if(cerr->num > 0) { goto execfin; } - /* 終了フラグがtrueの場合は、正常終了 */ + /* 終了フラグがtrueの場合は、モニターまたは正常終了 */ if(execptr->stop == true) { - break; + if(execmode.monitor == true) { + fprintf(stdout, "Return to top.\n"); + monitor(); + } else { + break; + } } /* クロック周波数の設定 */ do { diff --git a/src/monitor.c b/src/monitor.c index 24f2156..4278c6a 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -253,13 +253,26 @@ void mon_dump(int argc, char *argv[]) MONCMDTYPE monitorcmd(char *cmd, MONARGS *args) { MONCMDTYPE cmdtype = MONREPEAT; - if(stracmp(cmd, 2, (char* []){"b", "break"})) { + if(stracmp(cmd, 2, (char* []){"a", "assemble"})) { + if(args->argc == 0) { + fprintf(stderr, "Error: Input file name.\n"); + } else if(args->argc == 1) { + assemble(1, (char* []){args->argv[0]}, 0); + } else { + assemble(1, (char* []){args->argv[0]}, nh2word(args->argv[1])); + } + } else if(stracmp(cmd, 2, (char* []){"b", "break"})) { mon_break(args->argc, args->argv); } else if(stracmp(cmd, 2, (char* []){"c", "continue"})) { execmode.step = false; cmdtype = MONNEXT; } else if(stracmp(cmd, 2, (char* []){"d", "dump"})) { mon_dump(args->argc, args->argv); + } else if(stracmp(cmd, 2, (char* []){"l", "load"})) { + loadassemble(args->argv[0], nh2word(args->argv[1])); + } else if(stracmp(cmd, 2, (char* []){"n", "next"})) { + execmode.step = true; + cmdtype = MONNEXT; } else if(stracmp(cmd, 2, (char* []){"q", "quit"})) { fprintf(stdout, "Quit: COMET II monitor\n"); cmdtype = MONQUIT; @@ -267,9 +280,9 @@ MONCMDTYPE monitorcmd(char *cmd, MONARGS *args) if(args->argc == 2) { disassemble_memory(nh2word(args->argv[0]), nh2word(args->argv[1])); } - } else if(stracmp(cmd, 2, (char* []){"s", "step"})) { - execmode.step = true; - cmdtype = MONNEXT; + } else if(stracmp(cmd, 1, (char* []){"reset"})) { + fprintf(stdout, "Reset COMET II.\n"); + reset(sys->memsize, sys->clocks); /* COMET II仮想マシンのリセット */ } else if(stracmp(cmd, 2, (char* []){"t", "trace"})) { if(args->argc > 0 && stracmp(args->argv[0], 2, (char* []){"a", "auto"})) { execmode.logical = false; @@ -294,9 +307,12 @@ MONCMDTYPE monitorcmd(char *cmd, MONARGS *args) fprintf(stdout, "b[reak] -- Manipulate Breakpoints. See details, `b ?'.\n"); fprintf(stdout, "c[ontinue] -- Continue running your program.\n"); fprintf(stdout, "d[ump] -- Display memory dump. `d[ump] a[uto]/n[oauto]' set auto/noauto display.\n"); + fprintf(stdout, "l[oad] -- Load object from a file to the memory. `l[oad]
' if address is omitted, load to address 0.\n"); + fprintf(stdout, "n[ext] -- Go next instruction.\n"); fprintf(stdout, "q[uit] -- Quit running your program.\n"); + fprintf(stdout, "reset -- Reset the system.\n"); fprintf(stdout, "r[everse] -- Disassemble memory. `r[everse] .\n"); - fprintf(stdout, "s[tep] -- Step by step running your program until next interaction.\n"); + fprintf(stdout, "s[ave] -- Save object from the memory to a file. `s[ave] [ []]' if and is omitted, save the whole memory. if is omitted, save the memory after .\n"); fprintf(stdout, "t[race] -- Display CPU register. `t[race] a[uto]/n[oauto]' set auto/noauto display. \n"); fprintf(stdout, "T[race] -- Display CPU register as logical value. `t[race] a[uto]/n[oauto]' set auto/noauto display. \n"); fprintf(stdout, "?/h[elp] -- Display this help.\n"); @@ -327,8 +343,9 @@ void monitor() char *buf, *p; MONCMDLINE *moncmdl; MONCMDTYPE cmdtype = MONREPEAT; + do { - fprintf(stdout, "COMET II (Type ? for help) > "); + fprintf(stdout, "- "); buf = malloc_chk(MONINSIZE + 1, "monitor.buf"); fgets(buf, MONINSIZE, stdin); if((p = strchr(buf, '\n')) != NULL) { diff --git a/src/struct.c b/src/struct.c index c1a1542..12caf87 100644 --- a/src/struct.c +++ b/src/struct.c @@ -238,6 +238,18 @@ char *getcmdname(WORD code) return cmd; } +/** + * 汎用レジスタの番号からレジスタを表す文字列を返す + */ + +char *grstr(WORD word) +{ + assert(word <= 7); + char *str = malloc_chk(3 + 1, "grstr.str"); + sprintf(str, "GR%d", word); + return str; +} + /** * コードがキーの命令ハッシュ表を解放する */