~ubuntu-branches/ubuntu/precise/mame/precise-proposed

« back to all changes in this revision

Viewing changes to src/emu/cpu/scudsp/scudspdasm.c

  • Committer: Package Import Robot
  • Author(s): Cesare Falco
  • Date: 2011-11-30 18:50:10 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20111130185010-02hcxybht1mn082w
Tags: 0.144-0ubuntu1
* New upstream release (LP: #913550)
* mame.install:
  - Added artwork/ images to be used with -effect switch
  - Be more selective with hash/ contents
* contrib/mame.ini: added /usr/share/games/mame/artwork/ to artpath

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    Sega Saturn SCU DSP disassembler
 
3
 
 
4
    Written by Angelo Salese
 
5
*/
 
6
 
 
7
#include "emu.h"
 
8
 
 
9
enum
 
10
{
 
11
        EA_A = 1,
 
12
        EA_ALU,
 
13
        EA_D0,
 
14
        EA_IMM8,
 
15
        EA_IMM18,
 
16
        EA_IMM25,
 
17
        EA_MUL,
 
18
        EA_P,
 
19
        EA_X,
 
20
        EA_Y,
 
21
        EA_SRCMEMX,
 
22
        EA_SRCMEMY,
 
23
        EA_SRCMEMD1,
 
24
        EA_DMADSTMEM,
 
25
        EA_DSTMEM,
 
26
        EA_MVIDSTMEM,
 
27
};
 
28
 
 
29
typedef struct {
 
30
        char mnemonic[32];
 
31
        int address_mode_1;
 
32
        int address_mode_2;
 
33
        int address_mode_3,
 
34
} SCUDSP_OPCODE;
 
35
 
 
36
static const SCUDSP_OPCODE alu_table[16] =
 
37
{
 
38
        { "NOP", 0, 0, 0, }, /* 0000 */
 
39
        { "AND", 0, 0, 0, }, /* 0001 */
 
40
        { "OR ", 0, 0, 0, }, /* 0010 */
 
41
        { "XOR", 0, 0, 0, }, /* 0011 */
 
42
        { "ADD", 0, 0, 0, }, /* 0100 */
 
43
        { "SUB", 0, 0, 0, }, /* 0101 */
 
44
        { "AD2", 0, 0, 0, }, /* 0110 */
 
45
        { "???", 0, 0, 0, }, /* 0111 */
 
46
        { "SR ", 0, 0, 0, }, /* 1000 */
 
47
        { "RR ", 0, 0, 0, }, /* 1001 */
 
48
        { "SL ", 0, 0, 0, }, /* 1010 */
 
49
        { "RL ", 0, 0, 0, }, /* 1011 */
 
50
        { "???", 0, 0, 0, }, /* 1100 */
 
51
        { "???", 0, 0, 0, }, /* 1101 */
 
52
        { "???", 0, 0, 0, }, /* 1110 */
 
53
        { "RL8", 0, 0, 0, }, /* 1111 */
 
54
};
 
55
 
 
56
static const SCUDSP_OPCODE xbus_table[] =
 
57
{
 
58
        { "NOP", 0,          0,    0, },                        /* 000 */
 
59
        { "???", 0,          0,    0, },                        /* 001 */
 
60
        { "MOV", EA_MUL,     EA_P, 0, },        /* 010 */
 
61
        { "MOV", EA_SRCMEMX, EA_P, 0, },                /* 011 */ //MOV %s,P
 
62
        { "MOV", EA_SRCMEMX, EA_X, 0, },                /* 100 */ //MOV %s,X
 
63
        { "???", 0,          0,    0, },                        /* 101 */
 
64
        { "???", 0,          0,    0, },                        /* 110 */
 
65
        { "???", 0,          0,    0, },                        /* 111 */
 
66
};
 
67
 
 
68
static const SCUDSP_OPCODE ybus_table[] =
 
69
{
 
70
        { "NOP", 0,          0,    0, },        /* 000 */
 
71
        { "CLR", 0,          EA_A, 0, },        /* 001 */
 
72
        { "MOV", EA_ALU,     EA_A, 0, },        /* 010 */
 
73
        { "MOV", EA_SRCMEMY, EA_A, 0, },        /* 011 */ //MOV %s,A
 
74
        { "MOV", EA_SRCMEMY, EA_Y, 0, },        /* 100 */ //MOV %s,Y
 
75
        { "???", 0,          0,    0, },                                /* 101 */
 
76
        { "???", 0,          0,    0, },                                /* 110 */
 
77
        { "???", 0,          0,    0, },                                /* 111 */
 
78
};
 
79
 
 
80
static const SCUDSP_OPCODE d1bus_table[] =
 
81
{
 
82
        { "NOP", 0,          0,         0, },                                   /* 00 */
 
83
        { "MOV", EA_IMM8,    EA_DSTMEM, 0, },           /* 01 */ //MOV %I8,%d
 
84
        { "???", 0,          0,         0, },                                   /* 10 */
 
85
        { "MOV", EA_SRCMEMD1,0,         0, },                   /* 11 */ //MOV %S,%d
 
86
};
 
87
 
 
88
static const SCUDSP_OPCODE mvi_table[] =
 
89
{
 
90
        { "MVI", EA_IMM25,   EA_MVIDSTMEM,  0, },                                       /* 0 */ //"MVI %I,%d"
 
91
        { "MVI", EA_IMM18,   EA_MVIDSTMEM,  EA_FLAGS, },                        /* 1 */ //"MVI %I,%d,%f"
 
92
};
 
93
 
 
94
static const SCUDSP_OPCODE dma_table[] =
 
95
{
 
96
        { "DMA",  EA_D0,          EA_DMADSTMEM,  EA_IMM8, }, /* 000 */ // "DMA%H%A D0,%M,%I",
 
97
        { "DMA",  EA_DMASRCMEM,   EA_D0,  EA_IMM8, },   /* 001 */ // "DMA%H%A %s,D0,%I",
 
98
        { "DMA",  0,          0,  0, }, /* 010 */ // "DMA%H%A D0,%M,%s",
 
99
        { "DMA",  0,   0,  0, },                                                /* 011 */ // "DMA%H%A %s,D0,%s",
 
100
        { "DMAH", EA_D0,   EA_DMADSTMEM,  EA_IMM8, },   /* 100 */ // "DMA%H%A D0,%M,%I",
 
101
        { "DMAH", EA_DMASRCMEM,   EA_D0,  EA_IMM8, },   /* 101 */ // "DMA%H%A %s,D0,%I",
 
102
        { "DMAH", 0,   0,  0, },                                                /* 110 */ // "DMA%H%A D0,%M,%s",
 
103
        { "DMAH", 0,   0,  0, },                                                /* 111 */ // "DMA%H%A %s,D0,%s",
 
104
 
 
105
};
 
106
 
 
107
static const SCUDSP_OPCODE jmp_table[] =
 
108
{
 
109
        { "JMP", EA_IMM8, 0, 0, }, /* 0 */ // unconditional
 
110
        { "JMP", EA_IMM8, 0, EA_FLAGS, }, /* 1 */ // conditional
 
111
};
 
112
 
 
113
static const SCUDSP_OPCODE loop_table[] =
 
114
{
 
115
        { "BTM", 0,   0,  0, },                                 /* 00 */
 
116
        { "LPS", 0,   0,  0, },                                 /* 01 */
 
117
};
 
118
 
 
119
static const SCUDSP_OPCODE end_table[] =
 
120
{
 
121
        { "END", 0,   0,  0, },                                 /* 00 */
 
122
        { "ENDI",0,   0,  0, },                                 /* 01 */
 
123
};
 
124
 
 
125
 
 
126
static const char *const src_mem[] =
 
127
{
 
128
        "M0",                   /* 0000 */
 
129
        "M1",                   /* 0001 */
 
130
        "M2",                   /* 0010 */
 
131
        "M3",                   /* 0011 */
 
132
        "MC0",                  /* 0100 */
 
133
        "MC1",                  /* 0101 */
 
134
        "MC2",                  /* 0110 */
 
135
        "MC3",                  /* 0111 */
 
136
        "???",                  /* 1000 */
 
137
        "ALL",                  /* 1001 */
 
138
        "ALH",                  /* 1010 */
 
139
        "???",                  /* 1011 */
 
140
        "???",                  /* 1100 */
 
141
        "???",                  /* 1101 */
 
142
        "???",                  /* 1110 */
 
143
        "???",                  /* 1111 */
 
144
};
 
145
 
 
146
static const char *const dst_mem[] =
 
147
{
 
148
        "MC0",                  /* 0000 */
 
149
        "MC1",                  /* 0001 */
 
150
        "MC2",                  /* 0010 */
 
151
        "MC3",                  /* 0011 */
 
152
        "RX",                   /* 0100 */
 
153
        "PL",                   /* 0101 */
 
154
        "RA0",                  /* 0110 */
 
155
        "WA0",                  /* 0111 */
 
156
        "???",                  /* 1000 */
 
157
        "???",                  /* 1001 */
 
158
        "LOP",                  /* 1010 */
 
159
        "TOP",                  /* 1011 */
 
160
        "CT0",                  /* 1100 */
 
161
        "CT1",                  /* 1101 */
 
162
        "CT2",                  /* 1110 */
 
163
        "CT3",                  /* 1111 */
 
164
};
 
165
 
 
166
static const char *const mvi_dst_mem[] =
 
167
{
 
168
        "MC0",                  /* 0000 */
 
169
        "MC1",                  /* 0001 */
 
170
        "MC2",                  /* 0010 */
 
171
        "MC3",                  /* 0011 */
 
172
        "RX",                   /* 0100 */
 
173
        "PL",                   /* 0101 */
 
174
        "RA0",                  /* 0110 */
 
175
        "WA0",                  /* 0111 */
 
176
        "???",                  /* 1000 */
 
177
        "???",                  /* 1001 */
 
178
        "LOP",                  /* 1010 */
 
179
        "???",                  /* 1011 */
 
180
        "PC",           /* 1100 */ //???
 
181
        "???",                  /* 1101 */
 
182
        "???",                  /* 1110 */
 
183
        "???",                  /* 1111 */
 
184
};
 
185
 
 
186
static const char *const cond_flags[] =
 
187
{
 
188
        "??", /* 0000 */
 
189
        "Z ", /* 0001 */
 
190
        "S ", /* 0010 */
 
191
        "ZS", /* 0011 */
 
192
        "C ", /* 0100 */
 
193
        "??", /* 0101 */
 
194
        "??", /* 0110 */
 
195
        "??", /* 0111 */
 
196
        "T0", /* 1000 */
 
197
        "??", /* 1001 */
 
198
        "??", /* 1010 */
 
199
        "??", /* 1011 */
 
200
        "??", /* 1100 */
 
201
        "??", /* 1101 */
 
202
        "??", /* 1110 */
 
203
        "??", /* 1111 */
 
204
};
 
205
 
 
206
/*****************************************************************************/
 
207
 
 
208
static char *output;
 
209
static const UINT32 *rombase;
 
210
 
 
211
static void ATTR_PRINTF(1,2) print(const char *fmt, ...)
 
212
{
 
213
        va_list vl;
 
214
 
 
215
        va_start(vl, fmt);
 
216
        output += vsprintf(output, fmt, vl);
 
217
        va_end(vl);
 
218
}
 
219
 
 
220
static UINT32 fetch(void)
 
221
{
 
222
        return *rombase++;
 
223
}
 
224
 
 
225
static UINT8 add_table(UINT32 cur_opcode)
 
226
{
 
227
        UINT8 res = (cur_opcode & 0x00038000) >> 15;
 
228
 
 
229
        if(res == 0)
 
230
                res = 0;
 
231
        else
 
232
                res = 1 << (res-1);
 
233
 
 
234
        return res;
 
235
}
 
236
 
 
237
static UINT32 decode_opcode(UINT32 pc, const SCUDSP_OPCODE *op_table,UINT32 cur_opcode)
 
238
{
 
239
        INT8 rel8;
 
240
        UINT32 imm32;
 
241
        UINT8 op2;
 
242
        UINT32 flags = 0;
 
243
 
 
244
        //if (!strcmp(op_table->mnemonic, "jsr") || !strcmp(op_table->mnemonic, "bsr"))
 
245
        //  flags = DASMFLAG_STEP_OVER;
 
246
        //else if (!strcmp(op_table->mnemonic, "rts") || !strcmp(op_table->mnemonic, "rti"))
 
247
        //  flags = DASMFLAG_STEP_OUT;
 
248
 
 
249
        print("%s ", op_table->mnemonic);
 
250
 
 
251
        switch(op_table->address_mode_1)
 
252
        {
 
253
                case EA_ALU:       print("ALU "); break;
 
254
                case EA_IMM8:      print("%02X ",cur_opcode & 0xff); break;
 
255
                case EA_IMM18:     print("%08X ",cur_opcode & 0x7ffff); break;
 
256
                case EA_IMM25:     print("%08X ",cur_opcode & 0x1ffffff); break;
 
257
                case EA_MUL:       print("MUL "); break;
 
258
                case EA_SRCMEMX:   print("%s ", src_mem[(cur_opcode & 0x00700000) >> 20]); break;
 
259
                case EA_SRCMEMY:   print("%s ", src_mem[(cur_opcode & 0x0001c000) >> 14]); break;
 
260
                case EA_SRCMEMD1:  print("%s ", src_mem[(cur_opcode & 0x0000000f) >> 0]); break;
 
261
                case EA_D0:        print("%d D0 ",add_table(cur_opcode)); break;
 
262
                case EA_DMASRCMEM: print("%d %s ",add_table(cur_opcode),src_mem[(cur_opcode & 0x00000300) >> 8]); break;
 
263
 
 
264
                default:
 
265
                        break;
 
266
        }
 
267
 
 
268
        switch(op_table->address_mode_2)
 
269
        {
 
270
                case EA_A:                 print("A"); break;
 
271
                case EA_P:                 print("P"); break;
 
272
                case EA_X:                 print("X"); break;
 
273
                case EA_Y:                 print("Y"); break;
 
274
                case EA_DSTMEM:    print("%s ", dst_mem[(cur_opcode & 0x00000f00) >> 8]); break;
 
275
                case EA_DMADSTMEM: print("%s ", dst_mem[(cur_opcode & 0x00000300) >> 8]); break;
 
276
                case EA_MVIDSTMEM: print("%s ", mvi_dst_mem[(cur_opcode & 0x3c000000) >> 26]); break;
 
277
                case EA_D0:        print("D0 "); break;
 
278
 
 
279
                default:
 
280
                        break;
 
281
        }
 
282
 
 
283
        switch(op_table->address_mode_3)
 
284
        {
 
285
                case EA_IMM8:     print("%02X ",cur_opcode & 0xff); break;
 
286
                case EA_FLAGS:
 
287
                        if(!((cur_opcode >> 19) & 0x20))
 
288
                                print("N");
 
289
                        print("%s ", cond_flags[(cur_opcode & 0x0780000) >> 19]);
 
290
                        break;
 
291
 
 
292
                default:
 
293
                        break;
 
294
        }
 
295
 
 
296
        return flags;
 
297
}
 
298
 
 
299
CPU_DISASSEMBLE( scudsp )
 
300
{
 
301
        UINT32 flags = 0;
 
302
        UINT8 opcode;
 
303
 
 
304
        output = buffer;
 
305
        rombase = oprom;
 
306
 
 
307
        opcode = fetch();
 
308
        switch((opcode & 0xc0000000) >> 30)
 
309
        {
 
310
                case 0: // operation
 
311
                        flags =  decode_opcode(pc, &alu_table  [(opcode & 0x3c000000) >> 26],opcode);
 
312
                        flags |= decode_opcode(pc, &xbus_table [(opcode & 0x03800000) >> 23],opcode);
 
313
                        flags |= decode_opcode(pc, &ybus_table [(opcode & 0x000e0000) >> 17],opcode);
 
314
                        flags |= decode_opcode(pc, &d1bus_table[(opcode & 0x00003000) >> 12],opcode);
 
315
                        break;
 
316
                case 1: // unknown
 
317
                        print("???");
 
318
                        flags = 0;
 
319
                        break;
 
320
                case 2: // move immediate
 
321
                        flags = decode_opcode(pc,  &mvi_table  [(opcode & 0x02000000) >> 25],opcode);
 
322
                        break;
 
323
                case 3: // control
 
324
                        switch((opcode & 0x30000000) >> 28)
 
325
                        {
 
326
                                case 0:
 
327
                                        flags = decode_opcode(pc,  &dma_table  [(opcode & 0x7000) >> 12],opcode);
 
328
                                        break;
 
329
                                case 1:
 
330
                                        flags = decode_opcode(pc,  &jmp_table  [(opcode & 0x2000000) >> 25],opcode);
 
331
                                        break;
 
332
                                case 2:
 
333
                                        flags = decode_opcode(pc,  &loop_table [(opcode & 0x8000000) >> 27],opcode);
 
334
                                        break;
 
335
                                case 3:
 
336
                                        flags = decode_opcode(pc,  &end_table  [(opcode & 0x8000000) >> 27],opcode);
 
337
                                        break;
 
338
                        }
 
339
                        break;
 
340
        }
 
341
 
 
342
        return (rombase-oprom) | flags | DASMFLAG_SUPPORTED;
 
343
}