1 /// Types and constants of M680x architecture
2 module capstone.m680x;
3 
4 import std.conv: to;
5 import std.typecons: BitFlags;
6 
7 import capstone.api;
8 import capstone.capstone;
9 import capstone.detail;
10 import capstone.instruction;
11 import capstone.instructiongroup;
12 import capstone.internal;
13 import capstone.register;
14 import capstone.utils;
15 
16 /// Architecture-specific Register variant
17 class M680xRegister : RegisterImpl!M680xRegisterId {
18     package this(in Capstone cs, in int id) {
19         super(cs, id);
20     }
21 }
22 
23 /// Architecture-specific InstructionGroup variant
24 class M680xInstructionGroup : InstructionGroupImpl!M680xInstructionGroupId {
25     package this(in Capstone cs, in int id) {
26         super(cs, id);
27     }
28 }
29 
30 /// Architecture-specific Detail variant
31 class M680xDetail : DetailImpl!(M680xRegister, M680xInstructionGroup, M680xInstructionDetail) {
32     package this(in Capstone cs, cs_detail* internal) {
33 		super(cs, internal);
34 	}
35 }
36 
37 /// Architecture-specific instruction variant
38 class M680xInstruction : InstructionImpl!(M680xInstructionId, M680xRegister, M680xDetail) {
39     package this(in Capstone cs, cs_insn* internal) {
40 		super(cs, internal);
41 	}
42 }
43 
44 /// Architecture-specific Capstone variant
45 class CapstoneM680x : CapstoneImpl!(M680xInstructionId, M680xInstruction) {
46     /** Creates an architecture-specific instance with a given mode of interpretation
47     
48     Params:
49         modeFlags = The (initial) mode of interpretation, which can still be changed later on
50     */
51 	this(in ModeFlags modeFlags){
52         super(Arch.m680x, modeFlags);
53     }
54 }
55 
56 /// Instruction's operand referring to indexed addressing
57 struct M680xOpIdx {
58 	M680xRegister baseReg;	  /// Base register (or `M680xRegisterId.invalid` if irrelevant)
59 	M680xRegister offsetReg;  /// Offset register (or `M680xRegisterId.invalid` if irrelevant)
60 	short offset;	  		  /// 5-,8- or 16-bit offset
61 	ushort offsetAddr;		  /// = offset addr. if baseReg.id == M680xRegisterId.pc. Calculated as offset + PC
62 	M680xOffsetBits offsetBits;	/// Offset width in bits for indexed addressing
63 	byte incDec;			  /// Inc. or dec. value: 0: no inc-/decrement, 1 .. 8: increment by 1 .. 8, -1 .. -8: decrement by 1 .. 8.
64 							  /// If flag M680xFlag.postIncDec set it is post inc-/decrement otherwise pre inc-/decrement
65 	BitFlags!M680xFlag flags; /// 8-bit flags (see above)
66 
67 	package this(in Capstone cs, m680x_op_idx internal) {
68 		baseReg = new M680xRegister(cs, internal.base_reg);
69 		offsetReg = new M680xRegister(cs, internal.offset_reg);
70 		offset = internal.offset;
71 		offsetAddr = internal.offset_addr;
72 		offsetBits = internal.offset_bits.to!M680xOffsetBits;
73 		incDec = internal.inc_dec;
74 		flags = cast(M680xFlag)internal.flags;
75 	}
76 }
77 
78 /// Instruction's memory operand referring to relative addressing (Bcc/LBcc)
79 struct M680xOpRel {
80 	ushort address;	/// The absolute address. Calculated as PC + offset. PC is the first address after the instruction.
81 	short offset;	/// The offset/displacement value
82 
83 	package this(m680x_op_rel internal) {
84 		address = internal.address;
85 		offset = internal.offset;
86 	}
87 }
88 
89 /// Instruction's operand referring to extended addressing
90 struct M680xOpExt {
91 	ushort address; /// The absolute address
92 	bool indirect;  /// true if extended indirect addressing
93 
94 	package this(m680x_op_ext internal) {
95 		address = internal.address;
96 		indirect = internal.indirect;
97 	}
98 }
99 
100 /// Union of possible operand types
101 union M680xOpValue{
102 	int imm;			/// Immediate value for IMM operand
103 	M680xRegister reg;	/// Register value for REG operand
104 	M680xOpIdx idx;		/// Indexed addressing operand
105 	M680xOpRel rel;		/// Relative address. operand (Bcc/LBcc)
106 	M680xOpExt ext;		/// Extended address
107 	ubyte directAddr;	/// Direct address (lower 8-bit)
108 	ubyte constVal; 	/// Constant value (bit index, page nr.)
109 }
110 
111 /// Instruction's operand
112 struct M680xOp {
113 	M680xOpType type;             /// Operand type
114     SafeUnion!M680xOpValue value; /// Operand value of type `type`
115     alias value this;             /// Convenient access to value (as in original bindings)
116 
117 	ubyte size; /// Size of this operand (in bytes)
118 	
119 	/** How is this operand accessed? (READ, WRITE or READ|WRITE)
120 
121 	NOTE: This field is irrelevant, i.e. equals 0, if engine is compiled in DIET mode.
122     */
123 	AccessFlags access;
124 
125     package this(in Capstone cs, cs_m680x_op internal) {
126         type = internal.type.to!M680xOpType;
127 		final switch(type) {
128 			case M680xOpType.invalid:
129 				break;
130 			case M680xOpType.register:
131 				value.reg = new M680xRegister(cs, internal.reg);
132 				break;
133 			case M680xOpType.immediate:
134 				value.imm = internal.imm;
135 				break;
136 			case M680xOpType.indexed:
137 				value.idx = M680xOpIdx(cs, internal.idx);
138 				break;
139 			case M680xOpType.extended:
140 				value.ext = M680xOpExt(internal.ext);
141 				break;
142 			case M680xOpType.direct:
143 				value.directAddr = internal.direct_addr;
144 				break;
145 			case M680xOpType.relative:
146 				value.rel = M680xOpRel(internal.rel);
147 				break;
148 			case M680xOpType.constant:
149 				value.constVal = internal.const_val;
150 				break;
151 		}
152 		size = internal.size;
153         access = cast(AccessType)internal.access;
154 	}
155 }
156 
157 /// M680x-specific information about an instruction
158 struct M680xInstructionDetail {
159 	M680xOp[] operands; 				 /// Operands for this instruction
160 	BitFlags!M680xInstructionFlag flags; /// See `M680xInstructionFlag`
161 
162 	package this(in Capstone cs, cs_arch_detail arch_detail){
163         auto internal = arch_detail.m680x;
164         foreach(op; internal.operands[0..internal.op_count])
165             operands ~= M680xOp(cs, op);
166 		flags = cast(M680xInstructionFlag)internal.flags;
167     }
168 }
169 
170 //=============================================================================
171 // Constants
172 //=============================================================================
173 
174 /// Operand type for instruction's operands
175 enum M680xOpType {
176 	invalid = 0, /// Uninitialized
177 	register,    /// Register operand
178 	immediate,   /// Immediate operand
179 	indexed,     /// Indexed addressing operand
180 	extended,    /// Extended addressing operand
181 	direct,      /// Direct addressing operand
182 	relative,    /// Relative addressing operand
183 	constant,    /// Constant operand (Displayed as number only). Used e.g. for a bit index or page number.
184 }
185 
186 /// Supported bit values for `M680xOpIdx.offsetBits`
187 enum M680xOffsetBits {
188 	none = 0,
189 	_5 = 5,
190 	_8 = 8,
191 	_9 = 9,
192 	_16 = 16
193 }
194 
195 /// Supported bit flags for `M680xOpIdx.flags`
196 enum M680xFlag {
197 	indirect = 1,
198 	noComma = 2,
199 	postIncDec = 4
200 }
201 
202 /// M680X instruction flags:
203 enum M680xInstructionFlag {
204 	firstOpInMnem = 1, /// The first (register) operand is part of the instruction mnemonic
205 	secondOpInMnem = 2 /// The second (register) operand is part of the instruction mnemonic
206 }
207 
208 /// M680X registers and special registers
209 enum M680xRegisterId {
210 	invalid = 0,
211 
212 	a, /// M6800/1/2/3/9, HD6301/9
213 	b, /// M6800/1/2/3/9, HD6301/9
214 	e, /// HD6309
215 	f, /// HD6309
216 	_0, /// HD6309
217 
218 	d, /// M6801/3/9, HD6301/9
219 	w, /// HD6309
220 
221 	cc, /// M6800/1/2/3/9, M6301/9
222 	dp, /// M6809/M6309
223 	md, /// M6309
224 
225 	hx, /// M6808
226 	h, /// M6808
227 	x, /// M6800/1/2/3/9, M6301/9
228 	y, /// M6809/M6309
229 	s, /// M6809/M6309
230 	u, /// M6809/M6309
231 	v, /// M6309
232 
233 	q, /// M6309
234 
235 	pc, /// M6800/1/2/3/9, M6301/9
236 
237 	tmp2, /// CPU12
238 	tmp3, /// CPU12
239 }
240 
241 /// M680X instruction IDs
242 enum M680xInstructionId {
243 	invld = 0,
244 	aba, /// M6800/1/2/3
245 	abx,
246 	aby,
247 	adc,
248 	adca,
249 	adcb,
250 	adcd,
251 	adcr,
252 	add,
253 	adda,
254 	addb,
255 	addd,
256 	adde,
257 	addf,
258 	addr,
259 	addw,
260 	aim,
261 	ais,
262 	aix,
263 	and,
264 	anda,
265 	andb,
266 	andcc,
267 	andd,
268 	andr,
269 	asl,
270 	asla,
271 	aslb,
272 	asld, /// or LSLD
273 	asr,
274 	asra,
275 	asrb,
276 	asrd,
277 	asrx,
278 	band,
279 	bcc, /// or BHS
280 	bclr,
281 	bcs, /// or BLO
282 	beor,
283 	beq,
284 	bge,
285 	bgnd,
286 	bgt,
287 	bhcc,
288 	bhcs,
289 	bhi,
290 	biand,
291 	bieor,
292 	bih,
293 	bil,
294 	bior,
295 	bit,
296 	bita,
297 	bitb,
298 	bitd,
299 	bitmd,
300 	ble,
301 	bls,
302 	blt,
303 	bmc,
304 	bmi,
305 	bms,
306 	bne,
307 	bor,
308 	bpl,
309 	brclr,
310 	brset,
311 	bra,
312 	brn,
313 	bset,
314 	bsr,
315 	bvc,
316 	bvs,
317 	call,
318 	cba, /// M6800/1/2/3
319 	cbeq,
320 	cbeqa,
321 	cbeqx,
322 	clc, /// M6800/1/2/3
323 	cli, /// M6800/1/2/3
324 	clr,
325 	clra,
326 	clrb,
327 	clrd,
328 	clre,
329 	clrf,
330 	clrh,
331 	clrw,
332 	clrx,
333 	clv, /// M6800/1/2/3
334 	cmp,
335 	cmpa,
336 	cmpb,
337 	cmpd,
338 	cmpe,
339 	cmpf,
340 	cmpr,
341 	cmps,
342 	cmpu,
343 	cmpw,
344 	cmpx,
345 	cmpy,
346 	com,
347 	coma,
348 	comb,
349 	comd,
350 	come,
351 	comf,
352 	comw,
353 	comx,
354 	cpd,
355 	cphx,
356 	cps,
357 	cpx, /// M6800/1/2/3
358 	cpy,
359 	cwai,
360 	daa,
361 	dbeq,
362 	dbne,
363 	dbnz,
364 	dbnza,
365 	dbnzx,
366 	dec,
367 	deca,
368 	decb,
369 	decd,
370 	dece,
371 	decf,
372 	decw,
373 	decx,
374 	des, /// M6800/1/2/3
375 	dex, /// M6800/1/2/3
376 	dey,
377 	div,
378 	divd,
379 	divq,
380 	ediv,
381 	edivs,
382 	eim,
383 	emacs,
384 	emaxd,
385 	emaxm,
386 	emind,
387 	eminm,
388 	emul,
389 	emuls,
390 	eor,
391 	eora,
392 	eorb,
393 	eord,
394 	eorr,
395 	etbl,
396 	exg,
397 	fdiv,
398 	ibeq,
399 	ibne,
400 	idiv,
401 	idivs,
402 	illgl,
403 	inc,
404 	inca,
405 	incb,
406 	incd,
407 	ince,
408 	incf,
409 	incw,
410 	incx,
411 	ins, /// M6800/1/2/3
412 	inx, /// M6800/1/2/3
413 	iny,
414 	jmp,
415 	jsr,
416 	lbcc, /// or LBHS
417 	lbcs, /// or LBLO
418 	lbeq,
419 	lbge,
420 	lbgt,
421 	lbhi,
422 	lble,
423 	lbls,
424 	lblt,
425 	lbmi,
426 	lbne,
427 	lbpl,
428 	lbra,
429 	lbrn,
430 	lbsr,
431 	lbvc,
432 	lbvs,
433 	lda,
434 	ldaa, /// M6800/1/2/3
435 	ldab, /// M6800/1/2/3
436 	ldb,
437 	ldbt,
438 	ldd,
439 	lde,
440 	ldf,
441 	ldhx,
442 	ldmd,
443 	ldq,
444 	lds,
445 	ldu,
446 	ldw,
447 	ldx,
448 	ldy,
449 	leas,
450 	leau,
451 	leax,
452 	leay,
453 	lsl,
454 	lsla,
455 	lslb,
456 	lsld,
457 	lslx,
458 	lsr,
459 	lsra,
460 	lsrb,
461 	lsrd, /// or ASRD
462 	lsrw,
463 	lsrx,
464 	maxa,
465 	maxm,
466 	mem,
467 	mina,
468 	minm,
469 	mov,
470 	movb,
471 	movw,
472 	mul,
473 	muld,
474 	neg,
475 	nega,
476 	negb,
477 	negd,
478 	negx,
479 	nop,
480 	nsa,
481 	oim,
482 	ora,
483 	oraa, /// M6800/1/2/3
484 	orab, /// M6800/1/2/3
485 	orb,
486 	orcc,
487 	ord,
488 	orr,
489 	psha, /// M6800/1/2/3
490 	pshb, /// M6800/1/2/3
491 	pshc,
492 	pshd,
493 	pshh,
494 	pshs,
495 	pshsw,
496 	pshu,
497 	pshuw,
498 	pshx, /// M6800/1/2/3
499 	pshy,
500 	pula, /// M6800/1/2/3
501 	pulb, /// M6800/1/2/3
502 	pulc,
503 	puld,
504 	pulh,
505 	puls,
506 	pulsw,
507 	pulu,
508 	puluw,
509 	pulx, /// M6800/1/2/3
510 	puly,
511 	rev,
512 	revw,
513 	rol,
514 	rola,
515 	rolb,
516 	rold,
517 	rolw,
518 	rolx,
519 	ror,
520 	rora,
521 	rorb,
522 	rord,
523 	rorw,
524 	rorx,
525 	rsp,
526 	rtc,
527 	rti,
528 	rts,
529 	sba, /// M6800/1/2/3
530 	sbc,
531 	sbca,
532 	sbcb,
533 	sbcd,
534 	sbcr,
535 	sec,
536 	sei,
537 	sev,
538 	sex,
539 	sexw,
540 	slp,
541 	sta,
542 	staa, /// M6800/1/2/3
543 	stab, /// M6800/1/2/3
544 	stb,
545 	stbt,
546 	std,
547 	ste,
548 	stf,
549 	stop,
550 	sthx,
551 	stq,
552 	sts,
553 	stu,
554 	stw,
555 	stx,
556 	sty,
557 	sub,
558 	suba,
559 	subb,
560 	subd,
561 	sube,
562 	subf,
563 	subr,
564 	subw,
565 	swi,
566 	swi2,
567 	swi3,
568 	sync,
569 	tab, /// M6800/1/2/3
570 	tap, /// M6800/1/2/3
571 	tax,
572 	tba, /// M6800/1/2/3
573 	tbeq,
574 	tbl,
575 	tbne,
576 	test,
577 	tfm,
578 	tfr,
579 	tim,
580 	tpa, /// M6800/1/2/3
581 	tst,
582 	tsta,
583 	tstb,
584 	tstd,
585 	tste,
586 	tstf,
587 	tstw,
588 	tstx,
589 	tsx, /// M6800/1/2/3
590 	tsy,
591 	txa,
592 	txs, /// M6800/1/2/3
593 	tys,
594 	wai, /// M6800/1/2/3
595 	wait,
596 	wav,
597 	wavr,
598 	xgdx, /// HD6301
599 	xgdy,
600 }
601 
602 /// Group of M680X instructions
603 enum M680xInstructionGroupId {
604 	invalid = 0,
605 	// Generic groups
606 	// all jump instructions (conditional+direct+indirect jumps)
607 	jump,
608 	// all call instructions
609 	call,
610 	// all return instructions
611 	ret,
612 	// all interrupt instructions (int+syscall)
613 	int_,
614 	// all interrupt return instructions
615 	iret,
616 	// all privileged instructions
617 	priv,
618 	// all relative branching instructions
619 	brarel,
620 }