#include #include #include #include #include #include #include #include #include #define ZXDUMP_STRIDE_LINE 16 #define ZXDUMP_STRIDE_GROUP 2 #define ZXDUMP_CHARSET_LEN 64 static uint16_t charset[ZXDUMP_CHARSET_LEN] = { 0x0020, 0x2598, 0x259d, 0x2580, 0x2596, 0x258c, 0x259e, 0x259b, 0x2592, '.', '.', '"', 0x00a3, '$', ':', '?', '(', ')', '>', '<', '=', '+', '-', '*', '/', ';', ',', '.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', }; static void usage(int argc, char **argv, char *message, ...) { if (message != NULL) { va_list args; va_start(args, message); vfprintf(stderr, message, args); fputc('\n', stderr); va_end(args); } fprintf(stderr, "usage: %s file\n", argv[0]); exit(1); } static inline size_t utf8_encode(uint8_t *buf, uint32_t codepoint) { if ((codepoint & 0x007f) == codepoint) { buf[0] = codepoint & 0x007f; return 1; } else if ((codepoint & 0x07ff) == codepoint) { buf[0] = 0xc0 | ((codepoint & 0x07c0) >> 6); buf[1] = 0x80 | (codepoint & 0x003f); return 2; } else if ((codepoint & 0xffff) == codepoint) { buf[0] = 0xe0 | ((codepoint & 0xf000) >> 12); buf[1] = 0x80 | ((codepoint & 0x0fc0) >> 6); buf[2] = 0x80 | (codepoint & 0x003f); return 3; } else { buf[0] = 0xf0 | ((codepoint & 0x1c0000) >> 18); buf[1] = 0x80 | ((codepoint & 0x03f000) >> 12); buf[2] = 0x80 | ((codepoint & 0x000fc0) >> 6); buf[3] = 0x80 | (codepoint & 0x00003f); return 4; } } static ssize_t dump_line(off_t offset, void *buf, size_t len) { size_t i; if (printf("%08zx: ", offset) < 0) { goto error_io; } for (i=0; i 0 && (i % ZXDUMP_STRIDE_GROUP) == 0) { if (putchar(' ') < 0) { goto error_io; } } if (i < len) { if (printf("%02x", ((uint8_t *)buf)[offset+i]) < 0) { goto error_io; } } else { if (printf(" ") < 0) { goto error_io; } } } if (printf(" ") < 0) { goto error_io; } for (i=0; i