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. zero_data_cnt
  7. disassemble_file
  8. disassemble_memory

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

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