YACASL2
disassemble.c
Go to the documentation of this file.
1 #include "disassemble.h"
2 
6 int codecol = 32;
7 
15 WORD fgetword(FILE *stream);
16 
24 void fungetword(FILE *stream);
25 
33 WORD zero_data_cnt(FILE *stream);
34 
45 void disassemble_puts_code(int ascol, WORD pradr, int wordc, WORD wordv[]);
46 
58 void disassemble_cmd_adr_x(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD adr, WORD pradr);
59 
70 void disassemble_cmd_r(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD pradr);
71 
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");
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 }
#define FREE(ptr)
メモリを解放するマクロ
Definition: cmem.h:21
void disassemble_puts_code(int ascol, WORD pradr, int wordc, WORD wordv[])
機械コードをコメントとして標準出力へ出力する
Definition: disassemble.c:82
bool disassemble_file(const char *file)
CASL IIのオブジェクトファイルを逆アセンブルし、標準出力へ出力する
Definition: disassemble.c:183
void disassemble_memory(WORD start, WORD end)
COMET IIのメモリーを逆アセンブルし、標準出力へ出力する
Definition: disassemble.c:238
void disassemble_dc(WORD word, WORD pradr)
DCコマンドを逆アセンブルし、標準出力へ出力する
Definition: disassemble.c:134
void disassemble_cmd_r(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD pradr)
種類がR1_R2またはR_のコマンドを逆アセンブルし、標準出力へ出力する
Definition: disassemble.c:112
int codecol
機械コードの出力列
Definition: disassemble.c:6
void disassemble_cmd_adr_x(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD adr, WORD pradr)
種類がR_ADRまたはR_ADR_Xのコマンドを逆アセンブルし、標準出力へ出力する
Definition: disassemble.c:93
void fungetword(FILE *stream)
ファイルストリームを1ワード戻す
Definition: disassemble.c:163
WORD zero_data_cnt(FILE *stream)
ファイルストリームから、値が0の連続するWORD数を返す
Definition: disassemble.c:168
void disassemble_ds(WORD wcnt, WORD pradr)
Definition: disassemble.c:144
WORD fgetword(FILE *stream)
ファイルストリームから1ワードを取得する
Definition: disassemble.c:156
@ HASH_CODE
Definition: struct.h:62
char * getcmdname(WORD code)
Definition: struct.c:222
CMDTYPE getcmdtype(WORD code)
Definition: struct.c:205
bool create_cmdtable(CMDTAB_HASH hash)
命令ハッシュ表を作成する
Definition: struct.c:113
CMDTYPE
Definition: struct.h:70
@ R_
Definition: struct.h:94
@ R_ADR_X
Definition: struct.h:77
@ ADR_X
Definition: struct.h:89
@ NONE
Definition: struct.h:98
@ R1_R2
Definition: struct.h:83
void free_cmdtable(CMDTAB_HASH hash)
Definition: struct.c:135
SYSTEM * sys
COMET IIの仮想実行マシンシステム
Definition: struct.c:7
char * grstr(WORD word)
汎用レジスタの番号からレジスタを表す文字列を返す
Definition: struct.c:240
WORD * memory
Definition: struct.h:47
unsigned short WORD
16ビットの数値を表すデータ型
Definition: word.h:9
void print_dumpword(WORD word, bool logicalmode)
WORD値を解析して表示する
Definition: word.c:137