]> j8takagi.net git repositories - yacasl2.git/commitdiff
逆アセンブルで、GRの値が範囲外の場合はDC命令と解釈するように変更
authorj8takagi <j8takagi@nifty.com>
Wed, 1 Jul 2026 12:25:01 +0000 (21:25 +0900)
committerj8takagi <j8takagi@nifty.com>
Wed, 1 Jul 2026 12:25:01 +0000 (21:25 +0900)
include/struct.h
src/disassemble.c
src/struct.c

index 9b8abb23a4bd5504223fd214700811b3b80a0107..ba057f2724983c2695fd2d84a63b36e8ec58fa83 100644 (file)
@@ -219,7 +219,12 @@ void free_cmdtable(CMDTAB_HASH hash);
 WORD getcmdcode(const char *cmd, CMDTYPE type);
 
 /**
- * 命令の名前とタイプから、命令語長を返す\n
+ * コードが命令コードでR/R1またはR2/XのGRが範囲外の場合はfalse、それ以外はtrueを返す
+ */
+bool code_gr_valid(WORD code);
+
+/**
+ * 命令の名前とタイプから、命令語長を返す
  * 無効な場合は0を返す
  */
 WORD getcmdwordlen(const char *cmd, CMDTYPE type);
index 80db2c7cd42415b1f08a9556c1def787a599d652..bb50fe03c77de4845fce41ffd4786f40c6fc29f5 100644 (file)
@@ -147,9 +147,10 @@ WORD fgetword(FILE *stream)
 
 WORD zero_data_cnt(const WORD *data, WORD wordlen)
 {
-    WORD cnt = 1;
-    while(cnt < wordlen && data[cnt] == 0)
-        cnt++;
+    WORD cnt = 0;
+    for(cnt = 0; data[cnt] == 0 && cnt < wordlen; cnt++) {
+        ;
+    }
     return cnt;
 }
 
@@ -168,9 +169,8 @@ void disassemble_file(const char *file)
     buf = calloc_chk(MAX_MEMSIZE, sizeof(WORD), "disassemble_file");
     for(int i = 0; !feof(fp) && i < MAX_MEMSIZE; i++) {
         buf[i] = fgetword(fp);
-        len = i;
+        len = i - 1;
     }
-    len--;
     fclose(fp);
     fprintf(stdout, "MAIN    START\n");
     disassemble_memory(buf, 0, len);
@@ -185,33 +185,33 @@ void disassemble_memory(WORD *memory, WORD start, WORD end)
     bool inprogram = true;
     WORD zcnt = 0;
 
-    for(int i = start; i <= end; i++) {
-        cmd = memory[i] & 0xFF00;
+    WORD ptr = start;
+    while(ptr <= end) {
+        cmd = memory[ptr] & 0xFF00;
         cmdname = getcmdname(cmd);
         cmdtype = getcmdtype(cmd);
-        if(memory[i] == 0) {
-            if(inprogram == true) {  /* プログラム領域の場合  */
-                disassemble_cmd_r(NONE, "nop", 0, i);
-            } else {            /* データ領域の場合 */
-                zcnt = zero_data_cnt(memory+i, end-i+1);
-                /* fprintf(stdout, "DEBUG:::: i:%d; end:%04X\n", i,  end); */
-                if(zcnt == 1) { /* 1つだけの0はDCとみなす */
-                    disassemble_dc(0, i);
-                } else {        /* 連続する0はDSとみなす */
-                    disassemble_ds(zcnt, i);
-                    i += zcnt - 1;
+        if(inprogram == true) {  /* プログラム領域の場合  */
+            if(cmdname == NULL || code_gr_valid(memory[ptr]) == false) {
+                disassemble_dc(memory[ptr], ptr);
+                ptr++;
+            } else {
+                if(cmdtype == R_ADR_X || cmdtype == ADR_X) {
+                    disassemble_cmd_adr_x(cmdtype, cmdname, memory[ptr], memory[ptr + 1], ptr);
+                } else {
+                    disassemble_cmd_r(cmdtype, cmdname, memory[ptr], ptr);
                 }
+                ptr += code2cmdwordlen(cmd);
             }
-        } else if(cmd == 0 || cmdname ==NULL) {
-            disassemble_dc(memory[i], i);
+            inprogram = (cmd != 0x8100) ? true : false;
         } else {
-            if(cmdtype == R_ADR_X || cmdtype == ADR_X) {
-                disassemble_cmd_adr_x(cmdtype, cmdname, memory[i], memory[i+1], i);
-                i++;
+            /* if(memory[ptr] == 0 && ((zcnt = zero_data_cnt(memory + ptr, end - ptr + 1)) > 1 || ptr == end)) { /\* 0が2つ以上の場合とメモリー末尾の場合、DSとみなす *\/ */
+            if(memory[ptr] == 0 && (zcnt = zero_data_cnt(memory + ptr, end - ptr + 1)) > 1) { /* 0が2つ以上の場合、DSとみなす */
+                disassemble_ds(zcnt, ptr);
+                ptr += zcnt;
             } else {
-                disassemble_cmd_r(cmdtype, cmdname, memory[i], i);
+                disassemble_dc(memory[ptr], ptr);
+                ptr += 1;
             }
-            inprogram = (cmd != 0x8100) ? true : false;
         }
         fprintf(stdout, "\n");
     }
index 6c695e7023573fca0653c1e6003a007c2ead4142..a5d2c2c64264185f77fb10082a9cd54c93ad167c 100644 (file)
@@ -264,7 +264,31 @@ char *getcmdname(WORD code)
 }
 
 /**
- * 命令コードから、命令語長を返す\n
+ * 命令コードから、GRの範囲が正常な場合はtrue 異常な場合はfalseを返す
+ */
+bool code_gr_valid(WORD code)
+{
+    bool res = true;
+    CMDTYPE cmdtype = getcmdtype(code & 0xFF00);
+    WORD gr = 0;
+    if(cmdtype == R_ADR_X || cmdtype == R1_R2 || cmdtype == R_) {
+        gr = (code & 0x00F0) >> 4;
+        if(gr < 0 || GRSIZE <= gr) {
+            res = false;
+        }
+    }
+    if(cmdtype == R_ADR_X || cmdtype == R1_R2 || cmdtype == ADR_X) {
+        gr = code & 0x000F;
+        if(GRSIZE <= gr) {
+            res = false;
+        }
+
+    }
+    return res;
+}
+
+/**
+ * 命令コードから、命令語長を返す
  * 無効な場合は0を返す
  */
 WORD code2cmdwordlen(WORD code)