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