Commit | Line | Data |
---|---|---|
cf76e892 JPM |
1 | /* |
2 | * UAE - The Un*x Amiga Emulator - CPU core | |
3 | * | |
4 | * Read 68000 CPU specs from file "table68k" and build table68k.c | |
5 | * | |
6 | * Copyright 1995,1996 Bernd Schmidt | |
7 | * | |
8 | * Adaptation to Hatari by Thomas Huth | |
9 | * | |
10 | * This file is distributed under the GNU Public License, version 3 or at | |
11 | * your option any later version. Read the file GPLv3 for details. | |
12 | */ | |
13 | //const char Build68k_fileid[] = "Hatari build68k.c : " __DATE__ " " __TIME__; | |
14 | ||
15 | #include <assert.h> | |
16 | #include <ctype.h> | |
17 | #include <string.h> | |
18 | #include "readcpu.h" | |
19 | ||
20 | ||
21 | static FILE * tablef; | |
22 | static int nextch = 0; | |
23 | ||
24 | static void getnextch(void) | |
25 | { | |
26 | do | |
27 | { | |
28 | nextch = fgetc(tablef); | |
29 | ||
30 | if (nextch == '%') | |
31 | { | |
32 | do | |
33 | { | |
34 | nextch = fgetc(tablef); | |
35 | } | |
36 | while (nextch != EOF && nextch != '\n'); | |
37 | } | |
38 | } | |
39 | while (nextch != EOF && isspace(nextch)); | |
40 | } | |
41 | ||
42 | static int nextchtohex(void) | |
43 | { | |
44 | switch (isupper(nextch) ? tolower(nextch) : nextch) | |
45 | { | |
46 | case '0': return 0; | |
47 | case '1': return 1; | |
48 | case '2': return 2; | |
49 | case '3': return 3; | |
50 | case '4': return 4; | |
51 | case '5': return 5; | |
52 | case '6': return 6; | |
53 | case '7': return 7; | |
54 | case '8': return 8; | |
55 | case '9': return 9; | |
56 | case 'a': return 10; | |
57 | case 'b': return 11; | |
58 | case 'c': return 12; | |
59 | case 'd': return 13; | |
60 | case 'e': return 14; | |
61 | case 'f': return 15; | |
62 | default: abort(); | |
63 | } | |
64 | } | |
65 | ||
66 | int main(int argc, char ** argv) | |
67 | { | |
68 | int no_insns = 0; | |
69 | ||
70 | /*printf("#include \"sysconfig.h\"\n");*/ | |
71 | printf("#include \"sysdeps.h\"\n"); | |
72 | printf("#include \"readcpu.h\"\n"); | |
73 | printf("const struct instr_def defs68k[] = {\n"); | |
74 | #if 0 | |
75 | tablef = fopen("table68k","r"); | |
76 | if (tablef == NULL) { | |
77 | fprintf(stderr, "table68k not found\n"); | |
78 | exit(1); | |
79 | } | |
80 | #else | |
81 | tablef = stdin; | |
82 | #endif | |
83 | getnextch(); | |
84 | ||
85 | while (nextch != EOF) | |
86 | { | |
87 | int cpulevel, plevel, sduse; | |
88 | int i; | |
89 | ||
90 | char patbits[16]; | |
91 | char opcstr[256]; | |
92 | int bitpos[16]; | |
93 | int flagset[5], flaguse[5]; | |
94 | ||
95 | unsigned int bitmask, bitpattern; | |
96 | int n_variable; | |
97 | ||
98 | n_variable = 0; | |
99 | bitmask = bitpattern = 0; | |
100 | memset(bitpos, 0, sizeof(bitpos)); | |
101 | ||
102 | for(i=0; i<16; i++) | |
103 | { | |
104 | int currbit; | |
105 | bitmask <<= 1; | |
106 | bitpattern <<= 1; | |
107 | ||
108 | switch (nextch) | |
109 | { | |
110 | case '0': currbit = bit0; bitmask |= 1; break; | |
111 | case '1': currbit = bit1; bitmask |= 1; bitpattern |= 1; break; | |
112 | case 'c': currbit = bitc; break; | |
113 | case 'C': currbit = bitC; break; | |
114 | case 'f': currbit = bitf; break; | |
115 | case 'i': currbit = biti; break; | |
116 | case 'I': currbit = bitI; break; | |
117 | case 'j': currbit = bitj; break; | |
118 | case 'J': currbit = bitJ; break; | |
119 | case 'k': currbit = bitk; break; | |
120 | case 'K': currbit = bitK; break; | |
121 | case 's': currbit = bits; break; | |
122 | case 'S': currbit = bitS; break; | |
123 | case 'd': currbit = bitd; break; | |
124 | case 'D': currbit = bitD; break; | |
125 | case 'r': currbit = bitr; break; | |
126 | case 'R': currbit = bitR; break; | |
127 | case 'z': currbit = bitz; break; | |
128 | case 'p': currbit = bitp; break; | |
129 | default: abort(); | |
130 | } | |
131 | ||
132 | if (!(bitmask & 1)) | |
133 | { | |
134 | bitpos[n_variable] = currbit; | |
135 | n_variable++; | |
136 | } | |
137 | ||
138 | if (nextch == '0' || nextch == '1') | |
139 | bitmask |= 1; | |
140 | ||
141 | if (nextch == '1') | |
142 | bitpattern |= 1; | |
143 | ||
144 | patbits[i] = nextch; | |
145 | getnextch(); | |
146 | } | |
147 | ||
148 | while (isspace(nextch) || nextch == ':') /* Get CPU and privilege level */ | |
149 | getnextch(); | |
150 | ||
151 | switch (nextch) | |
152 | { | |
153 | case '0': cpulevel = 0; break; | |
154 | case '1': cpulevel = 1; break; | |
155 | case '2': cpulevel = 2; break; | |
156 | case '3': cpulevel = 3; break; | |
157 | case '4': cpulevel = 4; break; | |
158 | default: abort(); | |
159 | } | |
160 | ||
161 | getnextch(); | |
162 | ||
163 | switch (nextch) | |
164 | { | |
165 | case '0': plevel = 0; break; | |
166 | case '1': plevel = 1; break; | |
167 | case '2': plevel = 2; break; | |
168 | case '3': plevel = 3; break; | |
169 | default: abort(); | |
170 | } | |
171 | ||
172 | getnextch(); | |
173 | ||
174 | while (isspace(nextch)) /* Get flag set information */ | |
175 | getnextch(); | |
176 | ||
177 | if (nextch != ':') | |
178 | abort(); | |
179 | ||
180 | for(i=0; i<5; i++) | |
181 | { | |
182 | getnextch(); | |
183 | ||
184 | switch (nextch) | |
185 | { | |
186 | case '-': flagset[i] = fa_unset; break; | |
187 | case '/': flagset[i] = fa_isjmp; break; | |
188 | case '+': flagset[i] = fa_isbranch; break; | |
189 | case '0': flagset[i] = fa_zero; break; | |
190 | case '1': flagset[i] = fa_one; break; | |
191 | case 'x': flagset[i] = fa_dontcare; break; | |
192 | case '?': flagset[i] = fa_unknown; break; | |
193 | default: flagset[i] = fa_set; break; | |
194 | } | |
195 | } | |
196 | ||
197 | getnextch(); | |
198 | ||
199 | while (isspace(nextch)) | |
200 | getnextch(); | |
201 | ||
202 | if (nextch != ':') /* Get flag used information */ | |
203 | abort(); | |
204 | ||
205 | for(i=0; i<5; i++) | |
206 | { | |
207 | getnextch(); | |
208 | ||
209 | switch (nextch) | |
210 | { | |
211 | case '-': flaguse[i] = fu_unused; break; | |
212 | case '/': flaguse[i] = fu_isjmp; break; | |
213 | case '+': flaguse[i] = fu_maybecc; break; | |
214 | case '?': flaguse[i] = fu_unknown; break; | |
215 | default: flaguse[i] = fu_used; break; | |
216 | } | |
217 | } | |
218 | ||
219 | getnextch(); | |
220 | ||
221 | while (isspace(nextch)) | |
222 | getnextch(); | |
223 | ||
224 | if (nextch != ':') /* Get source/dest usage information */ | |
225 | abort(); | |
226 | ||
227 | getnextch(); | |
228 | sduse = nextchtohex() << 4; | |
229 | getnextch(); | |
230 | sduse |= nextchtohex(); | |
231 | getnextch(); | |
232 | ||
233 | while (isspace(nextch)) | |
234 | getnextch(); | |
235 | ||
236 | if (nextch != ':') | |
237 | abort(); | |
238 | ||
239 | if (fgets(opcstr, 250, tablef) == NULL) | |
240 | { | |
241 | perror("fgets"); | |
242 | return -1; | |
243 | } | |
244 | ||
245 | getnextch(); | |
246 | ||
247 | { | |
248 | int j; | |
249 | /* Remove superfluous spaces from the string */ | |
250 | char * opstrp = opcstr, * osendp; | |
251 | int slen = 0; | |
252 | ||
253 | while (isspace((unsigned)(*opstrp))) | |
254 | opstrp++; | |
255 | ||
256 | osendp = opstrp; | |
257 | ||
258 | while (*osendp) | |
259 | { | |
260 | if (!isspace ((unsigned)(*osendp))) | |
261 | slen = osendp - opstrp + 1; | |
262 | ||
263 | osendp++; | |
264 | } | |
265 | ||
266 | opstrp[slen] = 0; | |
267 | ||
268 | if (no_insns > 0) | |
269 | printf(",\n"); | |
270 | ||
271 | no_insns++; | |
272 | printf("{ %d, %d, {", bitpattern, n_variable); | |
273 | ||
274 | for(j=0; j<16; j++) | |
275 | { | |
276 | printf("%d", bitpos[j]); | |
277 | ||
278 | if (j < 15) | |
279 | printf(","); | |
280 | } | |
281 | ||
282 | printf ("}, %d, %d, %d, { ", bitmask, cpulevel, plevel); | |
283 | ||
284 | for(i=0; i<5; i++) | |
285 | { | |
286 | printf("{ %d, %d }%c ", flaguse[i], flagset[i], i == 4 ? ' ' : ','); | |
287 | } | |
288 | ||
289 | printf("}, %d, \"%s\"}", sduse, opstrp); | |
290 | } | |
291 | } | |
292 | ||
293 | printf("};\nint n_defs68k = %d;\n", no_insns); | |
294 | return 0; | |
295 | } |