]> git.sesse.net Git - pistorm/blob - m68kdasm.c
Add Meson build files.
[pistorm] / m68kdasm.c
1 /* ======================================================================== */
2 /* ========================= LICENSING & COPYRIGHT ======================== */
3 /* ======================================================================== */
4 /*
5  *                                  MUSASHI
6  *                                Version 3.32
7  *
8  * A portable Motorola M680x0 processor emulation engine.
9  * Copyright Karl Stenerud.  All rights reserved.
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a copy
12  * of this software and associated documentation files (the "Software"), to deal
13  * in the Software without restriction, including without limitation the rights
14  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15  * copies of the Software, and to permit persons to whom the Software is
16  * furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included in
19  * all copies or substantial portions of the Software.
20
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27  * THE SOFTWARE.
28  */
29
30
31
32 /* ======================================================================== */
33 /* ================================ INCLUDES ============================== */
34 /* ======================================================================== */
35
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include "m68k.h"
40
41 #ifndef uint32
42 #define uint32 uint
43 #endif
44
45 #ifndef uint16
46 #define uint16 unsigned short
47 #endif
48
49 #ifndef DECL_SPEC
50 #define DECL_SPEC
51 #endif
52
53 /* ======================================================================== */
54 /* ============================ GENERAL DEFINES =========================== */
55 /* ======================================================================== */
56
57 /* unsigned int and int must be at least 32 bits wide */
58 #undef uint
59 #define uint unsigned int
60
61 /* Bit Isolation Functions */
62 #define BIT_0(A)  ((A) & 0x00000001)
63 #define BIT_1(A)  ((A) & 0x00000002)
64 #define BIT_2(A)  ((A) & 0x00000004)
65 #define BIT_3(A)  ((A) & 0x00000008)
66 #define BIT_4(A)  ((A) & 0x00000010)
67 #define BIT_5(A)  ((A) & 0x00000020)
68 #define BIT_6(A)  ((A) & 0x00000040)
69 #define BIT_7(A)  ((A) & 0x00000080)
70 #define BIT_8(A)  ((A) & 0x00000100)
71 #define BIT_9(A)  ((A) & 0x00000200)
72 #define BIT_A(A)  ((A) & 0x00000400)
73 #define BIT_B(A)  ((A) & 0x00000800)
74 #define BIT_C(A)  ((A) & 0x00001000)
75 #define BIT_D(A)  ((A) & 0x00002000)
76 #define BIT_E(A)  ((A) & 0x00004000)
77 #define BIT_F(A)  ((A) & 0x00008000)
78 #define BIT_10(A) ((A) & 0x00010000)
79 #define BIT_11(A) ((A) & 0x00020000)
80 #define BIT_12(A) ((A) & 0x00040000)
81 #define BIT_13(A) ((A) & 0x00080000)
82 #define BIT_14(A) ((A) & 0x00100000)
83 #define BIT_15(A) ((A) & 0x00200000)
84 #define BIT_16(A) ((A) & 0x00400000)
85 #define BIT_17(A) ((A) & 0x00800000)
86 #define BIT_18(A) ((A) & 0x01000000)
87 #define BIT_19(A) ((A) & 0x02000000)
88 #define BIT_1A(A) ((A) & 0x04000000)
89 #define BIT_1B(A) ((A) & 0x08000000)
90 #define BIT_1C(A) ((A) & 0x10000000)
91 #define BIT_1D(A) ((A) & 0x20000000)
92 #define BIT_1E(A) ((A) & 0x40000000)
93 #define BIT_1F(A) ((A) & 0x80000000)
94
95 /* These are the CPU types understood by this disassembler */
96 #define TYPE_68000 1
97 #define TYPE_68010 2
98 #define TYPE_68020 4
99 #define TYPE_68030 8
100 #define TYPE_68040 16
101
102 #define M68000_ONLY             TYPE_68000
103
104 #define M68010_ONLY             TYPE_68010
105 #define M68010_LESS             (TYPE_68000 | TYPE_68010)
106 #define M68010_PLUS             (TYPE_68010 | TYPE_68020 | TYPE_68030 | TYPE_68040)
107
108 #define M68020_ONLY     TYPE_68020
109 #define M68020_LESS     (TYPE_68010 | TYPE_68020)
110 #define M68020_PLUS             (TYPE_68020 | TYPE_68030 | TYPE_68040)
111
112 #define M68030_ONLY     TYPE_68030
113 #define M68030_LESS     (TYPE_68010 | TYPE_68020 | TYPE_68030)
114 #define M68030_PLUS             (TYPE_68030 | TYPE_68040)
115
116 #define M68040_PLUS             TYPE_68040
117
118
119 /* Extension word formats */
120 #define EXT_8BIT_DISPLACEMENT(A)          ((A)&0xff)
121 #define EXT_FULL(A)                       BIT_8(A)
122 #define EXT_EFFECTIVE_ZERO(A)             (((A)&0xe4) == 0xc4 || ((A)&0xe2) == 0xc0)
123 #define EXT_BASE_REGISTER_PRESENT(A)      (!BIT_7(A))
124 #define EXT_INDEX_REGISTER_PRESENT(A)     (!BIT_6(A))
125 #define EXT_INDEX_REGISTER(A)             (((A)>>12)&7)
126 #define EXT_INDEX_PRE_POST(A)             (EXT_INDEX_PRESENT(A) && (A)&3)
127 #define EXT_INDEX_PRE(A)                  (EXT_INDEX_PRESENT(A) && ((A)&7) < 4 && ((A)&7) != 0)
128 #define EXT_INDEX_POST(A)                 (EXT_INDEX_PRESENT(A) && ((A)&7) > 4)
129 #define EXT_INDEX_SCALE(A)                (((A)>>9)&3)
130 #define EXT_INDEX_LONG(A)                 BIT_B(A)
131 #define EXT_INDEX_AR(A)                   BIT_F(A)
132 #define EXT_BASE_DISPLACEMENT_PRESENT(A)  (((A)&0x30) > 0x10)
133 #define EXT_BASE_DISPLACEMENT_WORD(A)     (((A)&0x30) == 0x20)
134 #define EXT_BASE_DISPLACEMENT_LONG(A)     (((A)&0x30) == 0x30)
135 #define EXT_OUTER_DISPLACEMENT_PRESENT(A) (((A)&3) > 1 && ((A)&0x47) < 0x44)
136 #define EXT_OUTER_DISPLACEMENT_WORD(A)    (((A)&3) == 2 && ((A)&0x47) < 0x44)
137 #define EXT_OUTER_DISPLACEMENT_LONG(A)    (((A)&3) == 3 && ((A)&0x47) < 0x44)
138
139
140 /* Opcode flags */
141 #if M68K_COMPILE_FOR_MAME == OPT_ON
142 #define SET_OPCODE_FLAGS(x)     g_opcode_type = x;
143 #define COMBINE_OPCODE_FLAGS(x) ((x) | g_opcode_type | DASMFLAG_SUPPORTED)
144 #else
145 #define SET_OPCODE_FLAGS(x)
146 #define COMBINE_OPCODE_FLAGS(X) (X)
147 #endif
148
149
150 /* ======================================================================== */
151 /* =============================== PROTOTYPES ============================= */
152 /* ======================================================================== */
153
154 /* Read data at the PC and increment PC */
155 uint  read_imm_8(void);
156 uint  read_imm_16(void);
157 uint  read_imm_32(void);
158
159 /* Read data at the PC but don't imcrement the PC */
160 uint  peek_imm_8(void);
161 uint  peek_imm_16(void);
162 uint  peek_imm_32(void);
163
164 /* make signed integers 100% portably */
165 static int make_int_8(int value);
166 static int make_int_16(int value);
167 static int make_int_32(int value);
168
169 /* make a string of a hex value */
170 static char* make_signed_hex_str_8(uint val);
171 static char* make_signed_hex_str_16(uint val);
172 static char* make_signed_hex_str_32(uint val);
173
174 /* make string of ea mode */
175 static char* get_ea_mode_str(uint instruction, uint size);
176
177 char* get_ea_mode_str_8(uint instruction);
178 char* get_ea_mode_str_16(uint instruction);
179 char* get_ea_mode_str_32(uint instruction);
180
181 /* make string of immediate value */
182 static char* get_imm_str_s(uint size);
183 static char* get_imm_str_u(uint size);
184
185 char* get_imm_str_s8(void);
186 char* get_imm_str_s16(void);
187 char* get_imm_str_s32(void);
188
189 /* Stuff to build the opcode handler jump table */
190 static void  build_opcode_table(void);
191 static int   valid_ea(uint opcode, uint mask);
192 static int DECL_SPEC compare_nof_true_bits(const void *aptr, const void *bptr);
193
194 /* used to build opcode handler jump table */
195 typedef struct
196 {
197         void (*opcode_handler)(void); /* handler function */
198         uint mask;                    /* mask on opcode */
199         uint match;                   /* what to match after masking */
200         uint ea_mask;                 /* what ea modes are allowed */
201 } opcode_struct;
202
203
204
205 /* ======================================================================== */
206 /* ================================= DATA ================================= */
207 /* ======================================================================== */
208
209 /* Opcode handler jump table */
210 static void (*g_instruction_table[0x10000])(void);
211 /* Flag if disassembler initialized */
212 static int  g_initialized = 0;
213
214 /* Address mask to simulate address lines */
215 static unsigned int g_address_mask = 0xffffffff;
216
217 static char g_dasm_str[100]; /* string to hold disassembly */
218 static char g_helper_str[100]; /* string to hold helpful info */
219 static uint g_cpu_pc;        /* program counter */
220 static uint g_cpu_ir;        /* instruction register */
221 static uint g_cpu_type;
222 static uint g_opcode_type;
223 static const unsigned char* g_rawop;
224 static uint g_rawbasepc;
225
226 /* used by ops like asr, ror, addq, etc */
227 static const uint g_3bit_qdata_table[8] = {8, 1, 2, 3, 4, 5, 6, 7};
228
229 static const uint g_5bit_data_table[32] =
230 {
231         32,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
232         16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
233 };
234
235 static const char *const g_cc[16] =
236 {"t", "f", "hi", "ls", "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi", "ge", "lt", "gt", "le"};
237
238 static const char *const g_cpcc[64] =
239 {/* 000    001    010    011    100    101    110    111 */
240           "f",  "eq", "ogt", "oge", "olt", "ole", "ogl",  "or", /* 000 */
241          "un", "ueq", "ugt", "uge", "ult", "ule",  "ne",   "t", /* 001 */
242          "sf", "seq",  "gt",  "ge",  "lt",  "le",  "gl"  "gle", /* 010 */
243   "ngle", "ngl", "nle", "nlt", "nge", "ngt", "sne",  "st", /* 011 */
244           "?",   "?",   "?",   "?",   "?",   "?",   "?",   "?", /* 100 */
245           "?",   "?",   "?",   "?",   "?",   "?",   "?",   "?", /* 101 */
246           "?",   "?",   "?",   "?",   "?",   "?",   "?",   "?", /* 110 */
247           "?",   "?",   "?",   "?",   "?",   "?",   "?",   "?"  /* 111 */
248 };
249
250 static const char *const g_mmuregs[8] =
251 {
252         "tc", "drp", "srp", "crp", "cal", "val", "sccr", "acr"
253 };
254
255 static const char *const g_mmucond[16] =
256 {
257         "bs", "bc", "ls", "lc", "ss", "sc", "as", "ac",
258         "ws", "wc", "is", "ic", "gs", "gc", "cs", "cc"
259 };
260
261 /* ======================================================================== */
262 /* =========================== UTILITY FUNCTIONS ========================== */
263 /* ======================================================================== */
264
265 #define LIMIT_CPU_TYPES(ALLOWED_CPU_TYPES)      \
266         if(!(g_cpu_type & ALLOWED_CPU_TYPES))   \
267         {                                                                               \
268                 if((g_cpu_ir & 0xf000) == 0xf000)       \
269                         d68000_1111();                                  \
270                 else d68000_illegal();                          \
271                 return;                                                         \
272         }
273
274 static uint dasm_read_imm_8(uint advance)
275 {
276         uint result;
277         if (g_rawop)
278                 result = g_rawop[g_cpu_pc + 1 - g_rawbasepc];
279         else
280                 result = m68k_read_disassembler_16(g_cpu_pc & g_address_mask) & 0xff;
281         g_cpu_pc += advance;
282         return result;
283 }
284
285 static uint dasm_read_imm_16(uint advance)
286 {
287         uint result;
288         if (g_rawop)
289                 result = (g_rawop[g_cpu_pc + 0 - g_rawbasepc] << 8) |
290                           g_rawop[g_cpu_pc + 1 - g_rawbasepc];
291         else
292                 result = m68k_read_disassembler_16(g_cpu_pc & g_address_mask) & 0xffff;
293         g_cpu_pc += advance;
294         return result;
295 }
296
297 static uint dasm_read_imm_32(uint advance)
298 {
299         uint result;
300         if (g_rawop)
301                 result = (g_rawop[g_cpu_pc + 0 - g_rawbasepc] << 24) |
302                          (g_rawop[g_cpu_pc + 1 - g_rawbasepc] << 16) |
303                          (g_rawop[g_cpu_pc + 2 - g_rawbasepc] << 8) |
304                           g_rawop[g_cpu_pc + 3 - g_rawbasepc];
305         else
306                 result = m68k_read_disassembler_32(g_cpu_pc & g_address_mask) & 0xffffffff;
307         g_cpu_pc += advance;
308         return result;
309 }
310
311 #define read_imm_8()  dasm_read_imm_8(2)
312 #define read_imm_16() dasm_read_imm_16(2)
313 #define read_imm_32() dasm_read_imm_32(4)
314
315 #define peek_imm_8()  dasm_read_imm_8(0)
316 #define peek_imm_16() dasm_read_imm_16(0)
317 #define peek_imm_32() dasm_read_imm_32(0)
318
319 /* Fake a split interface */
320 #define get_ea_mode_str_8(instruction) get_ea_mode_str(instruction, 0)
321 #define get_ea_mode_str_16(instruction) get_ea_mode_str(instruction, 1)
322 #define get_ea_mode_str_32(instruction) get_ea_mode_str(instruction, 2)
323
324 #define get_imm_str_s8() get_imm_str_s(0)
325 #define get_imm_str_s16() get_imm_str_s(1)
326 #define get_imm_str_s32() get_imm_str_s(2)
327
328 #define get_imm_str_u8() get_imm_str_u(0)
329 #define get_imm_str_u16() get_imm_str_u(1)
330 #define get_imm_str_u32() get_imm_str_u(2)
331
332 static int sext_7bit_int(int value)
333 {
334         return (value & 0x40) ? (value | 0xffffff80) : (value & 0x7f);
335 }
336
337
338 /* 100% portable signed int generators */
339 static int make_int_8(int value)
340 {
341         return (value & 0x80) ? value | ~0xff : value & 0xff;
342 }
343
344 static int make_int_16(int value)
345 {
346         return (value & 0x8000) ? value | ~0xffff : value & 0xffff;
347 }
348
349 static int make_int_32(int value)
350 {
351         return (value & 0x80000000) ? value | ~0xffffffff : value & 0xffffffff;
352 }
353
354 /* Get string representation of hex values */
355 static char* make_signed_hex_str_8(uint val)
356 {
357         static char str[20];
358
359         val &= 0xff;
360
361         if(val == 0x80)
362                 sprintf(str, "-$80");
363         else if(val & 0x80)
364                 sprintf(str, "-$%x", (0-val) & 0x7f);
365         else
366                 sprintf(str, "$%x", val & 0x7f);
367
368         return str;
369 }
370
371 static char* make_signed_hex_str_16(uint val)
372 {
373         static char str[20];
374
375         val &= 0xffff;
376
377         if(val == 0x8000)
378                 sprintf(str, "-$8000");
379         else if(val & 0x8000)
380                 sprintf(str, "-$%x", (0-val) & 0x7fff);
381         else
382                 sprintf(str, "$%x", val & 0x7fff);
383
384         return str;
385 }
386
387 static char* make_signed_hex_str_32(uint val)
388 {
389         static char str[20];
390
391         val &= 0xffffffff;
392
393         if(val == 0x80000000)
394                 sprintf(str, "-$80000000");
395         else if(val & 0x80000000)
396                 sprintf(str, "-$%x", (0-val) & 0x7fffffff);
397         else
398                 sprintf(str, "$%x", val & 0x7fffffff);
399
400         return str;
401 }
402
403
404 /* make string of immediate value */
405 static char* get_imm_str_s(uint size)
406 {
407         static char str[25];
408         if(size == 0)
409                 sprintf(str, "#%s", make_signed_hex_str_8(read_imm_8()));
410         else if(size == 1)
411                 sprintf(str, "#%s", make_signed_hex_str_16(read_imm_16()));
412         else
413                 sprintf(str, "#%s", make_signed_hex_str_32(read_imm_32()));
414         return str;
415 }
416
417 static char* get_imm_str_u(uint size)
418 {
419         static char str[25];
420         if(size == 0)
421                 sprintf(str, "#$%x", read_imm_8() & 0xff);
422         else if(size == 1)
423                 sprintf(str, "#$%x", read_imm_16() & 0xffff);
424         else
425                 sprintf(str, "#$%x", read_imm_32() & 0xffffffff);
426         return str;
427 }
428
429 /* Make string of effective address mode */
430 static char* get_ea_mode_str(uint instruction, uint size)
431 {
432         static char b1[64];
433         static char b2[64];
434         static char* mode = b2;
435         uint extension;
436         uint base;
437         uint outer;
438         char base_reg[4];
439         char index_reg[8];
440         uint preindex;
441         uint postindex;
442         uint comma = 0;
443         uint temp_value;
444
445         /* Switch buffers so we don't clobber on a double-call to this function */
446         mode = mode == b1 ? b2 : b1;
447
448         switch(instruction & 0x3f)
449         {
450                 case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
451                 /* data register direct */
452                         sprintf(mode, "D%d", instruction&7);
453                         break;
454                 case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
455                 /* address register direct */
456                         sprintf(mode, "A%d", instruction&7);
457                         break;
458                 case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
459                 /* address register indirect */
460                         sprintf(mode, "(A%d)", instruction&7);
461                         break;
462                 case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
463                 /* address register indirect with postincrement */
464                         sprintf(mode, "(A%d)+", instruction&7);
465                         break;
466                 case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
467                 /* address register indirect with predecrement */
468                         sprintf(mode, "-(A%d)", instruction&7);
469                         break;
470                 case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
471                 /* address register indirect with displacement*/
472                         sprintf(mode, "(%s,A%d)", make_signed_hex_str_16(read_imm_16()), instruction&7);
473                         break;
474                 case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
475                 /* address register indirect with index */
476                         extension = read_imm_16();
477
478                         if(EXT_FULL(extension))
479                         {
480                                 if(EXT_EFFECTIVE_ZERO(extension))
481                                 {
482                                         strcpy(mode, "0");
483                                         break;
484                                 }
485                                 base = EXT_BASE_DISPLACEMENT_PRESENT(extension) ? (EXT_BASE_DISPLACEMENT_LONG(extension) ? read_imm_32() : read_imm_16()) : 0;
486                                 outer = EXT_OUTER_DISPLACEMENT_PRESENT(extension) ? (EXT_OUTER_DISPLACEMENT_LONG(extension) ? read_imm_32() : read_imm_16()) : 0;
487                                 if(EXT_BASE_REGISTER_PRESENT(extension))
488                                         sprintf(base_reg, "A%d", instruction&7);
489                                 else
490                                         *base_reg = 0;
491                                 if(EXT_INDEX_REGISTER_PRESENT(extension))
492                                 {
493                                         sprintf(index_reg, "%c%d.%c", EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w');
494                                         if(EXT_INDEX_SCALE(extension))
495                                                 sprintf(index_reg+strlen(index_reg), "*%d", 1 << EXT_INDEX_SCALE(extension));
496                                 }
497                                 else
498                                         *index_reg = 0;
499                                 preindex = (extension&7) > 0 && (extension&7) < 4;
500                                 postindex = (extension&7) > 4;
501
502                                 strcpy(mode, "(");
503                                 if(preindex || postindex)
504                                         strcat(mode, "[");
505                                 if(base)
506                                 {
507                                         if (EXT_BASE_DISPLACEMENT_LONG(extension))
508                                         {
509                                                 strcat(mode, make_signed_hex_str_32(base));
510                                         }
511                                         else
512                                         {
513                                                 strcat(mode, make_signed_hex_str_16(base));
514                                         }
515                                         comma = 1;
516                                 }
517                                 if(*base_reg)
518                                 {
519                                         if(comma)
520                                                 strcat(mode, ",");
521                                         strcat(mode, base_reg);
522                                         comma = 1;
523                                 }
524                                 if(postindex)
525                                 {
526                                         strcat(mode, "]");
527                                         comma = 1;
528                                 }
529                                 if(*index_reg)
530                                 {
531                                         if(comma)
532                                                 strcat(mode, ",");
533                                         strcat(mode, index_reg);
534                                         comma = 1;
535                                 }
536                                 if(preindex)
537                                 {
538                                         strcat(mode, "]");
539                                         comma = 1;
540                                 }
541                                 if(outer)
542                                 {
543                                         if(comma)
544                                                 strcat(mode, ",");
545                                         strcat(mode, make_signed_hex_str_16(outer));
546                                 }
547                                 strcat(mode, ")");
548                                 break;
549                         }
550
551                         if(EXT_8BIT_DISPLACEMENT(extension) == 0)
552                                 sprintf(mode, "(A%d,%c%d.%c", instruction&7, EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w');
553                         else
554                                 sprintf(mode, "(%s,A%d,%c%d.%c", make_signed_hex_str_8(extension), instruction&7, EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w');
555                         if(EXT_INDEX_SCALE(extension))
556                                 sprintf(mode+strlen(mode), "*%d", 1 << EXT_INDEX_SCALE(extension));
557                         strcat(mode, ")");
558                         break;
559                 case 0x38:
560                 /* absolute short address */
561                         sprintf(mode, "$%x.w", read_imm_16());
562                         break;
563                 case 0x39:
564                 /* absolute long address */
565                         sprintf(mode, "$%x.l", read_imm_32());
566                         break;
567                 case 0x3a:
568                 /* program counter with displacement */
569                         temp_value = read_imm_16();
570                         sprintf(mode, "(%s,PC)", make_signed_hex_str_16(temp_value));
571                         sprintf(g_helper_str, "; ($%x)", (make_int_16(temp_value) + g_cpu_pc-2) & 0xffffffff);
572                         break;
573                 case 0x3b:
574                 /* program counter with index */
575                         extension = read_imm_16();
576
577                         if(EXT_FULL(extension))
578                         {
579                                 if(EXT_EFFECTIVE_ZERO(extension))
580                                 {
581                                         strcpy(mode, "0");
582                                         break;
583                                 }
584                                 base = EXT_BASE_DISPLACEMENT_PRESENT(extension) ? (EXT_BASE_DISPLACEMENT_LONG(extension) ? read_imm_32() : read_imm_16()) : 0;
585                                 outer = EXT_OUTER_DISPLACEMENT_PRESENT(extension) ? (EXT_OUTER_DISPLACEMENT_LONG(extension) ? read_imm_32() : read_imm_16()) : 0;
586                                 if(EXT_BASE_REGISTER_PRESENT(extension))
587                                         strcpy(base_reg, "PC");
588                                 else
589                                         *base_reg = 0;
590                                 if(EXT_INDEX_REGISTER_PRESENT(extension))
591                                 {
592                                         sprintf(index_reg, "%c%d.%c", EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w');
593                                         if(EXT_INDEX_SCALE(extension))
594                                                 sprintf(index_reg+strlen(index_reg), "*%d", 1 << EXT_INDEX_SCALE(extension));
595                                 }
596                                 else
597                                         *index_reg = 0;
598                                 preindex = (extension&7) > 0 && (extension&7) < 4;
599                                 postindex = (extension&7) > 4;
600
601                                 strcpy(mode, "(");
602                                 if(preindex || postindex)
603                                         strcat(mode, "[");
604                                 if(base)
605                                 {
606                                         strcat(mode, make_signed_hex_str_16(base));
607                                         comma = 1;
608                                 }
609                                 if(*base_reg)
610                                 {
611                                         if(comma)
612                                                 strcat(mode, ",");
613                                         strcat(mode, base_reg);
614                                         comma = 1;
615                                 }
616                                 if(postindex)
617                                 {
618                                         strcat(mode, "]");
619                                         comma = 1;
620                                 }
621                                 if(*index_reg)
622                                 {
623                                         if(comma)
624                                                 strcat(mode, ",");
625                                         strcat(mode, index_reg);
626                                         comma = 1;
627                                 }
628                                 if(preindex)
629                                 {
630                                         strcat(mode, "]");
631                                         comma = 1;
632                                 }
633                                 if(outer)
634                                 {
635                                         if(comma)
636                                                 strcat(mode, ",");
637                                         strcat(mode, make_signed_hex_str_16(outer));
638                                 }
639                                 strcat(mode, ")");
640                                 break;
641                         }
642
643                         if(EXT_8BIT_DISPLACEMENT(extension) == 0)
644                                 sprintf(mode, "(PC,%c%d.%c", EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w');
645                         else
646                                 sprintf(mode, "(%s,PC,%c%d.%c", make_signed_hex_str_8(extension), EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w');
647                         if(EXT_INDEX_SCALE(extension))
648                                 sprintf(mode+strlen(mode), "*%d", 1 << EXT_INDEX_SCALE(extension));
649                         strcat(mode, ")");
650                         break;
651                 case 0x3c:
652                 /* Immediate */
653                         sprintf(mode, "%s", get_imm_str_u(size));
654                         break;
655                 default:
656                         sprintf(mode, "INVALID %x", instruction & 0x3f);
657         }
658         return mode;
659 }
660
661
662
663 /* ======================================================================== */
664 /* ========================= INSTRUCTION HANDLERS ========================= */
665 /* ======================================================================== */
666 /* Instruction handler function names follow this convention:
667  *
668  * d68000_NAME_EXTENSIONS(void)
669  * where NAME is the name of the opcode it handles and EXTENSIONS are any
670  * extensions for special instances of that opcode.
671  *
672  * Examples:
673  *   d68000_add_er_8(): add opcode, from effective address to register,
674  *                      size = byte
675  *
676  *   d68000_asr_s_8(): arithmetic shift right, static count, size = byte
677  *
678  *
679  * Common extensions:
680  * 8   : size = byte
681  * 16  : size = word
682  * 32  : size = long
683  * rr  : register to register
684  * mm  : memory to memory
685  * r   : register
686  * s   : static
687  * er  : effective address -> register
688  * re  : register -> effective address
689  * ea  : using effective address mode of operation
690  * d   : data register direct
691  * a   : address register direct
692  * ai  : address register indirect
693  * pi  : address register indirect with postincrement
694  * pd  : address register indirect with predecrement
695  * di  : address register indirect with displacement
696  * ix  : address register indirect with index
697  * aw  : absolute word
698  * al  : absolute long
699  */
700
701 static void d68000_illegal(void)
702 {
703         sprintf(g_dasm_str, "dc.w $%04x; ILLEGAL", g_cpu_ir);
704 }
705
706 static void d68000_1010(void)
707 {
708         sprintf(g_dasm_str, "dc.w    $%04x; opcode 1010", g_cpu_ir);
709 }
710
711
712 static void d68000_1111(void)
713 {
714         sprintf(g_dasm_str, "dc.w    $%04x; opcode 1111", g_cpu_ir);
715 }
716
717
718 static void d68000_abcd_rr(void)
719 {
720         sprintf(g_dasm_str, "abcd    D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7);
721 }
722
723
724 static void d68000_abcd_mm(void)
725 {
726         sprintf(g_dasm_str, "abcd    -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7);
727 }
728
729 static void d68000_add_er_8(void)
730 {
731         sprintf(g_dasm_str, "add.b   %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7);
732 }
733
734
735 static void d68000_add_er_16(void)
736 {
737         sprintf(g_dasm_str, "add.w   %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7);
738 }
739
740 static void d68000_add_er_32(void)
741 {
742         sprintf(g_dasm_str, "add.l   %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7);
743 }
744
745 static void d68000_add_re_8(void)
746 {
747         sprintf(g_dasm_str, "add.b   D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir));
748 }
749
750 static void d68000_add_re_16(void)
751 {
752         sprintf(g_dasm_str, "add.w   D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir));
753 }
754
755 static void d68000_add_re_32(void)
756 {
757         sprintf(g_dasm_str, "add.l   D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir));
758 }
759
760 static void d68000_adda_16(void)
761 {
762         sprintf(g_dasm_str, "adda.w  %s, A%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7);
763 }
764
765 static void d68000_adda_32(void)
766 {
767         sprintf(g_dasm_str, "adda.l  %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7);
768 }
769
770 static void d68000_addi_8(void)
771 {
772         char* str = get_imm_str_s8();
773         sprintf(g_dasm_str, "addi.b  %s, %s", str, get_ea_mode_str_8(g_cpu_ir));
774 }
775
776 static void d68000_addi_16(void)
777 {
778         char* str = get_imm_str_s16();
779         sprintf(g_dasm_str, "addi.w  %s, %s", str, get_ea_mode_str_16(g_cpu_ir));
780 }
781
782 static void d68000_addi_32(void)
783 {
784         char* str = get_imm_str_s32();
785         sprintf(g_dasm_str, "addi.l  %s, %s", str, get_ea_mode_str_32(g_cpu_ir));
786 }
787
788 static void d68000_addq_8(void)
789 {
790         sprintf(g_dasm_str, "addq.b  #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_8(g_cpu_ir));
791 }
792
793 static void d68000_addq_16(void)
794 {
795         sprintf(g_dasm_str, "addq.w  #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_16(g_cpu_ir));
796 }
797
798 static void d68000_addq_32(void)
799 {
800         sprintf(g_dasm_str, "addq.l  #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_32(g_cpu_ir));
801 }
802
803 static void d68000_addx_rr_8(void)
804 {
805         sprintf(g_dasm_str, "addx.b  D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7);
806 }
807
808 static void d68000_addx_rr_16(void)
809 {
810         sprintf(g_dasm_str, "addx.w  D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7);
811 }
812
813 static void d68000_addx_rr_32(void)
814 {
815         sprintf(g_dasm_str, "addx.l  D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7);
816 }
817
818 static void d68000_addx_mm_8(void)
819 {
820         sprintf(g_dasm_str, "addx.b  -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7);
821 }
822
823 static void d68000_addx_mm_16(void)
824 {
825         sprintf(g_dasm_str, "addx.w  -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7);
826 }
827
828 static void d68000_addx_mm_32(void)
829 {
830         sprintf(g_dasm_str, "addx.l  -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7);
831 }
832
833 static void d68000_and_er_8(void)
834 {
835         sprintf(g_dasm_str, "and.b   %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7);
836 }
837
838 static void d68000_and_er_16(void)
839 {
840         sprintf(g_dasm_str, "and.w   %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7);
841 }
842
843 static void d68000_and_er_32(void)
844 {
845         sprintf(g_dasm_str, "and.l   %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7);
846 }
847
848 static void d68000_and_re_8(void)
849 {
850         sprintf(g_dasm_str, "and.b   D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir));
851 }
852
853 static void d68000_and_re_16(void)
854 {
855         sprintf(g_dasm_str, "and.w   D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir));
856 }
857
858 static void d68000_and_re_32(void)
859 {
860         sprintf(g_dasm_str, "and.l   D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir));
861 }
862
863 static void d68000_andi_8(void)
864 {
865         char* str = get_imm_str_u8();
866         sprintf(g_dasm_str, "andi.b  %s, %s", str, get_ea_mode_str_8(g_cpu_ir));
867 }
868
869 static void d68000_andi_16(void)
870 {
871         char* str = get_imm_str_u16();
872         sprintf(g_dasm_str, "andi.w  %s, %s", str, get_ea_mode_str_16(g_cpu_ir));
873 }
874
875 static void d68000_andi_32(void)
876 {
877         char* str = get_imm_str_u32();
878         sprintf(g_dasm_str, "andi.l  %s, %s", str, get_ea_mode_str_32(g_cpu_ir));
879 }
880
881 static void d68000_andi_to_ccr(void)
882 {
883         sprintf(g_dasm_str, "andi    %s, CCR", get_imm_str_u8());
884 }
885
886 static void d68000_andi_to_sr(void)
887 {
888         sprintf(g_dasm_str, "andi    %s, SR", get_imm_str_u16());
889 }
890
891 static void d68000_asr_s_8(void)
892 {
893         sprintf(g_dasm_str, "asr.b   #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7);
894 }
895
896 static void d68000_asr_s_16(void)
897 {
898         sprintf(g_dasm_str, "asr.w   #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7);
899 }
900
901 static void d68000_asr_s_32(void)
902 {
903         sprintf(g_dasm_str, "asr.l   #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7);
904 }
905
906 static void d68000_asr_r_8(void)
907 {
908         sprintf(g_dasm_str, "asr.b   D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
909 }
910
911 static void d68000_asr_r_16(void)
912 {
913         sprintf(g_dasm_str, "asr.w   D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
914 }
915
916 static void d68000_asr_r_32(void)
917 {
918         sprintf(g_dasm_str, "asr.l   D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
919 }
920
921 static void d68000_asr_ea(void)
922 {
923         sprintf(g_dasm_str, "asr.w   %s", get_ea_mode_str_16(g_cpu_ir));
924 }
925
926 static void d68000_asl_s_8(void)
927 {
928         sprintf(g_dasm_str, "asl.b   #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7);
929 }
930
931 static void d68000_asl_s_16(void)
932 {
933         sprintf(g_dasm_str, "asl.w   #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7);
934 }
935
936 static void d68000_asl_s_32(void)
937 {
938         sprintf(g_dasm_str, "asl.l   #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7);
939 }
940
941 static void d68000_asl_r_8(void)
942 {
943         sprintf(g_dasm_str, "asl.b   D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
944 }
945
946 static void d68000_asl_r_16(void)
947 {
948         sprintf(g_dasm_str, "asl.w   D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
949 }
950
951 static void d68000_asl_r_32(void)
952 {
953         sprintf(g_dasm_str, "asl.l   D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
954 }
955
956 static void d68000_asl_ea(void)
957 {
958         sprintf(g_dasm_str, "asl.w   %s", get_ea_mode_str_16(g_cpu_ir));
959 }
960
961 static void d68000_bcc_8(void)
962 {
963         uint temp_pc = g_cpu_pc;
964         sprintf(g_dasm_str, "b%-2s     $%x", g_cc[(g_cpu_ir>>8)&0xf], temp_pc + make_int_8(g_cpu_ir));
965 }
966
967 static void d68000_bcc_16(void)
968 {
969         uint temp_pc = g_cpu_pc;
970         sprintf(g_dasm_str, "b%-2s     $%x", g_cc[(g_cpu_ir>>8)&0xf], temp_pc + make_int_16(read_imm_16()));
971 }
972
973 static void d68020_bcc_32(void)
974 {
975         uint temp_pc = g_cpu_pc;
976         LIMIT_CPU_TYPES(M68020_PLUS);
977         sprintf(g_dasm_str, "b%-2s     $%x; (2+)", g_cc[(g_cpu_ir>>8)&0xf], temp_pc + read_imm_32());
978 }
979
980 static void d68000_bchg_r(void)
981 {
982         sprintf(g_dasm_str, "bchg    D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir));
983 }
984
985 static void d68000_bchg_s(void)
986 {
987         char* str = get_imm_str_u8();
988         sprintf(g_dasm_str, "bchg    %s, %s", str, get_ea_mode_str_8(g_cpu_ir));
989 }
990
991 static void d68000_bclr_r(void)
992 {
993         sprintf(g_dasm_str, "bclr    D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir));
994 }
995
996 static void d68000_bclr_s(void)
997 {
998         char* str = get_imm_str_u8();
999         sprintf(g_dasm_str, "bclr    %s, %s", str, get_ea_mode_str_8(g_cpu_ir));
1000 }
1001
1002 static void d68010_bkpt(void)
1003 {
1004         LIMIT_CPU_TYPES(M68010_PLUS);
1005         sprintf(g_dasm_str, "bkpt #%d; (1+)", g_cpu_ir&7);
1006 }
1007
1008 static void d68020_bfchg(void)
1009 {
1010         uint extension;
1011         char offset[3];
1012         char width[3];
1013
1014         LIMIT_CPU_TYPES(M68020_PLUS);
1015
1016         extension = read_imm_16();
1017
1018         if(BIT_B(extension))
1019                 sprintf(offset, "D%d", (extension>>6)&7);
1020         else
1021                 sprintf(offset, "%d", (extension>>6)&31);
1022         if(BIT_5(extension))
1023                 sprintf(width, "D%d", extension&7);
1024         else
1025                 sprintf(width, "%d", g_5bit_data_table[extension&31]);
1026         sprintf(g_dasm_str, "bfchg   %s {%s:%s}; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width);
1027 }
1028
1029 static void d68020_bfclr(void)
1030 {
1031         uint extension;
1032         char offset[3];
1033         char width[3];
1034
1035         LIMIT_CPU_TYPES(M68020_PLUS);
1036
1037         extension = read_imm_16();
1038
1039         if(BIT_B(extension))
1040                 sprintf(offset, "D%d", (extension>>6)&7);
1041         else
1042                 sprintf(offset, "%d", (extension>>6)&31);
1043         if(BIT_5(extension))
1044                 sprintf(width, "D%d", extension&7);
1045         else
1046                 sprintf(width, "%d", g_5bit_data_table[extension&31]);
1047         sprintf(g_dasm_str, "bfclr   %s {%s:%s}; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width);
1048 }
1049
1050 static void d68020_bfexts(void)
1051 {
1052         uint extension;
1053         char offset[3];
1054         char width[3];
1055
1056         LIMIT_CPU_TYPES(M68020_PLUS);
1057
1058         extension = read_imm_16();
1059
1060         if(BIT_B(extension))
1061                 sprintf(offset, "D%d", (extension>>6)&7);
1062         else
1063                 sprintf(offset, "%d", (extension>>6)&31);
1064         if(BIT_5(extension))
1065                 sprintf(width, "D%d", extension&7);
1066         else
1067                 sprintf(width, "%d", g_5bit_data_table[extension&31]);
1068         sprintf(g_dasm_str, "bfexts  %s {%s:%s}, D%d; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width, (extension>>12)&7);
1069 }
1070
1071 static void d68020_bfextu(void)
1072 {
1073         uint extension;
1074         char offset[3];
1075         char width[3];
1076
1077         LIMIT_CPU_TYPES(M68020_PLUS);
1078
1079         extension = read_imm_16();
1080
1081         if(BIT_B(extension))
1082                 sprintf(offset, "D%d", (extension>>6)&7);
1083         else
1084                 sprintf(offset, "%d", (extension>>6)&31);
1085         if(BIT_5(extension))
1086                 sprintf(width, "D%d", extension&7);
1087         else
1088                 sprintf(width, "%d", g_5bit_data_table[extension&31]);
1089         sprintf(g_dasm_str, "bfextu  %s {%s:%s}, D%d; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width, (extension>>12)&7);
1090 }
1091
1092 static void d68020_bfffo(void)
1093 {
1094         uint extension;
1095         char offset[3];
1096         char width[3];
1097
1098         LIMIT_CPU_TYPES(M68020_PLUS);
1099
1100         extension = read_imm_16();
1101
1102         if(BIT_B(extension))
1103                 sprintf(offset, "D%d", (extension>>6)&7);
1104         else
1105                 sprintf(offset, "%d", (extension>>6)&31);
1106         if(BIT_5(extension))
1107                 sprintf(width, "D%d", extension&7);
1108         else
1109                 sprintf(width, "%d", g_5bit_data_table[extension&31]);
1110         sprintf(g_dasm_str, "bfffo   %s {%s:%s}, D%d; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width, (extension>>12)&7);
1111 }
1112
1113 static void d68020_bfins(void)
1114 {
1115         uint extension;
1116         char offset[3];
1117         char width[3];
1118
1119         LIMIT_CPU_TYPES(M68020_PLUS);
1120
1121         extension = read_imm_16();
1122
1123         if(BIT_B(extension))
1124                 sprintf(offset, "D%d", (extension>>6)&7);
1125         else
1126                 sprintf(offset, "%d", (extension>>6)&31);
1127         if(BIT_5(extension))
1128                 sprintf(width, "D%d", extension&7);
1129         else
1130                 sprintf(width, "%d", g_5bit_data_table[extension&31]);
1131         sprintf(g_dasm_str, "bfins   D%d, %s {%s:%s}; (2+)", (extension>>12)&7, get_ea_mode_str_8(g_cpu_ir), offset, width);
1132 }
1133
1134 static void d68020_bfset(void)
1135 {
1136         uint extension;
1137         char offset[3];
1138         char width[3];
1139
1140         LIMIT_CPU_TYPES(M68020_PLUS);
1141
1142         extension = read_imm_16();
1143
1144         if(BIT_B(extension))
1145                 sprintf(offset, "D%d", (extension>>6)&7);
1146         else
1147                 sprintf(offset, "%d", (extension>>6)&31);
1148         if(BIT_5(extension))
1149                 sprintf(width, "D%d", extension&7);
1150         else
1151                 sprintf(width, "%d", g_5bit_data_table[extension&31]);
1152         sprintf(g_dasm_str, "bfset   %s {%s:%s}; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width);
1153 }
1154
1155 static void d68020_bftst(void)
1156 {
1157         uint extension;
1158         char offset[3];
1159         char width[3];
1160
1161         LIMIT_CPU_TYPES(M68020_PLUS);
1162
1163         extension = read_imm_16();
1164
1165         if(BIT_B(extension))
1166                 sprintf(offset, "D%d", (extension>>6)&7);
1167         else
1168                 sprintf(offset, "%d", (extension>>6)&31);
1169         if(BIT_5(extension))
1170                 sprintf(width, "D%d", extension&7);
1171         else
1172                 sprintf(width, "%d", g_5bit_data_table[extension&31]);
1173         sprintf(g_dasm_str, "bftst   %s {%s:%s}; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width);
1174 }
1175
1176 static void d68000_bra_8(void)
1177 {
1178         uint temp_pc = g_cpu_pc;
1179         sprintf(g_dasm_str, "bra     $%x", temp_pc + make_int_8(g_cpu_ir));
1180 }
1181
1182 static void d68000_bra_16(void)
1183 {
1184         uint temp_pc = g_cpu_pc;
1185         sprintf(g_dasm_str, "bra     $%x", temp_pc + make_int_16(read_imm_16()));
1186 }
1187
1188 static void d68020_bra_32(void)
1189 {
1190         uint temp_pc = g_cpu_pc;
1191         LIMIT_CPU_TYPES(M68020_PLUS);
1192         sprintf(g_dasm_str, "bra     $%x; (2+)", temp_pc + read_imm_32());
1193 }
1194
1195 static void d68000_bset_r(void)
1196 {
1197         sprintf(g_dasm_str, "bset    D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir));
1198 }
1199
1200 static void d68000_bset_s(void)
1201 {
1202         char* str = get_imm_str_u8();
1203         sprintf(g_dasm_str, "bset    %s, %s", str, get_ea_mode_str_8(g_cpu_ir));
1204 }
1205
1206 static void d68000_bsr_8(void)
1207 {
1208         uint temp_pc = g_cpu_pc;
1209         sprintf(g_dasm_str, "bsr     $%x", temp_pc + make_int_8(g_cpu_ir));
1210         SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER);
1211 }
1212
1213 static void d68000_bsr_16(void)
1214 {
1215         uint temp_pc = g_cpu_pc;
1216         sprintf(g_dasm_str, "bsr     $%x", temp_pc + make_int_16(read_imm_16()));
1217         SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER);
1218 }
1219
1220 static void d68020_bsr_32(void)
1221 {
1222         uint temp_pc = g_cpu_pc;
1223         LIMIT_CPU_TYPES(M68020_PLUS);
1224         sprintf(g_dasm_str, "bsr     $%x; (2+)", temp_pc + read_imm_32());
1225         SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER);
1226 }
1227
1228 static void d68000_btst_r(void)
1229 {
1230         sprintf(g_dasm_str, "btst    D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir));
1231 }
1232
1233 static void d68000_btst_s(void)
1234 {
1235         char* str = get_imm_str_u8();
1236         sprintf(g_dasm_str, "btst    %s, %s", str, get_ea_mode_str_8(g_cpu_ir));
1237 }
1238
1239 static void d68020_callm(void)
1240 {
1241         char* str;
1242         LIMIT_CPU_TYPES(M68020_ONLY);
1243         str = get_imm_str_u8();
1244
1245         sprintf(g_dasm_str, "callm   %s, %s; (2)", str, get_ea_mode_str_8(g_cpu_ir));
1246 }
1247
1248 static void d68020_cas_8(void)
1249 {
1250         uint extension;
1251         LIMIT_CPU_TYPES(M68020_PLUS);
1252         extension = read_imm_16();
1253         sprintf(g_dasm_str, "cas.b   D%d, D%d, %s; (2+)", extension&7, (extension>>6)&7, get_ea_mode_str_8(g_cpu_ir));
1254 }
1255
1256 static void d68020_cas_16(void)
1257 {
1258         uint extension;
1259         LIMIT_CPU_TYPES(M68020_PLUS);
1260         extension = read_imm_16();
1261         sprintf(g_dasm_str, "cas.w   D%d, D%d, %s; (2+)", extension&7, (extension>>6)&7, get_ea_mode_str_16(g_cpu_ir));
1262 }
1263
1264 static void d68020_cas_32(void)
1265 {
1266         uint extension;
1267         LIMIT_CPU_TYPES(M68020_PLUS);
1268         extension = read_imm_16();
1269         sprintf(g_dasm_str, "cas.l   D%d, D%d, %s; (2+)", extension&7, (extension>>6)&7, get_ea_mode_str_32(g_cpu_ir));
1270 }
1271
1272 static void d68020_cas2_16(void)
1273 {
1274 /* CAS2 Dc1:Dc2,Du1:Dc2:(Rn1):(Rn2)
1275 f e d c b a 9 8 7 6 5 4 3 2 1 0
1276  DARn1  0 0 0  Du1  0 0 0  Dc1
1277  DARn2  0 0 0  Du2  0 0 0  Dc2
1278 */
1279
1280         uint extension;
1281         LIMIT_CPU_TYPES(M68020_PLUS);
1282         extension = read_imm_32();
1283         sprintf(g_dasm_str, "cas2.w  D%d:D%d, D%d:D%d, (%c%d):(%c%d); (2+)",
1284                 (extension>>16)&7, extension&7, (extension>>22)&7, (extension>>6)&7,
1285                 BIT_1F(extension) ? 'A' : 'D', (extension>>28)&7,
1286                 BIT_F(extension) ? 'A' : 'D', (extension>>12)&7);
1287 }
1288
1289 static void d68020_cas2_32(void)
1290 {
1291         uint extension;
1292         LIMIT_CPU_TYPES(M68020_PLUS);
1293         extension = read_imm_32();
1294         sprintf(g_dasm_str, "cas2.l  D%d:D%d, D%d:D%d, (%c%d):(%c%d); (2+)",
1295                 (extension>>16)&7, extension&7, (extension>>22)&7, (extension>>6)&7,
1296                 BIT_1F(extension) ? 'A' : 'D', (extension>>28)&7,
1297                 BIT_F(extension) ? 'A' : 'D', (extension>>12)&7);
1298 }
1299
1300 static void d68000_chk_16(void)
1301 {
1302         sprintf(g_dasm_str, "chk.w   %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7);
1303         SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER);
1304 }
1305
1306 static void d68020_chk_32(void)
1307 {
1308         LIMIT_CPU_TYPES(M68020_PLUS);
1309         sprintf(g_dasm_str, "chk.l   %s, D%d; (2+)", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7);
1310         SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER);
1311 }
1312
1313 static void d68020_chk2_cmp2_8(void)
1314 {
1315         uint extension;
1316         LIMIT_CPU_TYPES(M68020_PLUS);
1317         extension = read_imm_16();
1318         sprintf(g_dasm_str, "%s.b  %s, %c%d; (2+)", BIT_B(extension) ? "chk2" : "cmp2", get_ea_mode_str_8(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7);
1319 }
1320
1321 static void d68020_chk2_cmp2_16(void)
1322 {
1323         uint extension;
1324         LIMIT_CPU_TYPES(M68020_PLUS);
1325         extension = read_imm_16();
1326         sprintf(g_dasm_str, "%s.w  %s, %c%d; (2+)", BIT_B(extension) ? "chk2" : "cmp2", get_ea_mode_str_16(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7);
1327 }
1328
1329 static void d68020_chk2_cmp2_32(void)
1330 {
1331         uint extension;
1332         LIMIT_CPU_TYPES(M68020_PLUS);
1333         extension = read_imm_16();
1334         sprintf(g_dasm_str, "%s.l  %s, %c%d; (2+)", BIT_B(extension) ? "chk2" : "cmp2", get_ea_mode_str_32(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7);
1335 }
1336
1337 static void d68040_cinv(void)
1338 {
1339         LIMIT_CPU_TYPES(M68040_PLUS);
1340         switch((g_cpu_ir>>3)&3)
1341         {
1342                 case 0:
1343                         sprintf(g_dasm_str, "cinv (illegal scope); (4)");
1344                         break;
1345                 case 1:
1346                         sprintf(g_dasm_str, "cinvl   %d, (A%d); (4)", (g_cpu_ir>>6)&3, g_cpu_ir&7);
1347                         break;
1348                 case 2:
1349                         sprintf(g_dasm_str, "cinvp   %d, (A%d); (4)", (g_cpu_ir>>6)&3, g_cpu_ir&7);
1350                         break;
1351                 case 3:
1352                         sprintf(g_dasm_str, "cinva   %d; (4)", (g_cpu_ir>>6)&3);
1353                         break;
1354         }
1355 }
1356
1357 static void d68000_clr_8(void)
1358 {
1359         sprintf(g_dasm_str, "clr.b   %s", get_ea_mode_str_8(g_cpu_ir));
1360 }
1361
1362 static void d68000_clr_16(void)
1363 {
1364         sprintf(g_dasm_str, "clr.w   %s", get_ea_mode_str_16(g_cpu_ir));
1365 }
1366
1367 static void d68000_clr_32(void)
1368 {
1369         sprintf(g_dasm_str, "clr.l   %s", get_ea_mode_str_32(g_cpu_ir));
1370 }
1371
1372 static void d68000_cmp_8(void)
1373 {
1374         sprintf(g_dasm_str, "cmp.b   %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7);
1375 }
1376
1377 static void d68000_cmp_16(void)
1378 {
1379         sprintf(g_dasm_str, "cmp.w   %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7);
1380 }
1381
1382 static void d68000_cmp_32(void)
1383 {
1384         sprintf(g_dasm_str, "cmp.l   %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7);
1385 }
1386
1387 static void d68000_cmpa_16(void)
1388 {
1389         sprintf(g_dasm_str, "cmpa.w  %s, A%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7);
1390 }
1391
1392 static void d68000_cmpa_32(void)
1393 {
1394         sprintf(g_dasm_str, "cmpa.l  %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7);
1395 }
1396
1397 static void d68000_cmpi_8(void)
1398 {
1399         char* str = get_imm_str_s8();
1400         sprintf(g_dasm_str, "cmpi.b  %s, %s", str, get_ea_mode_str_8(g_cpu_ir));
1401 }
1402
1403 static void d68020_cmpi_pcdi_8(void)
1404 {
1405         char* str;
1406         LIMIT_CPU_TYPES(M68010_PLUS);
1407         str = get_imm_str_s8();
1408         sprintf(g_dasm_str, "cmpi.b  %s, %s; (2+)", str, get_ea_mode_str_8(g_cpu_ir));
1409 }
1410
1411 static void d68020_cmpi_pcix_8(void)
1412 {
1413         char* str;
1414         LIMIT_CPU_TYPES(M68010_PLUS);
1415         str = get_imm_str_s8();
1416         sprintf(g_dasm_str, "cmpi.b  %s, %s; (2+)", str, get_ea_mode_str_8(g_cpu_ir));
1417 }
1418
1419 static void d68000_cmpi_16(void)
1420 {
1421         char* str;
1422         str = get_imm_str_s16();
1423         sprintf(g_dasm_str, "cmpi.w  %s, %s", str, get_ea_mode_str_16(g_cpu_ir));
1424 }
1425
1426 static void d68020_cmpi_pcdi_16(void)
1427 {
1428         char* str;
1429         LIMIT_CPU_TYPES(M68010_PLUS);
1430         str = get_imm_str_s16();
1431         sprintf(g_dasm_str, "cmpi.w  %s, %s; (2+)", str, get_ea_mode_str_16(g_cpu_ir));
1432 }
1433
1434 static void d68020_cmpi_pcix_16(void)
1435 {
1436         char* str;
1437         LIMIT_CPU_TYPES(M68010_PLUS);
1438         str = get_imm_str_s16();
1439         sprintf(g_dasm_str, "cmpi.w  %s, %s; (2+)", str, get_ea_mode_str_16(g_cpu_ir));
1440 }
1441
1442 static void d68000_cmpi_32(void)
1443 {
1444         char* str;
1445         str = get_imm_str_s32();
1446         sprintf(g_dasm_str, "cmpi.l  %s, %s", str, get_ea_mode_str_32(g_cpu_ir));
1447 }
1448
1449 static void d68020_cmpi_pcdi_32(void)
1450 {
1451         char* str;
1452         LIMIT_CPU_TYPES(M68010_PLUS);
1453         str = get_imm_str_s32();
1454         sprintf(g_dasm_str, "cmpi.l  %s, %s; (2+)", str, get_ea_mode_str_32(g_cpu_ir));
1455 }
1456
1457 static void d68020_cmpi_pcix_32(void)
1458 {
1459         char* str;
1460         LIMIT_CPU_TYPES(M68010_PLUS);
1461         str = get_imm_str_s32();
1462         sprintf(g_dasm_str, "cmpi.l  %s, %s; (2+)", str, get_ea_mode_str_32(g_cpu_ir));
1463 }
1464
1465 static void d68000_cmpm_8(void)
1466 {
1467         sprintf(g_dasm_str, "cmpm.b  (A%d)+, (A%d)+", g_cpu_ir&7, (g_cpu_ir>>9)&7);
1468 }
1469
1470 static void d68000_cmpm_16(void)
1471 {
1472         sprintf(g_dasm_str, "cmpm.w  (A%d)+, (A%d)+", g_cpu_ir&7, (g_cpu_ir>>9)&7);
1473 }
1474
1475 static void d68000_cmpm_32(void)
1476 {
1477         sprintf(g_dasm_str, "cmpm.l  (A%d)+, (A%d)+", g_cpu_ir&7, (g_cpu_ir>>9)&7);
1478 }
1479
1480 static void d68020_cpbcc_16(void)
1481 {
1482         uint extension;
1483         uint new_pc = g_cpu_pc;
1484         LIMIT_CPU_TYPES(M68020_PLUS);
1485         extension = read_imm_16();
1486         new_pc += make_int_16(read_imm_16());
1487         sprintf(g_dasm_str, "%db%-4s  %s; %x (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[g_cpu_ir&0x3f], get_imm_str_s16(), new_pc, extension);
1488 }
1489
1490 static void d68020_cpbcc_32(void)
1491 {
1492         uint extension;
1493         uint new_pc = g_cpu_pc;
1494         LIMIT_CPU_TYPES(M68020_PLUS);
1495         extension = read_imm_16();
1496         new_pc += read_imm_32();
1497         sprintf(g_dasm_str, "%db%-4s  %s; %x (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[g_cpu_ir&0x3f], get_imm_str_s16(), new_pc, extension);
1498 }
1499
1500 static void d68020_cpdbcc(void)
1501 {
1502         uint extension1;
1503         uint extension2;
1504         uint new_pc = g_cpu_pc;
1505         LIMIT_CPU_TYPES(M68020_PLUS);
1506         extension1 = read_imm_16();
1507         extension2 = read_imm_16();
1508         new_pc += make_int_16(read_imm_16());
1509         sprintf(g_dasm_str, "%ddb%-4s D%d,%s; %x (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], g_cpu_ir&7, get_imm_str_s16(), new_pc, extension2);
1510 }
1511
1512 static void d68020_cpgen(void)
1513 {
1514         LIMIT_CPU_TYPES(M68020_PLUS);
1515         sprintf(g_dasm_str, "%dgen    %s; (2-3)", (g_cpu_ir>>9)&7, get_imm_str_u32());
1516 }
1517
1518 static void d68020_cprestore(void)
1519 {
1520         LIMIT_CPU_TYPES(M68020_PLUS);
1521         if (((g_cpu_ir>>9)&7) == 1)
1522         {
1523                 sprintf(g_dasm_str, "frestore %s", get_ea_mode_str_8(g_cpu_ir));
1524         }
1525         else
1526         {
1527                 sprintf(g_dasm_str, "%drestore %s; (2-3)", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir));
1528         }
1529 }
1530
1531 static void d68020_cpsave(void)
1532 {
1533         LIMIT_CPU_TYPES(M68020_PLUS);
1534         if (((g_cpu_ir>>9)&7) == 1)
1535         {
1536                 sprintf(g_dasm_str, "fsave   %s", get_ea_mode_str_8(g_cpu_ir));
1537         }
1538         else
1539         {
1540                 sprintf(g_dasm_str, "%dsave   %s; (2-3)", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir));
1541         }
1542 }
1543
1544 static void d68020_cpscc(void)
1545 {
1546         uint extension1;
1547         uint extension2;
1548         LIMIT_CPU_TYPES(M68020_PLUS);
1549         extension1 = read_imm_16();
1550         extension2 = read_imm_16();
1551         sprintf(g_dasm_str, "%ds%-4s  %s; (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], get_ea_mode_str_8(g_cpu_ir), extension2);
1552 }
1553
1554 static void d68020_cptrapcc_0(void)
1555 {
1556         uint extension1;
1557         uint extension2;
1558         LIMIT_CPU_TYPES(M68020_PLUS);
1559         extension1 = read_imm_16();
1560         extension2 = read_imm_16();
1561         sprintf(g_dasm_str, "%dtrap%-4s; (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], extension2);
1562 }
1563
1564 static void d68020_cptrapcc_16(void)
1565 {
1566         uint extension1;
1567         uint extension2;
1568         LIMIT_CPU_TYPES(M68020_PLUS);
1569         extension1 = read_imm_16();
1570         extension2 = read_imm_16();
1571         sprintf(g_dasm_str, "%dtrap%-4s %s; (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], get_imm_str_u16(), extension2);
1572 }
1573
1574 static void d68020_cptrapcc_32(void)
1575 {
1576         uint extension1;
1577         uint extension2;
1578         LIMIT_CPU_TYPES(M68020_PLUS);
1579         extension1 = read_imm_16();
1580         extension2 = read_imm_16();
1581         sprintf(g_dasm_str, "%dtrap%-4s %s; (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], get_imm_str_u32(), extension2);
1582 }
1583
1584 static void d68040_cpush(void)
1585 {
1586         LIMIT_CPU_TYPES(M68040_PLUS);
1587         switch((g_cpu_ir>>3)&3)
1588         {
1589                 case 0:
1590                         sprintf(g_dasm_str, "cpush (illegal scope); (4)");
1591                         break;
1592                 case 1:
1593                         sprintf(g_dasm_str, "cpushl  %d, (A%d); (4)", (g_cpu_ir>>6)&3, g_cpu_ir&7);
1594                         break;
1595                 case 2:
1596                         sprintf(g_dasm_str, "cpushp  %d, (A%d); (4)", (g_cpu_ir>>6)&3, g_cpu_ir&7);
1597                         break;
1598                 case 3:
1599                         sprintf(g_dasm_str, "cpusha  %d; (4)", (g_cpu_ir>>6)&3);
1600                         break;
1601         }
1602 }
1603
1604 static void d68000_dbra(void)
1605 {
1606         uint temp_pc = g_cpu_pc;
1607         sprintf(g_dasm_str, "dbra    D%d, $%x", g_cpu_ir & 7, temp_pc + make_int_16(read_imm_16()));
1608         SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER);
1609 }
1610
1611 static void d68000_dbcc(void)
1612 {
1613         uint temp_pc = g_cpu_pc;
1614         sprintf(g_dasm_str, "db%-2s    D%d, $%x", g_cc[(g_cpu_ir>>8)&0xf], g_cpu_ir & 7, temp_pc + make_int_16(read_imm_16()));
1615         SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER);
1616 }
1617
1618 static void d68000_divs(void)
1619 {
1620         sprintf(g_dasm_str, "divs.w  %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7);
1621 }
1622
1623 static void d68000_divu(void)
1624 {
1625         sprintf(g_dasm_str, "divu.w  %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7);
1626 }
1627
1628 static void d68020_divl(void)
1629 {
1630         uint extension;
1631         LIMIT_CPU_TYPES(M68020_PLUS);
1632         extension = read_imm_16();
1633
1634         if(BIT_A(extension))
1635                 sprintf(g_dasm_str, "div%c.l  %s, D%d:D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), extension&7, (extension>>12)&7);
1636         else if((extension&7) == ((extension>>12)&7))
1637                 sprintf(g_dasm_str, "div%c.l  %s, D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), (extension>>12)&7);
1638         else
1639                 sprintf(g_dasm_str, "div%cl.l %s, D%d:D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), extension&7, (extension>>12)&7);
1640 }
1641
1642 static void d68000_eor_8(void)
1643 {
1644         sprintf(g_dasm_str, "eor.b   D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir));
1645 }
1646
1647 static void d68000_eor_16(void)
1648 {
1649         sprintf(g_dasm_str, "eor.w   D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir));
1650 }
1651
1652 static void d68000_eor_32(void)
1653 {
1654         sprintf(g_dasm_str, "eor.l   D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir));
1655 }
1656
1657 static void d68000_eori_8(void)
1658 {
1659         char* str = get_imm_str_u8();
1660         sprintf(g_dasm_str, "eori.b  %s, %s", str, get_ea_mode_str_8(g_cpu_ir));
1661 }
1662
1663 static void d68000_eori_16(void)
1664 {
1665         char* str = get_imm_str_u16();
1666         sprintf(g_dasm_str, "eori.w  %s, %s", str, get_ea_mode_str_16(g_cpu_ir));
1667 }
1668
1669 static void d68000_eori_32(void)
1670 {
1671         char* str = get_imm_str_u32();
1672         sprintf(g_dasm_str, "eori.l  %s, %s", str, get_ea_mode_str_32(g_cpu_ir));
1673 }
1674
1675 static void d68000_eori_to_ccr(void)
1676 {
1677         sprintf(g_dasm_str, "eori    %s, CCR", get_imm_str_u8());
1678 }
1679
1680 static void d68000_eori_to_sr(void)
1681 {
1682         sprintf(g_dasm_str, "eori    %s, SR", get_imm_str_u16());
1683 }
1684
1685 static void d68000_exg_dd(void)
1686 {
1687         sprintf(g_dasm_str, "exg     D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
1688 }
1689
1690 static void d68000_exg_aa(void)
1691 {
1692         sprintf(g_dasm_str, "exg     A%d, A%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
1693 }
1694
1695 static void d68000_exg_da(void)
1696 {
1697         sprintf(g_dasm_str, "exg     D%d, A%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
1698 }
1699
1700 static void d68000_ext_16(void)
1701 {
1702         sprintf(g_dasm_str, "ext.w   D%d", g_cpu_ir&7);
1703 }
1704
1705 static void d68000_ext_32(void)
1706 {
1707         sprintf(g_dasm_str, "ext.l   D%d", g_cpu_ir&7);
1708 }
1709
1710 static void d68020_extb_32(void)
1711 {
1712         LIMIT_CPU_TYPES(M68020_PLUS);
1713         sprintf(g_dasm_str, "extb.l  D%d; (2+)", g_cpu_ir&7);
1714 }
1715
1716 static void d68040_fpu(void)
1717 {
1718         char float_data_format[8][3] =
1719         {
1720                 ".l", ".s", ".x", ".p", ".w", ".d", ".b", ".p"
1721         };
1722
1723         char mnemonic[40];
1724         uint32 w2, src, dst_reg;
1725         LIMIT_CPU_TYPES(M68030_PLUS);
1726         w2 = read_imm_16();
1727
1728         src = (w2 >> 10) & 0x7;
1729         dst_reg = (w2 >> 7) & 0x7;
1730
1731         // special override for FMOVECR
1732         if ((((w2 >> 13) & 0x7) == 2) && (((w2>>10)&0x7) == 7))
1733         {
1734                 sprintf(g_dasm_str, "fmovecr   #$%0x, fp%d", (w2&0x7f), dst_reg);
1735                 return;
1736         }
1737
1738         switch ((w2 >> 13) & 0x7)
1739         {
1740                 case 0x0:
1741                 case 0x2:
1742                 {
1743                         switch(w2 & 0x7f)
1744                         {
1745                                 case 0x00:      sprintf(mnemonic, "fmove"); break;
1746                                 case 0x01:      sprintf(mnemonic, "fint"); break;
1747                                 case 0x02:      sprintf(mnemonic, "fsinh"); break;
1748                                 case 0x03:      sprintf(mnemonic, "fintrz"); break;
1749                                 case 0x04:      sprintf(mnemonic, "fsqrt"); break;
1750                                 case 0x06:      sprintf(mnemonic, "flognp1"); break;
1751                                 case 0x08:      sprintf(mnemonic, "fetoxm1"); break;
1752                                 case 0x09:      sprintf(mnemonic, "ftanh1"); break;
1753                                 case 0x0a:      sprintf(mnemonic, "fatan"); break;
1754                                 case 0x0c:      sprintf(mnemonic, "fasin"); break;
1755                                 case 0x0d:      sprintf(mnemonic, "fatanh"); break;
1756                                 case 0x0e:      sprintf(mnemonic, "fsin"); break;
1757                                 case 0x0f:      sprintf(mnemonic, "ftan"); break;
1758                                 case 0x10:      sprintf(mnemonic, "fetox"); break;
1759                                 case 0x11:      sprintf(mnemonic, "ftwotox"); break;
1760                                 case 0x12:      sprintf(mnemonic, "ftentox"); break;
1761                                 case 0x14:      sprintf(mnemonic, "flogn"); break;
1762                                 case 0x15:      sprintf(mnemonic, "flog10"); break;
1763                                 case 0x16:      sprintf(mnemonic, "flog2"); break;
1764                                 case 0x18:      sprintf(mnemonic, "fabs"); break;
1765                                 case 0x19:      sprintf(mnemonic, "fcosh"); break;
1766                                 case 0x1a:      sprintf(mnemonic, "fneg"); break;
1767                                 case 0x1c:      sprintf(mnemonic, "facos"); break;
1768                                 case 0x1d:      sprintf(mnemonic, "fcos"); break;
1769                                 case 0x1e:      sprintf(mnemonic, "fgetexp"); break;
1770                                 case 0x1f:      sprintf(mnemonic, "fgetman"); break;
1771                                 case 0x20:      sprintf(mnemonic, "fdiv"); break;
1772                                 case 0x21:      sprintf(mnemonic, "fmod"); break;
1773                                 case 0x22:      sprintf(mnemonic, "fadd"); break;
1774                                 case 0x23:      sprintf(mnemonic, "fmul"); break;
1775                                 case 0x24:      sprintf(mnemonic, "fsgldiv"); break;
1776                                 case 0x25:      sprintf(mnemonic, "frem"); break;
1777                                 case 0x26:      sprintf(mnemonic, "fscale"); break;
1778                                 case 0x27:      sprintf(mnemonic, "fsglmul"); break;
1779                                 case 0x28:      sprintf(mnemonic, "fsub"); break;
1780                                 case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
1781                                                         sprintf(mnemonic, "fsincos"); break;
1782                                 case 0x38:      sprintf(mnemonic, "fcmp"); break;
1783                                 case 0x3a:      sprintf(mnemonic, "ftst"); break;
1784                                 case 0x41:      sprintf(mnemonic, "fssqrt"); break;
1785                                 case 0x45:      sprintf(mnemonic, "fdsqrt"); break;
1786                                 case 0x58:      sprintf(mnemonic, "fsabs"); break;
1787                                 case 0x5a:      sprintf(mnemonic, "fsneg"); break;
1788                                 case 0x5c:      sprintf(mnemonic, "fdabs"); break;
1789                                 case 0x5e:      sprintf(mnemonic, "fdneg"); break;
1790                                 case 0x60:      sprintf(mnemonic, "fsdiv"); break;
1791                                 case 0x62:      sprintf(mnemonic, "fsadd"); break;
1792                                 case 0x63:      sprintf(mnemonic, "fsmul"); break;
1793                                 case 0x64:      sprintf(mnemonic, "fddiv"); break;
1794                                 case 0x66:      sprintf(mnemonic, "fdadd"); break;
1795                                 case 0x67:      sprintf(mnemonic, "fdmul"); break;
1796                                 case 0x68:      sprintf(mnemonic, "fssub"); break;
1797                                 case 0x6c:      sprintf(mnemonic, "fdsub"); break;
1798
1799                                 default:        sprintf(mnemonic, "FPU (?)"); break;
1800                         }
1801
1802                         if (w2 & 0x4000)
1803                         {
1804                                 sprintf(g_dasm_str, "%s%s   %s, FP%d", mnemonic, float_data_format[src], get_ea_mode_str_32(g_cpu_ir), dst_reg);
1805                         }
1806                         else
1807                         {
1808                                 sprintf(g_dasm_str, "%s.x   FP%d, FP%d", mnemonic, src, dst_reg);
1809                         }
1810                         break;
1811                 }
1812
1813                 case 0x3:
1814                 {
1815                         switch ((w2>>10)&7)
1816                         {
1817                                 case 3:         // packed decimal w/fixed k-factor
1818                                         sprintf(g_dasm_str, "fmove%s   FP%d, %s {#%d}", float_data_format[(w2>>10)&7], dst_reg, get_ea_mode_str_32(g_cpu_ir), sext_7bit_int(w2&0x7f));
1819                                         break;
1820
1821                                 case 7:         // packed decimal w/dynamic k-factor (register)
1822                                         sprintf(g_dasm_str, "fmove%s   FP%d, %s {D%d}", float_data_format[(w2>>10)&7], dst_reg, get_ea_mode_str_32(g_cpu_ir), (w2>>4)&7);
1823                                         break;
1824
1825                                 default:
1826                                         sprintf(g_dasm_str, "fmove%s   FP%d, %s", float_data_format[(w2>>10)&7], dst_reg, get_ea_mode_str_32(g_cpu_ir));
1827                                         break;
1828                         }
1829                         break;
1830                 }
1831
1832                 case 0x4:       // ea to control
1833                 {
1834                         sprintf(g_dasm_str, "fmovem.l   %s, ", get_ea_mode_str_32(g_cpu_ir));
1835                         if (w2 & 0x1000) strcat(g_dasm_str, "fpcr");
1836                         if (w2 & 0x0800) strcat(g_dasm_str, "/fpsr");
1837                         if (w2 & 0x0400) strcat(g_dasm_str, "/fpiar");
1838                         break;
1839                 }
1840
1841                 case 0x5:       // control to ea
1842                 {
1843                         
1844                         strcpy(g_dasm_str, "fmovem.l   ");
1845                         if (w2 & 0x1000) strcat(g_dasm_str, "fpcr");
1846                         if (w2 & 0x0800) strcat(g_dasm_str, "/fpsr");
1847                         if (w2 & 0x0400) strcat(g_dasm_str, "/fpiar");
1848                         strcat(g_dasm_str, ", ");
1849                         strcat(g_dasm_str, get_ea_mode_str_32(g_cpu_ir));
1850                         break;
1851                 }
1852
1853                 case 0x6:       // memory to FPU, list
1854                 {
1855                         char temp[32];
1856
1857                         if ((w2>>11) & 1)       // dynamic register list
1858                         {
1859                                 sprintf(g_dasm_str, "fmovem.x   %s, D%d", get_ea_mode_str_32(g_cpu_ir), (w2>>4)&7);
1860                         }
1861                         else    // static register list
1862                         {
1863                                 int i;
1864
1865                                 sprintf(g_dasm_str, "fmovem.x   %s, ", get_ea_mode_str_32(g_cpu_ir));
1866
1867                                 for (i = 0; i < 8; i++)
1868                                 {
1869                                         if (w2 & (1<<i))
1870                                         {
1871                                                 if ((w2>>12) & 1)       // postincrement or control
1872                                                 {
1873                                                         sprintf(temp, "FP%d ", 7-i);
1874                                                 }
1875                                                 else                    // predecrement
1876                                                 {
1877                                                         sprintf(temp, "FP%d ", i);
1878                                                 }
1879                                                 strcat(g_dasm_str, temp);
1880                                         }
1881                                 }
1882                         }
1883                         break;
1884                 }
1885
1886                 case 0x7:       // FPU to memory, list
1887                 {
1888                         char temp[32];
1889
1890                         if ((w2>>11) & 1)       // dynamic register list
1891                         {
1892                                 sprintf(g_dasm_str, "fmovem.x   D%d, %s", (w2>>4)&7, get_ea_mode_str_32(g_cpu_ir));
1893                         }
1894                         else    // static register list
1895                         {
1896                                 int i;
1897
1898                                 sprintf(g_dasm_str, "fmovem.x   ");
1899
1900                                 for (i = 0; i < 8; i++)
1901                                 {
1902                                         if (w2 & (1<<i))
1903                                         {
1904                                                 if ((w2>>12) & 1)       // postincrement or control
1905                                                 {
1906                                                         sprintf(temp, "FP%d ", 7-i);
1907                                                 }
1908                                                 else                    // predecrement
1909                                                 {
1910                                                         sprintf(temp, "FP%d ", i);
1911                                                 }
1912                                                 strcat(g_dasm_str, temp);
1913                                         }
1914                                 }
1915
1916                                 strcat(g_dasm_str, ", ");
1917                                 strcat(g_dasm_str, get_ea_mode_str_32(g_cpu_ir));
1918                         }
1919                         break;
1920                 }
1921
1922                 default:
1923                 {
1924                         sprintf(g_dasm_str, "FPU (?) ");
1925                         break;
1926                 }
1927         }
1928 }
1929
1930 static void d68000_jmp(void)
1931 {
1932         sprintf(g_dasm_str, "jmp     %s", get_ea_mode_str_32(g_cpu_ir));
1933 }
1934
1935 static void d68000_jsr(void)
1936 {
1937         sprintf(g_dasm_str, "jsr     %s", get_ea_mode_str_32(g_cpu_ir));
1938         SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER);
1939 }
1940
1941 static void d68000_lea(void)
1942 {
1943         sprintf(g_dasm_str, "lea     %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7);
1944 }
1945
1946 static void d68000_link_16(void)
1947 {
1948         sprintf(g_dasm_str, "link    A%d, %s", g_cpu_ir&7, get_imm_str_s16());
1949 }
1950
1951 static void d68020_link_32(void)
1952 {
1953         LIMIT_CPU_TYPES(M68020_PLUS);
1954         sprintf(g_dasm_str, "link    A%d, %s; (2+)", g_cpu_ir&7, get_imm_str_s32());
1955 }
1956
1957 static void d68000_lsr_s_8(void)
1958 {
1959         sprintf(g_dasm_str, "lsr.b   #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7);
1960 }
1961
1962 static void d68000_lsr_s_16(void)
1963 {
1964         sprintf(g_dasm_str, "lsr.w   #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7);
1965 }
1966
1967 static void d68000_lsr_s_32(void)
1968 {
1969         sprintf(g_dasm_str, "lsr.l   #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7);
1970 }
1971
1972 static void d68000_lsr_r_8(void)
1973 {
1974         sprintf(g_dasm_str, "lsr.b   D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
1975 }
1976
1977 static void d68000_lsr_r_16(void)
1978 {
1979         sprintf(g_dasm_str, "lsr.w   D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
1980 }
1981
1982 static void d68000_lsr_r_32(void)
1983 {
1984         sprintf(g_dasm_str, "lsr.l   D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
1985 }
1986
1987 static void d68000_lsr_ea(void)
1988 {
1989         sprintf(g_dasm_str, "lsr.w   %s", get_ea_mode_str_32(g_cpu_ir));
1990 }
1991
1992 static void d68000_lsl_s_8(void)
1993 {
1994         sprintf(g_dasm_str, "lsl.b   #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7);
1995 }
1996
1997 static void d68000_lsl_s_16(void)
1998 {
1999         sprintf(g_dasm_str, "lsl.w   #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7);
2000 }
2001
2002 static void d68000_lsl_s_32(void)
2003 {
2004         sprintf(g_dasm_str, "lsl.l   #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7);
2005 }
2006
2007 static void d68000_lsl_r_8(void)
2008 {
2009         sprintf(g_dasm_str, "lsl.b   D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
2010 }
2011
2012 static void d68000_lsl_r_16(void)
2013 {
2014         sprintf(g_dasm_str, "lsl.w   D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
2015 }
2016
2017 static void d68000_lsl_r_32(void)
2018 {
2019         sprintf(g_dasm_str, "lsl.l   D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
2020 }
2021
2022 static void d68000_lsl_ea(void)
2023 {
2024         sprintf(g_dasm_str, "lsl.w   %s", get_ea_mode_str_32(g_cpu_ir));
2025 }
2026
2027 static void d68000_move_8(void)
2028 {
2029         char* str = get_ea_mode_str_8(g_cpu_ir);
2030         sprintf(g_dasm_str, "move.b  %s, %s", str, get_ea_mode_str_8(((g_cpu_ir>>9) & 7) | ((g_cpu_ir>>3) & 0x38)));
2031 }
2032
2033 static void d68000_move_16(void)
2034 {
2035         char* str = get_ea_mode_str_16(g_cpu_ir);
2036         sprintf(g_dasm_str, "move.w  %s, %s", str, get_ea_mode_str_16(((g_cpu_ir>>9) & 7) | ((g_cpu_ir>>3) & 0x38)));
2037 }
2038
2039 static void d68000_move_32(void)
2040 {
2041         char* str = get_ea_mode_str_32(g_cpu_ir);
2042         sprintf(g_dasm_str, "move.l  %s, %s", str, get_ea_mode_str_32(((g_cpu_ir>>9) & 7) | ((g_cpu_ir>>3) & 0x38)));
2043 }
2044
2045 static void d68000_movea_16(void)
2046 {
2047         sprintf(g_dasm_str, "movea.w %s, A%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7);
2048 }
2049
2050 static void d68000_movea_32(void)
2051 {
2052         sprintf(g_dasm_str, "movea.l %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7);
2053 }
2054
2055 static void d68000_move_to_ccr(void)
2056 {
2057         sprintf(g_dasm_str, "move    %s, CCR", get_ea_mode_str_8(g_cpu_ir));
2058 }
2059
2060 static void d68010_move_fr_ccr(void)
2061 {
2062         LIMIT_CPU_TYPES(M68010_PLUS);
2063         sprintf(g_dasm_str, "move    CCR, %s; (1+)", get_ea_mode_str_8(g_cpu_ir));
2064 }
2065
2066 static void d68000_move_fr_sr(void)
2067 {
2068         sprintf(g_dasm_str, "move    SR, %s", get_ea_mode_str_16(g_cpu_ir));
2069 }
2070
2071 static void d68000_move_to_sr(void)
2072 {
2073         sprintf(g_dasm_str, "move    %s, SR", get_ea_mode_str_16(g_cpu_ir));
2074 }
2075
2076 static void d68000_move_fr_usp(void)
2077 {
2078         sprintf(g_dasm_str, "move    USP, A%d", g_cpu_ir&7);
2079 }
2080
2081 static void d68000_move_to_usp(void)
2082 {
2083         sprintf(g_dasm_str, "move    A%d, USP", g_cpu_ir&7);
2084 }
2085
2086 static void d68010_movec(void)
2087 {
2088         uint extension;
2089         char* reg_name;
2090         char* processor;
2091         LIMIT_CPU_TYPES(M68010_PLUS);
2092         extension = read_imm_16();
2093
2094         switch(extension & 0xfff)
2095         {
2096                 case 0x000:
2097                         reg_name = "SFC";
2098                         processor = "1+";
2099                         break;
2100                 case 0x001:
2101                         reg_name = "DFC";
2102                         processor = "1+";
2103                         break;
2104                 case 0x800:
2105                         reg_name = "USP";
2106                         processor = "1+";
2107                         break;
2108                 case 0x801:
2109                         reg_name = "VBR";
2110                         processor = "1+";
2111                         break;
2112                 case 0x002:
2113                         reg_name = "CACR";
2114                         processor = "2+";
2115                         break;
2116                 case 0x802:
2117                         reg_name = "CAAR";
2118                         processor = "2,3";
2119                         break;
2120                 case 0x803:
2121                         reg_name = "MSP";
2122                         processor = "2+";
2123                         break;
2124                 case 0x804:
2125                         reg_name = "ISP";
2126                         processor = "2+";
2127                         break;
2128                 case 0x003:
2129                         reg_name = "TC";
2130                         processor = "4+";
2131                         break;
2132                 case 0x004:
2133                         reg_name = "ITT0";
2134                         processor = "4+";
2135                         break;
2136                 case 0x005:
2137                         reg_name = "ITT1";
2138                         processor = "4+";
2139                         break;
2140                 case 0x006:
2141                         reg_name = "DTT0";
2142                         processor = "4+";
2143                         break;
2144                 case 0x007:
2145                         reg_name = "DTT1";
2146                         processor = "4+";
2147                         break;
2148                 case 0x805:
2149                         reg_name = "MMUSR";
2150                         processor = "4+";
2151                         break;
2152                 case 0x806:
2153                         reg_name = "URP";
2154                         processor = "4+";
2155                         break;
2156                 case 0x807:
2157                         reg_name = "SRP";
2158                         processor = "4+";
2159                         break;
2160                 default:
2161                         reg_name = make_signed_hex_str_16(extension & 0xfff);
2162                         processor = "?";
2163         }
2164
2165         if(BIT_0(g_cpu_ir))
2166                 sprintf(g_dasm_str, "movec %c%d, %s; (%s)", BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, reg_name, processor);
2167         else
2168                 sprintf(g_dasm_str, "movec %s, %c%d; (%s)", reg_name, BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, processor);
2169 }
2170
2171 static void d68000_movem_pd_16(void)
2172 {
2173         uint data = read_imm_16();
2174         char buffer[40];
2175         uint first;
2176         uint run_length;
2177         uint i;
2178
2179         buffer[0] = 0;
2180         for(i=0;i<8;i++)
2181         {
2182                 if(data&(1<<(15-i)))
2183                 {
2184                         first = i;
2185                         run_length = 0;
2186                         while(i<7 && (data&(1<<(15-(i+1)))))
2187                         {
2188                                 i++;
2189                                 run_length++;
2190                         }
2191                         if(buffer[0] != 0)
2192                                 strcat(buffer, "/");
2193                         sprintf(buffer+strlen(buffer), "D%d", first);
2194                         if(run_length > 0)
2195                                 sprintf(buffer+strlen(buffer), "-D%d", first + run_length);
2196                 }
2197         }
2198         for(i=0;i<8;i++)
2199         {
2200                 if(data&(1<<(7-i)))
2201                 {
2202                         first = i;
2203                         run_length = 0;
2204                         while(i<7 && (data&(1<<(7-(i+1)))))
2205                         {
2206                                 i++;
2207                                 run_length++;
2208                         }
2209                         if(buffer[0] != 0)
2210                                 strcat(buffer, "/");
2211                         sprintf(buffer+strlen(buffer), "A%d", first);
2212                         if(run_length > 0)
2213                                 sprintf(buffer+strlen(buffer), "-A%d", first + run_length);
2214                 }
2215         }
2216         sprintf(g_dasm_str, "movem.w %s, %s", buffer, get_ea_mode_str_16(g_cpu_ir));
2217 }
2218
2219 static void d68000_movem_pd_32(void)
2220 {
2221         uint data = read_imm_16();
2222         char buffer[40];
2223         uint first;
2224         uint run_length;
2225         uint i;
2226
2227         buffer[0] = 0;
2228         for(i=0;i<8;i++)
2229         {
2230                 if(data&(1<<(15-i)))
2231                 {
2232                         first = i;
2233                         run_length = 0;
2234                         while(i<7 && (data&(1<<(15-(i+1)))))
2235                         {
2236                                 i++;
2237                                 run_length++;
2238                         }
2239                         if(buffer[0] != 0)
2240                                 strcat(buffer, "/");
2241                         sprintf(buffer+strlen(buffer), "D%d", first);
2242                         if(run_length > 0)
2243                                 sprintf(buffer+strlen(buffer), "-D%d", first + run_length);
2244                 }
2245         }
2246         for(i=0;i<8;i++)
2247         {
2248                 if(data&(1<<(7-i)))
2249                 {
2250                         first = i;
2251                         run_length = 0;
2252                         while(i<7 && (data&(1<<(7-(i+1)))))
2253                         {
2254                                 i++;
2255                                 run_length++;
2256                         }
2257                         if(buffer[0] != 0)
2258                                 strcat(buffer, "/");
2259                         sprintf(buffer+strlen(buffer), "A%d", first);
2260                         if(run_length > 0)
2261                                 sprintf(buffer+strlen(buffer), "-A%d", first + run_length);
2262                 }
2263         }
2264         sprintf(g_dasm_str, "movem.l %s, %s", buffer, get_ea_mode_str_32(g_cpu_ir));
2265 }
2266
2267 static void d68000_movem_er_16(void)
2268 {
2269         uint data = read_imm_16();
2270         char buffer[40];
2271         uint first;
2272         uint run_length;
2273         uint i;
2274
2275         buffer[0] = 0;
2276         for(i=0;i<8;i++)
2277         {
2278                 if(data&(1<<i))
2279                 {
2280                         first = i;
2281                         run_length = 0;
2282                         while(i<7 && (data&(1<<(i+1))))
2283                         {
2284                                 i++;
2285                                 run_length++;
2286                         }
2287                         if(buffer[0] != 0)
2288                                 strcat(buffer, "/");
2289                         sprintf(buffer+strlen(buffer), "D%d", first);
2290                         if(run_length > 0)
2291                                 sprintf(buffer+strlen(buffer), "-D%d", first + run_length);
2292                 }
2293         }
2294         for(i=0;i<8;i++)
2295         {
2296                 if(data&(1<<(i+8)))
2297                 {
2298                         first = i;
2299                         run_length = 0;
2300                         while(i<7 && (data&(1<<(i+8+1))))
2301                         {
2302                                 i++;
2303                                 run_length++;
2304                         }
2305                         if(buffer[0] != 0)
2306                                 strcat(buffer, "/");
2307                         sprintf(buffer+strlen(buffer), "A%d", first);
2308                         if(run_length > 0)
2309                                 sprintf(buffer+strlen(buffer), "-A%d", first + run_length);
2310                 }
2311         }
2312         sprintf(g_dasm_str, "movem.w %s, %s", get_ea_mode_str_16(g_cpu_ir), buffer);
2313 }
2314
2315 static void d68000_movem_er_32(void)
2316 {
2317         uint data = read_imm_16();
2318         char buffer[40];
2319         uint first;
2320         uint run_length;
2321         uint i;
2322
2323         buffer[0] = 0;
2324         for(i=0;i<8;i++)
2325         {
2326                 if(data&(1<<i))
2327                 {
2328                         first = i;
2329                         run_length = 0;
2330                         while(i<7 && (data&(1<<(i+1))))
2331                         {
2332                                 i++;
2333                                 run_length++;
2334                         }
2335                         if(buffer[0] != 0)
2336                                 strcat(buffer, "/");
2337                         sprintf(buffer+strlen(buffer), "D%d", first);
2338                         if(run_length > 0)
2339                                 sprintf(buffer+strlen(buffer), "-D%d", first + run_length);
2340                 }
2341         }
2342         for(i=0;i<8;i++)
2343         {
2344                 if(data&(1<<(i+8)))
2345                 {
2346                         first = i;
2347                         run_length = 0;
2348                         while(i<7 && (data&(1<<(i+8+1))))
2349                         {
2350                                 i++;
2351                                 run_length++;
2352                         }
2353                         if(buffer[0] != 0)
2354                                 strcat(buffer, "/");
2355                         sprintf(buffer+strlen(buffer), "A%d", first);
2356                         if(run_length > 0)
2357                                 sprintf(buffer+strlen(buffer), "-A%d", first + run_length);
2358                 }
2359         }
2360         sprintf(g_dasm_str, "movem.l %s, %s", get_ea_mode_str_32(g_cpu_ir), buffer);
2361 }
2362
2363 static void d68000_movem_re_16(void)
2364 {
2365         uint data = read_imm_16();
2366         char buffer[40];
2367         uint first;
2368         uint run_length;
2369         uint i;
2370
2371         buffer[0] = 0;
2372         for(i=0;i<8;i++)
2373         {
2374                 if(data&(1<<i))
2375                 {
2376                         first = i;
2377                         run_length = 0;
2378                         while(i<7 && (data&(1<<(i+1))))
2379                         {
2380                                 i++;
2381                                 run_length++;
2382                         }
2383                         if(buffer[0] != 0)
2384                                 strcat(buffer, "/");
2385                         sprintf(buffer+strlen(buffer), "D%d", first);
2386                         if(run_length > 0)
2387                                 sprintf(buffer+strlen(buffer), "-D%d", first + run_length);
2388                 }
2389         }
2390         for(i=0;i<8;i++)
2391         {
2392                 if(data&(1<<(i+8)))
2393                 {
2394                         first = i;
2395                         run_length = 0;
2396                         while(i<7 && (data&(1<<(i+8+1))))
2397                         {
2398                                 i++;
2399                                 run_length++;
2400                         }
2401                         if(buffer[0] != 0)
2402                                 strcat(buffer, "/");
2403                         sprintf(buffer+strlen(buffer), "A%d", first);
2404                         if(run_length > 0)
2405                                 sprintf(buffer+strlen(buffer), "-A%d", first + run_length);
2406                 }
2407         }
2408         sprintf(g_dasm_str, "movem.w %s, %s", buffer, get_ea_mode_str_16(g_cpu_ir));
2409 }
2410
2411 static void d68000_movem_re_32(void)
2412 {
2413         uint data = read_imm_16();
2414         char buffer[40];
2415         uint first;
2416         uint run_length;
2417         uint i;
2418
2419         buffer[0] = 0;
2420         for(i=0;i<8;i++)
2421         {
2422                 if(data&(1<<i))
2423                 {
2424                         first = i;
2425                         run_length = 0;
2426                         while(i<7 && (data&(1<<(i+1))))
2427                         {
2428                                 i++;
2429                                 run_length++;
2430                         }
2431                         if(buffer[0] != 0)
2432                                 strcat(buffer, "/");
2433                         sprintf(buffer+strlen(buffer), "D%d", first);
2434                         if(run_length > 0)
2435                                 sprintf(buffer+strlen(buffer), "-D%d", first + run_length);
2436                 }
2437         }
2438         for(i=0;i<8;i++)
2439         {
2440                 if(data&(1<<(i+8)))
2441                 {
2442                         first = i;
2443                         run_length = 0;
2444                         while(i<7 && (data&(1<<(i+8+1))))
2445                         {
2446                                 i++;
2447                                 run_length++;
2448                         }
2449                         if(buffer[0] != 0)
2450                                 strcat(buffer, "/");
2451                         sprintf(buffer+strlen(buffer), "A%d", first);
2452                         if(run_length > 0)
2453                                 sprintf(buffer+strlen(buffer), "-A%d", first + run_length);
2454                 }
2455         }
2456         sprintf(g_dasm_str, "movem.l %s, %s", buffer, get_ea_mode_str_32(g_cpu_ir));
2457 }
2458
2459 static void d68000_movep_re_16(void)
2460 {
2461         sprintf(g_dasm_str, "movep.w D%d, ($%x,A%d)", (g_cpu_ir>>9)&7, read_imm_16(), g_cpu_ir&7);
2462 }
2463
2464 static void d68000_movep_re_32(void)
2465 {
2466         sprintf(g_dasm_str, "movep.l D%d, ($%x,A%d)", (g_cpu_ir>>9)&7, read_imm_16(), g_cpu_ir&7);
2467 }
2468
2469 static void d68000_movep_er_16(void)
2470 {
2471         sprintf(g_dasm_str, "movep.w ($%x,A%d), D%d", read_imm_16(), g_cpu_ir&7, (g_cpu_ir>>9)&7);
2472 }
2473
2474 static void d68000_movep_er_32(void)
2475 {
2476         sprintf(g_dasm_str, "movep.l ($%x,A%d), D%d", read_imm_16(), g_cpu_ir&7, (g_cpu_ir>>9)&7);
2477 }
2478
2479 static void d68010_moves_8(void)
2480 {
2481         uint extension;
2482         LIMIT_CPU_TYPES(M68010_PLUS);
2483         extension = read_imm_16();
2484         if(BIT_B(extension))
2485                 sprintf(g_dasm_str, "moves.b %c%d, %s; (1+)", BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, get_ea_mode_str_8(g_cpu_ir));
2486         else
2487                 sprintf(g_dasm_str, "moves.b %s, %c%d; (1+)", get_ea_mode_str_8(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7);
2488 }
2489
2490 static void d68010_moves_16(void)
2491 {
2492         uint extension;
2493         LIMIT_CPU_TYPES(M68010_PLUS);
2494         extension = read_imm_16();
2495         if(BIT_B(extension))
2496                 sprintf(g_dasm_str, "moves.w %c%d, %s; (1+)", BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, get_ea_mode_str_16(g_cpu_ir));
2497         else
2498                 sprintf(g_dasm_str, "moves.w %s, %c%d; (1+)", get_ea_mode_str_16(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7);
2499 }
2500
2501 static void d68010_moves_32(void)
2502 {
2503         uint extension;
2504         LIMIT_CPU_TYPES(M68010_PLUS);
2505         extension = read_imm_16();
2506         if(BIT_B(extension))
2507                 sprintf(g_dasm_str, "moves.l %c%d, %s; (1+)", BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, get_ea_mode_str_32(g_cpu_ir));
2508         else
2509                 sprintf(g_dasm_str, "moves.l %s, %c%d; (1+)", get_ea_mode_str_32(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7);
2510 }
2511
2512 static void d68000_moveq(void)
2513 {
2514         sprintf(g_dasm_str, "moveq   #%s, D%d", make_signed_hex_str_8(g_cpu_ir), (g_cpu_ir>>9)&7);
2515 }
2516
2517 static void d68040_move16_pi_pi(void)
2518 {
2519         LIMIT_CPU_TYPES(M68040_PLUS);
2520         sprintf(g_dasm_str, "move16  (A%d)+, (A%d)+; (4)", g_cpu_ir&7, (read_imm_16()>>12)&7);
2521 }
2522
2523 static void d68040_move16_pi_al(void)
2524 {
2525         LIMIT_CPU_TYPES(M68040_PLUS);
2526         sprintf(g_dasm_str, "move16  (A%d)+, %s; (4)", g_cpu_ir&7, get_imm_str_u32());
2527 }
2528
2529 static void d68040_move16_al_pi(void)
2530 {
2531         LIMIT_CPU_TYPES(M68040_PLUS);
2532         sprintf(g_dasm_str, "move16  %s, (A%d)+; (4)", get_imm_str_u32(), g_cpu_ir&7);
2533 }
2534
2535 static void d68040_move16_ai_al(void)
2536 {
2537         LIMIT_CPU_TYPES(M68040_PLUS);
2538         sprintf(g_dasm_str, "move16  (A%d), %s; (4)", g_cpu_ir&7, get_imm_str_u32());
2539 }
2540
2541 static void d68040_move16_al_ai(void)
2542 {
2543         LIMIT_CPU_TYPES(M68040_PLUS);
2544         sprintf(g_dasm_str, "move16  %s, (A%d); (4)", get_imm_str_u32(), g_cpu_ir&7);
2545 }
2546
2547 static void d68000_muls(void)
2548 {
2549         sprintf(g_dasm_str, "muls.w  %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7);
2550 }
2551
2552 static void d68000_mulu(void)
2553 {
2554         sprintf(g_dasm_str, "mulu.w  %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7);
2555 }
2556
2557 static void d68020_mull(void)
2558 {
2559         uint extension;
2560         LIMIT_CPU_TYPES(M68020_PLUS);
2561         extension = read_imm_16();
2562
2563         if(BIT_A(extension))
2564                 sprintf(g_dasm_str, "mul%c.l %s, D%d:D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), extension&7, (extension>>12)&7);
2565         else
2566                 sprintf(g_dasm_str, "mul%c.l  %s, D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), (extension>>12)&7);
2567 }
2568
2569 static void d68000_nbcd(void)
2570 {
2571         sprintf(g_dasm_str, "nbcd    %s", get_ea_mode_str_8(g_cpu_ir));
2572 }
2573
2574 static void d68000_neg_8(void)
2575 {
2576         sprintf(g_dasm_str, "neg.b   %s", get_ea_mode_str_8(g_cpu_ir));
2577 }
2578
2579 static void d68000_neg_16(void)
2580 {
2581         sprintf(g_dasm_str, "neg.w   %s", get_ea_mode_str_16(g_cpu_ir));
2582 }
2583
2584 static void d68000_neg_32(void)
2585 {
2586         sprintf(g_dasm_str, "neg.l   %s", get_ea_mode_str_32(g_cpu_ir));
2587 }
2588
2589 static void d68000_negx_8(void)
2590 {
2591         sprintf(g_dasm_str, "negx.b  %s", get_ea_mode_str_8(g_cpu_ir));
2592 }
2593
2594 static void d68000_negx_16(void)
2595 {
2596         sprintf(g_dasm_str, "negx.w  %s", get_ea_mode_str_16(g_cpu_ir));
2597 }
2598
2599 static void d68000_negx_32(void)
2600 {
2601         sprintf(g_dasm_str, "negx.l  %s", get_ea_mode_str_32(g_cpu_ir));
2602 }
2603
2604 static void d68000_nop(void)
2605 {
2606         sprintf(g_dasm_str, "nop");
2607 }
2608
2609 static void d68000_not_8(void)
2610 {
2611         sprintf(g_dasm_str, "not.b   %s", get_ea_mode_str_8(g_cpu_ir));
2612 }
2613
2614 static void d68000_not_16(void)
2615 {
2616         sprintf(g_dasm_str, "not.w   %s", get_ea_mode_str_16(g_cpu_ir));
2617 }
2618
2619 static void d68000_not_32(void)
2620 {
2621         sprintf(g_dasm_str, "not.l   %s", get_ea_mode_str_32(g_cpu_ir));
2622 }
2623
2624 static void d68000_or_er_8(void)
2625 {
2626         sprintf(g_dasm_str, "or.b    %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7);
2627 }
2628
2629 static void d68000_or_er_16(void)
2630 {
2631         sprintf(g_dasm_str, "or.w    %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7);
2632 }
2633
2634 static void d68000_or_er_32(void)
2635 {
2636         sprintf(g_dasm_str, "or.l    %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7);
2637 }
2638
2639 static void d68000_or_re_8(void)
2640 {
2641         sprintf(g_dasm_str, "or.b    D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir));
2642 }
2643
2644 static void d68000_or_re_16(void)
2645 {
2646         sprintf(g_dasm_str, "or.w    D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir));
2647 }
2648
2649 static void d68000_or_re_32(void)
2650 {
2651         sprintf(g_dasm_str, "or.l    D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir));
2652 }
2653
2654 static void d68000_ori_8(void)
2655 {
2656         char* str = get_imm_str_u8();
2657         sprintf(g_dasm_str, "ori.b   %s, %s", str, get_ea_mode_str_8(g_cpu_ir));
2658 }
2659
2660 static void d68000_ori_16(void)
2661 {
2662         char* str = get_imm_str_u16();
2663         sprintf(g_dasm_str, "ori.w   %s, %s", str, get_ea_mode_str_16(g_cpu_ir));
2664 }
2665
2666 static void d68000_ori_32(void)
2667 {
2668         char* str = get_imm_str_u32();
2669         sprintf(g_dasm_str, "ori.l   %s, %s", str, get_ea_mode_str_32(g_cpu_ir));
2670 }
2671
2672 static void d68000_ori_to_ccr(void)
2673 {
2674         sprintf(g_dasm_str, "ori     %s, CCR", get_imm_str_u8());
2675 }
2676
2677 static void d68000_ori_to_sr(void)
2678 {
2679         sprintf(g_dasm_str, "ori     %s, SR", get_imm_str_u16());
2680 }
2681
2682 static void d68020_pack_rr(void)
2683 {
2684         LIMIT_CPU_TYPES(M68020_PLUS);
2685         sprintf(g_dasm_str, "pack    D%d, D%d, %s; (2+)", g_cpu_ir&7, (g_cpu_ir>>9)&7, get_imm_str_u16());
2686 }
2687
2688 static void d68020_pack_mm(void)
2689 {
2690         LIMIT_CPU_TYPES(M68020_PLUS);
2691         sprintf(g_dasm_str, "pack    -(A%d), -(A%d), %s; (2+)", g_cpu_ir&7, (g_cpu_ir>>9)&7, get_imm_str_u16());
2692 }
2693
2694 static void d68000_pea(void)
2695 {
2696         sprintf(g_dasm_str, "pea     %s", get_ea_mode_str_32(g_cpu_ir));
2697 }
2698
2699 // this is a 68040-specific form of PFLUSH
2700 static void d68040_pflush(void)
2701 {
2702         LIMIT_CPU_TYPES(M68040_PLUS);
2703
2704         if (g_cpu_ir & 0x10)
2705         {
2706                 sprintf(g_dasm_str, "pflusha%s", (g_cpu_ir & 8) ? "" : "n");
2707         }
2708         else
2709         {
2710                 sprintf(g_dasm_str, "pflush%s(A%d)", (g_cpu_ir & 8) ? "" : "n", g_cpu_ir & 7);
2711         }
2712 }
2713
2714 static void d68000_reset(void)
2715 {
2716         sprintf(g_dasm_str, "reset");
2717 }
2718
2719 static void d68000_ror_s_8(void)
2720 {
2721         sprintf(g_dasm_str, "ror.b   #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7);
2722 }
2723
2724 static void d68000_ror_s_16(void)
2725 {
2726         sprintf(g_dasm_str, "ror.w   #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7],g_cpu_ir&7);
2727 }
2728
2729 static void d68000_ror_s_32(void)
2730 {
2731         sprintf(g_dasm_str, "ror.l   #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7);
2732 }
2733
2734 static void d68000_ror_r_8(void)
2735 {
2736         sprintf(g_dasm_str, "ror.b   D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
2737 }
2738
2739 static void d68000_ror_r_16(void)
2740 {
2741         sprintf(g_dasm_str, "ror.w   D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
2742 }
2743
2744 static void d68000_ror_r_32(void)
2745 {
2746         sprintf(g_dasm_str, "ror.l   D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
2747 }
2748
2749 static void d68000_ror_ea(void)
2750 {
2751         sprintf(g_dasm_str, "ror.w   %s", get_ea_mode_str_32(g_cpu_ir));
2752 }
2753
2754 static void d68000_rol_s_8(void)
2755 {
2756         sprintf(g_dasm_str, "rol.b   #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7);
2757 }
2758
2759 static void d68000_rol_s_16(void)
2760 {
2761         sprintf(g_dasm_str, "rol.w   #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7);
2762 }
2763
2764 static void d68000_rol_s_32(void)
2765 {
2766         sprintf(g_dasm_str, "rol.l   #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7);
2767 }
2768
2769 static void d68000_rol_r_8(void)
2770 {
2771         sprintf(g_dasm_str, "rol.b   D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
2772 }
2773
2774 static void d68000_rol_r_16(void)
2775 {
2776         sprintf(g_dasm_str, "rol.w   D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
2777 }
2778
2779 static void d68000_rol_r_32(void)
2780 {
2781         sprintf(g_dasm_str, "rol.l   D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
2782 }
2783
2784 static void d68000_rol_ea(void)
2785 {
2786         sprintf(g_dasm_str, "rol.w   %s", get_ea_mode_str_32(g_cpu_ir));
2787 }
2788
2789 static void d68000_roxr_s_8(void)
2790 {
2791         sprintf(g_dasm_str, "roxr.b  #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7);
2792 }
2793
2794 static void d68000_roxr_s_16(void)
2795 {
2796         sprintf(g_dasm_str, "roxr.w  #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7);
2797 }
2798
2799
2800 static void d68000_roxr_s_32(void)
2801 {
2802         sprintf(g_dasm_str, "roxr.l  #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7);
2803 }
2804
2805 static void d68000_roxr_r_8(void)
2806 {
2807         sprintf(g_dasm_str, "roxr.b  D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
2808 }
2809
2810 static void d68000_roxr_r_16(void)
2811 {
2812         sprintf(g_dasm_str, "roxr.w  D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
2813 }
2814
2815 static void d68000_roxr_r_32(void)
2816 {
2817         sprintf(g_dasm_str, "roxr.l  D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
2818 }
2819
2820 static void d68000_roxr_ea(void)
2821 {
2822         sprintf(g_dasm_str, "roxr.w  %s", get_ea_mode_str_32(g_cpu_ir));
2823 }
2824
2825 static void d68000_roxl_s_8(void)
2826 {
2827         sprintf(g_dasm_str, "roxl.b  #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7);
2828 }
2829
2830 static void d68000_roxl_s_16(void)
2831 {
2832         sprintf(g_dasm_str, "roxl.w  #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7);
2833 }
2834
2835 static void d68000_roxl_s_32(void)
2836 {
2837         sprintf(g_dasm_str, "roxl.l  #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7);
2838 }
2839
2840 static void d68000_roxl_r_8(void)
2841 {
2842         sprintf(g_dasm_str, "roxl.b  D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
2843 }
2844
2845 static void d68000_roxl_r_16(void)
2846 {
2847         sprintf(g_dasm_str, "roxl.w  D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
2848 }
2849
2850 static void d68000_roxl_r_32(void)
2851 {
2852         sprintf(g_dasm_str, "roxl.l  D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7);
2853 }
2854
2855 static void d68000_roxl_ea(void)
2856 {
2857         sprintf(g_dasm_str, "roxl.w  %s", get_ea_mode_str_32(g_cpu_ir));
2858 }
2859
2860 static void d68010_rtd(void)
2861 {
2862         LIMIT_CPU_TYPES(M68010_PLUS);
2863         sprintf(g_dasm_str, "rtd     %s; (1+)", get_imm_str_s16());
2864         SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT);
2865 }
2866
2867 static void d68000_rte(void)
2868 {
2869         sprintf(g_dasm_str, "rte");
2870         SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT);
2871 }
2872
2873 static void d68020_rtm(void)
2874 {
2875         LIMIT_CPU_TYPES(M68020_ONLY);
2876         sprintf(g_dasm_str, "rtm     %c%d; (2+)", BIT_3(g_cpu_ir) ? 'A' : 'D', g_cpu_ir&7);
2877         SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT);
2878 }
2879
2880 static void d68000_rtr(void)
2881 {
2882         sprintf(g_dasm_str, "rtr");
2883         SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT);
2884 }
2885
2886 static void d68000_rts(void)
2887 {
2888         sprintf(g_dasm_str, "rts");
2889         SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT);
2890 }
2891
2892 static void d68000_sbcd_rr(void)
2893 {
2894         sprintf(g_dasm_str, "sbcd    D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7);
2895 }
2896
2897 static void d68000_sbcd_mm(void)
2898 {
2899         sprintf(g_dasm_str, "sbcd    -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7);
2900 }
2901
2902 static void d68000_scc(void)
2903 {
2904         sprintf(g_dasm_str, "s%-2s     %s", g_cc[(g_cpu_ir>>8)&0xf], get_ea_mode_str_8(g_cpu_ir));
2905 }
2906
2907 static void d68000_stop(void)
2908 {
2909         sprintf(g_dasm_str, "stop    %s", get_imm_str_s16());
2910 }
2911
2912 static void d68000_sub_er_8(void)
2913 {
2914         sprintf(g_dasm_str, "sub.b   %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7);
2915 }
2916
2917 static void d68000_sub_er_16(void)
2918 {
2919         sprintf(g_dasm_str, "sub.w   %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7);
2920 }
2921
2922 static void d68000_sub_er_32(void)
2923 {
2924         sprintf(g_dasm_str, "sub.l   %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7);
2925 }
2926
2927 static void d68000_sub_re_8(void)
2928 {
2929         sprintf(g_dasm_str, "sub.b   D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir));
2930 }
2931
2932 static void d68000_sub_re_16(void)
2933 {
2934         sprintf(g_dasm_str, "sub.w   D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir));
2935 }
2936
2937 static void d68000_sub_re_32(void)
2938 {
2939         sprintf(g_dasm_str, "sub.l   D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir));
2940 }
2941
2942 static void d68000_suba_16(void)
2943 {
2944         sprintf(g_dasm_str, "suba.w  %s, A%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7);
2945 }
2946
2947 static void d68000_suba_32(void)
2948 {
2949         sprintf(g_dasm_str, "suba.l  %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7);
2950 }
2951
2952 static void d68000_subi_8(void)
2953 {
2954         char* str = get_imm_str_s8();
2955         sprintf(g_dasm_str, "subi.b  %s, %s", str, get_ea_mode_str_8(g_cpu_ir));
2956 }
2957
2958 static void d68000_subi_16(void)
2959 {
2960         char* str = get_imm_str_s16();
2961         sprintf(g_dasm_str, "subi.w  %s, %s", str, get_ea_mode_str_16(g_cpu_ir));
2962 }
2963
2964 static void d68000_subi_32(void)
2965 {
2966         char* str = get_imm_str_s32();
2967         sprintf(g_dasm_str, "subi.l  %s, %s", str, get_ea_mode_str_32(g_cpu_ir));
2968 }
2969
2970 static void d68000_subq_8(void)
2971 {
2972         sprintf(g_dasm_str, "subq.b  #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_8(g_cpu_ir));
2973 }
2974
2975 static void d68000_subq_16(void)
2976 {
2977         sprintf(g_dasm_str, "subq.w  #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_16(g_cpu_ir));
2978 }
2979
2980 static void d68000_subq_32(void)
2981 {
2982         sprintf(g_dasm_str, "subq.l  #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_32(g_cpu_ir));
2983 }
2984
2985 static void d68000_subx_rr_8(void)
2986 {
2987         sprintf(g_dasm_str, "subx.b  D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7);
2988 }
2989
2990 static void d68000_subx_rr_16(void)
2991 {
2992         sprintf(g_dasm_str, "subx.w  D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7);
2993 }
2994
2995 static void d68000_subx_rr_32(void)
2996 {
2997         sprintf(g_dasm_str, "subx.l  D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7);
2998 }
2999
3000 static void d68000_subx_mm_8(void)
3001 {
3002         sprintf(g_dasm_str, "subx.b  -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7);
3003 }
3004
3005 static void d68000_subx_mm_16(void)
3006 {
3007         sprintf(g_dasm_str, "subx.w  -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7);
3008 }
3009
3010 static void d68000_subx_mm_32(void)
3011 {
3012         sprintf(g_dasm_str, "subx.l  -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7);
3013 }
3014
3015 static void d68000_swap(void)
3016 {
3017         sprintf(g_dasm_str, "swap    D%d", g_cpu_ir&7);
3018 }
3019
3020 static void d68000_tas(void)
3021 {
3022         sprintf(g_dasm_str, "tas     %s", get_ea_mode_str_8(g_cpu_ir));
3023 }
3024
3025 static void d68000_trap(void)
3026 {
3027         sprintf(g_dasm_str, "trap    #$%x", g_cpu_ir&0xf);
3028 }
3029
3030 static void d68020_trapcc_0(void)
3031 {
3032         LIMIT_CPU_TYPES(M68020_PLUS);
3033         sprintf(g_dasm_str, "trap%-2s; (2+)", g_cc[(g_cpu_ir>>8)&0xf]);
3034         SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER);
3035 }
3036
3037 static void d68020_trapcc_16(void)
3038 {
3039         LIMIT_CPU_TYPES(M68020_PLUS);
3040         sprintf(g_dasm_str, "trap%-2s  %s; (2+)", g_cc[(g_cpu_ir>>8)&0xf], get_imm_str_u16());
3041         SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER);
3042 }
3043
3044 static void d68020_trapcc_32(void)
3045 {
3046         LIMIT_CPU_TYPES(M68020_PLUS);
3047         sprintf(g_dasm_str, "trap%-2s  %s; (2+)", g_cc[(g_cpu_ir>>8)&0xf], get_imm_str_u32());
3048         SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER);
3049 }
3050
3051 static void d68000_trapv(void)
3052 {
3053         sprintf(g_dasm_str, "trapv");
3054         SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER);
3055 }
3056
3057 static void d68000_tst_8(void)
3058 {
3059         sprintf(g_dasm_str, "tst.b   %s", get_ea_mode_str_8(g_cpu_ir));
3060 }
3061
3062 static void d68020_tst_pcdi_8(void)
3063 {
3064         LIMIT_CPU_TYPES(M68020_PLUS);
3065         sprintf(g_dasm_str, "tst.b   %s; (2+)", get_ea_mode_str_8(g_cpu_ir));
3066 }
3067
3068 static void d68020_tst_pcix_8(void)
3069 {
3070         LIMIT_CPU_TYPES(M68020_PLUS);
3071         sprintf(g_dasm_str, "tst.b   %s; (2+)", get_ea_mode_str_8(g_cpu_ir));
3072 }
3073
3074 static void d68020_tst_i_8(void)
3075 {
3076         LIMIT_CPU_TYPES(M68020_PLUS);
3077         sprintf(g_dasm_str, "tst.b   %s; (2+)", get_ea_mode_str_8(g_cpu_ir));
3078 }
3079
3080 static void d68000_tst_16(void)
3081 {
3082         sprintf(g_dasm_str, "tst.w   %s", get_ea_mode_str_16(g_cpu_ir));
3083 }
3084
3085 static void d68020_tst_a_16(void)
3086 {
3087         LIMIT_CPU_TYPES(M68020_PLUS);
3088         sprintf(g_dasm_str, "tst.w   %s; (2+)", get_ea_mode_str_16(g_cpu_ir));
3089 }
3090
3091 static void d68020_tst_pcdi_16(void)
3092 {
3093         LIMIT_CPU_TYPES(M68020_PLUS);
3094         sprintf(g_dasm_str, "tst.w   %s; (2+)", get_ea_mode_str_16(g_cpu_ir));
3095 }
3096
3097 static void d68020_tst_pcix_16(void)
3098 {
3099         LIMIT_CPU_TYPES(M68020_PLUS);
3100         sprintf(g_dasm_str, "tst.w   %s; (2+)", get_ea_mode_str_16(g_cpu_ir));
3101 }
3102
3103 static void d68020_tst_i_16(void)
3104 {
3105         LIMIT_CPU_TYPES(M68020_PLUS);
3106         sprintf(g_dasm_str, "tst.w   %s; (2+)", get_ea_mode_str_16(g_cpu_ir));
3107 }
3108
3109 static void d68000_tst_32(void)
3110 {
3111         sprintf(g_dasm_str, "tst.l   %s", get_ea_mode_str_32(g_cpu_ir));
3112 }
3113
3114 static void d68020_tst_a_32(void)
3115 {
3116         LIMIT_CPU_TYPES(M68020_PLUS);
3117         sprintf(g_dasm_str, "tst.l   %s; (2+)", get_ea_mode_str_32(g_cpu_ir));
3118 }
3119
3120 static void d68020_tst_pcdi_32(void)
3121 {
3122         LIMIT_CPU_TYPES(M68020_PLUS);
3123         sprintf(g_dasm_str, "tst.l   %s; (2+)", get_ea_mode_str_32(g_cpu_ir));
3124 }
3125
3126 static void d68020_tst_pcix_32(void)
3127 {
3128         LIMIT_CPU_TYPES(M68020_PLUS);
3129         sprintf(g_dasm_str, "tst.l   %s; (2+)", get_ea_mode_str_32(g_cpu_ir));
3130 }
3131
3132 static void d68020_tst_i_32(void)
3133 {
3134         LIMIT_CPU_TYPES(M68020_PLUS);
3135         sprintf(g_dasm_str, "tst.l   %s; (2+)", get_ea_mode_str_32(g_cpu_ir));
3136 }
3137
3138 static void d68000_unlk(void)
3139 {
3140         sprintf(g_dasm_str, "unlk    A%d", g_cpu_ir&7);
3141 }
3142
3143 static void d68020_unpk_rr(void)
3144 {
3145         LIMIT_CPU_TYPES(M68020_PLUS);
3146         sprintf(g_dasm_str, "unpk    D%d, D%d, %s; (2+)", g_cpu_ir&7, (g_cpu_ir>>9)&7, get_imm_str_u16());
3147 }
3148
3149 static void d68020_unpk_mm(void)
3150 {
3151         LIMIT_CPU_TYPES(M68020_PLUS);
3152         sprintf(g_dasm_str, "unpk    -(A%d), -(A%d), %s; (2+)", g_cpu_ir&7, (g_cpu_ir>>9)&7, get_imm_str_u16());
3153 }
3154
3155
3156 // PFLUSH:  001xxx0xxxxxxxxx
3157 // PLOAD:   001000x0000xxxxx
3158 // PVALID1: 0010100000000000
3159 // PVALID2: 0010110000000xxx
3160 // PMOVE 1: 010xxxx000000000
3161 // PMOVE 2: 011xxxx0000xxx00
3162 // PMOVE 3: 011xxxx000000000
3163 // PTEST:   100xxxxxxxxxxxxx
3164 // PFLUSHR:  1010000000000000
3165 static void d68851_p000(void)
3166 {
3167         char* str;
3168         uint modes = read_imm_16();
3169
3170         // do this after fetching the second PMOVE word so we properly get the 3rd if necessary
3171         str = get_ea_mode_str_32(g_cpu_ir);
3172
3173         if ((modes & 0xfde0) == 0x2000) // PLOAD
3174         {
3175                 if (modes & 0x0200)
3176                 {
3177                         sprintf(g_dasm_str, "pload  #%d, %s", (modes>>10)&7, str);
3178                 }
3179                 else
3180                 {
3181                         sprintf(g_dasm_str, "pload  %s, #%d", str, (modes>>10)&7);
3182                 }
3183                 return;
3184         }
3185
3186         if ((modes & 0xe200) == 0x2000) // PFLUSH
3187         {
3188                 sprintf(g_dasm_str, "pflushr %x, %x, %s", modes & 0x1f, (modes>>5)&0xf, str);
3189                 return;
3190         }
3191
3192         if (modes == 0xa000)    // PFLUSHR
3193         {
3194                 sprintf(g_dasm_str, "pflushr %s", str);
3195         }
3196
3197         if (modes == 0x2800)    // PVALID (FORMAT 1)
3198         {
3199                 sprintf(g_dasm_str, "pvalid VAL, %s", str);
3200                 return;
3201         }
3202
3203         if ((modes & 0xfff8) == 0x2c00) // PVALID (FORMAT 2)
3204         {
3205                 sprintf(g_dasm_str, "pvalid A%d, %s", modes & 0xf, str);
3206                 return;
3207         }
3208
3209         if ((modes & 0xe000) == 0x8000) // PTEST
3210         {
3211                 sprintf(g_dasm_str, "ptest #%d, %s", modes & 0x1f, str);
3212                 return;
3213         }
3214
3215         switch ((modes>>13) & 0x7)
3216         {
3217                 case 0: // MC68030/040 form with FD bit
3218                 case 2: // MC68881 form, FD never set
3219                         if (modes & 0x0100)
3220                         {
3221                                 if (modes & 0x0200)
3222                                 {
3223                                         sprintf(g_dasm_str, "pmovefd  %s, %s", g_mmuregs[(modes>>10)&7], str);
3224                                 }
3225                                 else
3226                                 {
3227                                         sprintf(g_dasm_str, "pmovefd  %s, %s", str, g_mmuregs[(modes>>10)&7]);
3228                                 }
3229                         }
3230                         else
3231                         {
3232                                 if (modes & 0x0200)
3233                                 {
3234                                         sprintf(g_dasm_str, "pmove  %s, %s", g_mmuregs[(modes>>10)&7], str);
3235                                 }
3236                                 else
3237                                 {
3238                                         sprintf(g_dasm_str, "pmove  %s, %s", str, g_mmuregs[(modes>>10)&7]);
3239                                 }
3240                         }
3241                         break;
3242
3243                 case 3: // MC68030 to/from status reg
3244                         if (modes & 0x0200)
3245                         {
3246                                 sprintf(g_dasm_str, "pmove  mmusr, %s", str);
3247                         }
3248                         else
3249                         {
3250                                 sprintf(g_dasm_str, "pmove  %s, mmusr", str);
3251                         }
3252                         break;
3253
3254                 default:
3255                         sprintf(g_dasm_str, "pmove [unknown form] %s", str);
3256                         break;
3257         }
3258 }
3259
3260 static void d68851_pbcc16(void)
3261 {
3262         uint32 temp_pc = g_cpu_pc;
3263
3264         sprintf(g_dasm_str, "pb%s %x", g_mmucond[g_cpu_ir&0xf], temp_pc + make_int_16(read_imm_16()));
3265 }
3266
3267 static void d68851_pbcc32(void)
3268 {
3269         uint32 temp_pc = g_cpu_pc;
3270
3271         sprintf(g_dasm_str, "pb%s %x", g_mmucond[g_cpu_ir&0xf], temp_pc + make_int_32(read_imm_32()));
3272 }
3273
3274 static void d68851_pdbcc(void)
3275 {
3276         uint32 temp_pc = g_cpu_pc;
3277         uint16 modes = read_imm_16();
3278
3279         sprintf(g_dasm_str, "pb%s %x", g_mmucond[modes&0xf], temp_pc + make_int_16(read_imm_16()));
3280 }
3281
3282 // PScc:  0000000000xxxxxx
3283 static void d68851_p001(void)
3284 {
3285         sprintf(g_dasm_str, "MMU 001 group");
3286 }
3287
3288 /* ======================================================================== */
3289 /* ======================= INSTRUCTION TABLE BUILDER ====================== */
3290 /* ======================================================================== */
3291
3292 /* EA Masks:
3293 800 = data register direct
3294 400 = address register direct
3295 200 = address register indirect
3296 100 = ARI postincrement
3297  80 = ARI pre-decrement
3298  40 = ARI displacement
3299  20 = ARI index
3300  10 = absolute short
3301   8 = absolute long
3302   4 = immediate / sr
3303   2 = pc displacement
3304   1 = pc idx
3305 */
3306
3307 static const opcode_struct g_opcode_info[] =
3308 {
3309 /*  opcode handler             mask    match   ea mask */
3310         {d68000_1010         , 0xf000, 0xa000, 0x000},
3311         {d68000_1111         , 0xf000, 0xf000, 0x000},
3312         {d68000_abcd_rr      , 0xf1f8, 0xc100, 0x000},
3313         {d68000_abcd_mm      , 0xf1f8, 0xc108, 0x000},
3314         {d68000_add_er_8     , 0xf1c0, 0xd000, 0xbff},
3315         {d68000_add_er_16    , 0xf1c0, 0xd040, 0xfff},
3316         {d68000_add_er_32    , 0xf1c0, 0xd080, 0xfff},
3317         {d68000_add_re_8     , 0xf1c0, 0xd100, 0x3f8},
3318         {d68000_add_re_16    , 0xf1c0, 0xd140, 0x3f8},
3319         {d68000_add_re_32    , 0xf1c0, 0xd180, 0x3f8},
3320         {d68000_adda_16      , 0xf1c0, 0xd0c0, 0xfff},
3321         {d68000_adda_32      , 0xf1c0, 0xd1c0, 0xfff},
3322         {d68000_addi_8       , 0xffc0, 0x0600, 0xbf8},
3323         {d68000_addi_16      , 0xffc0, 0x0640, 0xbf8},
3324         {d68000_addi_32      , 0xffc0, 0x0680, 0xbf8},
3325         {d68000_addq_8       , 0xf1c0, 0x5000, 0xbf8},
3326         {d68000_addq_16      , 0xf1c0, 0x5040, 0xff8},
3327         {d68000_addq_32      , 0xf1c0, 0x5080, 0xff8},
3328         {d68000_addx_rr_8    , 0xf1f8, 0xd100, 0x000},
3329         {d68000_addx_rr_16   , 0xf1f8, 0xd140, 0x000},
3330         {d68000_addx_rr_32   , 0xf1f8, 0xd180, 0x000},
3331         {d68000_addx_mm_8    , 0xf1f8, 0xd108, 0x000},
3332         {d68000_addx_mm_16   , 0xf1f8, 0xd148, 0x000},
3333         {d68000_addx_mm_32   , 0xf1f8, 0xd188, 0x000},
3334         {d68000_and_er_8     , 0xf1c0, 0xc000, 0xbff},
3335         {d68000_and_er_16    , 0xf1c0, 0xc040, 0xbff},
3336         {d68000_and_er_32    , 0xf1c0, 0xc080, 0xbff},
3337         {d68000_and_re_8     , 0xf1c0, 0xc100, 0x3f8},
3338         {d68000_and_re_16    , 0xf1c0, 0xc140, 0x3f8},
3339         {d68000_and_re_32    , 0xf1c0, 0xc180, 0x3f8},
3340         {d68000_andi_to_ccr  , 0xffff, 0x023c, 0x000},
3341         {d68000_andi_to_sr   , 0xffff, 0x027c, 0x000},
3342         {d68000_andi_8       , 0xffc0, 0x0200, 0xbf8},
3343         {d68000_andi_16      , 0xffc0, 0x0240, 0xbf8},
3344         {d68000_andi_32      , 0xffc0, 0x0280, 0xbf8},
3345         {d68000_asr_s_8      , 0xf1f8, 0xe000, 0x000},
3346         {d68000_asr_s_16     , 0xf1f8, 0xe040, 0x000},
3347         {d68000_asr_s_32     , 0xf1f8, 0xe080, 0x000},
3348         {d68000_asr_r_8      , 0xf1f8, 0xe020, 0x000},
3349         {d68000_asr_r_16     , 0xf1f8, 0xe060, 0x000},
3350         {d68000_asr_r_32     , 0xf1f8, 0xe0a0, 0x000},
3351         {d68000_asr_ea       , 0xffc0, 0xe0c0, 0x3f8},
3352         {d68000_asl_s_8      , 0xf1f8, 0xe100, 0x000},
3353         {d68000_asl_s_16     , 0xf1f8, 0xe140, 0x000},
3354         {d68000_asl_s_32     , 0xf1f8, 0xe180, 0x000},
3355         {d68000_asl_r_8      , 0xf1f8, 0xe120, 0x000},
3356         {d68000_asl_r_16     , 0xf1f8, 0xe160, 0x000},
3357         {d68000_asl_r_32     , 0xf1f8, 0xe1a0, 0x000},
3358         {d68000_asl_ea       , 0xffc0, 0xe1c0, 0x3f8},
3359         {d68000_bcc_8        , 0xf000, 0x6000, 0x000},
3360         {d68000_bcc_16       , 0xf0ff, 0x6000, 0x000},
3361         {d68020_bcc_32       , 0xf0ff, 0x60ff, 0x000},
3362         {d68000_bchg_r       , 0xf1c0, 0x0140, 0xbf8},
3363         {d68000_bchg_s       , 0xffc0, 0x0840, 0xbf8},
3364         {d68000_bclr_r       , 0xf1c0, 0x0180, 0xbf8},
3365         {d68000_bclr_s       , 0xffc0, 0x0880, 0xbf8},
3366         {d68020_bfchg        , 0xffc0, 0xeac0, 0xa78},
3367         {d68020_bfclr        , 0xffc0, 0xecc0, 0xa78},
3368         {d68020_bfexts       , 0xffc0, 0xebc0, 0xa7b},
3369         {d68020_bfextu       , 0xffc0, 0xe9c0, 0xa7b},
3370         {d68020_bfffo        , 0xffc0, 0xedc0, 0xa7b},
3371         {d68020_bfins        , 0xffc0, 0xefc0, 0xa78},
3372         {d68020_bfset        , 0xffc0, 0xeec0, 0xa78},
3373         {d68020_bftst        , 0xffc0, 0xe8c0, 0xa7b},
3374         {d68010_bkpt         , 0xfff8, 0x4848, 0x000},
3375         {d68000_bra_8        , 0xff00, 0x6000, 0x000},
3376         {d68000_bra_16       , 0xffff, 0x6000, 0x000},
3377         {d68020_bra_32       , 0xffff, 0x60ff, 0x000},
3378         {d68000_bset_r       , 0xf1c0, 0x01c0, 0xbf8},
3379         {d68000_bset_s       , 0xffc0, 0x08c0, 0xbf8},
3380         {d68000_bsr_8        , 0xff00, 0x6100, 0x000},
3381         {d68000_bsr_16       , 0xffff, 0x6100, 0x000},
3382         {d68020_bsr_32       , 0xffff, 0x61ff, 0x000},
3383         {d68000_btst_r       , 0xf1c0, 0x0100, 0xbff},
3384         {d68000_btst_s       , 0xffc0, 0x0800, 0xbfb},
3385         {d68020_callm        , 0xffc0, 0x06c0, 0x27b},
3386         {d68020_cas_8        , 0xffc0, 0x0ac0, 0x3f8},
3387         {d68020_cas_16       , 0xffc0, 0x0cc0, 0x3f8},
3388         {d68020_cas_32       , 0xffc0, 0x0ec0, 0x3f8},
3389         {d68020_cas2_16      , 0xffff, 0x0cfc, 0x000},
3390         {d68020_cas2_32      , 0xffff, 0x0efc, 0x000},
3391         {d68000_chk_16       , 0xf1c0, 0x4180, 0xbff},
3392         {d68020_chk_32       , 0xf1c0, 0x4100, 0xbff},
3393         {d68020_chk2_cmp2_8  , 0xffc0, 0x00c0, 0x27b},
3394         {d68020_chk2_cmp2_16 , 0xffc0, 0x02c0, 0x27b},
3395         {d68020_chk2_cmp2_32 , 0xffc0, 0x04c0, 0x27b},
3396         {d68040_cinv         , 0xff20, 0xf400, 0x000},
3397         {d68000_clr_8        , 0xffc0, 0x4200, 0xbf8},
3398         {d68000_clr_16       , 0xffc0, 0x4240, 0xbf8},
3399         {d68000_clr_32       , 0xffc0, 0x4280, 0xbf8},
3400         {d68000_cmp_8        , 0xf1c0, 0xb000, 0xbff},
3401         {d68000_cmp_16       , 0xf1c0, 0xb040, 0xfff},
3402         {d68000_cmp_32       , 0xf1c0, 0xb080, 0xfff},
3403         {d68000_cmpa_16      , 0xf1c0, 0xb0c0, 0xfff},
3404         {d68000_cmpa_32      , 0xf1c0, 0xb1c0, 0xfff},
3405         {d68000_cmpi_8       , 0xffc0, 0x0c00, 0xbf8},
3406         {d68020_cmpi_pcdi_8  , 0xffff, 0x0c3a, 0x000},
3407         {d68020_cmpi_pcix_8  , 0xffff, 0x0c3b, 0x000},
3408         {d68000_cmpi_16      , 0xffc0, 0x0c40, 0xbf8},
3409         {d68020_cmpi_pcdi_16 , 0xffff, 0x0c7a, 0x000},
3410         {d68020_cmpi_pcix_16 , 0xffff, 0x0c7b, 0x000},
3411         {d68000_cmpi_32      , 0xffc0, 0x0c80, 0xbf8},
3412         {d68020_cmpi_pcdi_32 , 0xffff, 0x0cba, 0x000},
3413         {d68020_cmpi_pcix_32 , 0xffff, 0x0cbb, 0x000},
3414         {d68000_cmpm_8       , 0xf1f8, 0xb108, 0x000},
3415         {d68000_cmpm_16      , 0xf1f8, 0xb148, 0x000},
3416         {d68000_cmpm_32      , 0xf1f8, 0xb188, 0x000},
3417         {d68020_cpbcc_16     , 0xf1c0, 0xf080, 0x000},
3418         {d68020_cpbcc_32     , 0xf1c0, 0xf0c0, 0x000},
3419         {d68020_cpdbcc       , 0xf1f8, 0xf048, 0x000},
3420         {d68020_cpgen        , 0xf1c0, 0xf000, 0x000},
3421         {d68020_cprestore    , 0xf1c0, 0xf140, 0x37f},
3422         {d68020_cpsave       , 0xf1c0, 0xf100, 0x2f8},
3423         {d68020_cpscc        , 0xf1c0, 0xf040, 0xbf8},
3424         {d68020_cptrapcc_0   , 0xf1ff, 0xf07c, 0x000},
3425         {d68020_cptrapcc_16  , 0xf1ff, 0xf07a, 0x000},
3426         {d68020_cptrapcc_32  , 0xf1ff, 0xf07b, 0x000},
3427         {d68040_cpush        , 0xff20, 0xf420, 0x000},
3428         {d68000_dbcc         , 0xf0f8, 0x50c8, 0x000},
3429         {d68000_dbra         , 0xfff8, 0x51c8, 0x000},
3430         {d68000_divs         , 0xf1c0, 0x81c0, 0xbff},
3431         {d68000_divu         , 0xf1c0, 0x80c0, 0xbff},
3432         {d68020_divl         , 0xffc0, 0x4c40, 0xbff},
3433         {d68000_eor_8        , 0xf1c0, 0xb100, 0xbf8},
3434         {d68000_eor_16       , 0xf1c0, 0xb140, 0xbf8},
3435         {d68000_eor_32       , 0xf1c0, 0xb180, 0xbf8},
3436         {d68000_eori_to_ccr  , 0xffff, 0x0a3c, 0x000},
3437         {d68000_eori_to_sr   , 0xffff, 0x0a7c, 0x000},
3438         {d68000_eori_8       , 0xffc0, 0x0a00, 0xbf8},
3439         {d68000_eori_16      , 0xffc0, 0x0a40, 0xbf8},
3440         {d68000_eori_32      , 0xffc0, 0x0a80, 0xbf8},
3441         {d68000_exg_dd       , 0xf1f8, 0xc140, 0x000},
3442         {d68000_exg_aa       , 0xf1f8, 0xc148, 0x000},
3443         {d68000_exg_da       , 0xf1f8, 0xc188, 0x000},
3444         {d68020_extb_32      , 0xfff8, 0x49c0, 0x000},
3445         {d68000_ext_16       , 0xfff8, 0x4880, 0x000},
3446         {d68000_ext_32       , 0xfff8, 0x48c0, 0x000},
3447         {d68040_fpu          , 0xffc0, 0xf200, 0x000},
3448         {d68000_illegal      , 0xffff, 0x4afc, 0x000},
3449         {d68000_jmp          , 0xffc0, 0x4ec0, 0x27b},
3450         {d68000_jsr          , 0xffc0, 0x4e80, 0x27b},
3451         {d68000_lea          , 0xf1c0, 0x41c0, 0x27b},
3452         {d68000_link_16      , 0xfff8, 0x4e50, 0x000},
3453         {d68020_link_32      , 0xfff8, 0x4808, 0x000},
3454         {d68000_lsr_s_8      , 0xf1f8, 0xe008, 0x000},
3455         {d68000_lsr_s_16     , 0xf1f8, 0xe048, 0x000},
3456         {d68000_lsr_s_32     , 0xf1f8, 0xe088, 0x000},
3457         {d68000_lsr_r_8      , 0xf1f8, 0xe028, 0x000},
3458         {d68000_lsr_r_16     , 0xf1f8, 0xe068, 0x000},
3459         {d68000_lsr_r_32     , 0xf1f8, 0xe0a8, 0x000},
3460         {d68000_lsr_ea       , 0xffc0, 0xe2c0, 0x3f8},
3461         {d68000_lsl_s_8      , 0xf1f8, 0xe108, 0x000},
3462         {d68000_lsl_s_16     , 0xf1f8, 0xe148, 0x000},
3463         {d68000_lsl_s_32     , 0xf1f8, 0xe188, 0x000},
3464         {d68000_lsl_r_8      , 0xf1f8, 0xe128, 0x000},
3465         {d68000_lsl_r_16     , 0xf1f8, 0xe168, 0x000},
3466         {d68000_lsl_r_32     , 0xf1f8, 0xe1a8, 0x000},
3467         {d68000_lsl_ea       , 0xffc0, 0xe3c0, 0x3f8},
3468         {d68000_move_8       , 0xf000, 0x1000, 0xbff},
3469         {d68000_move_16      , 0xf000, 0x3000, 0xfff},
3470         {d68000_move_32      , 0xf000, 0x2000, 0xfff},
3471         {d68000_movea_16     , 0xf1c0, 0x3040, 0xfff},
3472         {d68000_movea_32     , 0xf1c0, 0x2040, 0xfff},
3473         {d68000_move_to_ccr  , 0xffc0, 0x44c0, 0xbff},
3474         {d68010_move_fr_ccr  , 0xffc0, 0x42c0, 0xbf8},
3475         {d68000_move_to_sr   , 0xffc0, 0x46c0, 0xbff},
3476         {d68000_move_fr_sr   , 0xffc0, 0x40c0, 0xbf8},
3477         {d68000_move_to_usp  , 0xfff8, 0x4e60, 0x000},
3478         {d68000_move_fr_usp  , 0xfff8, 0x4e68, 0x000},
3479         {d68010_movec        , 0xfffe, 0x4e7a, 0x000},
3480         {d68000_movem_pd_16  , 0xfff8, 0x48a0, 0x000},
3481         {d68000_movem_pd_32  , 0xfff8, 0x48e0, 0x000},
3482         {d68000_movem_re_16  , 0xffc0, 0x4880, 0x2f8},
3483         {d68000_movem_re_32  , 0xffc0, 0x48c0, 0x2f8},
3484         {d68000_movem_er_16  , 0xffc0, 0x4c80, 0x37b},
3485         {d68000_movem_er_32  , 0xffc0, 0x4cc0, 0x37b},
3486         {d68000_movep_er_16  , 0xf1f8, 0x0108, 0x000},
3487         {d68000_movep_er_32  , 0xf1f8, 0x0148, 0x000},
3488         {d68000_movep_re_16  , 0xf1f8, 0x0188, 0x000},
3489         {d68000_movep_re_32  , 0xf1f8, 0x01c8, 0x000},
3490         {d68010_moves_8      , 0xffc0, 0x0e00, 0x3f8},
3491         {d68010_moves_16     , 0xffc0, 0x0e40, 0x3f8},
3492         {d68010_moves_32     , 0xffc0, 0x0e80, 0x3f8},
3493         {d68000_moveq        , 0xf100, 0x7000, 0x000},
3494         {d68040_move16_pi_pi , 0xfff8, 0xf620, 0x000},
3495         {d68040_move16_pi_al , 0xfff8, 0xf600, 0x000},
3496         {d68040_move16_al_pi , 0xfff8, 0xf608, 0x000},
3497         {d68040_move16_ai_al , 0xfff8, 0xf610, 0x000},
3498         {d68040_move16_al_ai , 0xfff8, 0xf618, 0x000},
3499         {d68000_muls         , 0xf1c0, 0xc1c0, 0xbff},
3500         {d68000_mulu         , 0xf1c0, 0xc0c0, 0xbff},
3501         {d68020_mull         , 0xffc0, 0x4c00, 0xbff},
3502         {d68000_nbcd         , 0xffc0, 0x4800, 0xbf8},
3503         {d68000_neg_8        , 0xffc0, 0x4400, 0xbf8},
3504         {d68000_neg_16       , 0xffc0, 0x4440, 0xbf8},
3505         {d68000_neg_32       , 0xffc0, 0x4480, 0xbf8},
3506         {d68000_negx_8       , 0xffc0, 0x4000, 0xbf8},
3507         {d68000_negx_16      , 0xffc0, 0x4040, 0xbf8},
3508         {d68000_negx_32      , 0xffc0, 0x4080, 0xbf8},
3509         {d68000_nop          , 0xffff, 0x4e71, 0x000},
3510         {d68000_not_8        , 0xffc0, 0x4600, 0xbf8},
3511         {d68000_not_16       , 0xffc0, 0x4640, 0xbf8},
3512         {d68000_not_32       , 0xffc0, 0x4680, 0xbf8},
3513         {d68000_or_er_8      , 0xf1c0, 0x8000, 0xbff},
3514         {d68000_or_er_16     , 0xf1c0, 0x8040, 0xbff},
3515         {d68000_or_er_32     , 0xf1c0, 0x8080, 0xbff},
3516         {d68000_or_re_8      , 0xf1c0, 0x8100, 0x3f8},
3517         {d68000_or_re_16     , 0xf1c0, 0x8140, 0x3f8},
3518         {d68000_or_re_32     , 0xf1c0, 0x8180, 0x3f8},
3519         {d68000_ori_to_ccr   , 0xffff, 0x003c, 0x000},
3520         {d68000_ori_to_sr    , 0xffff, 0x007c, 0x000},
3521         {d68000_ori_8        , 0xffc0, 0x0000, 0xbf8},
3522         {d68000_ori_16       , 0xffc0, 0x0040, 0xbf8},
3523         {d68000_ori_32       , 0xffc0, 0x0080, 0xbf8},
3524         {d68020_pack_rr      , 0xf1f8, 0x8140, 0x000},
3525         {d68020_pack_mm      , 0xf1f8, 0x8148, 0x000},
3526         {d68000_pea          , 0xffc0, 0x4840, 0x27b},
3527         {d68040_pflush       , 0xffe0, 0xf500, 0x000},
3528         {d68000_reset        , 0xffff, 0x4e70, 0x000},
3529         {d68000_ror_s_8      , 0xf1f8, 0xe018, 0x000},
3530         {d68000_ror_s_16     , 0xf1f8, 0xe058, 0x000},
3531         {d68000_ror_s_32     , 0xf1f8, 0xe098, 0x000},
3532         {d68000_ror_r_8      , 0xf1f8, 0xe038, 0x000},
3533         {d68000_ror_r_16     , 0xf1f8, 0xe078, 0x000},
3534         {d68000_ror_r_32     , 0xf1f8, 0xe0b8, 0x000},
3535         {d68000_ror_ea       , 0xffc0, 0xe6c0, 0x3f8},
3536         {d68000_rol_s_8      , 0xf1f8, 0xe118, 0x000},
3537         {d68000_rol_s_16     , 0xf1f8, 0xe158, 0x000},
3538         {d68000_rol_s_32     , 0xf1f8, 0xe198, 0x000},
3539         {d68000_rol_r_8      , 0xf1f8, 0xe138, 0x000},
3540         {d68000_rol_r_16     , 0xf1f8, 0xe178, 0x000},
3541         {d68000_rol_r_32     , 0xf1f8, 0xe1b8, 0x000},
3542         {d68000_rol_ea       , 0xffc0, 0xe7c0, 0x3f8},
3543         {d68000_roxr_s_8     , 0xf1f8, 0xe010, 0x000},
3544         {d68000_roxr_s_16    , 0xf1f8, 0xe050, 0x000},
3545         {d68000_roxr_s_32    , 0xf1f8, 0xe090, 0x000},
3546         {d68000_roxr_r_8     , 0xf1f8, 0xe030, 0x000},
3547         {d68000_roxr_r_16    , 0xf1f8, 0xe070, 0x000},
3548         {d68000_roxr_r_32    , 0xf1f8, 0xe0b0, 0x000},
3549         {d68000_roxr_ea      , 0xffc0, 0xe4c0, 0x3f8},
3550         {d68000_roxl_s_8     , 0xf1f8, 0xe110, 0x000},
3551         {d68000_roxl_s_16    , 0xf1f8, 0xe150, 0x000},
3552         {d68000_roxl_s_32    , 0xf1f8, 0xe190, 0x000},
3553         {d68000_roxl_r_8     , 0xf1f8, 0xe130, 0x000},
3554         {d68000_roxl_r_16    , 0xf1f8, 0xe170, 0x000},
3555         {d68000_roxl_r_32    , 0xf1f8, 0xe1b0, 0x000},
3556         {d68000_roxl_ea      , 0xffc0, 0xe5c0, 0x3f8},
3557         {d68010_rtd          , 0xffff, 0x4e74, 0x000},
3558         {d68000_rte          , 0xffff, 0x4e73, 0x000},
3559         {d68020_rtm          , 0xfff0, 0x06c0, 0x000},
3560         {d68000_rtr          , 0xffff, 0x4e77, 0x000},
3561         {d68000_rts          , 0xffff, 0x4e75, 0x000},
3562         {d68000_sbcd_rr      , 0xf1f8, 0x8100, 0x000},
3563         {d68000_sbcd_mm      , 0xf1f8, 0x8108, 0x000},
3564         {d68000_scc          , 0xf0c0, 0x50c0, 0xbf8},
3565         {d68000_stop         , 0xffff, 0x4e72, 0x000},
3566         {d68000_sub_er_8     , 0xf1c0, 0x9000, 0xbff},
3567         {d68000_sub_er_16    , 0xf1c0, 0x9040, 0xfff},
3568         {d68000_sub_er_32    , 0xf1c0, 0x9080, 0xfff},
3569         {d68000_sub_re_8     , 0xf1c0, 0x9100, 0x3f8},
3570         {d68000_sub_re_16    , 0xf1c0, 0x9140, 0x3f8},
3571         {d68000_sub_re_32    , 0xf1c0, 0x9180, 0x3f8},
3572         {d68000_suba_16      , 0xf1c0, 0x90c0, 0xfff},
3573         {d68000_suba_32      , 0xf1c0, 0x91c0, 0xfff},
3574         {d68000_subi_8       , 0xffc0, 0x0400, 0xbf8},
3575         {d68000_subi_16      , 0xffc0, 0x0440, 0xbf8},
3576         {d68000_subi_32      , 0xffc0, 0x0480, 0xbf8},
3577         {d68000_subq_8       , 0xf1c0, 0x5100, 0xbf8},
3578         {d68000_subq_16      , 0xf1c0, 0x5140, 0xff8},
3579         {d68000_subq_32      , 0xf1c0, 0x5180, 0xff8},
3580         {d68000_subx_rr_8    , 0xf1f8, 0x9100, 0x000},
3581         {d68000_subx_rr_16   , 0xf1f8, 0x9140, 0x000},
3582         {d68000_subx_rr_32   , 0xf1f8, 0x9180, 0x000},
3583         {d68000_subx_mm_8    , 0xf1f8, 0x9108, 0x000},
3584         {d68000_subx_mm_16   , 0xf1f8, 0x9148, 0x000},
3585         {d68000_subx_mm_32   , 0xf1f8, 0x9188, 0x000},
3586         {d68000_swap         , 0xfff8, 0x4840, 0x000},
3587         {d68000_tas          , 0xffc0, 0x4ac0, 0xbf8},
3588         {d68000_trap         , 0xfff0, 0x4e40, 0x000},
3589         {d68020_trapcc_0     , 0xf0ff, 0x50fc, 0x000},
3590         {d68020_trapcc_16    , 0xf0ff, 0x50fa, 0x000},
3591         {d68020_trapcc_32    , 0xf0ff, 0x50fb, 0x000},
3592         {d68000_trapv        , 0xffff, 0x4e76, 0x000},
3593         {d68000_tst_8        , 0xffc0, 0x4a00, 0xbf8},
3594         {d68020_tst_pcdi_8   , 0xffff, 0x4a3a, 0x000},
3595         {d68020_tst_pcix_8   , 0xffff, 0x4a3b, 0x000},
3596         {d68020_tst_i_8      , 0xffff, 0x4a3c, 0x000},
3597         {d68000_tst_16       , 0xffc0, 0x4a40, 0xbf8},
3598         {d68020_tst_a_16     , 0xfff8, 0x4a48, 0x000},
3599         {d68020_tst_pcdi_16  , 0xffff, 0x4a7a, 0x000},
3600         {d68020_tst_pcix_16  , 0xffff, 0x4a7b, 0x000},
3601         {d68020_tst_i_16     , 0xffff, 0x4a7c, 0x000},
3602         {d68000_tst_32       , 0xffc0, 0x4a80, 0xbf8},
3603         {d68020_tst_a_32     , 0xfff8, 0x4a88, 0x000},
3604         {d68020_tst_pcdi_32  , 0xffff, 0x4aba, 0x000},
3605         {d68020_tst_pcix_32  , 0xffff, 0x4abb, 0x000},
3606         {d68020_tst_i_32     , 0xffff, 0x4abc, 0x000},
3607         {d68000_unlk         , 0xfff8, 0x4e58, 0x000},
3608         {d68020_unpk_rr      , 0xf1f8, 0x8180, 0x000},
3609         {d68020_unpk_mm      , 0xf1f8, 0x8188, 0x000},
3610         {d68851_p000         , 0xffc0, 0xf000, 0x000},
3611         {d68851_pbcc16       , 0xffc0, 0xf080, 0x000},
3612         {d68851_pbcc32       , 0xffc0, 0xf0c0, 0x000},
3613         {d68851_pdbcc        , 0xfff8, 0xf048, 0x000},
3614         {d68851_p001         , 0xffc0, 0xf040, 0x000},
3615         {0, 0, 0, 0}
3616 };
3617
3618 /* Check if opcode is using a valid ea mode */
3619 static int valid_ea(uint opcode, uint mask)
3620 {
3621         if(mask == 0)
3622                 return 1;
3623
3624         switch(opcode & 0x3f)
3625         {
3626                 case 0x00: case 0x01: case 0x02: case 0x03:
3627                 case 0x04: case 0x05: case 0x06: case 0x07:
3628                         return (mask & 0x800) != 0;
3629                 case 0x08: case 0x09: case 0x0a: case 0x0b:
3630                 case 0x0c: case 0x0d: case 0x0e: case 0x0f:
3631                         return (mask & 0x400) != 0;
3632                 case 0x10: case 0x11: case 0x12: case 0x13:
3633                 case 0x14: case 0x15: case 0x16: case 0x17:
3634                         return (mask & 0x200) != 0;
3635                 case 0x18: case 0x19: case 0x1a: case 0x1b:
3636                 case 0x1c: case 0x1d: case 0x1e: case 0x1f:
3637                         return (mask & 0x100) != 0;
3638                 case 0x20: case 0x21: case 0x22: case 0x23:
3639                 case 0x24: case 0x25: case 0x26: case 0x27:
3640                         return (mask & 0x080) != 0;
3641                 case 0x28: case 0x29: case 0x2a: case 0x2b:
3642                 case 0x2c: case 0x2d: case 0x2e: case 0x2f:
3643                         return (mask & 0x040) != 0;
3644                 case 0x30: case 0x31: case 0x32: case 0x33:
3645                 case 0x34: case 0x35: case 0x36: case 0x37:
3646                         return (mask & 0x020) != 0;
3647                 case 0x38:
3648                         return (mask & 0x010) != 0;
3649                 case 0x39:
3650                         return (mask & 0x008) != 0;
3651                 case 0x3a:
3652                         return (mask & 0x002) != 0;
3653                 case 0x3b:
3654                         return (mask & 0x001) != 0;
3655                 case 0x3c:
3656                         return (mask & 0x004) != 0;
3657         }
3658         return 0;
3659
3660 }
3661
3662 /* Used by qsort */
3663 static int DECL_SPEC compare_nof_true_bits(const void *aptr, const void *bptr)
3664 {
3665         uint a = ((const opcode_struct*)aptr)->mask;
3666         uint b = ((const opcode_struct*)bptr)->mask;
3667
3668         a = ((a & 0xAAAA) >> 1) + (a & 0x5555);
3669         a = ((a & 0xCCCC) >> 2) + (a & 0x3333);
3670         a = ((a & 0xF0F0) >> 4) + (a & 0x0F0F);
3671         a = ((a & 0xFF00) >> 8) + (a & 0x00FF);
3672
3673         b = ((b & 0xAAAA) >> 1) + (b & 0x5555);
3674         b = ((b & 0xCCCC) >> 2) + (b & 0x3333);
3675         b = ((b & 0xF0F0) >> 4) + (b & 0x0F0F);
3676         b = ((b & 0xFF00) >> 8) + (b & 0x00FF);
3677
3678         return b - a; /* reversed to get greatest to least sorting */
3679 }
3680
3681 /* build the opcode handler jump table */
3682 static void build_opcode_table(void)
3683 {
3684         uint i;
3685         uint opcode;
3686         opcode_struct* ostruct;
3687         opcode_struct opcode_info[ARRAY_LENGTH(g_opcode_info)];
3688
3689         memcpy(opcode_info, g_opcode_info, sizeof(g_opcode_info));
3690         qsort((void *)opcode_info, ARRAY_LENGTH(opcode_info)-1, sizeof(opcode_info[0]), compare_nof_true_bits);
3691
3692         for(i=0;i<0x10000;i++)
3693         {
3694                 g_instruction_table[i] = d68000_illegal; /* default to illegal */
3695                 opcode = i;
3696                 /* search through opcode info for a match */
3697                 for(ostruct = opcode_info;ostruct->opcode_handler != 0;ostruct++)
3698                 {
3699                         /* match opcode mask and allowed ea modes */
3700                         if((opcode & ostruct->mask) == ostruct->match)
3701                         {
3702                                 /* Handle destination ea for move instructions */
3703                                 if((ostruct->opcode_handler == d68000_move_8 ||
3704                                          ostruct->opcode_handler == d68000_move_16 ||
3705                                          ostruct->opcode_handler == d68000_move_32) &&
3706                                          !valid_ea(((opcode>>9)&7) | ((opcode>>3)&0x38), 0xbf8))
3707                                                 continue;
3708                                 if(valid_ea(opcode, ostruct->ea_mask))
3709                                 {
3710                                         g_instruction_table[i] = ostruct->opcode_handler;
3711                                         break;
3712                                 }
3713                         }
3714                 }
3715         }
3716 }
3717
3718
3719
3720 /* ======================================================================== */
3721 /* ================================= API ================================== */
3722 /* ======================================================================== */
3723
3724 /* Disasemble one instruction at pc and store in str_buff */
3725 unsigned int m68k_disassemble(char* str_buff, unsigned int pc, unsigned int cpu_type)
3726 {
3727         if(!g_initialized)
3728         {
3729                 build_opcode_table();
3730                 g_initialized = 1;
3731         }
3732         switch(cpu_type)
3733         {
3734                 case M68K_CPU_TYPE_68000:
3735                         g_cpu_type = TYPE_68000;
3736                         g_address_mask = 0x00ffffff;
3737                         break;
3738                 case M68K_CPU_TYPE_68010:
3739                         g_cpu_type = TYPE_68010;
3740                         g_address_mask = 0x00ffffff;
3741                         break;
3742                 case M68K_CPU_TYPE_68EC020:
3743                         g_cpu_type = TYPE_68020;
3744                         g_address_mask = 0x00ffffff;
3745                         break;
3746                 case M68K_CPU_TYPE_68020:
3747                         g_cpu_type = TYPE_68020;
3748                         g_address_mask = 0xffffffff;
3749                         break;
3750                 case M68K_CPU_TYPE_68EC030:
3751                 case M68K_CPU_TYPE_68030:
3752                         g_cpu_type = TYPE_68030;
3753                         g_address_mask = 0xffffffff;
3754                         break;
3755                 case M68K_CPU_TYPE_68040:
3756                 case M68K_CPU_TYPE_68EC040:
3757                 case M68K_CPU_TYPE_68LC040:
3758                         g_cpu_type = TYPE_68040;
3759                         g_address_mask = 0xffffffff;
3760                         break;
3761                 default:
3762                         return 0;
3763         }
3764
3765         g_cpu_pc = pc;
3766         g_helper_str[0] = 0;
3767         g_cpu_ir = read_imm_16();
3768         g_opcode_type = 0;
3769         g_instruction_table[g_cpu_ir]();
3770         sprintf(str_buff, "%s%s", g_dasm_str, g_helper_str);
3771         return COMBINE_OPCODE_FLAGS(g_cpu_pc - pc);
3772 }
3773
3774 char* m68ki_disassemble_quick(unsigned int pc, unsigned int cpu_type)
3775 {
3776         static char buff[1000];
3777         buff[0] = 0;
3778         m68k_disassemble(buff, pc, cpu_type);
3779         return buff;
3780 }
3781
3782 unsigned int m68k_disassemble_raw(char* str_buff, unsigned int pc, const unsigned char* opdata, const unsigned char* argdata, unsigned int cpu_type)
3783 {
3784         unsigned int result;
3785         (void)argdata;
3786
3787         g_rawop = opdata;
3788         g_rawbasepc = pc;
3789         result = m68k_disassemble(str_buff, pc, cpu_type);
3790         g_rawop = NULL;
3791         return result;
3792 }
3793
3794 /* Check if the instruction is a valid one */
3795 unsigned int m68k_is_valid_instruction(unsigned int instruction, unsigned int cpu_type)
3796 {
3797         if(!g_initialized)
3798         {
3799                 build_opcode_table();
3800                 g_initialized = 1;
3801         }
3802
3803         instruction &= 0xffff;
3804         if(g_instruction_table[instruction] == d68000_illegal)
3805                 return 0;
3806
3807         switch(cpu_type)
3808         {
3809                 case M68K_CPU_TYPE_68000:
3810                         if(g_instruction_table[instruction] == d68010_bkpt)
3811                                 return 0;
3812                         if(g_instruction_table[instruction] == d68010_move_fr_ccr)
3813                                 return 0;
3814                         if(g_instruction_table[instruction] == d68010_movec)
3815                                 return 0;
3816                         if(g_instruction_table[instruction] == d68010_moves_8)
3817                                 return 0;
3818                         if(g_instruction_table[instruction] == d68010_moves_16)
3819                                 return 0;
3820                         if(g_instruction_table[instruction] == d68010_moves_32)
3821                                 return 0;
3822                         if(g_instruction_table[instruction] == d68010_rtd)
3823                                 return 0;
3824                         // Fallthrough
3825                 case M68K_CPU_TYPE_68010:
3826                         if(g_instruction_table[instruction] == d68020_bcc_32)
3827                                 return 0;
3828                         if(g_instruction_table[instruction] == d68020_bfchg)
3829                                 return 0;
3830                         if(g_instruction_table[instruction] == d68020_bfclr)
3831                                 return 0;
3832                         if(g_instruction_table[instruction] == d68020_bfexts)
3833                                 return 0;
3834                         if(g_instruction_table[instruction] == d68020_bfextu)
3835                                 return 0;
3836                         if(g_instruction_table[instruction] == d68020_bfffo)
3837                                 return 0;
3838                         if(g_instruction_table[instruction] == d68020_bfins)
3839                                 return 0;
3840                         if(g_instruction_table[instruction] == d68020_bfset)
3841                                 return 0;
3842                         if(g_instruction_table[instruction] == d68020_bftst)
3843                                 return 0;
3844                         if(g_instruction_table[instruction] == d68020_bra_32)
3845                                 return 0;
3846                         if(g_instruction_table[instruction] == d68020_bsr_32)
3847                                 return 0;
3848                         if(g_instruction_table[instruction] == d68020_callm)
3849                                 return 0;
3850                         if(g_instruction_table[instruction] == d68020_cas_8)
3851                                 return 0;
3852                         if(g_instruction_table[instruction] == d68020_cas_16)
3853                                 return 0;
3854                         if(g_instruction_table[instruction] == d68020_cas_32)
3855                                 return 0;
3856                         if(g_instruction_table[instruction] == d68020_cas2_16)
3857                                 return 0;
3858                         if(g_instruction_table[instruction] == d68020_cas2_32)
3859                                 return 0;
3860                         if(g_instruction_table[instruction] == d68020_chk_32)
3861                                 return 0;
3862                         if(g_instruction_table[instruction] == d68020_chk2_cmp2_8)
3863                                 return 0;
3864                         if(g_instruction_table[instruction] == d68020_chk2_cmp2_16)
3865                                 return 0;
3866                         if(g_instruction_table[instruction] == d68020_chk2_cmp2_32)
3867                                 return 0;
3868                         if(g_instruction_table[instruction] == d68020_cmpi_pcdi_8)
3869                                 return 0;
3870                         if(g_instruction_table[instruction] == d68020_cmpi_pcix_8)
3871                                 return 0;
3872                         if(g_instruction_table[instruction] == d68020_cmpi_pcdi_16)
3873                                 return 0;
3874                         if(g_instruction_table[instruction] == d68020_cmpi_pcix_16)
3875                                 return 0;
3876                         if(g_instruction_table[instruction] == d68020_cmpi_pcdi_32)
3877                                 return 0;
3878                         if(g_instruction_table[instruction] == d68020_cmpi_pcix_32)
3879                                 return 0;
3880                         if(g_instruction_table[instruction] == d68020_cpbcc_16)
3881                                 return 0;
3882                         if(g_instruction_table[instruction] == d68020_cpbcc_32)
3883                                 return 0;
3884                         if(g_instruction_table[instruction] == d68020_cpdbcc)
3885                                 return 0;
3886                         if(g_instruction_table[instruction] == d68020_cpgen)
3887                                 return 0;
3888                         if(g_instruction_table[instruction] == d68020_cprestore)
3889                                 return 0;
3890                         if(g_instruction_table[instruction] == d68020_cpsave)
3891                                 return 0;
3892                         if(g_instruction_table[instruction] == d68020_cpscc)
3893                                 return 0;
3894                         if(g_instruction_table[instruction] == d68020_cptrapcc_0)
3895                                 return 0;
3896                         if(g_instruction_table[instruction] == d68020_cptrapcc_16)
3897                                 return 0;
3898                         if(g_instruction_table[instruction] == d68020_cptrapcc_32)
3899                                 return 0;
3900                         if(g_instruction_table[instruction] == d68020_divl)
3901                                 return 0;
3902                         if(g_instruction_table[instruction] == d68020_extb_32)
3903                                 return 0;
3904                         if(g_instruction_table[instruction] == d68020_link_32)
3905                                 return 0;
3906                         if(g_instruction_table[instruction] == d68020_mull)
3907                                 return 0;
3908                         if(g_instruction_table[instruction] == d68020_pack_rr)
3909                                 return 0;
3910                         if(g_instruction_table[instruction] == d68020_pack_mm)
3911                                 return 0;
3912                         if(g_instruction_table[instruction] == d68020_rtm)
3913                                 return 0;
3914                         if(g_instruction_table[instruction] == d68020_trapcc_0)
3915                                 return 0;
3916                         if(g_instruction_table[instruction] == d68020_trapcc_16)
3917                                 return 0;
3918                         if(g_instruction_table[instruction] == d68020_trapcc_32)
3919                                 return 0;
3920                         if(g_instruction_table[instruction] == d68020_tst_pcdi_8)
3921                                 return 0;
3922                         if(g_instruction_table[instruction] == d68020_tst_pcix_8)
3923                                 return 0;
3924                         if(g_instruction_table[instruction] == d68020_tst_i_8)
3925                                 return 0;
3926                         if(g_instruction_table[instruction] == d68020_tst_a_16)
3927                                 return 0;
3928                         if(g_instruction_table[instruction] == d68020_tst_pcdi_16)
3929                                 return 0;
3930                         if(g_instruction_table[instruction] == d68020_tst_pcix_16)
3931                                 return 0;
3932                         if(g_instruction_table[instruction] == d68020_tst_i_16)
3933                                 return 0;
3934                         if(g_instruction_table[instruction] == d68020_tst_a_32)
3935                                 return 0;
3936                         if(g_instruction_table[instruction] == d68020_tst_pcdi_32)
3937                                 return 0;
3938                         if(g_instruction_table[instruction] == d68020_tst_pcix_32)
3939                                 return 0;
3940                         if(g_instruction_table[instruction] == d68020_tst_i_32)
3941                                 return 0;
3942                         if(g_instruction_table[instruction] == d68020_unpk_rr)
3943                                 return 0;
3944                         if(g_instruction_table[instruction] == d68020_unpk_mm)
3945                                 return 0;
3946                         // Fallthrough
3947                 case M68K_CPU_TYPE_68EC020:
3948                 case M68K_CPU_TYPE_68020:
3949                 case M68K_CPU_TYPE_68030:
3950                 case M68K_CPU_TYPE_68EC030:
3951                         if(g_instruction_table[instruction] == d68040_cinv)
3952                                 return 0;
3953                         if(g_instruction_table[instruction] == d68040_cpush)
3954                                 return 0;
3955                         if(g_instruction_table[instruction] == d68040_move16_pi_pi)
3956                                 return 0;
3957                         if(g_instruction_table[instruction] == d68040_move16_pi_al)
3958                                 return 0;
3959                         if(g_instruction_table[instruction] == d68040_move16_al_pi)
3960                                 return 0;
3961                         if(g_instruction_table[instruction] == d68040_move16_ai_al)
3962                                 return 0;
3963                         if(g_instruction_table[instruction] == d68040_move16_al_ai)
3964                                 return 0;
3965                         // Fallthrough
3966                 case M68K_CPU_TYPE_68040:
3967                 case M68K_CPU_TYPE_68EC040:
3968                 case M68K_CPU_TYPE_68LC040:
3969                         if(g_instruction_table[instruction] == d68020_cpbcc_16)
3970                                 return 0;
3971                         if(g_instruction_table[instruction] == d68020_cpbcc_32)
3972                                 return 0;
3973                         if(g_instruction_table[instruction] == d68020_cpdbcc)
3974                                 return 0;
3975                         if(g_instruction_table[instruction] == d68020_cpgen)
3976                                 return 0;
3977                         if(g_instruction_table[instruction] == d68020_cprestore)
3978                                 return 0;
3979                         if(g_instruction_table[instruction] == d68020_cpsave)
3980                                 return 0;
3981                         if(g_instruction_table[instruction] == d68020_cpscc)
3982                                 return 0;
3983                         if(g_instruction_table[instruction] == d68020_cptrapcc_0)
3984                                 return 0;
3985                         if(g_instruction_table[instruction] == d68020_cptrapcc_16)
3986                                 return 0;
3987                         if(g_instruction_table[instruction] == d68020_cptrapcc_32)
3988                                 return 0;
3989                         if(g_instruction_table[instruction] == d68040_pflush)
3990                                 return 0;
3991         }
3992         if(cpu_type != M68K_CPU_TYPE_68020 && cpu_type != M68K_CPU_TYPE_68EC020 &&
3993           (g_instruction_table[instruction] == d68020_callm ||
3994           g_instruction_table[instruction] == d68020_rtm))
3995                 return 0;
3996
3997         return 1;
3998 }
3999
4000 // f028 2215 0008
4001
4002 /* ======================================================================== */
4003 /* ============================== END OF FILE ============================= */
4004 /* ======================================================================== */