mirror of
https://github.com/ksherlock/wdc-utils.git
synced 2024-12-12 19:30:38 +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 mRelative = 0x9000;
|
||||
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_X = 0x0200;
|
||||
@ -69,7 +70,7 @@ static constexpr const int modes[] =
|
||||
1 | mDPIL, // 07 ora [dp]
|
||||
0 | mImplied, // 08 php
|
||||
1 | mImmediate | m_M, // 09 ora #imm
|
||||
0 | mImplied, // 0a asl a
|
||||
0 | mImpliedA, // 0a asl a
|
||||
0 | mImplied, // 0b phd
|
||||
2 | mAbsolute, // 0c tsb |abs
|
||||
2 | mAbsolute, // 0d ora |abs
|
||||
@ -86,7 +87,7 @@ static constexpr const int modes[] =
|
||||
1 | mDPIL | m_Y, // 17 ora [dp],y
|
||||
0 | mImplied, // 18 clc
|
||||
2 | mAbsolute | m_Y, // 19 ora |abs,y
|
||||
0 | mImplied, // 1a inc a
|
||||
0 | mImpliedA, // 1a inc a
|
||||
0 | mImplied, // 1b tcs
|
||||
2 | mAbsolute, // 1c trb |abs
|
||||
2 | mAbsolute | m_X, // 1d ora |abs,x
|
||||
@ -103,7 +104,7 @@ static constexpr const int modes[] =
|
||||
1 | mDPIL, // 27 and [dp]
|
||||
0 | mImplied, // 28 plp
|
||||
1 | mImmediate | m_M, // 29 and #imm
|
||||
0 | mImplied, // 2a rol a
|
||||
0 | mImpliedA, // 2a rol a
|
||||
0 | mImplied, // 2b pld
|
||||
2 | mAbsolute, // 2c bit |abs
|
||||
2 | mAbsolute, // 2d and |abs
|
||||
@ -120,7 +121,7 @@ static constexpr const int modes[] =
|
||||
1 | mDPIL | m_Y, // 37 and [dp],y
|
||||
0 | mImplied, // 38 sec
|
||||
2 | mAbsolute | m_Y, // 39 and |abs,y
|
||||
0 | mImplied, // 3a dec a
|
||||
0 | mImpliedA, // 3a dec a
|
||||
0 | mImplied, // 3b tsc
|
||||
2 | mAbsolute | m_X, // 3c bits |abs,x
|
||||
2 | mAbsolute | m_X, // 3d and |abs,x
|
||||
@ -137,7 +138,7 @@ static constexpr const int modes[] =
|
||||
1 | mDPIL, // 47 eor [dp]
|
||||
0 | mImplied, // 48 pha
|
||||
1 | mImmediate | m_M, // 49 eor #imm
|
||||
0 | mImplied, // 4a lsr a
|
||||
0 | mImpliedA, // 4a lsr a
|
||||
0 | mImplied, // 4b phk
|
||||
2 | mAbsolute, // 4c jmp |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() {
|
||||
|
||||
@ -440,15 +470,12 @@ void disassembler::dump() {
|
||||
if (!_st) return;
|
||||
|
||||
|
||||
auto p = format_data(_st, _bytes);
|
||||
|
||||
indent_to(line, kOpcodeTab);
|
||||
line += "db";
|
||||
line += p.first;
|
||||
indent_to(line, kOperandTab);
|
||||
|
||||
|
||||
for (unsigned i = 0; i < _st; ++i) {
|
||||
if (i > 0) line += ", ";
|
||||
line += to_x(_bytes[i], 2, '$');
|
||||
}
|
||||
line += p.second;
|
||||
|
||||
hexdump(line);
|
||||
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;
|
||||
|
||||
indent_to(line, kOpcodeTab);
|
||||
auto p = format_data(size, expr);
|
||||
|
||||
switch(size) {
|
||||
case 1: line += "db"; break;
|
||||
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, kOpcodeTab);
|
||||
line += p.first;
|
||||
indent_to(line, kOperandTab);
|
||||
line += expr;
|
||||
line += p.second;
|
||||
|
||||
hexdump(line);
|
||||
line.push_back('\n');
|
||||
@ -551,6 +570,10 @@ void disassembler::operator()(const std::string &expr, unsigned size) {
|
||||
|
||||
if (!_code) {
|
||||
dump(expr, size);
|
||||
if (_inline_data) {
|
||||
_inline_data -= size;
|
||||
if (_inline_data <= 0) _code = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -558,7 +581,7 @@ void disassembler::operator()(const std::string &expr, unsigned size) {
|
||||
dump(expr, size);
|
||||
return;
|
||||
}
|
||||
for(int i = 0; i < size; ++i) _bytes[_st++] = 0;
|
||||
for (int i = 0; i < size; ++i) _bytes[_st++] = 0;
|
||||
print(expr);
|
||||
}
|
||||
|
||||
@ -570,6 +593,13 @@ void disassembler::operator()(uint8_t byte) {
|
||||
|
||||
if (!_code) {
|
||||
_bytes[_st++] = byte;
|
||||
|
||||
if (_inline_data && --_inline_data <= 0) {
|
||||
dump();
|
||||
_code = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_st == 4) dump();
|
||||
return;
|
||||
}
|
||||
@ -578,12 +608,20 @@ void disassembler::operator()(uint8_t byte) {
|
||||
if (_st == 1) {
|
||||
_op = byte;
|
||||
_mode = modes[_op];
|
||||
|
||||
if (_orca && _op == 0xf4) _mode = 2 | mAbsolute;
|
||||
_size = _mode & 0x0f;
|
||||
if (_mode & _flags & m_I) _size++;
|
||||
if (_mode & _flags & m_M) _size++;
|
||||
|
||||
if (!_size) {
|
||||
print();
|
||||
|
||||
//if (byte == 0x6b) {
|
||||
// // rtl
|
||||
// set_code(false);
|
||||
//}
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -591,6 +629,9 @@ void disassembler::operator()(uint8_t byte) {
|
||||
_arg = _arg + (byte << shift);
|
||||
if (_st <= _size) return;
|
||||
|
||||
uint8_t op = _op;
|
||||
uint32_t arg = _arg;
|
||||
|
||||
switch(_op) {
|
||||
case 0xc2: // REP
|
||||
_flags |= (_arg & 0x30);
|
||||
@ -602,6 +643,19 @@ void disassembler::operator()(uint8_t byte) {
|
||||
|
||||
// all done... now print it.
|
||||
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;
|
||||
|
||||
|
||||
|
||||
|
||||
indent_to(line, kOpcodeTab);
|
||||
line.append(&opcodes[_op * 3], 3);
|
||||
|
||||
if (_mode == mImpliedA && _orca) {
|
||||
indent_to(line, kOperandTab);
|
||||
line.append("a");
|
||||
}
|
||||
|
||||
|
||||
hexdump(line);
|
||||
line.push_back('\n');
|
||||
|
@ -14,10 +14,10 @@ class disassembler {
|
||||
void operator()(const std::string &expr, unsigned size);
|
||||
|
||||
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>
|
||||
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);
|
||||
|
||||
@ -55,10 +55,24 @@ class disassembler {
|
||||
|
||||
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) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
virtual void event(uint8_t opcode, uint32_t operand) {}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void reset();
|
||||
@ -88,8 +102,11 @@ class disassembler {
|
||||
unsigned _arg = 0;
|
||||
|
||||
bool _code = true;
|
||||
int _inline_data = 0;
|
||||
int32_t _next_label = -1;
|
||||
|
||||
bool _orca = true;
|
||||
|
||||
void check_labels();
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user