11static constexpr char sign(uint8_t a)
13 return (a & 128) ?
'-' :
'+';
16static constexpr int abs(uint8_t a)
18 return (a & 128) ? (256 - a) : a;
23 strAppend(output,
'#', hex_string<4>(addr));
27 std::string& dest, EmuTime::param time,
30 const char* r =
nullptr;
32 buf[0] = interface.
peekMem(pc, time);
33 auto [s, i] = [&]() -> std::pair<const char*, unsigned> {
36 buf[1] = interface.
peekMem(pc + 1, time);
39 buf[1] = interface.
peekMem(pc + 1, time);
43 r = (buf[0] == 0xDD) ?
"ix" :
"iy";
44 buf[1] = interface.
peekMem(pc + 1, time);
48 buf[2] = interface.
peekMem(pc + 2, time);
49 buf[3] = interface.
peekMem(pc + 3, time);
57 for (
int j = 0; s[j]; ++j) {
60 buf[i] = interface.
peekMem(narrow_cast<uint16_t>(pc + i), time);
62 static_cast<uint16_t
>(buf[i])));
66 buf[i] = interface.
peekMem(narrow_cast<uint16_t>(pc + i), time);
67 appendAddr(dest, uint16_t(pc + 2 +
static_cast<int8_t
>(buf[i])));
72 buf[i + 0] = interface.
peekMem(narrow_cast<uint16_t>(pc + i + 0), time);
73 buf[i + 1] = interface.
peekMem(narrow_cast<uint16_t>(pc + i + 1), time);
74 appendAddr(dest, buf[i] + buf[i + 1] * 256);
78 buf[i] = interface.
peekMem(narrow_cast<uint16_t>(pc + i), time);
79 strAppend(dest,
'(', r, sign(buf[i]),
'#',
80 hex_string<2>(abs(buf[i])),
')');
84 strAppend(dest, r, sign(buf[2]),
'#', hex_string<2>(abs(buf[2])));
90 dest =
strCat(
"db #ED,#", hex_string<2>(buf[1]),
94 dest =
strCat(
"db #", hex_string<2>(buf[0]),
98 dest =
strCat(
"db #", hex_string<2>(buf[0]),
99 ",#CB,#", hex_string<2>(buf[2]),
117 auto op0 = interface.
peekMem(pc, time);
121 auto op1 = interface.
peekMem(pc + 1, time);
129static std::pair<uint16_t, unsigned> findGuaranteedBoundary(
const MSXCPUInterface& interface, uint16_t addr, EmuTime::param time)
135 std::array<unsigned, 4>
length;
136 for (
auto i :
xrange(4)) {
147 if ((length[1] == 1) && (length[2] <= 2) && (length[3] <= 3)) {
162static std::pair<uint16_t, unsigned> instructionBoundaryAndLength(
163 const MSXCPUInterface& interface, uint16_t addr, EmuTime::param time)
166 auto [candidate, len] = findGuaranteedBoundary(interface, addr, time);
169 if ((candidate + len) > addr)
return {candidate, len};
178 auto [result, len] = instructionBoundaryAndLength(interface, addr, time);
183 EmuTime::param time,
int n)
185 auto start = uint16_t(std::max(0,
int(addr - 4 * n)));
186 auto [tmp, len] = instructionBoundaryAndLength(interface, start, time);
188 std::vector<uint16_t> addresses;
189 while ((tmp + len) <= addr) {
190 addresses.push_back(tmp);
194 addresses.push_back(tmp);
196 return addresses[std::max(0, narrow<int>(addresses.size()) - 1 - n)];
byte peekMem(word address, EmuTime::param time) const
Peek memory location.
T length(const vecN< N, T > &x)
This file implemented 3 utility functions:
const std::array< const char *, 256 > mnemonic_xx
const std::array< const char *, 256 > mnemonic_ed
const std::array< const char *, 256 > mnemonic_xx_cb
const std::array< const char *, 256 > mnemonic_cb
const std::array< uint8_t, std::size_t(3) *256 > instr_len_tab
unsigned dasm(const MSXCPUInterface &interface, uint16_t pc, std::span< uint8_t, 4 > buf, std::string &dest, EmuTime::param time, function_ref< void(std::string &, uint16_t)> appendAddr)
Disassemble.
const std::array< const char *, 256 > mnemonic_main
uint16_t instructionBoundary(const MSXCPUInterface &interface, uint16_t addr, EmuTime::param time)
This is only an heuristic to display instructions in a debugger disassembly view.
uint16_t nInstructionsBefore(const MSXCPUInterface &interface, uint16_t addr, EmuTime::param time, int n)
Get the start address of the 'n'th instruction before the instruction containing the byte at the give...
unsigned instructionLength(const MSXCPUInterface &interface, uint16_t pc, EmuTime::param time)
Calculate the length of the instruction at the given address.
void appendAddrAsHex(std::string &output, uint16_t addr)
void strAppend(std::string &result, Ts &&...ts)
constexpr auto xrange(T e)