openMSX
Dasm.cc
Go to the documentation of this file.
1 #include "Dasm.hh"
2 #include "DasmTables.hh"
3 #include "MSXCPUInterface.hh"
4 #include "strCat.hh"
5 
6 namespace openmsx {
7 
8 static char sign(unsigned char a)
9 {
10  return (a & 128) ? '-' : '+';
11 }
12 
13 static int abs(unsigned char a)
14 {
15  return (a & 128) ? (256 - a) : a;
16 }
17 
18 unsigned dasm(const MSXCPUInterface& interf, word pc, byte buf[4],
19  std::string& dest, EmuTime::param time)
20 {
21  const char* s;
22  unsigned i = 0;
23  const char* r = nullptr;
24 
25  buf[0] = interf.peekMem(pc, time);
26  switch (buf[0]) {
27  case 0xCB:
28  buf[1] = interf.peekMem(pc + 1, time);
29  s = mnemonic_cb[buf[1]];
30  i = 2;
31  break;
32  case 0xED:
33  buf[1] = interf.peekMem(pc + 1, time);
34  s = mnemonic_ed[buf[1]];
35  i = 2;
36  break;
37  case 0xDD:
38  case 0xFD:
39  r = (buf[0] == 0xDD) ? "ix" : "iy";
40  buf[1] = interf.peekMem(pc + 1, time);
41  if (buf[1] != 0xcb) {
42  s = mnemonic_xx[buf[1]];
43  i = 2;
44  } else {
45  buf[2] = interf.peekMem(pc + 2, time);
46  buf[3] = interf.peekMem(pc + 3, time);
47  s = mnemonic_xx_cb[buf[3]];
48  i = 4;
49  }
50  break;
51  default:
52  s = mnemonic_main[buf[0]];
53  i = 1;
54  }
55 
56  for (int j = 0; s[j]; ++j) {
57  switch (s[j]) {
58  case 'B':
59  buf[i] = interf.peekMem(pc + i, time);
60  strAppend(dest, '#', hex_string<2>(
61  static_cast<uint16_t>(buf[i])));
62  i += 1;
63  break;
64  case 'R':
65  buf[i] = interf.peekMem(pc + i, time);
66  strAppend(dest, '#', hex_string<4>(
67  pc + 2 + static_cast<int8_t>(buf[i])));
68  i += 1;
69  break;
70  case 'W':
71  buf[i + 0] = interf.peekMem(pc + i + 0, time);
72  buf[i + 1] = interf.peekMem(pc + i + 1, time);
73  strAppend(dest, '#', hex_string<4>(buf[i] + buf[i + 1] * 256));
74  i += 2;
75  break;
76  case 'X':
77  buf[i] = interf.peekMem(pc + i, time);
78  strAppend(dest, '(', r, sign(buf[i]), '#',
79  hex_string<2>(abs(buf[i])), ')');
80  i += 1;
81  break;
82  case 'Y':
83  strAppend(dest, r, sign(buf[2]), '#', hex_string<2>(abs(buf[2])));
84  break;
85  case 'I':
86  dest += r;
87  break;
88  case '!':
89  dest = strCat("db #ED,#", hex_string<2>(buf[1]),
90  " ");
91  return 2;
92  case '@':
93  dest = strCat("db #", hex_string<2>(buf[0]),
94  " ");
95  return 1;
96  case '#':
97  dest = strCat("db #", hex_string<2>(buf[0]),
98  ",#CB,#", hex_string<2>(buf[2]),
99  ' ');
100  return 2;
101  case ' ': {
102  dest.resize(7, ' ');
103  break;
104  }
105  default:
106  dest += s[j];
107  break;
108  }
109  }
110  dest.resize(19, ' ');
111  return i;
112 }
113 
114 } // namespace openmsx
const char * mnemonic_cb[256]
Definition: DasmTables.cc:41
uint8_t byte
8 bit unsigned integer
Definition: openmsx.hh:26
const char * mnemonic_main[256]
Definition: DasmTables.cc:149
unsigned dasm(const MSXCPUInterface &interf, word pc, byte buf[4], std::string &dest, EmuTime::param time)
Disassemble.
Definition: Dasm.cc:18
void strAppend(std::string &result, Ts &&...ts)
Definition: strCat.hh:648
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
const char * mnemonic_ed[256]
Definition: DasmTables.cc:77
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
const char * mnemonic_xx_cb[256]
Definition: DasmTables.cc:5
byte peekMem(word address, EmuTime::param time) const
Peek memory location.
std::string strCat(Ts &&...ts)
Definition: strCat.hh:577
const char * mnemonic_xx[256]
Definition: DasmTables.cc:113