From 2e3aa7d8fd6ef4d7a64fd4db84629dba1e038d92 Mon Sep 17 00:00:00 2001 From: Christopher Kobayashi Date: Tue, 21 Apr 2020 18:11:21 +0900 Subject: [PATCH] Add makedc42 (convert raw image to DiskCopy 4.2) --- Makefile | 6 +-- makedc42.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 makedc42.c diff --git a/Makefile b/Makefile index 0171061..5821bb0 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,10 @@ -CFLAGS= -O2 -Wall -Werror +CFLAGS= -O2 -Wall -Werror -ggdb -all: dc42cksm +all: dc42cksm makedc42 install: all install -m755 dc42cksm /usr/local/bin/ clean: - rm -f dc42cksm *.o + rm -f dc42cksm makedc42 *.o diff --git a/makedc42.c b/makedc42.c new file mode 100644 index 0000000..000e91d --- /dev/null +++ b/makedc42.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include +#include + +struct dc42_header { + u_int8_t image_name_length; + char image_name[63]; + u_int32_t data_size; + u_int32_t tag_size; + u_int32_t data_checksum; + u_int32_t tag_checksum; + u_int8_t encoding; + u_int8_t format; + u_int16_t magic_number; +}; + +enum encoding { + gcr_ssdd, /* 400k */ + gcr_dsdd, /* 800k */ + mfm_dsdd, /* 720k */ + mfm_dshd /* 1440k */ +}; + +int main(int argc, char **argv) +{ + struct dc42_header header; + + FILE *inputfile = NULL; + FILE *outputfile = NULL; + char outputfilename[255]; + struct stat inputfile_stat; + u_int8_t *file_buffer = NULL; + u_int32_t rv = 0; + u_int16_t check; + int i; + + if (argc != 2) { + printf("usage: makedc42 \n"); + return -1; + } + + memset(&header, 0x00, sizeof(header)); + + if ( (inputfile = fopen(argv[1], "r")) == NULL) { + printf("%s: does not exist.\n", argv[1]); + return -1; + } + + if ( (stat(argv[1], &inputfile_stat)) ) { + printf("%s: could not stat\n", argv[1]); + } + + printf("%s: size is %li\n", argv[1], inputfile_stat.st_size); + + file_buffer = calloc(1, inputfile_stat.st_size); + if (file_buffer != NULL) + printf("%s: read %li bytes into buffer\n", argv[1], + fread(file_buffer, 1, inputfile_stat.st_size, inputfile)); + + if (inputfile != NULL) + fclose(inputfile); + + /* consistency checks */ + check = (file_buffer[0] << 8) + file_buffer[1]; + if (check != 0x4c4b) { + printf("%s: boot block failed consistency check (%x)\n", argv[1], check); + free(file_buffer); + return -1; + } + check = (file_buffer[0x400] << 8) + file_buffer[0x401]; + if (check != 0x4244) { + printf("%s: VIB failed consistency check (%x)\n", argv[1], check); + free(file_buffer); + return -1; + } + + header.magic_number = htons(0x0100); + header.image_name_length = strlen( (char *)&file_buffer[0x425]); + strncpy( (char *)&header.image_name, (char *)&file_buffer[0x425], 27); + + printf("%s: embedded filename is \"%s\" (length %i)\n", argv[1], header.image_name, header.image_name_length); + snprintf(outputfilename, 255, "%s-dc42.img", header.image_name); + printf("%s: output filename is \"%s\"\n", argv[1], outputfilename); + + switch (inputfile_stat.st_size) { + case 1474560: + header.encoding = mfm_dshd; + header.format = 0x22; + break; + case 819200: + header.encoding = gcr_dsdd; + header.format = 0x22; + break; + default: + printf("%s: unknown size, not doing format/encoding\n", argv[1]); + } + + header.data_size = htonl(inputfile_stat.st_size); + + for (i = 0; i < inputfile_stat.st_size; i += 2) { + rv += (file_buffer[i] << 8) + file_buffer[i+1]; + rv = (rv >> 1) + (rv << 31); + } + + printf("%s: calculated checksum %x\n", argv[1], rv); + + header.data_checksum = htonl(rv); + + outputfile = fopen(outputfilename, "w"); + + if (!outputfile) { + printf("%s: could not open output file\n", outputfilename); + free(file_buffer); + return -1; + } + + fwrite(&header, sizeof(header), 1, outputfile); + fwrite(file_buffer, inputfile_stat.st_size, 1, outputfile); + + if (file_buffer != NULL) + free(file_buffer); + + if (outputfile != NULL) + fclose(outputfile); + + return 0; +}