1 #include "core/command.hpp"
2 #include "interface/disassembler.hpp"
3 #include "library/bintohex.hpp"
4 #include "library/minmax.hpp"
5 #include "core/memorymanip.hpp"
6 #include "core/window.hpp"
7 #include "library/string.hpp"
21 unsigned char hex(char ch
)
34 case 'a': case 'A': return 10;
35 case 'b': case 'B': return 11;
36 case 'c': case 'C': return 12;
37 case 'd': case 'D': return 13;
38 case 'e': case 'E': return 14;
39 case 'f': case 'F': return 15;
41 throw std::runtime_error("Bad hex character");
44 uint64_t parse_hexordec(const std::string
& k
)
48 if(t
= regex("0x(.+)", k
)) {
49 if(t
[1].length() > 16)
52 for(unsigned i
= 0; i
< t
[1].length(); i
++)
53 address
= 16 * address
+ hex(t
[1][i
]);
55 address
= parse_value
<uint64_t>(k
);
60 function_ptr_command
<const std::string
&> disassemble(lsnes_cmd
, "disassemble", "Disassemble code",
61 "Syntax: disassemble <kind> <addr> [<count>] [to <filename>]\nDisassemble code\n",
62 [](const std::string
& t
) throw(std::bad_alloc
, std::runtime_error
) {
63 regex_results r
= regex("([^ \t]+)[ \t]+([0-9]+|0x[0-9A-Fa-f]+)([ \t]+([0-9]+))?"
64 "([ \t]+to[ \t]+(.+))?", t
);
66 messages
<< "Syntax: disassemble <kind> <addr> [<count>] [to <filename>]" << std::endl
;
69 std::string kind
= r
[1];
70 uint64_t addr
= parse_hexordec(r
[2]);
73 count
= parse_value
<uint64_t>(r
[4]);
77 std::list
<dres
> result
;
80 d
= &disassembler::byname(kind
);
81 } catch(std::exception
& e
) {
82 messages
<< "Can't find such disassembler" << std::endl
;
85 uint64_t laddr
= addr
;
87 for(uint64_t i
= 1; i
<= count
; i
++) {
91 x
.disasm
= d
->disassemble(laddr
, [&bytes
, laddr
]() -> unsigned char {
92 return lsnes_memory
.read
<uint8_t>(laddr
+ bytes
++);
96 longest
= max(longest
, bytes
);
99 std::ostream
* strm
= &messages
.getstream();
101 strm
= new std::ofstream(file
);
103 messages
<< "Can't open output file" << std::endl
;
107 for(auto i
: result
) {
108 std::vector
<unsigned char> tmp
;
110 lsnes_memory
.read_range(i
.addr
, &tmp
[0], i
.len
);
111 std::string l
= (stringfmt() << std::setw(16) << std::setfill('0') << std::hex
112 << i
.addr
).str() + " " + binary_to_hex(&tmp
[0], i
.len
) + " "
114 (*strm
) << l
<< std::endl
;