From 1d8eb1f88b1fbb405336bd4980f1884506843f8d Mon Sep 17 00:00:00 2001 From: Julian Blake Kongslie Date: Fri, 18 Mar 2022 11:31:33 -0700 Subject: Clean up p8bin2uart and support dumping multiple words per line. --- tool/p8bin2uart.c | 100 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 73 insertions(+), 27 deletions(-) (limited to 'tool') diff --git a/tool/p8bin2uart.c b/tool/p8bin2uart.c index 13ac38c..0eec14e 100644 --- a/tool/p8bin2uart.c +++ b/tool/p8bin2uart.c @@ -1,4 +1,4 @@ -// vim: set noexpandtab sw=8 +// vim: set noexpandtab sw=8 : /* * PDP-8 format converter. @@ -34,9 +34,13 @@ * at any 0377 byte, until another 0377 byte is seen. */ +#include #include +#include +#include #include #include +#include uint16_t mem[32768]; @@ -122,53 +126,95 @@ load(FILE *fp) return v; } +#define MAX_LINE_SIZE 1023 + +char buf[MAX_LINE_SIZE * 2] = {0}; + void -dump() +print(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + int size = vsnprintf(NULL, 0, fmt, args) + 1; + va_end(args); + char tmp[size]; + va_start(args, fmt); + vsnprintf(tmp, size, fmt, args); + va_end(args); + strncat(buf, tmp, MAX_LINE_SIZE * 2 - 1); + if (strlen(buf) > MAX_LINE_SIZE) { + char *space = strrchr(buf, ' '); + assert(space); + assert(space - buf <= MAX_LINE_SIZE); + *space = 0; + ++space; + assert(strlen(buf) <= MAX_LINE_SIZE); + printf("%s\n", buf); + memmove(buf, space, buf + sizeof(buf) - space); + } +} + +void +flush() +{ + if (buf[0]) + printf("%s\n", buf); + buf[0] = 0; +} + +void +dump(unsigned int wordsperline) { - unsigned int linesize = 0; unsigned int nextaddr = 0; - for (uint_fast32_t a = 0; a < 32768; ++a) { - if (mem[a] == 0) continue; + for (uint_fast32_t a = 0; a < 32768; a += wordsperline) { + uint16_t words[wordsperline]; + bool allzero = true; + for (uint_fast32_t i = 0; i < wordsperline; ++i) { + words[i] = mem[a+i]; + allzero &= words[i] == 0; + } + if (allzero) continue; if (nextaddr != a) { - if (nextaddr + 1 == a) - linesize += printf("="); + if (nextaddr + wordsperline == a) + print("= "); else - linesize += printf("!%x", (unsigned int)(a - nextaddr)); - if (linesize > 1018) { - printf("\n"); - linesize = 0; - } else { - linesize += printf(" "); - } + print("!%x ", (unsigned int)((a - nextaddr) / wordsperline)); } - linesize += printf("=%x", mem[a]); - if (linesize > 1018) { - printf("\n"); - linesize = 0; - } else { - linesize += printf(" "); + print("="); + for (uint_fast32_t i = 0; i < wordsperline; ++i) { + if (i != 0) + print(":"); + print("%04x", (unsigned int)words[i]); } - nextaddr = a + 1; + print(" "); + nextaddr = a + wordsperline; } if (nextaddr != 32768) - printf("!%x\n", (unsigned int)(32768 - nextaddr)); + print("!%x\n", (unsigned int)((32768 - nextaddr) / wordsperline)); + flush(); } int main(int argc, char *argv[]) { - if (argc != 2) { - fprintf(stderr, "usage: p8 filename.bin\n"); + if (argc != 3) { + fprintf(stderr, "usage: p8 wordsperline filename.bin\n"); exit(EXIT_FAILURE); } - FILE *fp = fopen(argv[1], "rb"); - if (!fp) { + char *end; + unsigned int wordsperline = strtol(argv[1], &end, 0); + if (*end) { perror(argv[1]); exit(EXIT_FAILURE); } + FILE *fp = fopen(argv[2], "rb"); + if (!fp) { + perror(argv[2]); + exit(EXIT_FAILURE); + } if (!load(fp)) exit(EXIT_FAILURE); fclose(fp); - dump(); + dump(wordsperline); exit(EXIT_SUCCESS); } -- cgit v1.2.3