2022-03-04 12:29:33 +01:00
|
|
|
#include "shell.h"
|
|
|
|
#include "parser.h"
|
|
|
|
#include "commands.h"
|
|
|
|
#include "theme.h"
|
|
|
|
|
|
|
|
#include <fmt/core.h>
|
|
|
|
|
2022-04-14 13:30:43 +02:00
|
|
|
using Selections = std::vector<std::pair<uint32_t, int>>;
|
2022-03-04 12:29:33 +01:00
|
|
|
|
|
|
|
static bool is_selected(uint32_t address, Selections const &sel)
|
|
|
|
{
|
2022-04-14 13:30:43 +02:00
|
|
|
for(auto &p: sel) {
|
|
|
|
if(address >= p.first && address < p.first + p.second)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
2022-03-04 12:29:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void _h_hexdump(Session &session, Range r, Selections sel)
|
|
|
|
{
|
2022-04-14 13:30:43 +02:00
|
|
|
if(!session.current_space)
|
|
|
|
return;
|
|
|
|
VirtualSpace &v = *session.current_space;
|
|
|
|
|
|
|
|
uint32_t start = r.start & ~0xf;
|
|
|
|
uint32_t end = (r.end + 15) & ~0xf;
|
|
|
|
|
|
|
|
for(uint32_t pos = start; pos != end; pos += 16) {
|
|
|
|
fmt::print(theme(3), " 0x{:08x} ", pos);
|
|
|
|
|
|
|
|
/* Hexdump */
|
|
|
|
for(int offset = 0; offset < 16; offset++) {
|
|
|
|
if(!(offset % 4))
|
|
|
|
fmt::print(" ");
|
|
|
|
|
|
|
|
uint32_t addr = pos + offset;
|
|
|
|
if(addr < r.start || addr >= r.end) {
|
|
|
|
fmt::print(" ");
|
|
|
|
}
|
|
|
|
else if(is_selected(addr, sel)) {
|
2023-08-26 23:49:40 +02:00
|
|
|
fmt::print(theme(13), "{:02x}", v.read_u8(addr).value);
|
2022-04-14 13:30:43 +02:00
|
|
|
}
|
|
|
|
else {
|
2023-08-26 23:49:40 +02:00
|
|
|
fmt::print("{:02x}", v.read_u8(addr).value);
|
2022-04-14 13:30:43 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ASCII */
|
|
|
|
fmt::print(" ");
|
|
|
|
for(int offset = 0; offset < 16; offset++) {
|
|
|
|
if(!(offset % 4))
|
|
|
|
fmt::print(" ");
|
|
|
|
|
|
|
|
uint32_t addr = pos + offset;
|
|
|
|
if(addr < r.start || addr >= r.end) {
|
|
|
|
fmt::print(" ");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
int c = v.read_u8(addr);
|
|
|
|
fmt::print(theme(11), "{:c}", isprint(c) ? c : '.');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt::print("\n");
|
|
|
|
}
|
2022-03-04 12:29:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//---
|
|
|
|
// h
|
|
|
|
//---
|
|
|
|
|
|
|
|
static Range parse_h(Session &session, Parser &parser)
|
|
|
|
{
|
2022-04-14 13:30:43 +02:00
|
|
|
Range r = parser.range(session.current_space, 0, 128);
|
|
|
|
parser.end();
|
|
|
|
return r;
|
2022-03-04 12:29:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void _h(Session &session, Range r)
|
|
|
|
{
|
2022-04-14 13:30:43 +02:00
|
|
|
_h_hexdump(session, r, {});
|
2022-03-04 12:29:33 +01:00
|
|
|
}
|
|
|
|
|
2022-04-14 13:30:43 +02:00
|
|
|
static ShellCommand _h_cmd(
|
|
|
|
"h", [](Session &s, Parser &p) { _h(s, parse_h(s, p)); },
|
|
|
|
[](Session &s, Parser &p) { parse_h(s, p); }, "Hexdump", R"(
|
2022-03-06 17:15:13 +01:00
|
|
|
h (<address>|<range>)
|
|
|
|
|
|
|
|
Dumps the specified range into hexadecimal and ASCII representations. When an
|
|
|
|
address is specified, defaults to a length of 128.
|
|
|
|
)");
|