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 		log_cb(RETRO_LOG_DEBUG, LOGPRE "{%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': log_cb(RETRO_LOG_DEBUG, LOGPRE "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 					log_cb(RETRO_LOG_DEBUG, LOGPRE "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