1 #include "disassemble.h"
9 * @brief ファイルストリームから1ワードを取得する
13 * @param stream ファイルストリーム
15 WORD fgetword(FILE *stream);
18 * @brief ファイルストリームを1ワード戻す
22 * @param stream ファイルストリーム
24 void fungetword(FILE *stream);
27 * @brief ファイルストリームから、値が0の連続するWORD数を返す
29 * @return 値が0の連続するWORD数
31 * @param stream ファイルストリーム
33 WORD zero_data_cnt(FILE *stream);
36 * @brief 機械コードをコメントとして標準出力へ出力する
40 * @param ascol アセンブラの列位置
41 * @param pradr 次に実行すべき命令語の先頭アドレス
43 * @param wordv ワード値の配列
45 void disassemble_puts_code(int ascol, WORD pradr, int wordc, WORD wordv[]);
48 * @brief 種類がR_ADRまたはR_ADR_Xのコマンドを逆アセンブルし、標準出力へ出力する
52 * @param cmdtype コマンドの種類
53 * @param *cmdname コマンドの名前
56 * @param pradr 次に実行すべき命令語の先頭アドレス
58 void disassemble_cmd_adr_x(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD adr, WORD pradr);
61 * @brief 種類がR1_R2またはR_のコマンドを逆アセンブルし、標準出力へ出力する
65 * @param cmdtype コマンドの種類
66 * @param *cmdname コマンドの名前
68 * @param pradr 次に実行すべき命令語の先頭アドレス
70 void disassemble_cmd_r(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD pradr);
73 * @brief DCコマンドを逆アセンブルし、標準出力へ出力する
78 * @param pradr 次に実行すべき命令語の先頭アドレス
80 void disassemble_dc(WORD word, WORD pradr);
82 void disassemble_puts_code(int ascol, WORD pradr, int wordc, WORD wordv[])
85 for(i = 0; i < codecol-ascol; i++){
89 fprintf(stdout, "; #%04X: #%04X", pradr, wordv[0]);
90 } else if(wordc == 2) {
91 fprintf(stdout, "; #%04X: #%04X #%04X", pradr, wordv[0], wordv[1]);
94 void disassemble_cmd_adr_x(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD adr, WORD pradr)
99 cnt += fprintf(stdout, " %-7s ", cmdname);
100 if(cmdtype == R_ADR_X) {
101 cnt += fprintf(stdout, "%s,", g = grstr((word & 0x00F0) >> 4));
104 cnt += fprintf(stdout, "#%04X", adr);
105 if((x = (word & 0x000F)) != 0) {
106 cnt += fprintf(stdout, ",%s", g = grstr(x));
109 disassemble_puts_code(cnt, pradr, 2, (WORD []){word, adr});
112 void disassemble_cmd_r(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD pradr)
114 char *g = NULL, *g1 = NULL, *g2 = NULL;
116 cnt += fprintf(stdout, " %-7s ", cmdname);
117 if(cmdtype == R1_R2) {
118 g1 = grstr((word & 0x00F0) >> 4);
119 g2 = grstr(word & 0x000F);
120 cnt += fprintf(stdout, "%s,%s", g1, g2);
123 } else if(cmdtype == R_) {
124 g = grstr((word & 0x00F0) >> 4);
125 cnt += fprintf(stdout, "%s", g);
128 disassemble_puts_code(cnt, pradr, 1, (WORD []){word});
131 void disassemble_dc(WORD word, WORD pradr)
134 cnt = fprintf(stdout, " DC %-5d ", word);
135 disassemble_puts_code(cnt, pradr, 1, (WORD []){word});
136 fprintf(stdout, " ::" );
137 print_dumpword(word, true);
140 void disassemble_ds(WORD wcnt, WORD pradr)
143 cnt = fprintf(stdout, " DS %-5d ", wcnt);
144 disassemble_puts_code(cnt, pradr, 1, (WORD []){0});
145 for(i = 0; i < wcnt - 1; i++) {
146 fprintf(stdout, "\n");
147 disassemble_puts_code(0, pradr+1, 1, (WORD []){0});
151 WORD fgetword(FILE *stream)
154 fread(&aword, sizeof(WORD), 1, stream);
158 void fungetword(FILE *stream)
160 fseek(stream, -sizeof(WORD), SEEK_CUR);
163 WORD zero_data_cnt(FILE *stream)
165 WORD cnt = 0, word = 0;
166 while(!feof(stream) && word == 0) {
167 word = fgetword(stream);
176 bool disassemble_file(const char *file)
180 WORD i = 0, word, cmd, zcnt;
185 assert(file != NULL);
186 if((fp = fopen(file, "rb")) == NULL) {
191 create_cmdtable(HASH_CODE); /* 命令のコードとタイプがキーのハッシュ表を作成 */
193 fprintf(stdout, "MAIN START\n");
194 for(word = fgetword(fp); !feof(fp); i++, word = fgetword(fp)) {
196 cmdname = getcmdname(cmd);
197 cmdtype = getcmdtype(cmd);
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);
210 } else if(cmd == 0) {
211 disassemble_dc(word, i);
213 if(cmdtype == R_ADR_X || cmdtype == ADR_X) {
214 disassemble_cmd_adr_x(cmdtype, cmdname, word, fgetword(fp), i++);
216 disassemble_cmd_r(cmdtype, cmdname, word, i);
218 inst = (cmd != 0x8100) ? true : false;
220 fprintf(stdout, "\n");
222 fprintf(stdout, " END\n");
223 free_cmdtable(HASH_CODE);
228 void disassemble_memory(WORD start, WORD end)
235 for(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);
245 } else if(cmd == 0) {
246 disassemble_dc(sys->memory[i], i);
248 if(cmdtype == R_ADR_X || cmdtype == ADR_X) {
249 disassemble_cmd_adr_x(cmdtype, cmdname, sys->memory[i], sys->memory[i+1], i);
252 disassemble_cmd_r(cmdtype, cmdname, sys->memory[i], i);
254 inst = (cmd != 0x8100) ? true : false;
256 fprintf(stdout, "\n");