summaryrefslogtreecommitdiff
path: root/tool
diff options
context:
space:
mode:
authorJulian Blake Kongslie2022-03-18 11:31:33 -0700
committerJulian Blake Kongslie2022-03-18 11:31:33 -0700
commit1d8eb1f88b1fbb405336bd4980f1884506843f8d (patch)
tree4b149c84beaeec6a1d266424a41b8a7a0fbbb2fc /tool
parentRedraw the diagram in PLAN to make it a little prettier. (diff)
downloadmultipdp8-1d8eb1f88b1fbb405336bd4980f1884506843f8d.tar.xz
Clean up p8bin2uart and support dumping multiple words per line.
Diffstat (limited to '')
-rw-r--r--tool/p8bin2uart.c100
1 files changed, 73 insertions, 27 deletions
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 @@
1// vim: set noexpandtab sw=8 1// vim: set noexpandtab sw=8 :
2 2
3/* 3/*
4 * PDP-8 format converter. 4 * PDP-8 format converter.
@@ -34,9 +34,13 @@
34 * at any 0377 byte, until another 0377 byte is seen. 34 * at any 0377 byte, until another 0377 byte is seen.
35 */ 35 */
36 36
37#include <assert.h>
37#include <inttypes.h> 38#include <inttypes.h>
39#include <stdarg.h>
40#include <stdbool.h>
38#include <stdio.h> 41#include <stdio.h>
39#include <stdlib.h> 42#include <stdlib.h>
43#include <string.h>
40 44
41uint16_t mem[32768]; 45uint16_t mem[32768];
42 46
@@ -122,53 +126,95 @@ load(FILE *fp)
122 return v; 126 return v;
123} 127}
124 128
129#define MAX_LINE_SIZE 1023
130
131char buf[MAX_LINE_SIZE * 2] = {0};
132
125void 133void
126dump() 134print(const char *fmt, ...)
135{
136 va_list args;
137 va_start(args, fmt);
138 int size = vsnprintf(NULL, 0, fmt, args) + 1;
139 va_end(args);
140 char tmp[size];
141 va_start(args, fmt);
142 vsnprintf(tmp, size, fmt, args);
143 va_end(args);
144 strncat(buf, tmp, MAX_LINE_SIZE * 2 - 1);
145 if (strlen(buf) > MAX_LINE_SIZE) {
146 char *space = strrchr(buf, ' ');
147 assert(space);
148 assert(space - buf <= MAX_LINE_SIZE);
149 *space = 0;
150 ++space;
151 assert(strlen(buf) <= MAX_LINE_SIZE);
152 printf("%s\n", buf);
153 memmove(buf, space, buf + sizeof(buf) - space);
154 }
155}
156
157void
158flush()
159{
160 if (buf[0])
161 printf("%s\n", buf);
162 buf[0] = 0;
163}
164
165void
166dump(unsigned int wordsperline)
127{ 167{
128 unsigned int linesize = 0;
129 unsigned int nextaddr = 0; 168 unsigned int nextaddr = 0;
130 for (uint_fast32_t a = 0; a < 32768; ++a) { 169 for (uint_fast32_t a = 0; a < 32768; a += wordsperline) {
131 if (mem[a] == 0) continue; 170 uint16_t words[wordsperline];
171 bool allzero = true;
172 for (uint_fast32_t i = 0; i < wordsperline; ++i) {
173 words[i] = mem[a+i];
174 allzero &= words[i] == 0;
175 }
176 if (allzero) continue;
132 if (nextaddr != a) { 177 if (nextaddr != a) {
133 if (nextaddr + 1 == a) 178 if (nextaddr + wordsperline == a)
134 linesize += printf("="); 179 print("= ");
135 else 180 else
136 linesize += printf("!%x", (unsigned int)(a - nextaddr)); 181 print("!%x ", (unsigned int)((a - nextaddr) / wordsperline));
137 if (linesize > 1018) {
138 printf("\n");
139 linesize = 0;
140 } else {
141 linesize += printf(" ");
142 }
143 } 182 }
144 linesize += printf("=%x", mem[a]); 183 print("=");
145 if (linesize > 1018) { 184 for (uint_fast32_t i = 0; i < wordsperline; ++i) {
146 printf("\n"); 185 if (i != 0)
147 linesize = 0; 186 print(":");
148 } else { 187 print("%04x", (unsigned int)words[i]);
149 linesize += printf(" ");
150 } 188 }
151 nextaddr = a + 1; 189 print(" ");
190 nextaddr = a + wordsperline;
152 } 191 }
153 if (nextaddr != 32768) 192 if (nextaddr != 32768)
154 printf("!%x\n", (unsigned int)(32768 - nextaddr)); 193 print("!%x\n", (unsigned int)((32768 - nextaddr) / wordsperline));
194 flush();
155} 195}
156 196
157int 197int
158main(int argc, char *argv[]) 198main(int argc, char *argv[])
159{ 199{
160 if (argc != 2) { 200 if (argc != 3) {
161 fprintf(stderr, "usage: p8 filename.bin\n"); 201 fprintf(stderr, "usage: p8 wordsperline filename.bin\n");
162 exit(EXIT_FAILURE); 202 exit(EXIT_FAILURE);
163 } 203 }
164 FILE *fp = fopen(argv[1], "rb"); 204 char *end;
165 if (!fp) { 205 unsigned int wordsperline = strtol(argv[1], &end, 0);
206 if (*end) {
166 perror(argv[1]); 207 perror(argv[1]);
167 exit(EXIT_FAILURE); 208 exit(EXIT_FAILURE);
168 } 209 }
210 FILE *fp = fopen(argv[2], "rb");
211 if (!fp) {
212 perror(argv[2]);
213 exit(EXIT_FAILURE);
214 }
169 if (!load(fp)) 215 if (!load(fp))
170 exit(EXIT_FAILURE); 216 exit(EXIT_FAILURE);
171 fclose(fp); 217 fclose(fp);
172 dump(); 218 dump(wordsperline);
173 exit(EXIT_SUCCESS); 219 exit(EXIT_SUCCESS);
174} 220}