From d6602155807fb32c44d437d8d6ccd5d5c2a5ddeb Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 19 Feb 2015 11:51:44 +0000 Subject: [PATCH] fstomdv: turn an fs image into a microdrive cartridge --- Kernel/tools/fstomdv.c | 139 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 Kernel/tools/fstomdv.c diff --git a/Kernel/tools/fstomdv.c b/Kernel/tools/fstomdv.c new file mode 100644 index 00000000..23d9865b --- /dev/null +++ b/Kernel/tools/fstomdv.c @@ -0,0 +1,139 @@ +#include +#include +#include +#include +#include +#include + +static int mdv_sec = 1; +static int fslen; +static uint8_t fsbuf[512 * 253]; + +static uint8_t mdv_csum(uint8_t *data, int len) +{ + uint32_t sum = 0; + while(len--) { + sum += *data++; + } + return sum % 0xFF; +} + + +static void mdv_write(FILE *fp, uint8_t *data, int len) +{ + if (fwrite(data, len, 1, fp) != 1) { + perror("mdv_write"); + exit(1); + } +} + +static void mdv_make_hdr(uint8_t *buf) +{ + memset(buf, 0, 14); + buf[0] = 1; + buf[1] = mdv_sec++; + memcpy(buf + 4, "FUZIX ", 10); + buf[14] = mdv_csum(buf, 14); +} + +static void mdv_make_bufhdr(uint8_t *buf, uint8_t rec, uint8_t *bits) +{ + memset(buf, 0, 14); + buf[0] = 0; + buf[1] = rec; /* Actually load page */ + buf[2] = 0; + buf[3] = 2; /* Always 512 bytes */ + strncpy(buf+4, "FUZIX ", 10); + buf[14] = mdv_csum(buf, 14); + memcpy(buf + 15, bits, 512); + buf[527] = mdv_csum(buf + 15, 512); +} + +static uint8_t blank[512]; +static uint8_t sectormap[512]; + + +static void mdv_write_tape(FILE *fp) +{ + uint8_t buf[528]; + uint8_t *bits; + int block = 1; + uint8_t *stream = fsbuf; + + while (block < 254) { + mdv_make_hdr(buf); + mdv_write(fp, buf, 15); + if (block == 1 || block == 128) + bits = sectormap; + else { + bits = stream; + stream += 512; + } + mdv_make_bufhdr(buf, block, bits); + mdv_write(fp, buf, 528); + block++; + } +} + +static void mdv_make_map(void) { + int n = 2; + int i; + + memset(sectormap, 0xFF, 512); + sectormap[256] = 0xA5; + sectormap[257] = 0x5A; + + /* Logical to physical map, so start at 2 and go up missing 128 as its + a copy of this map (as is 1) */ + + for (i = 0 ; i < 252; i++) { + sectormap[i] = n++; + if (n == 128) + n++; + } +} + +static void load_filesystem(char *name) +{ + int fd = open(name, O_RDONLY); + long len; + + if (fd == -1) { + perror(name); + exit(1); + } + len = read(fd, fsbuf, 253 * 512); + if (len > 252 * 512) { + fprintf(stderr, "%s: too long.\n"); + exit(1); + } + if (len < 65536) { + fprintf(stderr, "%s: too short ?\n"); + exit(1); + } + fslen = len; +} + +void main(int argc, char *argv[]) +{ + FILE *fp; + uint8_t zero = 0; + + if (argc != 3) { + fprintf(stderr, "%s: imagefile microdrive.mdr\n", argv[0]); + exit(1); + } + + load_filesystem(argv[1]); + + mdv_make_map(); + fp = fopen(argv[2], "w"); + if (fp == NULL) { + perror(argv[1]); + exit(1); + } + mdv_write_tape(fp); + fwrite(&zero, 1, 1, fp); + fclose(fp); + exit(0); +} -- 2.34.1