READMEのCASL II仕様書へのリンクを修正
[YACASL2.git] / src / disassemble.c
index f2df812..dc40f1d 100644 (file)
@@ -3,7 +3,34 @@
 /**
  * @brief 機械コードの出力列
  */
-int codecol = 38;
+int codecol = 32;
+
+/**
+ * @brief ファイルストリームから1ワードを取得する
+ *
+ * @return 取得した1ワード
+ *
+ * @param stream ファイルストリーム
+ */
+WORD fgetword(FILE *stream);
+
+/**
+ * @brief ファイルストリームを1ワード戻す
+ *
+ * @return なし
+ *
+ * @param stream ファイルストリーム
+ */
+void fungetword(FILE *stream);
+
+/**
+ * @brief ファイルストリームから、値が0の連続するWORD数を返す
+ *
+ * @return 値が0の連続するWORD数
+ *
+ * @param stream ファイルストリーム
+ */
+WORD zero_data_cnt(FILE *stream);
 
 /**
  * @brief 機械コードをコメントとして標準出力へ出力する
@@ -47,18 +74,14 @@ 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);
 
 void disassemble_puts_code(int ascol, WORD pradr, int wordc, WORD wordv[])
 {
-    int i;
-    for(i = 0; i < codecol-ascol; i++){
+    for(int i = 0; i < codecol-ascol; i++){
         fprintf(stdout, " ");
     }
     if(wordc == 1) {
@@ -69,9 +92,10 @@ void disassemble_puts_code(int ascol, WORD pradr, int wordc, WORD wordv[])
 }
 void disassemble_cmd_adr_x(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD adr, WORD pradr)
 {
-    WORD x;
-    char *g;
+    WORD x = 0;
+    char *g = NULL;
     int cnt = 0;
+
     cnt += fprintf(stdout, "        %-7s ", cmdname);
     if(cmdtype == R_ADR_X) {
         cnt += fprintf(stdout, "%s,", g = grstr((word & 0x00F0) >> 4));
@@ -87,8 +111,11 @@ void disassemble_cmd_adr_x(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD
 
 void disassemble_cmd_r(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD pradr)
 {
-    char *g, *g1, *g2;
+    char *g = NULL;
+    char *g1 = NULL;
+    char *g2 = NULL;
     int cnt = 0;
+
     cnt += fprintf(stdout, "        %-7s ", cmdname);
     if(cmdtype == R1_R2) {
         g1 = grstr((word & 0x00F0) >> 4);
@@ -107,6 +134,7 @@ void disassemble_cmd_r(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD pra
 void disassemble_dc(WORD word, WORD pradr)
 {
     int cnt = 0;
+
     cnt = fprintf(stdout, "        DC      %-5d ", word);
     disassemble_puts_code(cnt, pradr, 1, (WORD []){word});
     fprintf(stdout, " ::" );
@@ -115,22 +143,53 @@ void disassemble_dc(WORD word, WORD pradr)
 
 void disassemble_ds(WORD wcnt, WORD pradr)
 {
-    int cnt = 0, i;
+    int cnt = 0;
+
     cnt = fprintf(stdout, "        DS      %-5d ", wcnt);
     disassemble_puts_code(cnt, pradr, 1, (WORD []){0});
-    for(i = 0; i < wcnt - 1; i++) {
+    for(int i = 0; i < wcnt - 1; i++) {
         fprintf(stdout, "\n");
         disassemble_puts_code(0, pradr+1, 1, (WORD []){0});
     }
 }
 
+WORD fgetword(FILE *stream)
+{
+    WORD aword;
+    fread(&aword, sizeof(WORD), 1, stream);
+    return aword;
+}
+
+void fungetword(FILE *stream)
+{
+    fseek(stream, -sizeof(WORD), SEEK_CUR);
+}
+
+WORD zero_data_cnt(FILE *stream)
+{
+    WORD cnt = 0;
+    WORD word = 0;
+
+    while(!feof(stream) && word == 0) {
+        word = fgetword(stream);
+        cnt++;
+    }
+    if(!feof(stream)) {
+        fungetword(stream);
+    }
+    return cnt;
+}
+
 bool disassemble_file(const char *file)
 {
     bool stat = true;
-    FILE *fp;
-    WORD i = 0, w, cmd, adr, dsarea;
+    FILE *fp = NULL;
+    WORD i = 0;
+    WORD word = 0;
+    WORD cmd = 0;
+    WORD zcnt = 0;
     CMDTYPE cmdtype = 0;
-    char *cmdname;
+    const char *cmdname = NULL;
     bool inst = true;
 
     assert(file != NULL);
@@ -139,77 +198,68 @@ bool disassemble_file(const char *file)
         return false;
     }
 
-    create_code_cmdtype();                          /* 命令のコードとタイプがキーのハッシュ表を作成 */
+    create_cmdtable(HASH_CODE);                   /* 命令のコードとタイプがキーのハッシュ表を作成 */
 
     fprintf(stdout, "MAIN    START\n");
-    for(fread(&w, sizeof(WORD), 1, fp); !feof(fp); i++, fread(&w, sizeof(WORD), 1, fp)) {
-        cmd = w & 0xFF00;
+    for(word = fgetword(fp); !feof(fp); i++, word = fgetword(fp)) {
+        cmd = word & 0xFF00;
         cmdname = getcmdname(cmd);
         cmdtype = getcmdtype(cmd);
-        if(w == 0){
-            if(inst == true) {
+        if(word == 0){
+            if(inst == true) {  /* プログラム領域の場合  */
                 disassemble_cmd_r(NONE, "nop", 0, i);
-            } else {
-                dsarea = 1;
-                do {
-                    fread(&w, sizeof(WORD), 1, fp);
-                    dsarea++;
-                } while(w == 0 && !feof(fp));
-                if(!feof(fp)) {
-                    fseek(fp, -1 * sizeof(WORD) , SEEK_CUR);
-                }
-                if(dsarea == 1) {
+            } else {            /* データ領域の場合 */
+                zcnt = zero_data_cnt(fp);
+                if(zcnt == 1) { /* 1つだけの0はDCとみなす */
                     disassemble_dc(0, i);
-                } else {
-                    disassemble_ds(dsarea, i);
-                    i += dsarea - 1;
+                } else {        /* 連続する0はDSとみなす */
+                    disassemble_ds(zcnt, i);
+                    i += zcnt - 1;
                 }
             }
         } else if(cmd == 0) {
-            disassemble_dc(w, i);
+            disassemble_dc(word, i);
         } else {
             if(cmdtype == R_ADR_X || cmdtype == ADR_X) {
-                fread(&adr, sizeof(WORD), 1, fp);
-                disassemble_cmd_adr_x(cmdtype, cmdname, w, adr, i++);
+                disassemble_cmd_adr_x(cmdtype, cmdname, word, fgetword(fp), i++);
             } else {
-                disassemble_cmd_r(cmdtype, cmdname, w, i);
+                disassemble_cmd_r(cmdtype, cmdname, word, i);
             }
             inst = (cmd != 0x8100) ? true : false;
         }
         fprintf(stdout, "\n");
     }
     fprintf(stdout, "        END\n");
-    free_code_cmdtype();
+    free_cmdtable(HASH_CODE);
     fclose(fp);
     return stat;
 }
 
 void disassemble_memory(WORD start, WORD end)
 {
-    WORD i, w, cmd, adr;
+    WORD cmd = 0;
     CMDTYPE cmdtype = 0;
-    char *cmdname;
+    const char *cmdname = NULL;
     bool inst = true;
 
-    for(i = start; i <= end; i++) {
-        w = sys->memory[i];
-        cmd = w & 0xFF00;
+    for(int i = start; i <= end; i++) {
+        cmd = sys->memory[i] & 0xFF00;
         cmdname = getcmdname(cmd);
         cmdtype = getcmdtype(cmd);
-        if(w == 0) {
-            if(inst == true) {
+        if(sys->memory[i] == 0) {
+            if(inst == true) {  /* プログラム領域の場合  */
                 disassemble_cmd_r(NONE, "nop", 0, i);
-            } else {
+            } else {            /* データ領域の場合。メモリーでは、DC 0とみなす */
                 disassemble_dc(0, i);
             }
         } else if(cmd == 0) {
-            disassemble_dc(w, i);
+            disassemble_dc(sys->memory[i], i);
         } else {
             if(cmdtype == R_ADR_X || cmdtype == ADR_X) {
-                adr = sys->memory[i+1];
-                disassemble_cmd_adr_x(cmdtype, cmdname, w, adr, i++);
+                disassemble_cmd_adr_x(cmdtype, cmdname, sys->memory[i], sys->memory[i+1], i);
+                i++;
             } else {
-                disassemble_cmd_r(cmdtype, cmdname, w, i);
+                disassemble_cmd_r(cmdtype, cmdname, sys->memory[i], i);
             }
             inst = (cmd != 0x8100) ? true : false;
         }