#include #include #include #include #include #include #include #define TRACK_SIZE 5325 int main(int argc, char *argv[]) { int done = 0; int rc; uint8_t type = 0; int cyls[] = {0, 256, 512, 1172}; int heads[] = {0, 4, 8, 7}; uint8_t buf[TRACK_SIZE*3]; uint8_t metadata[TRACK_SIZE*2]; int metadata_ndx; uint8_t data[TRACK_SIZE*2]; int data_ndx; int ignore; int header_count; int data_fd, metadata_fd; int tracks = 0; int i; rc = read(STDIN_FILENO, &type, 1); if (rc != 1 || type < 1 || type > 3) { fprintf(stderr, "Invalid type byte %d\n", type); exit(1); } data_fd = open("convert.ext", O_WRONLY | O_CREAT | O_TRUNC, 0666); if (data_fd < 1) { fprintf(stderr, "convert.ext open failed\n"); exit(1); } metadata_fd = open("convert.ext.metadata", O_WRONLY | O_CREAT | O_TRUNC, 0666); if (metadata_fd < 1) { fprintf(stderr, "convert.ext.metadata open failed\n"); exit(1); } do { ignore = 1; metadata_ndx = 0; data_ndx = 0; rc = read(STDIN_FILENO, &buf, TRACK_SIZE*3); if (rc == 0) { done = 1; } else if (rc < 0) { fprintf(stderr, "Read error\n"); exit(1); } else if (rc != TRACK_SIZE*3) { fprintf(stderr, "Short read %d\n", rc); exit(1); } else { for (i = 0; i < TRACK_SIZE*3; i += 3) { if (buf[i+2] == 1) { if (buf[i] == 0x41) { ignore = 1; header_count = 0; } else if (buf[i] == 0x43) { ignore = 0; header_count++; } else { fprintf(stderr, "Bad sector header %x\n", buf[i]); exit(1); } } else if (buf[i+2] == 2) { } else if (buf[i+2] == 0) { if (!ignore) { if (header_count == 1) { metadata[metadata_ndx++] = buf[i+1]; metadata[metadata_ndx++] = buf[i]; if (metadata_ndx % 24 == 0) { ignore = 1; } } else if (header_count == 2) { data[data_ndx++] = buf[i+1]; data[data_ndx++] = buf[i]; if (data_ndx % 512 == 0) { ignore = 1; } } } } else { fprintf(stderr, "Bad word flag %x %d\n", buf[i+2], i); exit(1); } } write(metadata_fd, metadata, metadata_ndx); write(data_fd, data, data_ndx); tracks++; } } while (!done); close(data_fd); close(metadata_fd); printf("Disk is %d cyl %d heads %d tracks. Converted %d tracks\n", cyls[type], heads[type], cyls[type]*heads[type], tracks); }