From 91a86332437e669255002668ba7c97c3efc00cc4 Mon Sep 17 00:00:00 2001 From: Annwan Date: Wed, 3 Jun 2026 00:31:32 +0200 Subject: [PATCH] new: add dump12 utility --- include/common.h | 1 + src/dump12.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ src/logging.c | 10 +++++- src/main.c | 5 ++- 4 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 src/dump12.c diff --git a/include/common.h b/include/common.h index 6763445..78de0b1 100644 --- a/include/common.h +++ b/include/common.h @@ -38,6 +38,7 @@ typedef double f64; // # LOGGING FACILITES [[gnu::format(printf, 1, 2)]] void log_debug(char const *format, ...); +[[gnu::format(printf, 1, 2)]] void log_info(char const *format, ...); [[gnu::format(printf, 1, 2)]] void log_warn(char const *format, ...); [[gnu::format(printf, 1, 2)]] void log_err(char const *format, ...); [[gnu::format(printf, 1, 2)]] void log_err_errno(char const *format, ...); diff --git a/src/dump12.c b/src/dump12.c new file mode 100644 index 0000000..7d21d40 --- /dev/null +++ b/src/dump12.c @@ -0,0 +1,85 @@ +#include +#include +#include + +void dump12_usage() { log_info("Usage: dump12 [-b|-t] [source] [dest]"); } + +i32 dump12_main(i32 argc, char *argv[]) { + bool to_bin = true; + char *inpath = nullptr; + char *outpath = nullptr; + for (i32 i = 1; i < argc; ++i) { + char *arg = argv[i]; + if (arg[0] == '-' && arg[1] == 'b' && arg[2] == '\0') { + to_bin = true; + } else if (arg[0] == '-' && arg[1] == 't' && arg[2] == '\0') { + to_bin = false; + } else if (arg[0] == '-' && arg[1] == 'h' && arg[2] == '\0') { + dump12_usage(); + return 0; + } else if (inpath == nullptr) { + inpath = arg; + } else if (outpath == nullptr) { + outpath = arg; + } else { + log_err("Too many arguments"); + return 1; + } + } + int infd = (inpath == nullptr) ? 0 : open(inpath, O_RDONLY); + if (infd < 0) { + log_err_errno("Couldn't open `%s`", inpath); + return 1; + } + int outfd = + (inpath == nullptr) ? 1 : open(outpath, O_CREAT | O_TRUNC | O_WRONLY); + if (outfd < 0) { + log_err_errno("Couldn't open `%s`", outpath); + return 1; + } + if (to_bin) { + u12 byte12 = 0; + u8 count = 0; + u8 c; + while (read(infd, &c, 1) > 0) { + switch (c) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + byte12 = (byte12 << 3) | (c - '0'); + count++; + break; + default: + } + if (count == 4) { + u8 bs[2] = {byte12 & 0xFF, (byte12 >> 8) & 0xFF}; + write(outfd, bs, 2); + count = 0; + byte12 = 0; + } + } + } else { + usz bytecount = 0; + u8 readbuf[2]; + while (read(infd, readbuf, 2) > 0) { + u12 byte12 = readbuf[0] | (readbuf[1] << 8); + bytecount ++; + u8 outbuf[5] = { + ((byte12 >> 9) & 7) + '0', + ((byte12 >> 6) & 7) + '0', + ((byte12 >> 3) & 7) + '0', + (byte12 & 7) + '0', + (bytecount % 8) ? ' ': '\n', + }; + write(outfd, outbuf, 5); + } + } + close(infd); + close(outfd); + return 0; +} diff --git a/src/logging.c b/src/logging.c index e0db26b..4fe216c 100644 --- a/src/logging.c +++ b/src/logging.c @@ -14,7 +14,7 @@ bool logcolours = true; void log_debug([[maybe_unused]] const char* format, ...) {} #else void log_debug(const char* format, ...) { - fprintf(logfile, "%s[DEBUG]%s ", logcolours ? "\033[1;44;97m" : "", logcolours ? "\033[0" : ""); + fprintf(logfile, "%s[DEBUG]%s ", logcolours ? "\033[1;44;97m" : "", logcolours ? "\033[0m" : ""); va_list va; va_start(va); vfprintf(logfile, format, va); @@ -22,6 +22,14 @@ void log_debug(const char* format, ...) { fprintf(logfile, "\n"); } #endif +void log_info(const char* format, ...) { + fprintf(logfile, "%s[WARN]%s ", logcolours ? "\033[1;43;97m": "", logcolours ? "\033[0m" : ""); + va_list va; + va_start(va); + vfprintf(logfile, format, va); + va_end(va); + fprintf(logfile, "\n"); +} void log_warn(const char* format, ...) { fprintf(logfile, "%s[WARN]%s ", logcolours ? "\033[1;43;97m": "", logcolours ? "\033[0m" : ""); va_list va; diff --git a/src/main.c b/src/main.c index 58fbb22..d084d25 100644 --- a/src/main.c +++ b/src/main.c @@ -7,9 +7,10 @@ enum subprorgram { }; const char *available = (R"m( - asm)m"); + asm, dump12)m"); i32 asm_main(i32 argc, char *argv[]); +i32 dump12_main(i32 argc, char *argv[]); i32 main(i32 argc, char *argv[]) { if (argc < 2) { log_err("No subprogram called\nAvailable subprograms:%s", available); @@ -17,6 +18,8 @@ i32 main(i32 argc, char *argv[]) { } if (!strcmp(argv[1], "asm")) { return asm_main(argc - 1, argv + 1); + } else if (!strcmp(argv[1], "dump12")) { + return dump12_main(argc - 1, argv + 1); } else { log_err("Unknown subprogram `%s`\nAvailable subpograms:%s", argv[1], available); return 1;