summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/util/disasmintf.h
blob: 78c77a9abb2b0312ccd12428b2ff8f7b5b980275 (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
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert
/***************************************************************************

    disasmintf.h

    Generic disassembler interface.

***************************************************************************/

#pragma once

#ifndef MAME_UTIL_DISASMINTF_H
#define MAME_UTIL_DISASMINTF_H

#include "coretmpl.h"

namespace util {

// class implementing a disassembler
class disasm_interface
{
public:
	virtual ~disasm_interface() = default;

	// independence from emu.h
	using u8 = osd::u8;
	using u16 = osd::u16;
	using u32 = osd::u32;
	using u64 = osd::u64;
	using s8 = osd::s8;
	using s16 = osd::s16;
	using s32 = osd::s32;
	using s64 = osd::s64;
	using offs_t = u32;

	// Disassembler constants for the return value
	static constexpr u32 SUPPORTED       = 0x80000000;   // are disassembly flags supported?
	static constexpr u32 STEP_OUT        = 0x40000000;   // this instruction should be the end of a step out sequence
	static constexpr u32 STEP_OVER       = 0x20000000;   // this instruction should be stepped over by setting a breakpoint afterwards
	static constexpr u32 OVERINSTMASK    = 0x18000000;   // number of extra instructions to skip when stepping over
	static constexpr u32 OVERINSTSHIFT   = 27;           // bits to shift after masking to get the value
	static constexpr u32 LENGTHMASK      = 0x0000ffff;   // the low 16-bits contain the actual length

	static inline u32 step_over_extra(u32 x) {
		return x << OVERINSTSHIFT;
	}

	class data_buffer {
	public:
		virtual ~data_buffer() = default;
		virtual u8  r8 (offs_t pc) const = 0;
		virtual u16 r16(offs_t pc) const = 0;
		virtual u32 r32(offs_t pc) const = 0;
		virtual u64 r64(offs_t pc) const = 0;
	};

	enum {
		NONLINEAR_PC        = 0x00000001,
		PAGED               = 0x00000002,
		PAGED2LEVEL         = 0x00000006,
		INTERNAL_DECRYPTION = 0x00000008,
		SPLIT_DECRYPTION    = 0x00000018
	};

	virtual u32 interface_flags() const;
	virtual u32 page_address_bits() const;
	virtual u32 page2_address_bits() const;
	virtual offs_t pc_linear_to_real(offs_t pc) const;
	virtual offs_t pc_real_to_linear(offs_t pc) const;
	virtual u8  decrypt8 (u8  value, offs_t pc, bool opcode) const;
	virtual u16 decrypt16(u16 value, offs_t pc, bool opcode) const;
	virtual u32 decrypt32(u32 value, offs_t pc, bool opcode) const;
	virtual u64 decrypt64(u64 value, offs_t pc, bool opcode) const;

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

#endif