diff options
Diffstat (limited to 'atr2xfd.c')
-rw-r--r-- | atr2xfd.c | 87 |
1 files changed, 84 insertions, 3 deletions
@@ -13,9 +13,12 @@ #define SELF "atr2xfd" #define CHECK "atrcheck" +char *self = SELF; + +void classify_boot_sector(FILE *); + int main(int argc, char **argv) { char *type; - char *self = SELF; struct stat st; char infile[4096], outfile[4096]; unsigned char buf[16]; @@ -177,7 +180,9 @@ int main(int argc, char **argv) { fprintf(stderr, "%s: %s is a %s\n", self, infile, type); - fprintf(stderr, "%s: ATR image OK (no fatal errors).\n", self); + if(checkonly) { + classify_boot_sector(in); + } hparas = buf[2] + (buf[3] << 8) + (buf[6] << 16); if(hparas != paras) { @@ -197,8 +202,11 @@ int main(int argc, char **argv) { self); } - if(checkonly) + if(checkonly) { exit(0); + } + + fprintf(stderr, "%s: ATR image OK (no fatal errors).\n", self); /* Only open the output file after the ATR is known to be good */ if(strcmp(outfile, "-") == 0) { @@ -242,3 +250,76 @@ int main(int argc, char **argv) { return i; } + +/* these signatures are for the first N bytes of sector 1. */ +unsigned char dos1_sig[] = "\x00\x01\x00\x07\x00\x13\x4c\x12"; +unsigned char dos2_sig[] = "\x00\x03\x00\x07\x40\x15\x4c\x14"; +unsigned char dos3_sig[] = "\x01\x09\x00\x32\x06\x32"; +unsigned char mydos3_sig[] = "\x00\x03\x00\x07\xe0\x07\x4c\x14"; +unsigned char mydos4_sig[] = "\x4d\x03\x00\x07\xe0\x07\x4c\x14"; +unsigned char topdos11_sig[] = "\xc0\x03\x00\x07\x40\x15\x4c\x24"; +unsigned char topdos15_sig[] = "\x80\x03\x00\x07\x40\x15\x4c\x24"; +unsigned char blank_sig[] = "\x00\x00\x00\x00\x00\x00\x00\x00"; +unsigned char pico_sig[] = "\x00\x03\x00\x10\x10\x4c"; + +/* these signatures are for offset $18 of sector 1. */ +unsigned char dos2_code_sig[] = "\x36\xad\x12\x07"; +unsigned char dos25_code_sig[] = "\x35\x20\x5f\x07"; + +#define SIG_MATCH(x, y) (memcmp(x, y, sizeof(y) - 1) == 0) + +void classify_boot_sector(FILE *f) { + unsigned char buf[128]; + char *dos_type = "Unknown", *boot_text = ""; + int bootable = -1; /* -1 = unknown, 0 = no, 1 = yes */ + int i; + + /* read 1st sector... */ + if( (fread(buf, 1, 128, f) < 128) ) { + fprintf(stderr, "%s: EOF reading sector 1, truncated image.\n", self); + exit(2); + } + +#if 1 + for(i = 0; i < 8; i++) fprintf(stderr, "\\x%02x", buf[i]); + fputc('\n', stderr); +#endif + + /* now figure out what kind of boot sector this is */ + if(SIG_MATCH(buf, dos1_sig)) { + dos_type = "DOS 1.0"; + } else if(SIG_MATCH(buf, dos3_sig)) { + dos_type = "DOS 3.0"; + } else if(SIG_MATCH(buf, dos2_sig)) { + if(SIG_MATCH(buf + 0x18, dos2_code_sig)) + dos_type = "DOS 2.0"; + else if(SIG_MATCH(buf + 0x18, dos25_code_sig)) + dos_type = "DOS 2.5"; + else + dos_type = "DOS 2.0 compatible"; + bootable = (buf[14] != 0); + } else if(buf[0] == 0x00 && buf[1] == 0x03 && + (buf[32] == 0x11 || buf[32] == 0x20) && + buf[6] == 0x4c && buf[7] == 0x80) { + if(buf[32] == 0x11) + dos_type = "SpartaDOS 1.1"; + else + dos_type = "SpartaDOS >= 2"; + } else if(SIG_MATCH(buf, mydos3_sig)) { + dos_type = "MyDOS 3.x"; + } else if(SIG_MATCH(buf, mydos4_sig)) { + dos_type = "MyDOS 4.x"; + } else if(SIG_MATCH(buf, pico_sig)) { + dos_type = "MyPicoDOS 4.x"; + } else if(SIG_MATCH(buf, blank_sig)) { + dos_type = "None (empty boot sector)"; + bootable = 0; + } + + if(bootable == 0) + boot_text = ", not bootable"; + else if(bootable == 1) + boot_text = ", bootable"; + + fprintf(stderr, "%s: DOS type is: %s%s\n", self, dos_type, boot_text); +} |