*/
void freebps();
+
+/**
+ * @brief モニター終了時の処理をする
+ *
+ */
+int monquit();
+
/**
* @brief COMET IIモニターを起動する
*
/**
* COMET II仮想マシンのリセット
*/
-void reset(int memsize, int clocks);
+void comet2_init(int memsize, int clocks);
+
+/**
+ * COMET II仮想マシンのCPUをリセット
+ */
+void comet2_reset();
+
+/**
+ * COMET II仮想マシンのCPUとメモリをリセット
+ */
+void comet2_resetall();
/**
* COMET II仮想マシンのシャットダウン
*/
-void shutdown();
+void comet2_shutdown();
/**
* @brief 命令ハッシュ表を作成する
l hello.o
-d a 0 #22
+d 0 #22
r 0 #22
# コマンド
CC := gcc
CFLAGS := -g -Wall -Wextra -I$(INCLUDEDIR)
+LDFLAGS := -lreadline
CTAGS := ctags
ETAGS := etags
ECHO := echo
goto casl2fin;
}
create_cmdtable(HASH_CMDTYPE); /* 命令の名前とタイプがキーのハッシュ表を作成 */
- reset(memsize, clocks); /* 仮想マシンCOMET IIのリセット */
+ comet2_init(memsize, clocks); /* 仮想マシンCOMET IIの初期化 */
asfilecnt = argc - optind;
asfile = calloc_chk(asfilecnt, sizeof(char *), "asfile");
for(int i = 0; i < asfilecnt; i++) { /* 引数からファイル名配列を取得 */
exec(); /* 仮想マシンCOMET IIの実行 */
}
shutdown:
- shutdown(); /* 仮想マシンCOMET IIのシャットダウン */
+ comet2_shutdown(); /* 仮想マシンCOMET IIのシャットダウン */
casl2fin:
FREE(objfile);
FREE(asfile);
fprintf(stderr, "comet2 error - %d: %s\n", cerr->num, cerr->msg);
goto comet2fin;
}
- reset(memsize, clocks); /* COMET II仮想マシンのリセット */
+ comet2_init(memsize, clocks); /* COMET II仮想マシンの初期化 */
execptr->start = 0;
execptr->end = loadassemble(argv[optind], execptr->start);
if(execptr->end > 0 && cerr->num == 0) {
exec(); /* プログラム実行 */
}
- shutdown(); /* COMET II仮想マシンのシャットダウン */
+ comet2_shutdown(); /* COMET II仮想マシンのシャットダウン */
comet2fin:
if(cerr->num > 0) {
stat = 1;
warn_ignore_arg(argc - optind, argv + optind);
}
create_cmdtable(HASH_CMDTYPE);
- reset(memsize, clocks); /* COMET II仮想マシンのリセット */
+ comet2_init(memsize, clocks); /* COMET II仮想マシンの初期化 */
execptr->start = 0;
execmode.monitor = true;
exec(); /* プログラム実行 */
- shutdown();
+ comet2_shutdown();
comet2monitorfin:
free_cmdtable(HASH_CMDTYPE);
free_cmdtable(HASH_CODE);
+#include <readline/readline.h>
+#include <readline/history.h>
#include "monitor.h"
/**
/**
* @brief comet2monitorのプロンプト
*/
-static char *monitor_prompt = "(comet2 monitor)";
+static char *monitor_prompt = "(comet2 monitor) ";
unsigned adrhash(WORD adr)
{
{
int i = 0;
WORD dump_start = 0, dump_end = 0x40;
- if(argc > 0 && stracmp(argv[0], 2, (char* []){"a", "auto"})) {
+ if(stracmp(argv[0], 2, (char* []){"a", "auto"})) {
execmode.dump = true;
- i++;
- } else if(argc > 0 && stracmp(argv[0], 2, (char* []){"no", "noauto"})) {
+ } else if(stracmp(argv[0], 2, (char* []){"no", "noauto"})) {
execmode.dump = false;
- i++;
- }
- if(argc > i) {
- dump_start = nh2word(argv[i++]);
+ } else {
if(argc > i) {
- if(argv[i][0] =='+') {
- dump_end = dump_start + nh2word(argv[i] + 1);
+ dump_start = nh2word(argv[i++]);
+ if(argc > i) {
+ if(argv[i][0] =='+') {
+ dump_end = dump_start + nh2word(argv[i] + 1);
+ } else {
+ dump_end = nh2word(argv[i]) + 1;
+ }
} else {
- dump_end = nh2word(argv[i]);
+ dump_end += dump_start;
}
- } else {
- dump_end += dump_start;
}
- i++;
+ dumpmemory(dump_start, dump_end);
+ execmode.dump_start = dump_start;
+ execmode.dump_end = dump_end;
}
- if(argc > i) {
+ if(argc > ++i) {
warn_ignore_arg(argc - i, argv + i);
}
- dumpmemory(dump_start, dump_end);
- execmode.dump_start = dump_start;
- execmode.dump_end = dump_end;
}
MONCMDTYPE monitorcmd(char *cmd, MONARGS *args)
disassemble_memory(nh2word(args->argv[0]), nh2word(args->argv[1]));
}
} else if(stracmp(cmd, 1, (char* []){"reset"})) {
- fprintf(stdout, "Reset COMET II.\n");
- reset(sys->memsize, sys->clocks); /* COMET II仮想マシンのリセット */
+ fprintf(stdout, "Reset COMET II CPU.\n");
+ comet2_reset(); /* COMET II仮想マシンのCPUのリセット */
+ } else if(stracmp(cmd, 1, (char* []){"resetall"})) {
+ fprintf(stdout, "Reset COMET II CPU and memory.\n");
+ comet2_resetall(); /* COMET II仮想マシンのCPUとメモリのリセット */
} else if(stracmp(cmd, 2, (char* []){"t", "trace"})) {
if(args->argc > 0 && stracmp(args->argv[0], 2, (char* []){"a", "auto"})) {
execmode.logical = false;
dspregister();
}
} else if(stracmp(cmd, 3, (char* []){"?", "h", "help"})) {
+ fprintf(stdout, "!<system command> -- Run a system command.\n");
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] <filepath> <address>' 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, "reset -- Reset COMET II CPU.\n");
+ fprintf(stdout, "resetall -- Reset COMET II CPU and memory.\n");
fprintf(stdout, "r[everse] -- Disassemble memory. `r[everse] <start address> <end address>.\n");
fprintf(stdout, "s[ave] -- Save object from the memory to a file. `s[ave] <filepath> [<start address1> [<end address>]]' if <start address> and <end address> is omitted, save the whole memory. if <end address> is omitted, save the memory after <start address>.\n");
fprintf(stdout, "t[race] -- Display CPU register. `t[race] a[uto]/n[oauto]' set auto/noauto display. \n");
int monquit()
{
int stat = 0;
- shutdown();
+ comet2_shutdown();
freebps();
free_cmdtable(HASH_CMDTYPE);
free_cmdtable(HASH_CODE);
void monitor()
{
- char *buf = NULL;
+ static char *buf = NULL;
+ static char *last_buf = NULL;
MONCMDLINE *moncmdl = NULL;
MONCMDTYPE cmdtype = MONREPEAT;
do {
- fprintf(stdout, "%s ", monitor_prompt);
- buf = malloc_chk(MONINSIZE + 1, "monitor.buf");
- fgets(buf, MONINSIZE, stdin);
- if(!buf[0]) {
- cmdtype = MONQUIT;
+ buf = readline(monitor_prompt);
+ /* EOFの処理 */
+ if(buf == NULL) {
+ FREE(buf);
+ FREE(last_buf);
+ exit(monquit());
+ }
+ /* 空行(Enterだけ)の場合は、前回のコマンドをリピート */
+ if(buf[0] == '\0') {
+ if(last_buf == NULL) {
+ /* 前回実行したコマンドがなければ何もしない */
+ FREE(buf);
+ fprintf(stdout, ">\n");
+ } else {
+ buf = strdup_chk(last_buf, "monitor.buf_repeat");
+ cmdtype = MONREPEAT;
+ }
+ } else {
+ strip_end(buf); /* 文字列末尾の改行と空白を削除 */
+ /* 履歴(ヒストリ)に追加 */
+ add_history(buf);
+ last_buf = strdup_chk(buf, "monitor.last_buf");
}
- strip_end(buf); /* 文字列末尾の改行と空白を削除 */
- fprintf(stdout, "%s\n", buf);
+ /* 実行コマンドをstdout に出力。ログに残すため */
+ fprintf(stdout, "> %s\n", buf);
+
if(buf[0] == '!') {
system(buf + 1);
} else if((moncmdl = monlinetok(buf)) != NULL) {
cmdtype = monitorcmd(moncmdl->cmd, moncmdl->args);
free_moncmdline(moncmdl);
}
- FREE(buf);
if(cmdtype == MONQUIT) {
+ FREE(buf);
+ FREE(last_buf);
exit(monquit());
}
} while(cmdtype == MONREPEAT);
+ FREE(buf);
+ FREE(last_buf);
}
return str;
}
+void cpu_reset() {
+ sys->cpu = malloc_chk(sizeof(CPU), "cpu");
+ for(int i = 0; i < GRSIZE; i++) { /* 汎用レジスタ */
+ sys->cpu->gr[i] = 0x0;
+ }
+ sys->cpu->sp = sys->memsize; /* スタックポインタ */
+ sys->cpu->pr = 0x0; /* プログラムレジスタ */
+ sys->cpu->fr = 0x0; /* フラグレジスタ */
+}
+
+void memory_reset() {
+}
+
+
/**
- * COMET II仮想マシンのリセット
+ * COMET II仮想マシンの初期化
*/
-void reset(int memsize, int clocks)
+void comet2_init(int memsize, int clocks)
{
sys = malloc_chk(sizeof(SYSTEM), "sys");
/* メモリサイズを設定 */
sys->memsize = memsize;
/* クロック周波数を設定 */
sys->clocks = clocks;
- /* メモリを初期化 */
+ /* メモリ領域の確保 */
sys->memory = calloc_chk(sys->memsize, sizeof(WORD), "memory");
- /* CPUを初期化 */
- sys->cpu = malloc_chk(sizeof(CPU), "cpu");
- for(int i = 0; i < GRSIZE; i++) { /* 汎用レジスタ */
- sys->cpu->gr[i] = 0x0;
- }
- sys->cpu->sp = sys->memsize; /* スタックポインタ */
- sys->cpu->pr = 0x0; /* プログラムレジスタ */
- sys->cpu->fr = 0x0; /* フラグレジスタ */
+ /* CPUをクリア */
+ cpu_reset();
/* CASL2プログラムの開始と終了のアドレスを初期化 */
execptr = malloc_chk(sizeof(EXECPTR), "execptr");
execptr->stop = false;
}
+/**
+ * COMET II仮想マシンのCPUリセット
+ */
+void comet2_reset()
+{
+ /* CPUをリセット */
+ cpu_reset();
+}
+
+/**
+ * COMET II仮想マシンのCPUとメモリをリセット
+ */
+void comet2_resetall()
+{
+ /* CPUをリセット */
+ cpu_reset();
+ /* メモリをリセット */
+ memset(sys->memory, 0, sys->memsize * sizeof(WORD));
+}
+
/**
* COMET II仮想マシンのシャットダウン
*/
-void shutdown()
+void comet2_shutdown()
{
FREE(execptr);
FREE(sys->memory);
COMET II machine code monitor. Type ? for help.
-(comet2 monitor) b ?
+> b ?
breakpoint manipulate:
b[reak] a[dd] <address>
b[reak] d[el] <address>
b[reak] l[ist]
b[reak] r[eset]
-(comet2 monitor)
COMET II machine code monitor. Type ? for help.
-(comet2 monitor) b ? 1
+> b ? 1
breakpoint manipulate:
b[reak] a[dd] <address>
b[reak] d[el] <address>
b[reak] l[ist]
b[reak] r[eset]
-(comet2 monitor)
Info: arguments '1' are ignored.
COMET II machine code monitor. Type ? for help.
-(comet2 monitor) l sum_10.o
-(comet2 monitor) d
+> l sum_10.o
+> d
#0000: adr : 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F
-------------------------------------------------------------------------------------
#0000: 0000: 7001 0000 7002 0000 3622 1010 0015 2621 2210 0017 4110 0016 6500 0010 6400 0007
#0000: 0010: 1120 0018 7120 7110 8100 0001 000A 0001 0000 0000 0000 0000 0000 0000 0000 0000
#0000: 0020: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
#0000: 0030: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
-(comet2 monitor)
COMET II machine code monitor. Type ? for help.
-(comet2 monitor) l sum_10.o
-(comet2 monitor) d 0
+> l sum_10.o
+> d 0
#0000: adr : 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F
-------------------------------------------------------------------------------------
#0000: 0000: 7001 0000 7002 0000 3622 1010 0015 2621 2210 0017 4110 0016 6500 0010 6400 0007
#0000: 0010: 1120 0018 7120 7110 8100 0001 000A 0001 0000 0000 0000 0000 0000 0000 0000 0000
#0000: 0020: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
#0000: 0030: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
-(comet2 monitor)
COMET II machine code monitor. Type ? for help.
-(comet2 monitor) l sum_10.o
-(comet2 monitor) d 0 #20
+> l sum_10.o
+> d 0 #20
#0000: adr : 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F
-------------------------------------------------------------------------------------
#0000: 0000: 7001 0000 7002 0000 3622 1010 0015 2621 2210 0017 4110 0016 6500 0010 6400 0007
#0000: 0010: 1120 0018 7120 7110 8100 0001 000A 0001 0000 0000 0000 0000 0000 0000 0000 0000
-(comet2 monitor)
+#0000: 0020: 0000
COMET II machine code monitor. Type ? for help.
-(comet2 monitor) l sum_10.o
-(comet2 monitor) d 0 #20 #40
+> l sum_10.o
+> d 0 #20 #40
#0000: adr : 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F
-------------------------------------------------------------------------------------
#0000: 0000: 7001 0000 7002 0000 3622 1010 0015 2621 2210 0017 4110 0016 6500 0010 6400 0007
#0000: 0010: 1120 0018 7120 7110 8100 0001 000A 0001 0000 0000 0000 0000 0000 0000 0000 0000
-(comet2 monitor)
+#0000: 0020: 0000
Info: arguments '#40' are ignored.
COMET II machine code monitor. Type ? for help.
-(comet2 monitor) l sum_10.o
-(comet2 monitor) d 0 +#20
+> l sum_10.o
+> d 0 +#20
#0000: adr : 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F
-------------------------------------------------------------------------------------
#0000: 0000: 7001 0000 7002 0000 3622 1010 0015 2621 2210 0017 4110 0016 6500 0010 6400 0007
#0000: 0010: 1120 0018 7120 7110 8100 0001 000A 0001 0000 0000 0000 0000 0000 0000 0000 0000
-(comet2 monitor)
COMET II machine code monitor. Type ? for help.
-(comet2 monitor) ?
+> ?
+!<system command> -- Run a system command.
b[reak] -- Manipulate Breakpoints. See details, `b ?'.
c[ontinue] -- Continue running your program.
d[ump] -- Display memory dump. `d[ump] a[uto]/n[oauto]' set auto/noauto display.
l[oad] -- Load object from a file to the memory. `l[oad] <filepath> <address>' if address is omitted, load to address 0.
n[ext] -- Go next instruction.
q[uit] -- Quit running your program.
-reset -- Reset the system.
+reset -- Reset COMET II CPU.
+resetall -- Reset COMET II CPU and memory.
r[everse] -- Disassemble memory. `r[everse] <start address> <end address>.
s[ave] -- Save object from the memory to a file. `s[ave] <filepath> [<start address1> [<end address>]]' if <start address> and <end address> is omitted, save the whole memory. if <end address> is omitted, save the memory after <start address>.
t[race] -- Display CPU register. `t[race] a[uto]/n[oauto]' set auto/noauto display.
T[race] -- Display CPU register as logical value. `t[race] a[uto]/n[oauto]' set auto/noauto display.
?/h[elp] -- Display this help.
-(comet2 monitor)
COMET II machine code monitor. Type ? for help.
-(comet2 monitor) l sum_10.o
-(comet2 monitor) d
+> l sum_10.o
+> d
#0000: adr : 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F
-------------------------------------------------------------------------------------
#0000: 0000: 7001 0000 7002 0000 3622 1010 0015 2621 2210 0017 4110 0016 6500 0010 6400 0007
#0000: 0010: 1120 0018 7120 7110 8100 0001 000A 0001 0000 0000 0000 0000 0000 0000 0000 0000
#0000: 0020: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
#0000: 0030: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
-(comet2 monitor)
COMET II machine code monitor. Type ? for help.
-(comet2 monitor) q
+> q
Quit: COMET II monitor
COMET II machine code monitor. Type ? for help.
-(comet2 monitor) l hello.o
-(comet2 monitor) d a 0 #22
+> l hello.o
+> d 0 #22
#0000: adr : 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F
-------------------------------------------------------------------------------------
#0000: 0000: 7001 0000 7002 0000 1210 0013 1220 0020 F000 0002 1210 0021 1220 0022 F000 0002
#0000: 0010: 7120 7110 8100 0048 0065 006C 006C 006F 002C 0020 0057 006F 0072 006C 0064 0021
-#0000: 0020: 000D 000A
-(comet2 monitor) r 0 #22
+#0000: 0020: 000D 000A 0001
+> r 0 #22
PUSH #0000,GR1 ; #0000: #7001 #0000
PUSH #0000,GR2 ; #0002: #7002 #0000
LAD GR1,#0013 ; #0004: #1210 #0013
DC 13 ; #0020: #000D :: 13 = #000D = 0000000000001101
DC 10 ; #0021: #000A :: 10 = #000A = 0000000000001010 = '\n'
DC 1 ; #0022: #0001 :: 1 = #0001 = 0000000000000001
-(comet2 monitor)