From: Alan Cox Date: Thu, 27 Nov 2014 01:03:41 +0000 (+0000) Subject: decbdragon: Turn the DECB stream into a set of ROM images X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=e84cee92831052e8bd049ecd5cb3c67ea97d9388;p=FUZIX.git decbdragon: Turn the DECB stream into a set of ROM images --- diff --git a/Kernel/tools/decbdragon.c b/Kernel/tools/decbdragon.c new file mode 100755 index 00000000..6fb719ce --- /dev/null +++ b/Kernel/tools/decbdragon.c @@ -0,0 +1,150 @@ +#include +#include +#include + +static enum { + NEW_BLOCK, + PREAMBLE_1, + PREAMBLE_2, + PREAMBLE_3, + PREAMBLE_4, + POSTAMBLE_1, + POSTAMBLE_2, + POSTAMBLE_3, + POSTAMBLE_4, + DONE, + BYTESTREAM +} state = NEW_BLOCK; + +static int copying = 0; + +static unsigned char roms[32768]; +static unsigned char decb[16384]; +static unsigned char *decbptr = decb; + +static void write_rom(char *path, unsigned char *buf, int len) +{ + int fd = creat(path, 0666); + if (fd == -1) { + perror(path); + exit(1); + } + if (write(fd, buf, len) != len) { + perror(path); + exit(1); + } + if (close(fd) != 0) { + perror(path); + exit(1); + } +} + +int main(int argc, char *argv[]) +{ + unsigned int c; + unsigned int base, size; + + if (argc != 5) { + fprintf(stderr, "%s: [bootrom] [secondrom] [cart1rom] [cart2rom]\n", + argv[0]); + exit(1); + } + while(state != DONE && (c = getchar()) != EOF) { + switch(state) { + case NEW_BLOCK: + if (c == 0xFF) { + state = POSTAMBLE_1; + break; + } + if (c == 0x00) { + state = PREAMBLE_1; + break; + } + fprintf(stderr, "Corrupt DECB (%d)\n", c); + exit(1); + break; + + case POSTAMBLE_1: + if (c != 0x00) { + fprintf(stderr, "DECB postamble byte 0 not 0x00\n"); + exit(1); + } + state = POSTAMBLE_2; + break; + case POSTAMBLE_2: + if (c != 0x00) { + fprintf(stderr, "DECB postamble byte 2 not 0x00\n"); + exit(1); + } + state = POSTAMBLE_3; + break; + case POSTAMBLE_3: + state = POSTAMBLE_4; + break; + case POSTAMBLE_4: + *decbptr++ = 0xFF; + *decbptr++ = 0x00; + *decbptr++ = 0x00; + *decbptr++ = 0x80; + *decbptr++ = 0x00; + state = DONE; + break; + + case PREAMBLE_1: + size = c << 8; + state = PREAMBLE_2; + break; + case PREAMBLE_2: + size += c; + state = PREAMBLE_3; + break; + case PREAMBLE_3: + base = c << 8; + state = PREAMBLE_4; + break; + case PREAMBLE_4: + base += c; + state = BYTESTREAM; + if (base < 0x8000 && base + size > 0x8000) { + fprintf(stderr, "Split block\n"); + exit(1); + } + if (base < 0x8000) { + copying = 1; + fprintf(stderr, "Copy block at %04x for %04x\n", base, size); + *decbptr++ = 0x00; + *decbptr++ = size >> 8; + *decbptr++ = size & 0xff; + *decbptr++ = base >> 8; + *decbptr++ = base & 0xff; + } + else { + fprintf(stderr, "ROM block at %04x for %04x\n", base, size); + copying = 0; + } + break; + case BYTESTREAM: + if (copying) + *decbptr++ = c; + else + roms[base++ - 0x8000] = c; + size--; + if (size == 0) + state = NEW_BLOCK; + break; + default: + fprintf(stderr, "State machine horked.\n"); + exit(1); + } + } + if (state != DONE) { + fprintf(stderr, "Unexpected EOF in state %d\n", state); + exit(1); + } + write_rom(argv[1], decb, decbptr-decb); + write_rom(argv[2], roms, 0x4000); + write_rom(argv[3], roms + 0x4000, 0x2000); + write_rom(argv[4], roms + 0x6000, 0x2000); + + exit(0); +}