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

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