diff options
author | H. Peter Anvin <hpa@zytor.com> | 2008-06-07 14:39:01 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2008-06-07 14:39:01 -0700 |
commit | 8a6f179a7d7d1016988497e2a25b9706ad4ebcd7 (patch) | |
tree | 878a4ebfbfc28a93a78745275175d555059d19d4 /memdisk | |
parent | 6389a53252be6f3eaf8248ee6d58dff88697aad0 (diff) | |
download | syslinux-8a6f179a7d7d1016988497e2a25b9706ad4ebcd7.tar.gz |
MEMDISK: algorithmic determination of floppy formats
Consider all disks < 4 MB to be floppies, and guess their geometry
algorithmically.
Diffstat (limited to 'memdisk')
-rwxr-xr-x | memdisk/fdgeo.pl | 54 | ||||
-rw-r--r-- | memdisk/setup.c | 67 |
2 files changed, 102 insertions, 19 deletions
diff --git a/memdisk/fdgeo.pl b/memdisk/fdgeo.pl new file mode 100755 index 00000000..47d19afa --- /dev/null +++ b/memdisk/fdgeo.pl @@ -0,0 +1,54 @@ +#!/usr/bin/perl +# +# Try automatic generation of geometries +# + +($k) = @ARGV; +$sec = int($k*2+0.5); + +if ($sec < 320*2) { + $c = 40; + $h = 1; + $type = 1; +} elsif ($sec < 640*2) { + $c = 40; + $h = 2; + $type = 1; +} elsif ($sec < 1200*2) { + $c = 80; + $h = 2; + $type = 3; +} elsif ($sec < 1440*2) { + $c = 80; + $h = 2; + $type = 2; +} elsif ($sec < 2880*2) { + $c = 80; + $h = 2; + $type = 4; +} elsif ($sec < 4096*2) { + $c = 80; + $h = 2; + $type = 6; +} else { + printf "%.1fK, %d sectors: ", $sec/2, $sec; + print "Considered a hard disk\n"; +} + +$ok = 0; +while ($c < 256) { + $s = int($sec/($c*$h)+0.5); + if ($s <= 63 && $sec == $c*$h*$s) { + $ok = 1; + last; + } + $c++; +} + +printf "%.1fK, %d sectors: ", $sec/2, $sec; +if ($ok) { + print "c=$c, h=$h, s=$s, type=$type\n"; +} else { + print "No valid geometry found (MEMDISK will fake it)\n"; +} + diff --git a/memdisk/setup.c b/memdisk/setup.c index 298720a5..4d38598a 100644 --- a/memdisk/setup.c +++ b/memdisk/setup.c @@ -362,19 +362,6 @@ struct geometry { uint8_t driveno; /* Drive no */ }; -static const struct geometry geometries[] = -{ - { 360*2, 40, 2, 9, 0, 0x01, 0 }, /* 360 K */ - { 720*2, 80, 2, 9, 0, 0x03, 0 }, /* 720 K*/ - { 1200*2, 80, 2, 15, 0, 0x02, 0 }, /* 1200 K */ - { 1440*2, 80, 2, 18, 0, 0x04, 0 }, /* 1440 K */ - { 1680*2, 80, 2, 21, 0, 0x04, 0 }, /* 1680 K */ - { 1722*2, 82, 2, 21, 0, 0x04, 0 }, /* 1722 K */ - { 2880*2, 80, 2, 36, 0, 0x06, 0 }, /* 2880 K */ - { 3840*2, 80, 2, 48, 0, 0x06, 0 }, /* 3840 K */ -}; -#define known_geometries (sizeof(geometries)/sizeof(struct geometry)) - /* Format of a DOS partition table entry */ struct ptab_entry { uint8_t active; @@ -399,7 +386,7 @@ struct dosemu_header { const struct geometry *get_disk_image_geometry(uint32_t where, uint32_t size) { - static struct geometry hd_geometry = { 0, 0, 0, 0, 0, 0, 0x80 }; + static struct geometry hd_geometry; struct ptab_entry ptab[4]; /* Partition table buffer */ struct dosemu_header dosemu; unsigned int sectors, v; @@ -416,11 +403,52 @@ const struct geometry *get_disk_image_geometry(uint32_t where, uint32_t size) offset = v; sectors = (size-offset) >> 9; - for ( i = 0 ; i < known_geometries ; i++ ) { - if ( sectors == geometries[i].sectors ) { - hd_geometry = geometries[i]; - break; + + if (sectors < 4096*2) { + int ok = 0; + unsigned int xsectors = sectors; + + while (!ok) { + /* Assume it's a floppy drive, guess a geometry */ + unsigned int type, track; + + if (xsectors < 320*2) { + c = 40; h = 1; type = 1; + } else if (xsectors < 640*2) { + c = 40; h = 2; type = 1; + } else if (xsectors < 1200*2) { + c = 80; h = 2; type = 3; + } else if (xsectors < 1440*2) { + c = 80; h = 2; type = 2; + } else if (xsectors < 2880*2) { + c = 80; h = 2; type = 4; + } else { + c = 80; h = 2; type = 6; + } + track = c*h; + while (c < 256) { + s = xsectors/track; + if (s < 63 && (xsectors % track) == 0) { + ok = 1; + break; + } + c++; + track += h; + } + if (ok) { + hd_geometry.driveno = 0; + hd_geometry.c = c; + hd_geometry.h = h; + hd_geometry.s = s; + } else { + /* No valid floppy geometry, fake it by simulating broken + sectors at the end of the image... */ + xsectors++; + } } + } else { + /* Hard disk */ + hd_geometry.driveno = 0x80; } hd_geometry.sectors = sectors; @@ -606,10 +634,11 @@ __cdecl void setup(__cdecl syscall_t cs_syscall, void *cs_bounce) else do_edd = (geometry->driveno & 0x80) ? 1 : 0; - printf("Disk is %s %d, %u K, C/H/S = %u/%u/%u, EDD %s\n", + printf("Disk is %s %d, %u%s K, C/H/S = %u/%u/%u, EDD %s\n", (geometry->driveno & 0x80) ? "hard disk" : "floppy", geometry->driveno & 0x7f, geometry->sectors >> 1, + (geometry->sectors & 1) ? ".5" : "", geometry->c, geometry->h, geometry->s, do_edd ? "on" : "off"); |