|
|
|
@ -1,5 +1,6 @@
|
|
|
|
|
#include <fmt/format.h>
|
|
|
|
|
#include <span.hpp>
|
|
|
|
|
#include <hex.hpp>
|
|
|
|
|
|
|
|
|
|
const static constexpr char ascii_map[256] = {
|
|
|
|
|
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
|
|
|
|
@ -20,7 +21,7 @@ const static constexpr char ascii_map[256] = {
|
|
|
|
|
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
constexpr const char* hex_map[256] = {
|
|
|
|
|
constexpr const static char* hex_map[256] = {
|
|
|
|
|
"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f",
|
|
|
|
|
"10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f",
|
|
|
|
|
"20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2a", "2b", "2c", "2d", "2e", "2f",
|
|
|
|
@ -59,52 +60,80 @@ inline void hex02(std::uint8_t byte, char buffer[2])
|
|
|
|
|
buffer[1] =hex_map[byte][1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<int N>
|
|
|
|
|
template<std::size_t N>
|
|
|
|
|
inline __attribute__((always_inline)) void print_exact(const char* ar)
|
|
|
|
|
{
|
|
|
|
|
fwrite(ar, 1, N, stdout);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<std::size_t N>
|
|
|
|
|
inline __attribute__((always_inline)) void print_exact(const char (&ar)[N])
|
|
|
|
|
{
|
|
|
|
|
fwrite(ar, N, 1, stdout);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline static void u64_to_hex(std::uint64_t num, char* s)
|
|
|
|
|
{
|
|
|
|
|
hv::lookup_hex_string(num, s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
namespace hv {
|
|
|
|
|
void print_screen(const span<unsigned char> memory, unsigned long offset)
|
|
|
|
|
{
|
|
|
|
|
#ifndef FIXED_ROW_SIZE
|
|
|
|
|
#define S (const char*)
|
|
|
|
|
#define S (2+ROW_SZ)
|
|
|
|
|
#define P_EX(n, buf) fwrite(buf, 1, n, stdout)
|
|
|
|
|
int ROW_SZ = 24;
|
|
|
|
|
#else
|
|
|
|
|
#define S
|
|
|
|
|
#define P_EX(n, buf) print_exact(buf)
|
|
|
|
|
#endif
|
|
|
|
|
fmt::print("0x{:016x} ", offset);
|
|
|
|
|
char hxbuf[3];
|
|
|
|
|
char posbuf[3 + 16 + 2];
|
|
|
|
|
posbuf[0] = '\n';
|
|
|
|
|
posbuf[1] = '0';
|
|
|
|
|
posbuf[2] = 'x';
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
std::memset(posbuf+3, '0', 16);
|
|
|
|
|
#endif
|
|
|
|
|
posbuf[3 + 16] = ' ';
|
|
|
|
|
posbuf[3 + 16 + 1] = ' ';
|
|
|
|
|
|
|
|
|
|
u64_to_hex(offset, posbuf+3);
|
|
|
|
|
prints(posbuf+1);
|
|
|
|
|
|
|
|
|
|
char hxbuf[3] = { ' ', ' ', ' ' };
|
|
|
|
|
std::size_t i=0;
|
|
|
|
|
char r_ascii[2 + ROW_SZ];
|
|
|
|
|
r_ascii[0] = ' ';
|
|
|
|
|
r_ascii[1] = ' ';
|
|
|
|
|
char* ascii = r_ascii + 2;
|
|
|
|
|
const auto memsize = memory.size();
|
|
|
|
|
|
|
|
|
|
hxbuf[2] = ' ';
|
|
|
|
|
for(;i<memory.size();i++) {
|
|
|
|
|
for(;i<memsize;i++) {
|
|
|
|
|
if (i && i % ROW_SZ == 0) { //TODO: Change to i +=16 so we don't have to branch here on every byte. Make sure to not overrun buffer tho
|
|
|
|
|
print_exact(r_ascii);
|
|
|
|
|
fmt::print("\n0x{:016x} ", i+offset);
|
|
|
|
|
P_EX(S, r_ascii);
|
|
|
|
|
|
|
|
|
|
u64_to_hex(i+offset, posbuf+3);
|
|
|
|
|
print_exact(posbuf);
|
|
|
|
|
}
|
|
|
|
|
unsigned char idx = memory[i];
|
|
|
|
|
hex02(idx, hxbuf);
|
|
|
|
|
print_exact(hxbuf);
|
|
|
|
|
|
|
|
|
|
ascii[i%ROW_SZ] = ascii_map[idx];
|
|
|
|
|
}
|
|
|
|
|
if (memory.size() % ROW_SZ != 0)
|
|
|
|
|
if (memsize % ROW_SZ != 0)
|
|
|
|
|
{
|
|
|
|
|
auto rest = memory.size() % ROW_SZ;
|
|
|
|
|
auto rest = memsize % ROW_SZ;
|
|
|
|
|
ascii[rest] = 0;
|
|
|
|
|
constexpr const char output[3] = { ' ', ' ', ' ' };
|
|
|
|
|
for(std::size_t j=0;j< ROW_SZ - rest;j++)
|
|
|
|
|
print_exact(output);
|
|
|
|
|
|
|
|
|
|
prints(r_ascii);
|
|
|
|
|
prints((const char*) r_ascii);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
print_exact(r_ascii);
|
|
|
|
|
P_EX(S, r_ascii);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|