aboutsummaryrefslogtreecommitdiff
path: root/atr2xfd.c
diff options
context:
space:
mode:
Diffstat (limited to 'atr2xfd.c')
-rw-r--r--atr2xfd.c87
1 files changed, 84 insertions, 3 deletions
diff --git a/atr2xfd.c b/atr2xfd.c
index c941266..bed24fe 100644
--- a/atr2xfd.c
+++ b/atr2xfd.c
@@ -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);
+}