OXYGENHUB
◆ main openmsx / src / cpu / Dasm.hh
3.9 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#ifndef DASM_HH
2
#define DASM_HH
3
4
#include "EmuTime.hh"
5
6
#include "function_ref.hh"
7
8
#include <cstdint>
9
#include <functional>
10
#include <span>
11
#include <string>
12
13
namespace openmsx {
14
15
class MSXCPUInterface;
16
17
void appendAddrAsHex(std::string& output, uint16_t addr);
18
19
/** Calculate the length of the instruction at the given address.
20
  * This is exactly the same value as calculated by the dasm() function above,
21
  * though this function executes much faster.
22
  * Note that this function (and also dasm()) ignores illegal instructions with
23
  * repeated prefixes (e.g. an instruction like 'DD DD DD DD DD 00'). Because of
24
  * this, the instruction length is always between 1 and 4 (inclusive).
25
  */
26
std::optional<unsigned> instructionLength(std::span<const uint8_t> bin);
27
28
std::span<uint8_t> fetchInstruction(const MSXCPUInterface& interface, uint16_t addr,
29
                                    std::span<uint8_t, 4> buffer, EmuTime time);
30
31
/** Disassemble
32
  * @param opcode Buffer containing the machine language instruction
33
                  The length of this buffer _must_ be exact. So typically
34
                  calculated via instructionLength() or fetchInstruction().
35
  * @param pc Program Counter used for disassembling relative addresses
36
  * @param dest String [output] representation of the disassembled opcode
37
  * @return Length of the disassembled opcode in bytes.
38
            Should always be the same as 'opcode.size()', so only useful in unittest.
39
  */
40
unsigned dasm(std::span<const uint8_t> opcode, uint16_t pc, std::string& dest,
41
              function_ref<void(std::string&, uint16_t)> appendAddr = &appendAddrAsHex);
42
43
/** Disassemble
44
  * @param interface The CPU interface, used to peek bytes from memory
45
  * @param pc The position (program counter) where to start disassembling
46
  * @param buf The bytes that form this opcode (max 4). The buffer is only
47
  *            filled with the min required bytes (see return value)
48
  * @param dest String representation of the disassembled opcode
49
  * @param time TODO
50
  * @return Length of the disassembled opcode in bytes
51
  */
52
unsigned dasm(const MSXCPUInterface& interface, uint16_t pc, std::span<uint8_t, 4> buf,
53
              std::string& dest, EmuTime time,
54
              function_ref<void(std::string&, uint16_t)> appendAddr = &appendAddrAsHex);
55
56
/** This is only an _heuristic_ to display instructions in a debugger disassembly
57
  * view. (In reality Z80 instruction can really start at _any_ address).
58
  *
59
  * Z80 instruction have a variable length between 1 and 4 bytes inclusive (we
60
  * ignore illegal instructions). If you were to start disassembling the full
61
  * address space from address 0, some addresses are at the start of an
62
  * instructions, others are not. To be able to show a 'stable' disassembly view
63
  * when scrolling up/down in the debugger, it's useful to know at which
64
  * addresses instructions start.
65
  *
66
  * This function can calculate such start addresses (on average) in a more
67
  * efficient way than just starting to disassemble from the top.
68
  *
69
  * More in detail: this function calculates the largest address smaller or
70
  * equal to a given address where an instruction starts. In other words: it
71
  * calculates the start address of the instruction that contains the given
72
  * address.
73
  */
74
uint16_t instructionBoundary(const MSXCPUInterface& interface, uint16_t addr,
75
                             EmuTime time);
76
77
/** Get the start address of the 'n'th instruction before the instruction
78
  * containing the byte at the given address 'addr'.
79
  * In other words, stepping 'n' instructions forwards from the resulting
80
  * address lands at the address that would be returned from
81
  * 'instuctionBoundary()'.
82
  * Unless there aren't enough instructions in front. In that case address 0 is
83
  * returned.
84
  */
85
uint16_t nInstructionsBefore(const MSXCPUInterface& interface, uint16_t addr,
86
                             EmuTime time, int n);
87
88
} // namespace openmsx
89
90
#endif