mirror of
https://github.com/ksherlock/wdc-utils.git
synced 2025-01-05 20:32:42 +00:00
disassembler updates.
This commit is contained in:
parent
7f3ccd84c8
commit
b18467a641
112
disassembler.cpp
112
disassembler.cpp
@ -49,6 +49,7 @@ static constexpr const int mDPI = 0x7000;
|
|||||||
static constexpr const int mDPIL = 0x8000;
|
static constexpr const int mDPIL = 0x8000;
|
||||||
static constexpr const int mRelative = 0x9000;
|
static constexpr const int mRelative = 0x9000;
|
||||||
static constexpr const int mBlockMove = 0xa000;
|
static constexpr const int mBlockMove = 0xa000;
|
||||||
|
static constexpr const int mImpliedA = 0xb000; // inc a, dec a, etc.
|
||||||
|
|
||||||
static constexpr const int m_S = 0x0100;
|
static constexpr const int m_S = 0x0100;
|
||||||
static constexpr const int m_X = 0x0200;
|
static constexpr const int m_X = 0x0200;
|
||||||
@ -69,7 +70,7 @@ static constexpr const int modes[] =
|
|||||||
1 | mDPIL, // 07 ora [dp]
|
1 | mDPIL, // 07 ora [dp]
|
||||||
0 | mImplied, // 08 php
|
0 | mImplied, // 08 php
|
||||||
1 | mImmediate | m_M, // 09 ora #imm
|
1 | mImmediate | m_M, // 09 ora #imm
|
||||||
0 | mImplied, // 0a asl a
|
0 | mImpliedA, // 0a asl a
|
||||||
0 | mImplied, // 0b phd
|
0 | mImplied, // 0b phd
|
||||||
2 | mAbsolute, // 0c tsb |abs
|
2 | mAbsolute, // 0c tsb |abs
|
||||||
2 | mAbsolute, // 0d ora |abs
|
2 | mAbsolute, // 0d ora |abs
|
||||||
@ -86,7 +87,7 @@ static constexpr const int modes[] =
|
|||||||
1 | mDPIL | m_Y, // 17 ora [dp],y
|
1 | mDPIL | m_Y, // 17 ora [dp],y
|
||||||
0 | mImplied, // 18 clc
|
0 | mImplied, // 18 clc
|
||||||
2 | mAbsolute | m_Y, // 19 ora |abs,y
|
2 | mAbsolute | m_Y, // 19 ora |abs,y
|
||||||
0 | mImplied, // 1a inc a
|
0 | mImpliedA, // 1a inc a
|
||||||
0 | mImplied, // 1b tcs
|
0 | mImplied, // 1b tcs
|
||||||
2 | mAbsolute, // 1c trb |abs
|
2 | mAbsolute, // 1c trb |abs
|
||||||
2 | mAbsolute | m_X, // 1d ora |abs,x
|
2 | mAbsolute | m_X, // 1d ora |abs,x
|
||||||
@ -103,7 +104,7 @@ static constexpr const int modes[] =
|
|||||||
1 | mDPIL, // 27 and [dp]
|
1 | mDPIL, // 27 and [dp]
|
||||||
0 | mImplied, // 28 plp
|
0 | mImplied, // 28 plp
|
||||||
1 | mImmediate | m_M, // 29 and #imm
|
1 | mImmediate | m_M, // 29 and #imm
|
||||||
0 | mImplied, // 2a rol a
|
0 | mImpliedA, // 2a rol a
|
||||||
0 | mImplied, // 2b pld
|
0 | mImplied, // 2b pld
|
||||||
2 | mAbsolute, // 2c bit |abs
|
2 | mAbsolute, // 2c bit |abs
|
||||||
2 | mAbsolute, // 2d and |abs
|
2 | mAbsolute, // 2d and |abs
|
||||||
@ -120,7 +121,7 @@ static constexpr const int modes[] =
|
|||||||
1 | mDPIL | m_Y, // 37 and [dp],y
|
1 | mDPIL | m_Y, // 37 and [dp],y
|
||||||
0 | mImplied, // 38 sec
|
0 | mImplied, // 38 sec
|
||||||
2 | mAbsolute | m_Y, // 39 and |abs,y
|
2 | mAbsolute | m_Y, // 39 and |abs,y
|
||||||
0 | mImplied, // 3a dec a
|
0 | mImpliedA, // 3a dec a
|
||||||
0 | mImplied, // 3b tsc
|
0 | mImplied, // 3b tsc
|
||||||
2 | mAbsolute | m_X, // 3c bits |abs,x
|
2 | mAbsolute | m_X, // 3c bits |abs,x
|
||||||
2 | mAbsolute | m_X, // 3d and |abs,x
|
2 | mAbsolute | m_X, // 3d and |abs,x
|
||||||
@ -137,7 +138,7 @@ static constexpr const int modes[] =
|
|||||||
1 | mDPIL, // 47 eor [dp]
|
1 | mDPIL, // 47 eor [dp]
|
||||||
0 | mImplied, // 48 pha
|
0 | mImplied, // 48 pha
|
||||||
1 | mImmediate | m_M, // 49 eor #imm
|
1 | mImmediate | m_M, // 49 eor #imm
|
||||||
0 | mImplied, // 4a lsr a
|
0 | mImpliedA, // 4a lsr a
|
||||||
0 | mImplied, // 4b phk
|
0 | mImplied, // 4b phk
|
||||||
2 | mAbsolute, // 4c jmp |abs
|
2 | mAbsolute, // 4c jmp |abs
|
||||||
2 | mAbsolute, // 4d eor |abs
|
2 | mAbsolute, // 4d eor |abs
|
||||||
@ -431,7 +432,36 @@ void disassembler::reset() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::pair<std::string, std::string>
|
||||||
|
disassembler::format_data(unsigned size, const uint8_t *data) {
|
||||||
|
|
||||||
|
std::string tmp;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < size; ++i) {
|
||||||
|
if (i > 0) tmp += ", ";
|
||||||
|
tmp += to_x(data[i], 2, '$');
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_pair("db", tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<std::string, std::string>
|
||||||
|
disassembler::format_data(unsigned size, const std::string &data) {
|
||||||
|
|
||||||
|
switch(size) {
|
||||||
|
case 1: return std::make_pair("db", data);
|
||||||
|
case 2: return std::make_pair("dw", data);
|
||||||
|
case 3: return std::make_pair("da", data);
|
||||||
|
case 4: return std::make_pair("dl", data);
|
||||||
|
|
||||||
|
default: {
|
||||||
|
std::string tmp;
|
||||||
|
tmp = std::to_string(size) + " bytes";
|
||||||
|
return std::make_pair(tmp, data);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void disassembler::dump() {
|
void disassembler::dump() {
|
||||||
|
|
||||||
@ -440,15 +470,12 @@ void disassembler::dump() {
|
|||||||
if (!_st) return;
|
if (!_st) return;
|
||||||
|
|
||||||
|
|
||||||
|
auto p = format_data(_st, _bytes);
|
||||||
|
|
||||||
indent_to(line, kOpcodeTab);
|
indent_to(line, kOpcodeTab);
|
||||||
line += "db";
|
line += p.first;
|
||||||
indent_to(line, kOperandTab);
|
indent_to(line, kOperandTab);
|
||||||
|
line += p.second;
|
||||||
|
|
||||||
for (unsigned i = 0; i < _st; ++i) {
|
|
||||||
if (i > 0) line += ", ";
|
|
||||||
line += to_x(_bytes[i], 2, '$');
|
|
||||||
}
|
|
||||||
|
|
||||||
hexdump(line);
|
hexdump(line);
|
||||||
line.push_back('\n');
|
line.push_back('\n');
|
||||||
@ -466,20 +493,12 @@ void disassembler::dump(const std::string &expr, unsigned size) {
|
|||||||
|
|
||||||
for (_st = 0; _st < size; ++_st) _bytes[_st] = 0;
|
for (_st = 0; _st < size; ++_st) _bytes[_st] = 0;
|
||||||
|
|
||||||
indent_to(line, kOpcodeTab);
|
auto p = format_data(size, expr);
|
||||||
|
|
||||||
switch(size) {
|
indent_to(line, kOpcodeTab);
|
||||||
case 1: line += "db"; break;
|
line += p.first;
|
||||||
case 2: line += "dw"; break;
|
|
||||||
case 3: line += "da"; break;
|
|
||||||
case 4: line += "dl"; break;
|
|
||||||
default:
|
|
||||||
line += std::to_string(size);
|
|
||||||
line += " bytes";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
indent_to(line, kOperandTab);
|
indent_to(line, kOperandTab);
|
||||||
line += expr;
|
line += p.second;
|
||||||
|
|
||||||
hexdump(line);
|
hexdump(line);
|
||||||
line.push_back('\n');
|
line.push_back('\n');
|
||||||
@ -551,6 +570,10 @@ void disassembler::operator()(const std::string &expr, unsigned size) {
|
|||||||
|
|
||||||
if (!_code) {
|
if (!_code) {
|
||||||
dump(expr, size);
|
dump(expr, size);
|
||||||
|
if (_inline_data) {
|
||||||
|
_inline_data -= size;
|
||||||
|
if (_inline_data <= 0) _code = true;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -558,7 +581,7 @@ void disassembler::operator()(const std::string &expr, unsigned size) {
|
|||||||
dump(expr, size);
|
dump(expr, size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for(int i = 0; i < size; ++i) _bytes[_st++] = 0;
|
for (int i = 0; i < size; ++i) _bytes[_st++] = 0;
|
||||||
print(expr);
|
print(expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,6 +593,13 @@ void disassembler::operator()(uint8_t byte) {
|
|||||||
|
|
||||||
if (!_code) {
|
if (!_code) {
|
||||||
_bytes[_st++] = byte;
|
_bytes[_st++] = byte;
|
||||||
|
|
||||||
|
if (_inline_data && --_inline_data <= 0) {
|
||||||
|
dump();
|
||||||
|
_code = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (_st == 4) dump();
|
if (_st == 4) dump();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -578,12 +608,20 @@ void disassembler::operator()(uint8_t byte) {
|
|||||||
if (_st == 1) {
|
if (_st == 1) {
|
||||||
_op = byte;
|
_op = byte;
|
||||||
_mode = modes[_op];
|
_mode = modes[_op];
|
||||||
|
|
||||||
|
if (_orca && _op == 0xf4) _mode = 2 | mAbsolute;
|
||||||
_size = _mode & 0x0f;
|
_size = _mode & 0x0f;
|
||||||
if (_mode & _flags & m_I) _size++;
|
if (_mode & _flags & m_I) _size++;
|
||||||
if (_mode & _flags & m_M) _size++;
|
if (_mode & _flags & m_M) _size++;
|
||||||
|
|
||||||
if (!_size) {
|
if (!_size) {
|
||||||
print();
|
print();
|
||||||
|
|
||||||
|
//if (byte == 0x6b) {
|
||||||
|
// // rtl
|
||||||
|
// set_code(false);
|
||||||
|
//}
|
||||||
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -591,6 +629,9 @@ void disassembler::operator()(uint8_t byte) {
|
|||||||
_arg = _arg + (byte << shift);
|
_arg = _arg + (byte << shift);
|
||||||
if (_st <= _size) return;
|
if (_st <= _size) return;
|
||||||
|
|
||||||
|
uint8_t op = _op;
|
||||||
|
uint32_t arg = _arg;
|
||||||
|
|
||||||
switch(_op) {
|
switch(_op) {
|
||||||
case 0xc2: // REP
|
case 0xc2: // REP
|
||||||
_flags |= (_arg & 0x30);
|
_flags |= (_arg & 0x30);
|
||||||
@ -602,6 +643,19 @@ void disassembler::operator()(uint8_t byte) {
|
|||||||
|
|
||||||
// all done... now print it.
|
// all done... now print it.
|
||||||
print();
|
print();
|
||||||
|
|
||||||
|
switch(op) {
|
||||||
|
case 0xc2:
|
||||||
|
case 0xe2:
|
||||||
|
case 0x22:
|
||||||
|
case 0x5c:
|
||||||
|
case 0xdc:
|
||||||
|
event(op, arg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -808,9 +862,17 @@ void disassembler::print() {
|
|||||||
|
|
||||||
std::string line;
|
std::string line;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
indent_to(line, kOpcodeTab);
|
indent_to(line, kOpcodeTab);
|
||||||
line.append(&opcodes[_op * 3], 3);
|
line.append(&opcodes[_op * 3], 3);
|
||||||
|
|
||||||
|
if (_mode == mImpliedA && _orca) {
|
||||||
|
indent_to(line, kOperandTab);
|
||||||
|
line.append("a");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
hexdump(line);
|
hexdump(line);
|
||||||
line.push_back('\n');
|
line.push_back('\n');
|
||||||
|
@ -14,10 +14,10 @@ class disassembler {
|
|||||||
void operator()(const std::string &expr, unsigned size);
|
void operator()(const std::string &expr, unsigned size);
|
||||||
|
|
||||||
template<class Iter>
|
template<class Iter>
|
||||||
void operator()(Iter begin, Iter end) { while (begin != end) code(*begin++); }
|
void operator()(Iter begin, Iter end) { while (begin != end) (*this)(*begin++); }
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void operator()(const T &t) { code(std::begin(t), std::end(t)); }
|
void operator()(const T &t) { (*this)(std::begin(t), std::end(t)); }
|
||||||
|
|
||||||
void space(unsigned bytes);
|
void space(unsigned bytes);
|
||||||
|
|
||||||
@ -55,10 +55,24 @@ class disassembler {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
||||||
|
virtual std::pair<std::string, std::string> format_data(unsigned size, const uint8_t *data);
|
||||||
|
virtual std::pair<std::string, std::string> format_data(unsigned size, const std::string &);
|
||||||
|
|
||||||
|
|
||||||
|
void set_inline_data(int count) {
|
||||||
|
flush();
|
||||||
|
_code = count ? false : true;
|
||||||
|
_inline_data = count;
|
||||||
|
}
|
||||||
|
|
||||||
virtual int32_t next_label(int32_t pc) {
|
virtual int32_t next_label(int32_t pc) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void event(uint8_t opcode, uint32_t operand) {}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
@ -88,8 +102,11 @@ class disassembler {
|
|||||||
unsigned _arg = 0;
|
unsigned _arg = 0;
|
||||||
|
|
||||||
bool _code = true;
|
bool _code = true;
|
||||||
|
int _inline_data = 0;
|
||||||
int32_t _next_label = -1;
|
int32_t _next_label = -1;
|
||||||
|
|
||||||
|
bool _orca = true;
|
||||||
|
|
||||||
void check_labels();
|
void check_labels();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user