]> j8takagi.net git repositories - yacasl2.git/commitdiff
monitorで、逆アセンブル表示機能を追加し、デフォルト表示するように
authorj8takagi <j8takagi@nifty.com>
Fri, 26 Jun 2026 15:01:16 +0000 (00:01 +0900)
committerj8takagi <j8takagi@nifty.com>
Fri, 26 Jun 2026 15:01:16 +0000 (00:01 +0900)
https://claude.ai/share/6eb72216-cd19-4e32-9d59-b389e84d1c87

include/struct.h
src/comet2monitor.c
src/dump.c
src/exec.c
src/monitor.c
src/struct.c

index 36de1be5c7680563c9e0e6ab21caf6e6e9185734..9b8abb23a4bd5504223fd214700811b3b80a0107 100644 (file)
@@ -149,12 +149,13 @@ typedef struct {
     bool dump;            /**<メモリの内容をステップごとに表示する場合はtrue */
     WORD dump_start;      /**<メモリの内容をステップごとに表示する場合の開始アドレス */
     WORD dump_end;        /**<メモリの内容をステップごとに表示する場合の終了アドレス */
+    bool reverse;         /**<逆アセンブルの結果をステップごとに表示する場合はtrue */
     bool monitor;         /**<モニターモードの場合はtrue */
     bool step;            /**<ステップ実行の場合はtrue */
 } EXECMODE;
 
 /**
- * @brief 実行モード: trace, logical, dump, monitor, step
+ * @brief 実行モード: trace, logical, dump, reverse, monitor, step
  */
 extern EXECMODE execmode;
 
@@ -239,3 +240,9 @@ CMDTYPE getcmdtype(WORD code);
 char *getcmdname(WORD code);
 
 #endif
+
+/**
+ * 命令コードから、命令語長を返す\n
+ * 無効な場合は0を返す
+ */
+WORD code2cmdwordlen(WORD code);
index 338a2d061f1fc4a3b4847618da589aa7c509bd58..299802dc7541a7931639d0ed78c583f16a035bdc 100644 (file)
@@ -12,6 +12,7 @@ static struct option longopts[] = {
     {"tracearithmetic", no_argument, NULL, 't'},
     {"tracelogical", no_argument, NULL, 'T'},
     {"dump", no_argument, NULL, 'd'},
+    {"reverse", no_argument, NULL, 'r'},
     {"memorysize", required_argument, NULL, 'M'},
     {"clocks", required_argument, NULL, 'C'},
     {"version", no_argument, NULL, 'v' },
@@ -47,7 +48,7 @@ int main(int argc, char *argv[])
     int stat = 0;
     const char *version = PACKAGE_VERSION;
     const char *cmdversion = "comet2monitor: COMET II machine code monitor of YACASL2 version %s\n";
-    const char *usage = "Usage: %s [-tTdvh] [-M <MEMORYSIZE>] [-C <CLOCKS>] FILE\n";
+    const char *usage = "Usage: %s [-tTdrvh] [-M <MEMORYSIZE>] [-C <CLOCKS>] FILE\n";
 
     /* エラーの定義 */
     cerr_init();
@@ -55,8 +56,9 @@ int main(int argc, char *argv[])
     addcerrlist_exec();
     addcerrlist_comet2monitor();
 
+    execmode.reverse = true;
     /* オプションの処理 */
-    while((opt = getopt_long(argc, argv, "tTdM:C:vh", longopts, NULL)) != -1) {
+    while((opt = getopt_long(argc, argv, "tTdqM:C:vh", longopts, NULL)) != -1) {
         switch(opt) {
         case 't':
             execmode.trace = true;
@@ -68,6 +70,9 @@ int main(int argc, char *argv[])
         case 'd':
             execmode.dump = true;
             break;
+        case 'q':
+            execmode.reverse = false;
+            break;
         case 'M':
             if((memsize = memsize_str2word(optarg)) == 0) {
                 goto comet2monitorfin;
index a6c70d7a3559d41ef5397be426b2e5115195b11e..343cced291f5e07781c8bb7acfd62f45e94bd9dc 100644 (file)
@@ -1,4 +1,6 @@
 #include "exec.h"
+#include "struct.h"
+#include "disassemble.h"
 
 /* exec.hに定義された関数群 */
 void dumpmemory(WORD start, WORD end)
@@ -58,15 +60,23 @@ void dspregister()
 
 void dsp_trace_dump()
 {
-    if(execptr->stop == false && (execmode.dump || execmode.trace)) {      /* traceまたはdumpオプション指定時、改行を出力 */
-        if(execmode.trace) {                   /* traceオプション指定時、レジスタを出力 */
+    if(execptr->stop == false && (execmode.dump == true || execmode.trace == true || execmode.reverse == true)) {      /* traceまたはdumpオプション指定時、改行を出力 */
+        if(sys->cpu->pr == execptr->start && execmode.reverse == true) { /* reverseオプション指定時、スタート時にプログラム全体を逆アセンブル */
+            fprintf(stdout, "Disassemble::::\n");
+            disassemble_memory(execptr->start, execptr->end);
+        }
+        if(execmode.trace == true) { /* traceオプション指定時、レジスタを出力 */
             fprintf(stdout, "#%04X: Register::::\n", sys->cpu->pr);
             dspregister();
         }
-        if(execmode.dump) {                    /* dumpオプション指定時、メモリを出力 */
+        if(execmode.dump == true) { /* dumpオプション指定時、メモリを出力 */
             fprintf(stdout, "#%04X: Memory::::\n", sys->cpu->pr);
             dumpmemory(execmode.dump_start, execmode.dump_end);
         }
+        if(execmode.reverse == true) { /* reverseオプション指定時、ステップごとに語長分を逆アセンブル */
+            fprintf(stdout, "#%04X: Disassemble::::\n", sys->cpu->pr);
+            disassemble_memory(sys->cpu->pr, sys->cpu->pr + code2cmdwordlen(sys->memory[sys->cpu->pr] & 0xFF00) - 1);
+        }
         fprintf(stdout, "\n");
     }
 }
index e8f2f64754d4bcb2a9546b288ad9301690e3a66c..15df2611f930d59da9480fd3343c102d3c994296 100644 (file)
@@ -85,9 +85,9 @@ static CERR cerr_exec[] = {
 };
 
 /**
- * @brief 実行モード: trace, logical, dump, dump_start, dump_end,  monitor, step
+ * @brief 実行モード: trace, logical, dump, dump_start, dump_end, reverse, monitor, step
  */
-EXECMODE execmode = {false, false, false, 0, 0xFFFF, false, false};
+EXECMODE execmode = {false, false, false, 0, 0xFFFF, false, false, false};
 
 CLOCK clock_str2clock(const char *str) {
     long val = str2l_range(str, 1, LONG_MAX, "Clock");
index b742486a5fb473b5b35e12b32684861577a4f086..abbce7e960cf2368ea1fe143834f78250adaea5b 100644 (file)
@@ -301,8 +301,14 @@ MONCMDTYPE monitorcmd(char *cmd, MONARGS *args)
         fprintf(stdout, "Quit: COMET II monitor\n");
         cmdtype = MONQUIT;
     } else if(stracmp(cmd, 2, (char* []){"r", "reverse"})) {
-        if(args->argc == 2) {
+        if(args->argc > 0 && stracmp(args->argv[0], 2, (char* []){"a", "auto"})) {
+            execmode.reverse = true;
+        } else if(args->argc > 0 && stracmp(args->argv[0], 2, (char* []){"n", "noauto"})) {
+            execmode.reverse = false;
+        } else if(args->argc == 2) {
             disassemble_memory(nh2word(args->argv[0]), nh2word(args->argv[1]));
+        } else {
+            disassemble_memory(execptr->start, execptr->end);
         }
     } else if(stracmp(cmd, 1, (char* []){"reset"})) {
         fprintf(stdout, "Reset COMET II CPU.\n");
@@ -310,21 +316,15 @@ MONCMDTYPE monitorcmd(char *cmd, MONARGS *args)
     } 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"})) {
+    } else if(stracmp(cmd, 2, (char* []){"t", "trace", "T", "tracelogical"})) {
+        if(stracmp(cmd, 2, (char* []){"t", "trace"})) {
             execmode.logical = false;
-            execmode.trace = true;
-        } else if(args->argc > 0 && stracmp(args->argv[0], 2, (char* []){"no", "noauto"})) {
-            execmode.trace = false;
         } else {
-            fprintf(stdout, "#%04X: Register::::\n", sys->cpu->pr);
-            dspregister();
+            execmode.logical = true;
         }
-    } else if(stracmp(cmd, 2, (char* []){"T", "tracelogical"})) {
         if(args->argc > 0 && stracmp(args->argv[0], 2, (char* []){"a", "auto"})) {
-            execmode.logical = true;
             execmode.trace = true;
-        } else if(args->argc > 0 && stracmp(args->argv[0], 2, (char* []){"no", "noauto"})) {
+        } else if(args->argc > 0 && stracmp(args->argv[0], 2, (char* []){"n", "noauto"})) {
             execmode.trace = false;
         } else {
             fprintf(stdout, "#%04X: Register::::\n", sys->cpu->pr);
@@ -340,10 +340,10 @@ MONCMDTYPE monitorcmd(char *cmd, MONARGS *args)
         fprintf(stdout, "q[uit] -- Quit running your program.\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, "r[everse] -- Disassemble memory. `r[everse] <start address> <end address>'. `r[everse] a[uto]/n[oauto]' set auto/noauto display.\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");
-        fprintf(stdout, "T[race] -- Display CPU register as logical value. `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");
     }
     return cmdtype;
index 70d0be716dba09252c6051a6c27694573fb469e0..6c695e7023573fca0653c1e6003a007c2ead4142 100644 (file)
@@ -183,16 +183,16 @@ WORD getcmdcode(const char *cmd, CMDTYPE type)
 WORD getcmdwordlen(const char *cmd, CMDTYPE type)
 {
     CMDTAB *p = NULL;
-    int l = 0;
+    int wl = 0;
 
     assert(cmd != NULL);
     for(p = cmdtab[HASH_CMDTYPE][hash_cmdtype(cmd, type)]; p != NULL; p = p->next) {
         if(strcmp(cmd, p->cmd->name) == 0 && type == p->cmd->type) {
-            l = p->cmd->wordlen;
+            wl = p->cmd->wordlen;
             break;
         }
     }
-    return l;
+    return wl;
 }
 
 /**
@@ -263,6 +263,24 @@ char *getcmdname(WORD code)
     return cmd;
 }
 
+/**
+ * 命令コードから、命令語長を返す\n
+ * 無効な場合は0を返す
+ */
+WORD code2cmdwordlen(WORD code)
+{
+    CMDTAB *t = NULL;
+    int wl = 0;
+
+    for(t = cmdtab[HASH_CODE][hash_code(code)]; t != NULL; t = t->next) {
+        if(code == t->cmd->code) {
+            wl = t->cmd->wordlen;
+            break;
+        }
+    }
+    return wl;
+}
+
 /**
  * 汎用レジスタの番号からレジスタを表す文字列を返す
  */