diff options
| author | Julian Blake Kongslie | 2022-03-18 11:31:33 -0700 |
|---|---|---|
| committer | Julian Blake Kongslie | 2022-03-18 11:31:33 -0700 |
| commit | 1d8eb1f88b1fbb405336bd4980f1884506843f8d (patch) | |
| tree | 4b149c84beaeec6a1d266424a41b8a7a0fbbb2fc | |
| parent | Redraw the diagram in PLAN to make it a little prettier. (diff) | |
| download | multipdp8-1d8eb1f88b1fbb405336bd4980f1884506843f8d.tar.xz | |
Clean up p8bin2uart and support dumping multiple words per line.
Diffstat (limited to '')
| -rw-r--r-- | tool/p8bin2uart.c | 100 |
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 | ||
| 41 | uint16_t mem[32768]; | 45 | uint16_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 | |||
| 131 | char buf[MAX_LINE_SIZE * 2] = {0}; | ||
| 132 | |||
| 125 | void | 133 | void |
| 126 | dump() | 134 | print(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 | |||
| 157 | void | ||
| 158 | flush() | ||
| 159 | { | ||
| 160 | if (buf[0]) | ||
| 161 | printf("%s\n", buf); | ||
| 162 | buf[0] = 0; | ||
| 163 | } | ||
| 164 | |||
| 165 | void | ||
| 166 | dump(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 | ||
| 157 | int | 197 | int |
| 158 | main(int argc, char *argv[]) | 198 | main(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 | } |
