diff --git a/CHANGES.md b/CHANGES.md
index eec918f..8321f7b 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,8 @@
# Changes
+## Version 0.3.2
+- `vgsdrun` にステップ実行機能 ( `-s` オプション ) を追加
+
## Version 0.3.1
- `vgsdrun` の出力結果にラベル情報を表示するように変更
- `vgsasm` のテストを追加
diff --git a/README.md b/README.md
index 22713fa..815d0c2 100644
--- a/README.md
+++ b/README.md
@@ -282,17 +282,18 @@ negative:
## Debugger
### vgsdrun command
-アセンブリ言語ソース (.asm) ファイルを実際に vgs-cpu で実行した時の流れを表示
```
-$ vgsdrun input-source
+$ vgsdrun [-s] input-source
```
+- アセンブリ言語ソース (.asm) ファイルを実際に vgs-cpu で実行した時の流れを表示
+- `-s` オプションを指定すればステップ実行
#### record format
```
: opcodes : line# > assembly-source
```
-#### example
+#### example: run all
```
$ ./vgsdrun src/test/asm_add_a.asm
assembling: src/test/asm_add_a.asm on memory
@@ -360,8 +361,32 @@ starting debug run.
000000ff: 46 01 : line#00070 > LD D, 1
00000101: 00 : line#00071 > BRK
-[registers]
+registers:
c->r.a = 22222222, c->r.b = 11110000, c->r.c = 00001111, c->r.d = 00000001
c->r.p = 00000101, c->r.s = 00000000, c->f.z = 00000000, c->f.q = 00000000
$
```
+
+#### example: step execution
+```
+$ ./vgsdrun src/test/asm_mul.asm -s
+assembling: src/test/asm_mul.asm on memory
+starting debug run.
+00000000: ----- start-a -----
+00000000: 08 E8 03 : line#00006 > LD A, 1000
+00000003: 6F 64 : line#00007 > MUL A, 100
+00000005: A7 A0 86 01 00 : line#00008 > CMP A, 100000
+0000000a: F8 08 03 00 00 : line#00009 > JNE $308 (test-failed)
+> h
+command usage:
+- h ... help
+- r ... show registers
+- q ... quit
+- other ... execute next line
+> r
+registers:
+c->r.a = 000186A0, c->r.b = 00000000, c->r.c = 00000000, c->r.d = 00000000
+c->r.p = 0000000A, c->r.s = 00000000, c->f.z = 00000000, c->f.q = 00000000
+> q
+$
+```
\ No newline at end of file
diff --git a/src/asm/vgsasm.c b/src/asm/vgsasm.c
index ea1ebc8..7428a36 100644
--- a/src/asm/vgsasm.c
+++ b/src/asm/vgsasm.c
@@ -19,6 +19,11 @@ static int check_arguments(int argc, char* argv[])
if (argc <= ++i) return -1;
if (sizeof(PT.output) <= strlen(argv[i])) return -1;
strcpy(PT.output, argv[i]);
+#ifdef VGSDRUN
+ } else if (0 == strcmp("-s", argv[i])) {
+ if (PT.step_exec) return -1;
+ PT.step_exec = 1;
+#endif
} else {
if (PT.input[0]) return -1;
if (sizeof(PT.input) <= strlen(argv[i])) return -1;
diff --git a/src/asm/vgsasm.h b/src/asm/vgsasm.h
index ad422ba..7c226bc 100644
--- a/src/asm/vgsasm.h
+++ b/src/asm/vgsasm.h
@@ -71,6 +71,7 @@ struct program_table {
char* buffer;
struct line_data* line;
int line_number;
+ int step_exec;
};
char* load_file(const char* path);
diff --git a/src/asm/vgsdrun.c b/src/asm/vgsdrun.c
index 04630f1..4b1fc4d 100644
--- a/src/asm/vgsdrun.c
+++ b/src/asm/vgsdrun.c
@@ -115,13 +115,40 @@ int vgsdrun(struct program_table* pt)
return 0;
}
+static void put_registers(struct vgscpu_context* c)
+{
+ printf("registers:\n");
+ printf("c->r.a = %08X, c->r.b = %08X, c->r.c = %08X, c->r.d = %08X\n", c->r.a, c->r.b, c->r.c, c->r.d);
+ printf("c->r.p = %08X, c->r.s = %08X, c->f.z = %08X, c->f.q = %08X\n", c->r.p, c->r.s, c->f.z, c->f.z);
+}
+
void vgsdrun_callback(struct vgscpu_context* c)
{
if (show_op(c->r.p)) {
printf("invalid address: $%x\n", c->r.p);
} else if (0x00 == c->p[c->r.p]) {
- printf("\n[registers]\n");
- printf("c->r.a = %08X, c->r.b = %08X, c->r.c = %08X, c->r.d = %08X\n", c->r.a, c->r.b, c->r.c, c->r.d);
- printf("c->r.p = %08X, c->r.s = %08X, c->f.z = %08X, c->f.q = %08X\n", c->r.p, c->r.s, c->f.z, c->f.z);
+ puts("");
+ put_registers(c);
+ } else if (PT.step_exec) {
+ while (1) {
+ char buf[1024];
+ printf("> ");
+ buf[sizeof(buf) - 1] = '\0';
+ if (!fgets(buf, sizeof(buf) - 1, stdin)) return;
+ if (0 == strncmp(buf, "h", 1)) {
+ puts("command usage:");
+ puts("- h ... help");
+ puts("- r ... show registers");
+ puts("- q ... quit");
+ puts("- other ... execute next line");
+ } else if (0 == strncmp(buf, "r", 1)) {
+ put_registers(c);
+ } else if (0 == strncmp(buf, "q", 1)) {
+ exit(0);
+ } else {
+ printf("\033[1A");
+ break;
+ }
+ }
}
}