tools: add cartman
authorAlan Cox <alan@linux.intel.com>
Fri, 28 Sep 2018 12:03:26 +0000 (13:03 +0100)
committerAlan Cox <alan@linux.intel.com>
Fri, 28 Sep 2018 12:03:26 +0000 (13:03 +0100)
Tool to build our MSX cartridge

Kernel/tools/cartman.c [new file with mode: 0644]

diff --git a/Kernel/tools/cartman.c b/Kernel/tools/cartman.c
new file mode 100644 (file)
index 0000000..9a11e3e
--- /dev/null
@@ -0,0 +1,146 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* This code has probably killed Kenny.... */
+
+static unsigned char buf[65536];
+static unsigned char out[65536];
+
+static unsigned int s__CODE, s__INITIALIZER, s__DATA,
+    s__INITIALIZED, s__INITIALIZER, s__COMMONMEM, l__INITIALIZED,
+    l__COMMONMEM, l__CODE, l__DATA;
+
+
+static void ProcessMap(FILE * fp)
+{
+       char buf[512];
+
+       while (fgets(buf, 511, fp)) {
+               char *p1 = strtok(buf, " \t\n");
+               char *p2 = NULL;
+
+               if (p1)
+                       p2 = strtok(NULL, " \t\n");
+
+               if (p1 == NULL || p2 == NULL)
+                       continue;
+
+               if (strcmp(p2, "s__CODE") == 0)
+                       sscanf(p1, "%x", &s__CODE);
+               if (strcmp(p2, "l__CODE") == 0)
+                       sscanf(p1, "%x", &l__CODE);
+               if (strcmp(p2, "s__DATA") == 0)
+                       sscanf(p1, "%x", &s__DATA);
+               if (strcmp(p2, "l__DATA") == 0)
+                       sscanf(p1, "%x", &l__DATA);
+               if (strcmp(p2, "s__INITIALIZED") == 0)
+                       sscanf(p1, "%x", &s__INITIALIZED);
+               if (strcmp(p2, "s__INITIALIZER") == 0)
+                       sscanf(p1, "%x", &s__INITIALIZER);
+               if (strcmp(p2, "l__INITIALIZED") == 0)
+                       sscanf(p1, "%x", &l__INITIALIZED);
+               if (strcmp(p2, "s__COMMONMEM") == 0)
+                       sscanf(p1, "%x", &s__COMMONMEM);
+               if (strcmp(p2, "l__COMMONMEM") == 0)
+                       sscanf(p1, "%x", &l__COMMONMEM);
+       }
+}
+
+
+int main(int argc, char *argv[])
+{
+       FILE *map, *bin;
+       int tail = 0;
+       int start;
+       unsigned int end = 0;
+       int reloc = 0;
+       int pack_discard = 0;
+       int no_pack = 0;
+       int base;
+
+       if (argc != 4) {
+               fprintf(stderr, "%s: [binary] [map] [output]\n", argv[0]);
+               exit(1);
+       }
+       bin = fopen(argv[1], "r");
+       if (bin == NULL) {
+               perror(argv[1]);
+               exit(1);
+       }
+       if (fread(buf, 1, 65536, bin) == 0) {
+               fprintf(stderr, "%s: read error on %s\n", argv[0],
+                       argv[1]);
+               exit(1);
+       }
+       fclose(bin);
+
+        /* Start with the output matching the input */
+       memcpy(out, buf, 65536);
+
+       map = fopen(argv[2], "r");
+       if (map == NULL) {
+               perror(argv[2]);
+               exit(1);
+       }
+       ProcessMap(map);
+       fclose(map);
+
+       /* The packing for an MSX cartridge is not dissimilar to the usual
+          but has different constaints and because it's ROM we actually
+          have to pack difering bits */
+
+        printf("Scanning data from 0x%x to 0x%x\n",
+                s__DATA, s__DATA + l__DATA);
+       base = s__DATA;
+       while (base < s__DATA + l__DATA) {
+               if (buf[base] && buf[base] != 0xFF) {
+                       fprintf(stderr, "0x%04x:0x%02x\n",
+                               base, (unsigned char)buf[base]);
+                }
+                base++;
+        }
+
+       /* Our standard layout begins with the code */
+       start = s__CODE;
+
+       if (s__CODE != 0 || l__CODE > 0x4000) {
+               fprintf(stderr, "Segment CODE must start at 0 and be under 16K long (%04X %04X).\n",
+                       s__CODE, l__CODE);
+               exit(1);
+       }
+       /* We need to pack the writable stuff. We use the same basic model as
+          the other packers. */
+
+       /* Our prepared image ends with initializer in ROM to go to INITIALIZED
+          Append the common on the end of it */
+       end = s__INITIALIZER + l__INITIALIZED;
+       memcpy(out + end, buf + s__COMMONMEM, l__COMMONMEM);
+
+       printf("Commonmem packed at %04X for %04X bytes.\n",
+               end, l__COMMONMEM);
+       end += l__COMMONMEM;
+       printf("Image ends at %04X\n", end);
+
+       if (end >= 0xC000) {
+               /* One day we may have to put discard in the top 16K and
+                  juggle it into RAM */
+               fprintf(stderr, "Image does not fit in 48K of cartridge.\n");
+               exit(1);
+       }
+
+       bin = fopen(argv[3], "w");
+       if (bin == NULL) {
+               perror(argv[3]);
+               exit(1);
+       }
+       printf("Image file: %04X to %04X\n", start, end);
+       if (fwrite(out, 65536, 1, bin) != 1) {
+               perror(argv[3]);
+               exit(1);
+       }
+       fclose(bin);
+       exit(0);
+}
+