ss_int24_t and ss_uint24_t are integers
[lsnes.git] / src / core / disassemble.cpp
blob6b9c738c1c4ddd405bd3f2eed0148a4d79914fda
1 #include "cmdhelp/disassemble.hpp"
2 #include "core/command.hpp"
3 #include "core/instance.hpp"
4 #include "core/memorymanip.hpp"
5 #include "core/messages.hpp"
6 #include "interface/disassembler.hpp"
7 #include "library/hex.hpp"
8 #include "library/memoryspace.hpp"
9 #include "library/minmax.hpp"
10 #include "library/string.hpp"
12 #include <iomanip>
13 #include <fstream>
14 #include <iostream>
16 namespace
18 struct dres
20 uint64_t addr;
21 uint64_t len;
22 std::string disasm;
25 command::fnptr<const std::string&> CMD_disassemble(lsnes_cmds, CDISASM::d,
26 [](const std::string& t) throw(std::bad_alloc, std::runtime_error) {
27 auto& core = CORE();
28 regex_results r = regex("([^ \t]+)[ \t]+([0-9]+|0x[0-9A-Fa-f]+)([ \t]+([0-9]+))?"
29 "([ \t]+to[ \t]+(.+))?", t);
30 if(!r) {
31 messages << "Syntax: disassemble <kind> <addr> [<count>] [to <filename>]" << std::endl;
32 return;
34 std::string kind = r[1];
35 uint64_t addr = parse_value<uint64_t>(r[2]);
36 uint64_t count = 1;
37 if(r[4] != "")
38 count = parse_value<uint64_t>(r[4]);
39 std::string file;
40 if(r[6] != "")
41 file = r[6];
42 std::list<dres> result;
43 disassembler* d;
44 try {
45 d = &disassembler::byname(kind);
46 } catch(std::exception& e) {
47 messages << "Can't find such disassembler" << std::endl;
48 return;
50 uint64_t laddr = addr;
51 uint64_t longest = 0;
52 for(uint64_t i = 1; i <= count; i++) {
53 uint64_t bytes = 0;
54 dres x;
55 x.addr = laddr;
56 x.disasm = d->disassemble(laddr, [&core, &bytes, laddr]() -> unsigned char {
57 return core.memory->read<uint8_t>(laddr + bytes++);
58 });
59 x.len = bytes;
60 result.push_back(x);
61 longest = max(longest, bytes);
62 laddr += bytes;
64 std::ostream* strm = &messages.getstream();
65 if(file != "") {
66 strm = new std::ofstream(file);
67 if(!*strm) {
68 messages << "Can't open output file" << std::endl;
69 return;
72 for(auto i : result) {
73 std::vector<unsigned char> tmp;
74 tmp.resize(i.len);
75 core.memory->read_range(i.addr, &tmp[0], i.len);
76 std::string l = hex::to(i.addr) + " " + hex::b_to(&tmp[0], i.len) + " " + i.disasm;
77 (*strm) << l << std::endl;
79 if(file != "")
80 delete strm;
81 });