9static constexpr char sign(uint8_t a)
11 return (a & 128) ?
'-' :
'+';
14static constexpr int abs(uint8_t a)
16 return (a & 128) ? (256 - a) : a;
21 strAppend(output,
'#', hex_string<4>(addr));
25 std::string& dest, EmuTime::param time,
26 std::function<
void(std::string&, uint16_t)> appendAddr)
28 const char* r =
nullptr;
30 buf[0] = interface.
peekMem(pc, time);
31 auto [s, i] = [&]() -> std::pair<const char*, unsigned> {
34 buf[1] = interface.
peekMem(pc + 1, time);
37 buf[1] = interface.
peekMem(pc + 1, time);
41 r = (buf[0] == 0xDD) ?
"ix" :
"iy";
42 buf[1] = interface.
peekMem(pc + 1, time);
46 buf[2] = interface.
peekMem(pc + 2, time);
47 buf[3] = interface.
peekMem(pc + 3, time);
55 for (
int j = 0; s[j]; ++j) {
58 buf[i] = interface.
peekMem(narrow_cast<uint16_t>(pc + i), time);
60 static_cast<uint16_t
>(buf[i])));
64 buf[i] = interface.
peekMem(narrow_cast<uint16_t>(pc + i), time);
65 appendAddr(dest, pc + 2 +
static_cast<int8_t
>(buf[i]));
70 buf[i + 0] = interface.
peekMem(narrow_cast<uint16_t>(pc + i + 0), time);
71 buf[i + 1] = interface.
peekMem(narrow_cast<uint16_t>(pc + i + 1), time);
72 appendAddr(dest, buf[i] + buf[i + 1] * 256);
76 buf[i] = interface.
peekMem(narrow_cast<uint16_t>(pc + i), time);
77 strAppend(dest,
'(', r, sign(buf[i]),
'#',
78 hex_string<2>(abs(buf[i])),
')');
82 strAppend(dest, r, sign(buf[2]),
'#', hex_string<2>(abs(buf[2])));
88 dest =
strCat(
"db #ED,#", hex_string<2>(buf[1]),
92 dest =
strCat(
"db #", hex_string<2>(buf[0]),
96 dest =
strCat(
"db #", hex_string<2>(buf[0]),
97 ",#CB,#", hex_string<2>(buf[2]),
115 auto op0 = interface.
peekMem(pc, time);
119 auto op1 = interface.
peekMem(pc + 1, time);
127static std::pair<uint16_t, unsigned> findGuaranteedBoundary(
const MSXCPUInterface& interface, uint16_t addr, EmuTime::param time)
133 std::array<unsigned, 4>
length;
134 for (
auto i :
xrange(4)) {
160static std::pair<uint16_t, unsigned> instructionBoundaryAndLength(
164 auto [candidate, len] = findGuaranteedBoundary(interface, addr, time);
167 if ((candidate + len) > addr)
return {candidate, len};
176 auto [result, len] = instructionBoundaryAndLength(interface, addr, time);
181 EmuTime::param time,
int n)
183 unsigned start =
std::max(0,
int(addr - 4 * n));
184 auto [tmp, len] = instructionBoundaryAndLength(interface, start, time);
186 std::vector<uint16_t> addresses;
187 while ((tmp + len) <= addr) {
188 addresses.push_back(tmp);
192 addresses.push_back(tmp);
194 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)
constexpr vecN< N, T > max(const vecN< N, T > &x, const vecN< N, T > &y)
This file implemented 3 utility functions:
const std::array< const char *, 256 > mnemonic_xx
const std::array< const char *, 256 > mnemonic_ed
unsigned dasm(const MSXCPUInterface &interface, uint16_t pc, std::span< uint8_t, 4 > buf, std::string &dest, EmuTime::param time, std::function< void(std::string &, uint16_t)> appendAddr)
Disassemble.
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
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)
std::string strCat(Ts &&...ts)
void strAppend(std::string &result, Ts &&...ts)
constexpr auto xrange(T e)