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. fungetword
  8. zero_data_cnt
  9. disassemble_file
  10. 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 ファイルストリームを1ワード戻す
  19  *
  20  * @return なし
  21  *
  22  * @param stream ファイルストリーム
  23  */
  24 void fungetword(FILE *stream);
  25 
  26 /**
  27  * @brief ファイルストリームから、値が0の連続するWORD数を返す
  28  *
  29  * @return 値が0の連続するWORD数
  30  *
  31  * @param stream ファイルストリーム
  32  */
  33 WORD zero_data_cnt(FILE *stream);
  34 
  35 /**
  36  * @brief 機械コードをコメントとして標準出力へ出力する
  37  *
  38  * @return なし
  39  *
  40  * @param ascol アセンブラの列位置
  41  * @param pradr 次に実行すべき命令語の先頭アドレス
  42  * @param wordc ワード値の数
  43  * @param wordv ワード値の配列
  44  */
  45 void disassemble_puts_code(int ascol, WORD pradr, int wordc, WORD wordv[]);
  46 
  47 /**
  48  * @brief 種類がR_ADRまたはR_ADR_Xのコマンドを逆アセンブルし、標準出力へ出力する
  49  *
  50  * @return なし
  51  *
  52  * @param cmdtype コマンドの種類
  53  * @param *cmdname コマンドの名前
  54  * @param word ワード値
  55  * @param adr アドレス値
  56  * @param pradr 次に実行すべき命令語の先頭アドレス
  57  */
  58 void disassemble_cmd_adr_x(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD adr, WORD pradr);
  59 
  60 /**
  61  * @brief 種類がR1_R2またはR_のコマンドを逆アセンブルし、標準出力へ出力する
  62  *
  63  * @return なし
  64  *
  65  * @param cmdtype コマンドの種類
  66  * @param *cmdname コマンドの名前
  67  * @param word ワード値
  68  * @param pradr 次に実行すべき命令語の先頭アドレス
  69  */
  70 void disassemble_cmd_r(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD pradr);
  71 
  72 /**
  73  * @brief DCコマンドを逆アセンブルし、標準出力へ出力する
  74  *
  75  * @return なし
  76  *
  77  * @param word ワード値
  78  * @param pradr 次に実行すべき命令語の先頭アドレス
  79  */
  80 void disassemble_dc(WORD word, WORD pradr);
  81 
  82 void disassemble_puts_code(int ascol, WORD pradr, int wordc, WORD wordv[])
  83 {
  84     for(int i = 0; i < codecol-ascol; i++){
  85         fprintf(stdout, " ");
  86     }
  87     if(wordc == 1) {
  88         fprintf(stdout, "; #%04X: #%04X", pradr, wordv[0]);
  89     } else if(wordc == 2) {
  90         fprintf(stdout, "; #%04X: #%04X #%04X", pradr, wordv[0], wordv[1]);
  91     }
  92 }
  93 void disassemble_cmd_adr_x(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD adr, WORD pradr)
  94 {
  95     WORD x = 0;
  96     char *g = NULL;
  97     int cnt = 0;
  98 
  99     cnt += fprintf(stdout, "        %-7s ", cmdname);
 100     if(cmdtype == R_ADR_X) {
 101         cnt += fprintf(stdout, "%s,", g = grstr((word & 0x00F0) >> 4));
 102         FREE(g);
 103     }
 104     cnt += fprintf(stdout, "#%04X", adr);
 105     if((x = (word & 0x000F)) != 0) {
 106         cnt += fprintf(stdout, ",%s", g = grstr(x));
 107         FREE(g);
 108     }
 109     disassemble_puts_code(cnt, pradr, 2, (WORD []){word, adr});
 110 }
 111 
 112 void disassemble_cmd_r(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD pradr)
 113 {
 114     char *g = NULL;
 115     char *g1 = NULL;
 116     char *g2 = NULL;
 117     int cnt = 0;
 118 
 119     cnt += fprintf(stdout, "        %-7s ", cmdname);
 120     if(cmdtype == R1_R2) {
 121         g1 = grstr((word & 0x00F0) >> 4);
 122         g2 = grstr(word & 0x000F);
 123         cnt += fprintf(stdout, "%s,%s", g1, g2);
 124         FREE(g1);
 125         FREE(g2);
 126     } else if(cmdtype == R_) {
 127         g = grstr((word & 0x00F0) >> 4);
 128         cnt += fprintf(stdout, "%s", g);
 129         FREE(g);
 130     }
 131     disassemble_puts_code(cnt, pradr, 1, (WORD []){word});
 132 }
 133 
 134 void disassemble_dc(WORD word, WORD pradr)
 135 {
 136     int cnt = 0;
 137 
 138     cnt = fprintf(stdout, "        DC      %-5d ", word);
 139     disassemble_puts_code(cnt, pradr, 1, (WORD []){word});
 140     fprintf(stdout, " ::" );
 141     print_dumpword(word, true);
 142 }
 143 
 144 void disassemble_ds(WORD wcnt, WORD pradr)
 145 {
 146     int cnt = 0;
 147 
 148     cnt = fprintf(stdout, "        DS      %-5d ", wcnt);
 149     disassemble_puts_code(cnt, pradr, 1, (WORD []){0});
 150     for(int i = 0; i < wcnt - 1; i++) {
 151         fprintf(stdout, "\n");
 152         disassemble_puts_code(0, pradr+1, 1, (WORD []){0});
 153     }
 154 }
 155 
 156 WORD fgetword(FILE *stream)
 157 {
 158     WORD aword;
 159     fread(&aword, sizeof(WORD), 1, stream);
 160     return aword;
 161 }
 162 
 163 void fungetword(FILE *stream)
 164 {
 165     fseek(stream, -sizeof(WORD), SEEK_CUR);
 166 }
 167 
 168 WORD zero_data_cnt(FILE *stream)
 169 {
 170     WORD cnt = 0;
 171     WORD word = 0;
 172 
 173     while(!feof(stream) && word == 0) {
 174         word = fgetword(stream);
 175         cnt++;
 176     }
 177     if(!feof(stream)) {
 178         fungetword(stream);
 179     }
 180     return cnt;
 181 }
 182 
 183 bool disassemble_file(const char *file)
 184 {
 185     bool stat = true;
 186     FILE *fp = NULL;
 187     WORD i = 0;
 188     WORD word = 0;
 189     WORD cmd = 0;
 190     WORD zcnt = 0;
 191     CMDTYPE cmdtype = 0;
 192     const char *cmdname = NULL;
 193     bool inst = true;
 194 
 195     assert(file != NULL);
 196     if((fp = fopen(file, "rb")) == NULL) {
 197         perror(file);
 198         return false;
 199     }
 200 
 201     create_cmdtable(HASH_CODE);                   /* 命令のコードとタイプがキーのハッシュ表を作成 */
 202 
 203     fprintf(stdout, "MAIN    START\n");
 204     for(word = fgetword(fp); !feof(fp); i++, word = fgetword(fp)) {
 205         cmd = word & 0xFF00;
 206         cmdname = getcmdname(cmd);
 207         cmdtype = getcmdtype(cmd);
 208         if(word == 0){
 209             if(inst == true) {  /* プログラム領域の場合  */
 210                 disassemble_cmd_r(NONE, "nop", 0, i);
 211             } else {            /* データ領域の場合 */
 212                 zcnt = zero_data_cnt(fp);
 213                 if(zcnt == 1) { /* 1つだけの0はDCとみなす */
 214                     disassemble_dc(0, i);
 215                 } else {        /* 連続する0はDSとみなす */
 216                     disassemble_ds(zcnt, i);
 217                     i += zcnt - 1;
 218                 }
 219             }
 220         } else if(cmd == 0) {
 221             disassemble_dc(word, i);
 222         } else {
 223             if(cmdtype == R_ADR_X || cmdtype == ADR_X) {
 224                 disassemble_cmd_adr_x(cmdtype, cmdname, word, fgetword(fp), i++);
 225             } else {
 226                 disassemble_cmd_r(cmdtype, cmdname, word, i);
 227             }
 228             inst = (cmd != 0x8100) ? true : false;
 229         }
 230         fprintf(stdout, "\n");
 231     }
 232     fprintf(stdout, "        END\n");
 233     free_cmdtable(HASH_CODE);
 234     fclose(fp);
 235     return stat;
 236 }
 237 
 238 void disassemble_memory(WORD start, WORD end)
 239 {
 240     WORD cmd = 0;
 241     CMDTYPE cmdtype = 0;
 242     const char *cmdname = NULL;
 243     bool inst = true;
 244 
 245     for(int i = start; i <= end; i++) {
 246         cmd = sys->memory[i] & 0xFF00;
 247         cmdname = getcmdname(cmd);
 248         cmdtype = getcmdtype(cmd);
 249         if(sys->memory[i] == 0) {
 250             if(inst == true) {  /* プログラム領域の場合  */
 251                 disassemble_cmd_r(NONE, "nop", 0, i);
 252             } else {            /* データ領域の場合。メモリーでは、DC 0とみなす */
 253                 disassemble_dc(0, i);
 254             }
 255         } else if(cmd == 0) {
 256             disassemble_dc(sys->memory[i], i);
 257         } else {
 258             if(cmdtype == R_ADR_X || cmdtype == ADR_X) {
 259                 disassemble_cmd_adr_x(cmdtype, cmdname, sys->memory[i], sys->memory[i+1], i);
 260                 i++;
 261             } else {
 262                 disassemble_cmd_r(cmdtype, cmdname, sys->memory[i], i);
 263             }
 264             inst = (cmd != 0x8100) ? true : false;
 265         }
 266         fprintf(stdout, "\n");
 267     }
 268 }

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