1 /**************************************************************************\
2 * Texas Instruments TMS320x25 DSP Disassembler *
3 * *
4 * Copyright (C) 2001-2002+ Tony La Porta *
5 * To be used with TMS320x25 DSP Emulator engine. *
6 * Written for the MAME project. *
7 * *
8 * Many thanks to those involved in the i8039 Disassembler *
9 * as the structure here was borrowed from it. *
10 * *
11 * Note : This is a word based microcontroller, with addressing *
12 * architecture based on the Harvard addressing scheme. *
13 * *
14 * *
15 * A Memory Address *
16 * B Opcode Address Argument (Requires next opcode read) *
17 * C Compare mode *
18 * D Immediate byte load *
19 * K Immediate bit load *
20 * W Immediate word load *
21 * M AR[x] register modification type (for indirect addressing) *
22 * N ARP register to change ARP pointer to (for indirect addressing) *
23 * P I/O port address number *
24 * R AR[R] register to use *
25 * S Shift ALU left *
26 * T Shift ALU left (Hex) / Nibble data *
27 * X Don't care bit *
28 * *
29 \**************************************************************************/
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <ctype.h>
35
36 #ifdef MAME_DEBUG /* Compile interface to MAME */
37 #include "memory.h"
38 #include "tms32025.h"
39 #include "mamedbg.h"
40 extern offs_t TMS32025_DATA_BANK[0x10];
41 extern offs_t TMS32025_PRGM_BANK[0x10];
42 //#define READOP16(A) (cpu_readop16((A) | (TMS32025_PGM_OFFSET << 1)))
43 //#define READARG16(A) (cpu_readop_arg16((A) | (TMS32025_PGM_OFFSET << 1)))
44 #define READOP16(A) (cpu_readop16(TMS32025_PRGM_BANK( (A>>1) )))
45 #define READARG16(A) (cpu_readop_arg16(TMS32025_PRGM_BANK( (A>>1) )))
46 #else /* Compile interface for standalone */
47 extern unsigned char *Buffer;
48 #ifdef MSB_FIRST
49 #define READOP16(A) ( ((Buffer[A+1]<<8) | Buffer[A]) )
50 #define READARG16(A) ( ((Buffer[A+1]<<8) | Buffer[A]) )
51 #else
52 #define READOP16(A) ( ((Buffer[A]<<8) | Buffer[A+1]) )
53 #define READARG16(A) ( ((Buffer[A]<<8) | Buffer[A+1]) )
54 #endif
55 #endif
56
57
58
59 typedef unsigned char byte;
60 typedef unsigned short int word;
61
62 #define FMT(a,b) a, b
63 #define PTRS_PER_FORMAT 2
64
65 static const char *arith[8] = { "*", "*-", "*+", "??", "*0-", "*0+", "*BR0-", "*BR0+" } ;
66 static const char *nextar[16] = { "", "", "", "", "", "", "", "", ",AR0", ",AR1", ",AR2", ",AR3", ",AR4", ",AR5", ",AR6", ",AR7" } ;
67 static const char *cmpmode[4] = { "0 (ARx = AR0)" , "1 (ARx < AR0)" , "2 (ARx > AR0)" , "3 (ARx <> AR0)" } ;
68
69
70 static const char *TMS32025Formats[] = {
71 FMT("0000tttt0aaaaaaa", "add %A,%T"), /* 0xxx */
72 FMT("0000tttt1mmmnnnn", "add %M,%T%N"),
73 FMT("0001tttt0aaaaaaa", "sub %A,%T"), /* 1xxx */
74 FMT("0001tttt1mmmnnnn", "sub %M,%T%N"),
75 FMT("0010tttt0aaaaaaa", "lac %A,%T"), /* 2xxx */
76 FMT("0010tttt1mmmnnnn", "lac %M,%T%N"),
77 FMT("00110rrr0aaaaaaa", "lar %R,%A"), /* 3xxx */
78 FMT("00110rrr1mmmnnnn", "lar %R%M%N"),
79 FMT("001110000aaaaaaa", "mpy %A"), /* 38xx */
80 FMT("001110001mmmnnnn", "mpy %M%N"),
81 FMT("001110010aaaaaaa", "sqra %A"), /* 39xx */
82 FMT("001110011mmmnnnn", "sqra %M%N"),
83 FMT("001110100aaaaaaa", "mpya %A"), /* 3Axx */
84 FMT("001110101mmmnnnn", "mpya %M%N"),
85 FMT("001110110aaaaaaa", "mpys %A"), /* 3Bxx */
86 FMT("001110111mmmnnnn", "mpys %M%N"),
87 FMT("001111000aaaaaaa", "lt %A"), /* 3Cxx */
88 FMT("001111001mmmnnnn", "lt %M%N"),
89 FMT("001111010aaaaaaa", "lta %A"), /* 3Dxx */
90 FMT("001111011mmmnnnn", "lta %M%N"),
91 FMT("001111100aaaaaaa", "ltp %A"), /* 3Exx */
92 FMT("001111101mmmnnnn", "ltp %M%N"),
93 FMT("001111110aaaaaaa", "ltd %A"), /* 3Fxx */
94 FMT("001111111mmmnnnn", "ltd %M%N"),
95 FMT("010000000aaaaaaa", "zalh %A"), /* 40xx */
96 FMT("010000001mmmnnnn", "zalh %M%N"),
97 FMT("010000010aaaaaaa", "zals %A"), /* 41xx */
98 FMT("010000011mmmnnnn", "zals %M%N"),
99 FMT("010000100aaaaaaa", "lact %A"), /* 42xx */
100 FMT("010000101mmmnnnn", "lact %M%N"),
101 FMT("010000110aaaaaaa", "addc %A%S"), /* 43xx */
102 FMT("010000111mmmnnnn", "addc %M%S%N"),
103 FMT("010001000aaaaaaa", "subh %A"), /* 44xx */
104 FMT("010001001mmmnnnn", "subh %M%N"),
105 FMT("010001010aaaaaaa", "subs %A"), /* 45xx */
106 FMT("010001011mmmnnnn", "subs %M%N"),
107 FMT("010001100aaaaaaa", "subt %A"), /* 46xx */
108 FMT("010001101mmmnnnn", "subt %M%N"),
109 FMT("010001110aaaaaaa", "subc %A"), /* 47xx */
110 FMT("010001111mmmnnnn", "subc %M%N"),
111 FMT("010010000aaaaaaa", "addh %A"), /* 48xx */
112 FMT("010010001mmmnnnn", "addh %M%N"),
113 FMT("010010010aaaaaaa", "adds %A"), /* 49xx */
114 FMT("010010011mmmnnnn", "adds %M%N"),
115 FMT("010010100aaaaaaa", "addt %A"), /* 4Axx */
116 FMT("010010101mmmnnnn", "addt %M%N"),
117 FMT("010010110aaaaaaa", "rpt %A"), /* 4Bxx */
118 FMT("010010111mmmnnnn", "rpt %M%N"),
119 FMT("010011000aaaaaaa", "xor %A"), /* 4Cxx */
120 FMT("010011001mmmnnnn", "xor %M%N"),
121 FMT("010011010aaaaaaa", "or %A"), /* 4Dxx */
122 FMT("010011011mmmnnnn", "or %M%N"),
123 FMT("010011100aaaaaaa", "and %A"), /* 4Exx */
124 FMT("010011101mmmnnnn", "and %M%N"),
125 FMT("010011110aaaaaaa", "subb %A"), /* 4Fxx */
126 FMT("010011111mmmnnnn", "subb %M%N"),
127 FMT("010100000aaaaaaa", "lst %A"), /* 50xx */
128 FMT("010100001mmmnnnn", "lst %M%N"),
129 FMT("010100010aaaaaaa", "lst1 %A"), /* 51xx */
130 FMT("010100011mmmnnnn", "lst1 %M%N"),
131 FMT("010100100aaaaaaa", "ldp %A"), /* 52xx */
132 FMT("010100101mmmnnnn", "ldp %M%N"),
133 FMT("010100110aaaaaaa", "lph %A"), /* 53xx */
134 FMT("010100111mmmnnnn", "lph %M%N"),
135 FMT("010101000aaaaaaa", "pshd %A"), /* 54xx */
136 FMT("010101001mmmnnnn", "pshd %M%N"),
137
138 /* FMT("010101010aaaaaaa", "mar %A"), 55xx */
139 /* MAR direct has been expanded out to all its variations because one of its */
140 /* its opcodes is the same as NOP. Actually MAR direct just performs a NOP */
141 FMT("0101010100000000", "nop"), /* 5500 */
142 FMT("0101010100000001", "mar $01"),
143 FMT("0101010100000010", "mar $02"),
144 FMT("0101010100000011", "mar $03"),
145 FMT("0101010100000100", "mar $04"),
146 FMT("0101010100000101", "mar $05"),
147 FMT("0101010100000110", "mar $06"),
148 FMT("0101010100000111", "mar $07"),
149 FMT("0101010100001000", "mar $08"),
150 FMT("0101010100001001", "mar $09"),
151 FMT("0101010100001010", "mar $0A"),
152 FMT("0101010100001011", "mar $0B"),
153 FMT("0101010100001100", "mar $0C"),
154 FMT("0101010100001101", "mar $0D"),
155 FMT("0101010100001110", "mar $0E"),
156 FMT("0101010100001111", "mar $0F"),
157 FMT("010101010001tttt", "mar $1%T"),
158 FMT("010101010010tttt", "mar $2%T"),
159 FMT("010101010011tttt", "mar $3%T"),
160 FMT("010101010100tttt", "mar $4%T"),
161 FMT("010101010101tttt", "mar $5%T"),
162 FMT("010101010110tttt", "mar $6%T"),
163 FMT("010101010111tttt", "mar $7%T"),
164
165 /* FMT("010101011mmmnnnn", "mar %M%N"), 55xx */
166 /* MAR indirect has been expanded out to all its variations because one of */
167 /* its opcodes, is the same as LARP (actually performs the same function) */
168 FMT("0101010110000xxx", "mar *"), /* 558x */
169 FMT("0101010110001kkk", "larp %K"), /* 558x */
170 FMT("010101011001nnnn", "mar *-%N"), /* 558x */
171 FMT("010101011010nnnn", "mar *+%N"),
172 FMT("010101011011nnnn", "mar ??%N"),
173 FMT("010101011100nnnn", "mar *BR0-%N"),
174 FMT("010101011101nnnn", "mar *0-%N"),
175 FMT("010101011110nnnn", "mar *0+%N"),
176 FMT("010101011111nnnn", "mar *BR0+%N"),
177
178 FMT("010101100aaaaaaa", "dmov %A"), /* 56xx */
179 FMT("010101101mmmnnnn", "dmov %M%N"),
180 FMT("010101110aaaaaaa", "bitt %A"), /* 57xx */
181 FMT("010101111mmmnnnn", "bitt %M%N"),
182 FMT("010110000aaaaaaa", "tblr %A"), /* 58xx */
183 FMT("010110001mmmnnnn", "tblr %M%N"),
184 FMT("010110010aaaaaaa", "tblw %A"), /* 59xx */
185 FMT("010110011mmmnnnn", "tblw %M%N"),
186 FMT("010110100aaaaaaa", "sqrs %A"), /* 5Axx */
187 FMT("010110101mmmnnnn", "sqrs %M%N"),
188 FMT("010110110aaaaaaa", "lts %A"), /* 5Bxx */
189 FMT("010110111mmmnnnn", "lts %M%N"),
190 FMT("010111000aaaaaaabbbbbbbbbbbbbbbb", "macd %B,%A"), /* 5Cxx */
191 FMT("010111001mmmnnnnbbbbbbbbbbbbbbbb", "macd %B,%M%N"),
192 FMT("010111010aaaaaaabbbbbbbbbbbbbbbb", "mac %B,%A"), /* 5Dxx */
193 FMT("010111011mmmnnnnbbbbbbbbbbbbbbbb", "mac %B,%M%N"),
194 FMT("010111101mmmnnnnbbbbbbbbbbbbbbbb", "bc %B %M%N"), /* 5Exx */
195 FMT("010111111mmmnnnnbbbbbbbbbbbbbbbb", "bnc %B %M%N"), /* 5Fxx */
196 FMT("01100sss0aaaaaaa", "sacl %A%S"), /* 6xxx */
197 FMT("01100sss1mmmnnnn", "sacl %M%S%N"),
198 FMT("01101sss0aaaaaaa", "sach %A%S"), /* 6Xxx */
199 FMT("01101sss1mmmnnnn", "sach %M%S%N"),
200 FMT("01110rrr0aaaaaaa", "sar %R,%A"), /* 7xxx */
201 FMT("01110rrr1mmmnnnn", "sar %R%M%N"),
202 FMT("011110000aaaaaaa", "sst %A"), /* 78xx */
203 FMT("011110001mmmnnnn", "sst %M%N"),
204 FMT("011110010aaaaaaa", "sst1 %A"), /* 79xx */
205 FMT("011110011mmmnnnn", "sst1 %M%N"),
206 FMT("011110100aaaaaaa", "popd %A"), /* 7Axx */
207 FMT("011110101mmmnnnn", "popd %M%N"),
208 FMT("011110110aaaaaaa", "zalr %A"), /* 7Bxx */
209 FMT("011110111mmmnnnn", "zalr %M%N"),
210 FMT("011111000aaaaaaa", "spl %A"), /* 7Cxx */
211 FMT("011111001mmmnnnn", "spl %M%N"),
212 FMT("011111010aaaaaaa", "sph %A"), /* 7Dxx */
213 FMT("011111011mmmnnnn", "sph %M%N"),
214 FMT("011111100aaaaaaa", "adrk %A"), /* 7Exx */
215 FMT("011111101mmmnnnn", "adrk %M%N"),
216 FMT("011111110aaaaaaa", "sbrk %A"), /* 7Fxx */
217 FMT("011111111mmmnnnn", "sbrk %M%N"),
218 FMT("1000pppp0aaaaaaa", "in %A,%P"), /* 8xxx */
219 FMT("1000pppp1mmmnnnn", "in %M,%P%N"),
220 FMT("1001tttt0aaaaaaa", "bit %A,%T"), /* 9xxx */
221 FMT("1001tttt1mmmnnnn", "bit %M,%T%N"),
222 FMT("101wwwwwwwwwwwww", "mpyk %W"), /* Axxx-Bxxx */
223 FMT("11000rrrdddddddd", "lark %R,%D"), /* Cxxx */
224 FMT("1100100kdddddddd", "ldpk %K%D"), /* Cxxx */
225 /* FMT("11001010dddddddd", "lack %D"), CAxx */
226 /* LACK has been expanded out to all its variations because one of its */
227 /* its opcodes is the same as ZAC. Actually, it performs the same function */
228 FMT("1100101000000000", "zac"), /* CA00 */
229 FMT("1100101000000001", "lack 01h"), /* CAxx */
230 FMT("1100101000000010", "lack 02h"),
231 FMT("1100101000000011", "lack 03h"),
232 FMT("1100101000000100", "lack 04h"),
233 FMT("1100101000000101", "lack 05h"),
234 FMT("1100101000000110", "lack 06h"),
235 FMT("1100101000000111", "lack 07h"),
236 FMT("1100101000001000", "lack 08h"),
237 FMT("1100101000001001", "lack 09h"),
238 FMT("1100101000001010", "lack 0Ah"),
239 FMT("1100101000001011", "lack 0Bh"),
240 FMT("1100101000001100", "lack 0Ch"),
241 FMT("1100101000001101", "lack 0Dh"),
242 FMT("1100101000001110", "lack 0Eh"),
243 FMT("1100101000001111", "lack 0Fh"),
244 FMT("110010100001tttt", "lack 1%T"),
245 FMT("110010100010tttt", "lack 2%T"),
246 FMT("110010100011tttt", "lack 3%T"),
247 FMT("110010100100tttt", "lack 4%T"),
248 FMT("110010100101tttt", "lack 5%T"),
249 FMT("110010100110tttt", "lack 6%T"),
250 FMT("110010100111tttt", "lack 7%T"),
251 FMT("110010101000tttt", "lack 8%T"),
252 FMT("110010101001tttt", "lack 9%T"),
253 FMT("110010101010tttt", "lack A%T"),
254 FMT("110010101011tttt", "lack B%T"),
255 FMT("110010101100tttt", "lack C%T"),
256 FMT("110010101101tttt", "lack D%T"),
257 FMT("110010101110tttt", "lack E%T"),
258 FMT("110010101111tttt", "lack F%T"),
259
260 FMT("11001011dddddddd", "rptk %D"), /* CBxx */
261 FMT("11001100dddddddd", "addk %D"), /* CCxx */
262 FMT("11001101dddddddd", "subk %D"), /* CDxx */
263 FMT("1100111000000000", "eint"), /* CE00 */
264 FMT("1100111000000001", "dint"), /* CE01 */
265 FMT("1100111000000010", "rovm"), /* CE02 */
266 FMT("1100111000000011", "sovm"), /* CE03 */
267 FMT("1100111000000100", "cnfd"), /* CE04 */
268 FMT("1100111000000101", "cnfp"), /* CE05 */
269 FMT("1100111000000110", "rsxm"), /* CE06 */
270 FMT("1100111000000111", "ssxm"), /* CE07 */
271 FMT("11001110000010kk", "spm %K"), /* CE0x */
272 FMT("1100111000001100", "rxf"), /* CE0C */
273 FMT("1100111000001101", "sxf"), /* CE0D */
274 FMT("110011100000111k", "fort %K"), /* CE0x */
275 FMT("1100111000010100", "pac"), /* CE14 */
276 FMT("1100111000010101", "apac"), /* CE15 */
277 FMT("1100111000010110", "spac"), /* CE16 */
278 FMT("1100111000011000", "sfl"), /* CE18 */
279 FMT("1100111000011001", "sfr"), /* CE19 */
280 FMT("1100111000011011", "abs"), /* CE1B */
281 FMT("1100111000011100", "push"), /* CE1C */
282 FMT("1100111000011101", "pop"), /* CE1D */
283 FMT("1100111000011110", "trap"), /* CE1E */
284 FMT("1100111000011111", "idle"), /* CE1F */
285 FMT("1100111000100000", "rtxm"), /* CE20 */
286 FMT("1100111000100001", "stxm"), /* CE21 */
287 FMT("1100111000100011", "neg"), /* CE23 */
288 FMT("1100111000100100", "cala"), /* CE24 */
289 FMT("1100111000100101", "bacc"), /* CE25 */
290 FMT("1100111000100110", "ret"), /* CE26 */
291 FMT("1100111000100111", "cmpl"), /* CE27 */
292 FMT("1100111000110000", "rc"), /* CE30 */
293 FMT("1100111000110001", "sc"), /* CE31 */
294 FMT("1100111000110010", "rtc"), /* CE32 */
295 FMT("1100111000110011", "stc"), /* CE33 */
296 FMT("1100111000110100", "rol"), /* CE34 */
297 FMT("1100111000110101", "ror"), /* CE35 */
298 FMT("1100111000110110", "rfsm"), /* CE36 */
299 FMT("1100111000110111", "sfsm"), /* CE37 */
300 FMT("1100111000111000", "rhm"), /* CE38 */
301 FMT("1100111000111001", "shm"), /* CE39 */
302 FMT("11001110001111kk", "conf %K"), /* CE3x */
303 FMT("11001110010100cc", "cmpr %C"), /* CE5x */
304 FMT("110011101mmm0010", "norm %M"), /* CEx2 */
305 FMT("110011110aaaaaaa", "mpys %A"), /* CFxx */
306 FMT("110011111mmmnnnn", "mpys %M%N"),
307 FMT("11010rrr00000000wwwwwwwwwwwwwwww", "lrlk %R,%W"), /* Dx00 */
308 FMT("1101tttt00000001wwwwwwwwwwwwwwww", "lalk %W,%T"), /* Dx01 */
309 FMT("1101tttt00000010wwwwwwwwwwwwwwww", "adlk %W,%T"), /* Dx02 */
310 FMT("1101tttt00000011wwwwwwwwwwwwwwww", "sblk %W,%T"), /* Dx03 */
311 FMT("1101tttt00000100wwwwwwwwwwwwwwww", "andk %W,%T"), /* Dx04 */
312 FMT("1101tttt00000101wwwwwwwwwwwwwwww", "ork %W,%T"), /* Dx05 */
313 FMT("1101tttt00000110wwwwwwwwwwwwwwww", "xork %W,%T"), /* Dx06 */
314 FMT("1110pppp0aaaaaaa", "out %A,%P"), /* Exxx */
315 FMT("1110pppp1mmmnnnn", "out %M,%P%N"),
316 FMT("111100001mmmnnnnbbbbbbbbbbbbbbbb", "bv %B %M%N"), /* F0xx */
317 FMT("111100011mmmnnnnbbbbbbbbbbbbbbbb", "bgz %B %M%N"), /* F1xx */
318 FMT("111100101mmmnnnnbbbbbbbbbbbbbbbb", "blez %B %M%N"), /* F2xx */
319 FMT("111100111mmmnnnnbbbbbbbbbbbbbbbb", "blz %B %M%N"), /* F3xx */
320 FMT("111101001mmmnnnnbbbbbbbbbbbbbbbb", "bgez %B %M%N"), /* F4xx */
321 FMT("111101011mmmnnnnbbbbbbbbbbbbbbbb", "bnz %B %M%N"), /* F5xx */
322 FMT("111101101mmmnnnnbbbbbbbbbbbbbbbb", "bz %B %M%N"), /* F6xx */
323 FMT("111101111mmmnnnnbbbbbbbbbbbbbbbb", "bnv %B %M%N"), /* F7xx */
324 FMT("111110001mmmnnnnbbbbbbbbbbbbbbbb", "bbz %B %M%N"), /* F8xx */
325 FMT("111110011mmmnnnnbbbbbbbbbbbbbbbb", "bbnz %B %M%N"), /* F9xx */
326 FMT("111110101mmmnnnnbbbbbbbbbbbbbbbb", "bioz %B %M%N"), /* FAxx */
327 FMT("111110111mmmnnnnbbbbbbbbbbbbbbbb", "banz %B %M%N"), /* FBxx */
328 FMT("111111000aaaaaaabbbbbbbbbbbbbbbb", "blkp %B,%A"), /* FCxx */
329 FMT("111111001mmmnnnnbbbbbbbbbbbbbbbb", "blkp %B,%M%N"),
330 FMT("111111010aaaaaaabbbbbbbbbbbbbbbb", "blkd %B,%A"), /* FDxx */
331 FMT("111111011mmmnnnnbbbbbbbbbbbbbbbb", "blkd %B,%M%N"),
332 FMT("111111101mmmnnnnbbbbbbbbbbbbbbbb", "call %B %M%N"), /* FExx */
333 FMT("111111111mmmnnnnbbbbbbbbbbbbbbbb", "b %B %M%N"), /* FFxx */
334 NULL
335 };
336
337 #define MAX_OPS (((sizeof(TMS32025Formats) / sizeof(TMS32025Formats[0])) - 1) / PTRS_PER_FORMAT)
338
339 typedef struct opcode {
340 word mask; /* instruction mask */
341 word bits; /* constant bits */
342 word extcode; /* value that gets extension code */
343 const char *parse; /* how to parse bits */
344 const char *fmt; /* instruction format */
345 } TMS32025Opcode;
346
347 static TMS32025Opcode Op[MAX_OPS+1];
348 static int OpInizialized = 0;
349
InitDasm32025(void)350 static void InitDasm32025(void)
351 {
352 const char *p, **ops;
353 word mask, bits;
354 int bit;
355 int i;
356
357 ops = TMS32025Formats; i = 0;
358 while (*ops)
359 {
360 p = *ops;
361 mask = 0; bits = 0; bit = 15;
362 while (*p && bit >= 0)
363 {
364 switch (*p++)
365 {
366 case '1': mask |= 1<<bit; bits |= 1<<bit; bit--; break;
367 case '0': mask |= 1<<bit; bit--; break;
368 case ' ': break;
369 case 'a':
370 case 'b':
371 case 'c':
372 case 'd':
373 case 'k':
374 case 'm':
375 case 'n':
376 case 'p':
377 case 'r':
378 case 's':
379 case 't':
380 case 'w':
381 case 'x':
382 bit --;
383 break;
384 default: printf("Invalid instruction encoding '%s %s'\n",
385 ops[0],ops[1]);
386 exit(1);
387 }
388 }
389 if (bit != -1 )
390 {
391 printf("not enough bits in encoding '%s %s' %d\n",
392 ops[0],ops[1],bit);
393 exit(1);
394 }
395 while (isspace(*p)) p++;
396 if (*p) Op[i].extcode = *p;
397 Op[i].bits = bits;
398 Op[i].mask = mask;
399 Op[i].fmt = ops[1];
400 Op[i].parse = ops[0];
401
402 ops += PTRS_PER_FORMAT;
403 i++;
404 }
405
406 OpInizialized = 1;
407 }
408
Dasm32025(char * str,unsigned pc)409 unsigned Dasm32025(char *str, unsigned pc)
410 {
411 int a, b, c, d, k, m, n, p, r, s, t, w, x; /* these can all be filled in by parsing an instruction */
412 int i;
413 int op;
414 int cnt = 1;
415 int code;
416 int bit;
417 char *strtmp;
418 const char *cp; /* character pointer in OpFormats */
419
420 if (!OpInizialized) InitDasm32025();
421
422 op = -1; /* no matching opcode */
423 code = READOP16(2*pc);
424 for ( i = 0; i < MAX_OPS; i++)
425 {
426 if ((code & Op[i].mask) == Op[i].bits)
427 {
428 if (op != -1)
429 {
430 printf("Error: opcode %04Xh matches %d (%s) and %d (%s)\n",
431 code,i,Op[i].fmt,op,Op[op].fmt);
432 }
433 op = i;
434 }
435 }
436 if (op == -1)
437 {
438 sprintf(str,"???? dw %04Xh",code);
439 return cnt;
440 }
441 strtmp = str;
442 if (Op[op].extcode)
443 {
444 bit = 31;
445 code <<= 16;
446 code |= READARG16(2*(pc+cnt));
447 cnt++;
448 }
449 else
450 {
451 bit = 15;
452 }
453
454 /* shift out operands */
455 cp = Op[op].parse;
456 a = b = c = d = k = m = n = p = r = s = t = w = x = 0;
457
458 while (bit >= 0)
459 {
460 /* printf("{%c/%d}",*cp,bit); */
461 switch(*cp)
462 {
463 case 'a': a <<=1; a |= ((code & (1<<bit)) ? 1 : 0); bit--; break;
464 case 'b': b <<=1; b |= ((code & (1<<bit)) ? 1 : 0); bit--; break;
465 case 'c': c <<=1; c |= ((code & (1<<bit)) ? 1 : 0); bit--; break;
466 case 'd': d <<=1; d |= ((code & (1<<bit)) ? 1 : 0); bit--; break;
467 case 'k': k <<=1; k |= ((code & (1<<bit)) ? 1 : 0); bit--; break;
468 case 'm': m <<=1; m |= ((code & (1<<bit)) ? 1 : 0); bit--; break;
469 case 'n': n <<=1; n |= ((code & (1<<bit)) ? 1 : 0); bit--; break;
470 case 'p': p <<=1; p |= ((code & (1<<bit)) ? 1 : 0); bit--; break;
471 case 'r': r <<=1; r |= ((code & (1<<bit)) ? 1 : 0); bit--; break;
472 case 's': s <<=1; s |= ((code & (1<<bit)) ? 1 : 0); bit--; break;
473 case 't': t <<=1; t |= ((code & (1<<bit)) ? 1 : 0); bit--; break;
474 case 'w': w <<=1; w |= ((code & (1<<bit)) ? 1 : 0); bit--; break;
475 case 'x': bit--; break;
476 case ' ': break;
477 case '1': case '0': bit--; break;
478 case '\0': printf("premature end of parse string, opcode %x, bit = %d\n",code,bit); exit(1);
479 }
480 cp++;
481 }
482
483 /* now traverse format string */
484 cp = Op[op].fmt;
485 while (*cp)
486 {
487 if (*cp == '%')
488 {
489 char num[30], *q;
490 cp++;
491 switch (*cp++)
492 {
493 case 'A': sprintf(num,"$%02X",a); break;
494 case 'B': sprintf(num,"$%04X",b); break;
495 case 'C': sprintf(num,"%s",cmpmode[c]); break;
496 case 'D': sprintf(num,"%02Xh",d); break;
497 case 'K': sprintf(num,"%d",k); break;
498 case 'M': sprintf(num,"%s",arith[m]); break;
499 case 'N': sprintf(num,"%s",nextar[n]); break;
500 case 'P': sprintf(num,"PA$%01X",p); break;
501 case 'R': sprintf(num,"AR%d",r); break;
502 case 'S': sprintf(num,",%d",s); break;
503 case 'T': sprintf(num,"%01Xh",t); break;
504 case 'W': sprintf(num,"%04Xh",w); break;
505 case 'X': break;
506 default:
507 printf("illegal escape character in format '%s'\n",Op[op].fmt);
508 exit(1);
509 }
510 q = num; while (*q) *str++ = *q++;
511 *str = '\0';
512 }
513 else
514 {
515 *str++ = *cp++;
516 *str = '\0';
517 }
518 }
519 return cnt;
520 }
521