summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/m68000/m68kdasm.h
blob: 43dfd1449807fdb803a19c1bb2f6cdd88edc4c06 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
// license:BSD-3-Clause
// copyright-holders:Karl Stenerud
/* ======================================================================== */
/* ========================= LICENSING & COPYRIGHT ======================== */
/* ======================================================================== */
/*
 *                                  MUSASHI
 *                                Version 3.32
 *
 * A portable Motorola M680x0 processor emulation engine.
 * Copyright Karl Stenerud.  All rights reserved.
 *
 */

#ifndef MAME_CPU_M68000_M68KDASM_H
#define MAME_CPU_M68000_M68KDASM_H

#pragma once

class m68k_disassembler : public util::disasm_interface
{
public:
	enum {
		TYPE_68000 = 1,
		TYPE_68008 = 2,
		TYPE_68010 = 4,
		TYPE_68020 = 8,
		TYPE_68030 = 16,
		TYPE_68040 = 32,
		TYPE_68340 = 64,   // (CPU32)
		TYPE_COLDFIRE = 128,
	};

	m68k_disassembler(u32 type);
	virtual ~m68k_disassembler() = default;

	virtual u32 opcode_alignment() const override;
	virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params) override;

protected:
	enum {
		M68000_ONLY = (TYPE_68000 | TYPE_68008),
		M68010_ONLY = TYPE_68010,
		M68010_LESS = (TYPE_68000 | TYPE_68008 | TYPE_68010),
		M68010_PLUS = (TYPE_68010 | TYPE_68020 | TYPE_68030 | TYPE_68040 | TYPE_68340 | TYPE_COLDFIRE),
		M68020_ONLY = (TYPE_68020 | TYPE_68340),
		M68020_LESS = (TYPE_68010 | TYPE_68020 | TYPE_68340),
		M68020_PLUS = (TYPE_68020 | TYPE_68030 | TYPE_68040 | TYPE_68340 | TYPE_COLDFIRE),

		M68030_ONLY = TYPE_68030,
		M68030_LESS = (TYPE_68010 | TYPE_68020 | TYPE_68030 | TYPE_68340 ),
		M68030_PLUS = (TYPE_68030 | TYPE_68040),
		M68040_PLUS = TYPE_68040,

		COLDFIRE    = TYPE_COLDFIRE
	};

	typedef std::string (m68k_disassembler::*opcode_handler)();

	struct opcode_struct {
		opcode_handler handler; /* handler function */
		u32 mask;               /* mask on opcode */
		u32 match;              /* what to match after masking */
		u32 ea_mask;            /* what ea modes are allowed */
	};

	/* Extension word formats */
	static inline u32 ext_8bit_displacement(u32 A)          { return ((A)&0xff); }
	static inline u32 ext_full(u32 A)                       { return BIT(A, 8); }
	static inline u32 ext_effective_zero(u32 A)             { return (((A)&0xe4) == 0xc4 || ((A)&0xe2) == 0xc0); }
	static inline u32 ext_base_register_present(u32 A)      { return (!BIT(A, 7)); }
	static inline u32 ext_index_register_present(u32 A)     { return (!BIT(A, 6)); }
	static inline u32 ext_index_register(u32 A)             { return (((A)>>12)&7); }
	static inline u32 ext_index_scale(u32 A)                { return (((A)>>9)&3); }
	static inline u32 ext_index_long(u32 A)                 { return BIT(A, 11); }
	static inline u32 ext_index_ar(u32 A)                   { return BIT(A, 15); }
	static inline u32 ext_base_displacement_present(u32 A)  { return (((A)&0x30) > 0x10); }
	static inline u32 ext_base_displacement_word(u32 A)     { return (((A)&0x30) == 0x20); }
	static inline u32 ext_base_displacement_long(u32 A)     { return (((A)&0x30) == 0x30); }
	static inline u32 ext_outer_displacement_present(u32 A) { return (((A)&3) > 1 && ((A)&0x47) < 0x44); }
	static inline u32 ext_outer_displacement_word(u32 A)    { return (((A)&3) == 2 && ((A)&0x47) < 0x44); }
	static inline u32 ext_outer_displacement_long(u32 A)    { return (((A)&3) == 3 && ((A)&0x47) < 0x44); }

	static inline s32 sext_7bit_int(u32 value) { return (value & 0x40) ? (value | 0xffffff80) : (value & 0x7f); }
	static inline s32 make_int_8(u8 value) { return s8(value); }
	static inline s32 make_int_16(u16 value) { return s16(value); }
	static inline s32 make_int_32(u32 value) { return s32(value); }

	static std::string make_signed_hex_str_8(u8 val);
	static std::string make_signed_hex_str_16(u16 val);
	static std::string make_signed_hex_str_32(u32 val);

	inline u32 read_imm_8 (u32 advance) { u32 result = m_buffer->r8 (m_cpu_pc + 1); m_cpu_pc += advance; return result; }
	inline u32 read_imm_16(u32 advance) { u32 result = m_buffer->r16(m_cpu_pc);     m_cpu_pc += advance; return result; }
	inline u32 read_imm_32(u32 advance) { u32 result = m_buffer->r32(m_cpu_pc);     m_cpu_pc += advance; return result; }

	inline u32 read_imm_8 () { return read_imm_8 (2); } // 2 to keep alignement
	inline u32 read_imm_16() { return read_imm_16(2); }
	inline u32 read_imm_32() { return read_imm_32(4); }

	inline u32 peek_imm_8 () { return read_imm_8 (0); }
	inline u32 peek_imm_16() { return read_imm_16(0); }
	inline u32 peek_imm_32() { return read_imm_32(0); }

	std::string get_imm_str_s(u32 size);
	inline std::string get_imm_str_s8 () { return get_imm_str_s(0); }
	inline std::string get_imm_str_s16() { return get_imm_str_s(1); }
	inline std::string get_imm_str_s32() { return get_imm_str_s(2); }

	std::string get_imm_str_u(u32 size);
	inline std::string get_imm_str_u8 () { return get_imm_str_u(0); }
	inline std::string get_imm_str_u16() { return get_imm_str_u(1); }
	inline std::string get_imm_str_u32() { return get_imm_str_u(2); }

	std::string get_ea_mode_str(u16 instruction, u32 size);
	inline std::string get_ea_mode_str_8 (u16 instruction) { return get_ea_mode_str(instruction, 0); }
	inline std::string get_ea_mode_str_16(u16 instruction) { return get_ea_mode_str(instruction, 1); }
	inline std::string get_ea_mode_str_32(u16 instruction) { return get_ea_mode_str(instruction, 2); }

	inline std::pair<bool, std::string> limit_cpu_types(u32 allowed);

	std::string d68000_illegal();
	std::string d68000_1010();
	std::string d68000_1111();
	std::string d68000_abcd_rr();
	std::string d68000_abcd_mm();
	std::string d68000_add_er_8();
	std::string d68000_add_er_16();
	std::string d68000_add_er_32();
	std::string d68000_add_re_8();
	std::string d68000_add_re_16();
	std::string d68000_add_re_32();
	std::string d68000_adda_16();
	std::string d68000_adda_32();
	std::string d68000_addi_8();
	std::string d68000_addi_16();
	std::string d68000_addi_32();
	std::string d68000_addq_8();
	std::string d68000_addq_16();
	std::string d68000_addq_32();
	std::string d68000_addx_rr_8();
	std::string d68000_addx_rr_16();
	std::string d68000_addx_rr_32();
	std::string d68000_addx_mm_8();
	std::string d68000_addx_mm_16();
	std::string d68000_addx_mm_32();
	std::string d68000_and_er_8();
	std::string d68000_and_er_16();
	std::string d68000_and_er_32();
	std::string d68000_and_re_8();
	std::string d68000_and_re_16();
	std::string d68000_and_re_32();
	std::string d68000_andi_8();
	std::string d68000_andi_16();
	std::string d68000_andi_32();
	std::string d68000_andi_to_ccr();
	std::string d68000_andi_to_sr();
	std::string d68000_asr_s_8();
	std::string d68000_asr_s_16();
	std::string d68000_asr_s_32();
	std::string d68000_asr_r_8();
	std::string d68000_asr_r_16();
	std::string d68000_asr_r_32();
	std::string d68000_asr_ea();
	std::string d68000_asl_s_8();
	std::string d68000_asl_s_16();
	std::string d68000_asl_s_32();
	std::string d68000_asl_r_8();
	std::string d68000_asl_r_16();
	std::string d68000_asl_r_32();
	std::string d68000_asl_ea();
	std::string d68000_bcc_8();
	std::string d68000_bcc_16();
	std::string d68020_bcc_32();
	std::string d68000_bchg_r();
	std::string d68000_bchg_s();
	std::string d68000_bclr_r();
	std::string d68000_bclr_s();
	std::string d68010_bkpt();
	std::string d68020_bfchg();
	std::string d68020_bfclr();
	std::string d68020_bfexts();
	std::string d68020_bfextu();
	std::string d68020_bfffo();
	std::string d68020_bfins();
	std::string d68020_bfset();
	std::string d68020_bftst();
	std::string d68000_bra_8();
	std::string d68000_bra_16();
	std::string d68020_bra_32();
	std::string d68000_bset_r();
	std::string d68000_bset_s();
	std::string d68000_bsr_8();
	std::string d68000_bsr_16();
	std::string d68020_bsr_32();
	std::string d68000_btst_r();
	std::string d68000_btst_s();
	std::string d68020_callm();
	std::string d68020_cas_8();
	std::string d68020_cas_16();
	std::string d68020_cas_32();
	std::string d68020_cas2_16();
	std::string d68020_cas2_32();
	std::string d68000_chk_16();
	std::string d68020_chk_32();
	std::string d68020_chk2_cmp2_8();
	std::string d68020_chk2_cmp2_16();
	std::string d68020_chk2_cmp2_32();
	std::string d68040_cinv();
	std::string d68000_clr_8();
	std::string d68000_clr_16();
	std::string d68000_clr_32();
	std::string d68000_cmp_8();
	std::string d68000_cmp_16();
	std::string d68000_cmp_32();
	std::string d68000_cmpa_16();
	std::string d68000_cmpa_32();
	std::string d68000_cmpi_8();
	std::string d68020_cmpi_pcdi_8();
	std::string d68020_cmpi_pcix_8();
	std::string d68000_cmpi_16();
	std::string d68020_cmpi_pcdi_16();
	std::string d68020_cmpi_pcix_16();
	std::string d68000_cmpi_32();
	std::string d68020_cmpi_pcdi_32();
	std::string d68020_cmpi_pcix_32();
	std::string d68000_cmpm_8();
	std::string d68000_cmpm_16();
	std::string d68000_cmpm_32();
	std::string d68020_cpbcc_16();
	std::string d68020_cpbcc_32();
	std::string d68020_cpdbcc();
	std::string d68020_cpgen();
	std::string d68020_cprestore();
	std::string d68020_cpsave();
	std::string d68020_cpscc();
	std::string d68020_cptrapcc_0();
	std::string d68020_cptrapcc_16();
	std::string d68020_cptrapcc_32();
	std::string d68040_cpush();
	std::string d68000_dbra();
	std::string d68000_dbcc();
	std::string d68000_divs();
	std::string d68000_divu();
	std::string d68020_divl();
	std::string d68000_eor_8();
	std::string d68000_eor_16();
	std::string d68000_eor_32();
	std::string d68000_eori_8();
	std::string d68000_eori_16();
	std::string d68000_eori_32();
	std::string d68000_eori_to_ccr();
	std::string d68000_eori_to_sr();
	std::string d68000_exg_dd();
	std::string d68000_exg_aa();
	std::string d68000_exg_da();
	std::string d68000_ext_16();
	std::string d68000_ext_32();
	std::string d68020_extb_32();
	std::string d68881_ftrap();
	std::string d68040_fpu();
	std::string d68000_jmp();
	std::string d68000_jsr();
	std::string d68000_lea();
	std::string d68000_link_16();
	std::string d68020_link_32();
	std::string d68000_lsr_s_8();
	std::string d68000_lsr_s_16();
	std::string d68000_lsr_s_32();
	std::string d68000_lsr_r_8();
	std::string d68000_lsr_r_16();
	std::string d68000_lsr_r_32();
	std::string d68000_lsr_ea();
	std::string d68000_lsl_s_8();
	std::string d68000_lsl_s_16();
	std::string d68000_lsl_s_32();
	std::string d68000_lsl_r_8();
	std::string d68000_lsl_r_16();
	std::string d68000_lsl_r_32();
	std::string d68000_lsl_ea();
	std::string d68000_move_8();
	std::string d68000_move_16();
	std::string d68000_move_32();
	std::string d68000_movea_16();
	std::string d68000_movea_32();
	std::string d68000_move_to_ccr();
	std::string d68010_move_fr_ccr();
	std::string d68000_move_fr_sr();
	std::string d68000_move_to_sr();
	std::string d68000_move_fr_usp();
	std::string d68000_move_to_usp();
	std::string d68010_movec();
	std::string d68000_movem_pd_16();
	std::string d68000_movem_pd_32();
	std::string d68000_movem_er_16();
	std::string d68000_movem_er_32();
	std::string d68000_movem_re_16();
	std::string d68000_movem_re_32();
	std::string d68000_movep_re_16();
	std::string d68000_movep_re_32();
	std::string d68000_movep_er_16();
	std::string d68000_movep_er_32();
	std::string d68010_moves_8();
	std::string d68010_moves_16();
	std::string d68010_moves_32();
	std::string d68000_moveq();
	std::string d68040_move16_pi_pi();
	std::string d68040_move16_pi_al();
	std::string d68040_move16_al_pi();
	std::string d68040_move16_ai_al();
	std::string d68040_move16_al_ai();
	std::string d68000_muls();
	std::string d68000_mulu();
	std::string d68020_mull();
	std::string d68000_nbcd();
	std::string d68000_neg_8();
	std::string d68000_neg_16();
	std::string d68000_neg_32();
	std::string d68000_negx_8();
	std::string d68000_negx_16();
	std::string d68000_negx_32();
	std::string d68000_nop();
	std::string d68000_not_8();
	std::string d68000_not_16();
	std::string d68000_not_32();
	std::string d68000_or_er_8();
	std::string d68000_or_er_16();
	std::string d68000_or_er_32();
	std::string d68000_or_re_8();
	std::string d68000_or_re_16();
	std::string d68000_or_re_32();
	std::string d68000_ori_8();
	std::string d68000_ori_16();
	std::string d68000_ori_32();
	std::string d68000_ori_to_ccr();
	std::string d68000_ori_to_sr();
	std::string d68020_pack_rr();
	std::string d68020_pack_mm();
	std::string d68000_pea();
	std::string d68040_pflush();
	std::string d68000_reset();
	std::string d68000_ror_s_8();
	std::string d68000_ror_s_16();
	std::string d68000_ror_s_32();
	std::string d68000_ror_r_8();
	std::string d68000_ror_r_16();
	std::string d68000_ror_r_32();
	std::string d68000_ror_ea();
	std::string d68000_rol_s_8();
	std::string d68000_rol_s_16();
	std::string d68000_rol_s_32();
	std::string d68000_rol_r_8();
	std::string d68000_rol_r_16();
	std::string d68000_rol_r_32();
	std::string d68000_rol_ea();
	std::string d68000_roxr_s_8();
	std::string d68000_roxr_s_16();
	std::string d68000_roxr_s_32();
	std::string d68000_roxr_r_8();
	std::string d68000_roxr_r_16();
	std::string d68000_roxr_r_32();
	std::string d68000_roxr_ea();
	std::string d68000_roxl_s_8();
	std::string d68000_roxl_s_16();
	std::string d68000_roxl_s_32();
	std::string d68000_roxl_r_8();
	std::string d68000_roxl_r_16();
	std::string d68000_roxl_r_32();
	std::string d68000_roxl_ea();
	std::string d68010_rtd();
	std::string d68000_rte();
	std::string d68020_rtm();
	std::string d68000_rtr();
	std::string d68000_rts();
	std::string d68000_sbcd_rr();
	std::string d68000_sbcd_mm();
	std::string d68000_scc();
	std::string d68000_stop();
	std::string d68000_sub_er_8();
	std::string d68000_sub_er_16();
	std::string d68000_sub_er_32();
	std::string d68000_sub_re_8();
	std::string d68000_sub_re_16();
	std::string d68000_sub_re_32();
	std::string d68000_suba_16();
	std::string d68000_suba_32();
	std::string d68000_subi_8();
	std::string d68000_subi_16();
	std::string d68000_subi_32();
	std::string d68000_subq_8();
	std::string d68000_subq_16();
	std::string d68000_subq_32();
	std::string d68000_subx_rr_8();
	std::string d68000_subx_rr_16();
	std::string d68000_subx_rr_32();
	std::string d68000_subx_mm_8();
	std::string d68000_subx_mm_16();
	std::string d68000_subx_mm_32();
	std::string d68000_swap();
	std::string d68000_tas();
	std::string d68000_trap();
	std::string d68020_trapcc_0();
	std::string d68020_trapcc_16();
	std::string d68020_trapcc_32();
	std::string d68000_trapv();
	std::string d68000_tst_8();
	std::string d68020_tst_pcdi_8();
	std::string d68020_tst_pcix_8();
	std::string d68020_tst_i_8();
	std::string d68000_tst_16();
	std::string d68020_tst_a_16();
	std::string d68020_tst_pcdi_16();
	std::string d68020_tst_pcix_16();
	std::string d68020_tst_i_16();
	std::string d68000_tst_32();
	std::string d68020_tst_a_32();
	std::string d68020_tst_pcdi_32();
	std::string d68020_tst_pcix_32();
	std::string d68020_tst_i_32();
	std::string d68000_unlk();
	std::string d68020_unpk_rr();
	std::string d68020_unpk_mm();
	std::string d68851_p000();
	std::string d68851_pbcc16();
	std::string d68851_pbcc32();
	std::string d68851_pdbcc();
	std::string d68851_p001();
	std::string d68040_fbcc_16();
	std::string d68040_fbcc_32();

	static bool valid_ea(u32 opcode, u32 mask);
	static bool compare_nof_true_bits(const opcode_struct *aptr, const opcode_struct *bptr);
	void build_opcode_table();


	/* used by ops like asr, ror, addq, etc */
	static const u32 m_3bit_qdata_table[8];
	static const u32 m_5bit_data_table[32];

	static const char *const m_cc[16];
	static const char *const m_cpcc[64];
	static const char *const m_mmuregs[8];
	static const char *const m_mmucond[16];

	static const opcode_struct m_opcode_info[];
	opcode_handler m_instruction_table[0x10000];

	const data_buffer *m_buffer;
	u32 m_cpu_type, m_cpu_pc, m_flags;
	u16 m_cpu_ir;
};


#endif