root/src/disassemble.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. disassemble_puts_code
  2. disassemble_cmd_adr_x
  3. disassemble_cmd_r
  4. disassemble_dc
  5. disassemble_ds
  6. fgetword
  7. zero_data_cnt
  8. disassemble_file
  9. disassemble_memory

   1 #include "disassemble.h"
   2 
   3 /**
   4  * @brief 機械コードの出力列
   5  */
   6 int codecol = 32;
   7 
   8 /**
   9  * @brief ファイルストリームから1ワードを取得する
  10  *
  11  * @return 取得した1ワード
  12  *
  13  * @param stream ファイルストリーム
  14  */
  15 WORD fgetword(FILE *stream);
  16 
  17 /**
  18  * @brief WORDデータから、値が0のWORDがいくつ連続するか返す
  19  *
  20  * @return 値が0の連続するWORD数
  21  *
  22  * @param data WORDデータ
  23  * @param wordlen データのWORD数
  24  */
  25 WORD zero_data_cnt(const WORD *data, WORD wordlen);
  26 
  27 /**
  28  * @brief 機械コードをコメントとして標準出力へ出力する
  29  *
  30  * @param ascol アセンブラの列位置
  31  * @param pradr 次に実行すべき命令語の先頭アドレス
  32  * @param wordc ワード値の数
  33  * @param wordv ワード値の配列
  34  */
  35 void disassemble_puts_code(int ascol, WORD pradr, int wordc, WORD wordv[]);
  36 
  37 /**
  38  * @brief 種類がR_ADRまたはR_ADR_Xのコマンドを逆アセンブルし、標準出力へ出力する
  39  *
  40  * @param cmdtype コマンドの種類
  41  * @param *cmdname コマンドの名前
  42  * @param word ワード値
  43  * @param adr アドレス値
  44  * @param pradr 次に実行すべき命令語の先頭アドレス
  45  */
  46 void disassemble_cmd_adr_x(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD adr, WORD pradr);
  47 
  48 /**
  49  * @brief 種類がR1_R2またはR_のコマンドを逆アセンブルし、標準出力へ出力する
  50  *
  51  * @param cmdtype コマンドの種類
  52  * @param *cmdname コマンドの名前
  53  * @param word ワード値
  54  * @param pradr 次に実行すべき命令語の先頭アドレス
  55  */
  56 void disassemble_cmd_r(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD pradr);
  57 
  58 /**
  59  * @brief DCコマンドを逆アセンブルし、標準出力へ出力する
  60  *
  61  * @param word ワード値
  62  * @param pradr 次に実行すべき命令語の先頭アドレス
  63  */
  64 void disassemble_dc(WORD word, WORD pradr);
  65 
  66 void disassemble_puts_code(int ascol, WORD pradr, int wordc, WORD wordv[])
  67 {
  68     for(int i = 0; i < codecol-ascol; i++){
  69         fprintf(stdout, " ");
  70     }
  71     if(wordc == 1) {
  72         fprintf(stdout, "; #%04X: #%04X", pradr, wordv[0]);
  73     } else if(wordc == 2) {
  74         fprintf(stdout, "; #%04X: #%04X #%04X", pradr, wordv[0], wordv[1]);
  75     }
  76 }
  77 
  78 void disassemble_cmd_adr_x(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD adr, WORD pradr)
  79 {
  80     WORD x = 0;
  81     char *g = NULL;
  82     int cnt = 0;
  83 
  84     cnt += fprintf(stdout, "        %-7s ", cmdname);
  85     if(cmdtype == R_ADR_X) {
  86         cnt += fprintf(stdout, "%s,", g = grstr((word & 0x00F0) >> 4));
  87         FREE(g);
  88     }
  89     cnt += fprintf(stdout, "#%04X", adr);
  90     if((x = (word & 0x000F)) != 0) {
  91         cnt += fprintf(stdout, ",%s", g = grstr(x));
  92         FREE(g);
  93     }
  94     disassemble_puts_code(cnt, pradr, 2, (WORD []){word, adr});
  95 }
  96 
  97 void disassemble_cmd_r(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD pradr)
  98 {
  99     char *g = NULL;
 100     char *g1 = NULL;
 101     char *g2 = NULL;
 102     int cnt = 0;
 103 
 104     cnt += fprintf(stdout, "        %-7s ", cmdname);
 105     if(cmdtype == R1_R2) {
 106         g1 = grstr((word & 0x00F0) >> 4);
 107         g2 = grstr(word & 0x000F);
 108         cnt += fprintf(stdout, "%s,%s", g1, g2);
 109         FREE(g1);
 110         FREE(g2);
 111     } else if(cmdtype == R_) {
 112         g = grstr((word & 0x00F0) >> 4);
 113         cnt += fprintf(stdout, "%s", g);
 114         FREE(g);
 115     }
 116     disassemble_puts_code(cnt, pradr, 1, (WORD []){word});
 117 }
 118 
 119 void disassemble_dc(WORD word, WORD pradr)
 120 {
 121     int cnt = 0;
 122 
 123     cnt = fprintf(stdout, "        DC      %-5d ", word);
 124     disassemble_puts_code(cnt, pradr, 1, (WORD []){word});
 125     fprintf(stdout, " ::" );
 126     print_dumpword(word, true);
 127 }
 128 
 129 void disassemble_ds(WORD wcnt, WORD pradr)
 130 {
 131     int cnt = 0;
 132 
 133     cnt = fprintf(stdout, "        DS      %-5d ", wcnt);
 134     disassemble_puts_code(cnt, pradr, 1, (WORD []){0});
 135     for(int i = 1; i < wcnt; i++) {
 136         fprintf(stdout, "\n");
 137         disassemble_puts_code(0, pradr+i, 1, (WORD []){0});
 138     }
 139 }
 140 
 141 WORD fgetword(FILE *stream)
 142 {
 143     WORD aword;
 144     fread(&aword, sizeof(WORD), 1, stream);
 145     return aword;
 146 }
 147 
 148 WORD zero_data_cnt(const WORD *data, WORD wordlen)
 149 {
 150     WORD cnt = 0;
 151     for(cnt = 0; cnt < wordlen && data[cnt] == 0; cnt++) {
 152         ;
 153     }
 154     return cnt;
 155 }
 156 
 157 void disassemble_file(const char *file)
 158 {
 159     WORD *buf = NULL;
 160     WORD endptr = 0;
 161     FILE *fp = NULL;
 162 
 163     assert(file != NULL);
 164     if((fp = fopen(file, "rb")) == NULL) {
 165         perror(file);
 166         return;
 167     }
 168 
 169     buf = calloc_chk(MAX_MEMSIZE, sizeof(WORD), "disassemble_file");
 170     for(WORD i = 0; !feof(fp); i++) {
 171         buf[i] = fgetword(fp);
 172         endptr = i;
 173     }
 174     fclose(fp);
 175     endptr--;
 176     fprintf(stdout, "MAIN    START\n");
 177     disassemble_memory(buf, 0, endptr);
 178     fprintf(stdout, "        END\n");
 179 }
 180 
 181 void disassemble_memory(WORD *memory, WORD start, WORD end)
 182 {
 183     WORD cmd = 0;
 184     CMDTYPE cmdtype = 0;
 185     const char *cmdname = NULL;
 186     bool inprogram = true;
 187     WORD zcnt = 0;
 188 
 189     WORD ptr = start;
 190     while(ptr <= end) {
 191         cmd = memory[ptr] & 0xFF00;
 192         cmdname = getcmdname(cmd);
 193         cmdtype = getcmdtype(cmd);
 194         if((cmd > 0 && cmdname != NULL && code_gr_valid(memory[ptr]) == true) || (inprogram == true && memory[ptr] == 0)) {
 195             if(cmdtype == R_ADR_X || cmdtype == ADR_X) {
 196                 disassemble_cmd_adr_x(cmdtype, cmdname, memory[ptr], memory[ptr + 1], ptr);
 197             } else {
 198                 disassemble_cmd_r(cmdtype, cmdname, memory[ptr], ptr);
 199             }
 200             ptr += code2cmdwordlen(cmd);
 201             inprogram = (cmd != 0x8100) ? true : false;
 202         } else {
 203             if(memory[ptr] == 0 && ((zcnt = zero_data_cnt(memory + ptr, end - ptr + 1)) > 1 || ptr == end)) { /* 0が2つ以上の場合とメモリー末尾の場合は、DSとみなす */
 204                 disassemble_ds(zcnt, ptr);
 205                 ptr += zcnt;
 206             } else {
 207                 disassemble_dc(memory[ptr], ptr);
 208                 ptr++;
 209             }
 210         }
 211         fprintf(stdout, "\n");
 212     }
 213 }

/* [<][>][^][v][top][bottom][index][help] */