diff options
-rw-r--r-- | memdisk/Makefile | 3 | ||||
-rw-r--r-- | memdisk/memdisk.asm | 15 | ||||
-rw-r--r-- | memdisk/memdisk.doc | 23 | ||||
-rw-r--r-- | memdisk/setup.c | 41 |
4 files changed, 54 insertions, 28 deletions
diff --git a/memdisk/Makefile b/memdisk/Makefile index ed573525..b896577e 100644 --- a/memdisk/Makefile +++ b/memdisk/Makefile @@ -18,8 +18,9 @@ gcc_ok = $(shell if gcc $(1) -c -x c /dev/null -o /dev/null 2>/dev/null; \ M32 := $(call gcc_ok,-m32,) ALIGN := $(call gcc_ok,-falign-functions=0 -falign-jumps=0 -falign-loops=0,-malign-functions=0 -malign-jumps=0 -malign-loops=0) +FREE := $(call gcc_ok,-ffreestanding,) -CC = gcc $(M32) +CC = gcc $(M32) $(FREE) CFLAGS = -g -W -Wall -Wno-sign-compare \ -Os -fomit-frame-pointer -march=i386 $(ALIGN) \ -DVERSION='"$(VERSION)"' -DDATE='"$(DATE)"' diff --git a/memdisk/memdisk.asm b/memdisk/memdisk.asm index 6eb83302..c59704da 100644 --- a/memdisk/memdisk.asm +++ b/memdisk/memdisk.asm @@ -177,19 +177,24 @@ DoneWeird: Reset: ; Reset affects multiple drives, so we need to pass it on TRACER 'R' + xor ax,ax ; Bottom of memory + mov es,ax test dl,dl ; Always pass it on if we are resetting HD - js .pass_on ; Bit 7 set + js .hard_disk ; Bit 7 set ; Some BIOSes get very unhappy if we pass a reset floppy ; command to them and don't actually have any floppies. ; This is a bug, but we have to deal with it nontheless. ; Therefore, if we are the *ONLY* floppy drive, and the ; user didn't request HD reset, then just drop the command. - xor ax,ax ; Bottom of memory - mov es,ax ; BIOS equipment byte, top two bits + 1 == total # of floppies - test byte [es:0x410],0C0h + test byte [es:0x410],0C0h jz success - ; ... otherwise pass it to the BIOS + jmp .pass_on ; ... otherwise pass it to the BIOS +.hard_disk: + ; ... same thing for hard disks, sigh ... + cmp byte [es:0x475],1 ; BIOS variable for number of hard disks + jbe success + .pass_on: pop ax ; Drop return address popad ; Restore all registers diff --git a/memdisk/memdisk.doc b/memdisk/memdisk.doc index b8fbfb07..6a8c94a0 100644 --- a/memdisk/memdisk.doc +++ b/memdisk/memdisk.doc @@ -52,14 +52,21 @@ b) If the disk image is one of the following sizes, it's assumed to be a You can also specify the geometry manually with the following command line options: - c=<number> Specify number of cylinders (max 1024[*]) - h=<number> Specify number of heads (max 256[*]) - s=<number> Specify number of sectors (max 63) - floppy The image is a floppy image - harddisk The image is a hard disk image - - [*] MS-DOS only allows max 255 heads, and only allows 255 cylinders - on floppy disks. + c=# Specify number of cylinders (max 1024[*]) + h=# Specify number of heads (max 256[*]) + s=# Specify number of sectors (max 63) + floppy[=#] The image is a floppy image[**] + harddisk[=#] The image is a hard disk image[**] + + # represents a decimal number. + + [*] MS-DOS only allows max 255 heads, and only allows 255 cylinders + on floppy disks. + + [**] Normally MEMDISK emulates the first floppy or hard disk. This + can be overridden by specifying an index, e.g. floppy=1 will + simulate fd1 (B:). This may not work on all operating systems + or BIOSes. c) The disk is normally writable (although, of course, there is nothing backing it up, so it only lasts until reset.) If you want, diff --git a/memdisk/setup.c b/memdisk/setup.c index 559b1aaf..187cbf95 100644 --- a/memdisk/setup.c +++ b/memdisk/setup.c @@ -1,7 +1,7 @@ #ident "$Id$" /* ----------------------------------------------------------------------- * * - * Copyright 2001-2004 H. Peter Anvin - All Rights Reserved + * Copyright 2001-2005 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -427,13 +427,13 @@ const struct geometry *get_disk_image_geometry(uint32_t where, uint32_t size) if ( CMD_HASDATA(p = getcmditem("s")) && (v = atou(p)) ) hd_geometry.s = v; - if ( getcmditem("floppy") != CMD_NOTFOUND ) { - hd_geometry.driveno = 0; + if ( (p = getcmditem("floppy")) != CMD_NOTFOUND ) { + hd_geometry.driveno = CMD_HASDATA(p) ? atou(p) & 0x7f : 0; if ( hd_geometry.type == 0 ) hd_geometry.type = 0x10; /* ATAPI floppy, e.g. LS-120 */ drive_specified = 1; - } else if ( getcmditem("harddisk") != CMD_NOTFOUND ) { - hd_geometry.driveno = 0x80; + } else if ( (p = getcmditem("harddisk")) != CMD_NOTFOUND ) { + hd_geometry.driveno = CMD_HASDATA(p) ? atou(p) | 0x80 : 0x80; hd_geometry.type = 0; drive_specified = 1; } @@ -717,18 +717,31 @@ uint32_t setup(syscall_t cs_syscall, void *cs_bounce) if ( geometry->driveno & 0x80 ) { /* Update BIOS hard disk count */ - wrz_8(BIOS_HD_COUNT, rdz_8(BIOS_HD_COUNT)+1); + int nhd = rdz_8(BIOS_HD_COUNT); + + nhd++; + if ( nhd <= (geometry->driveno & 0x7f) ) + nhd = (geometry->driveno & 0x7f) + 1; + + if ( nhd > 128 ) + nhd = 128; + + wrz_8(BIOS_HD_COUNT, nhd); } else { /* Update BIOS floppy disk count */ uint8_t equip = rdz_8(BIOS_EQUIP); - if ( equip & 1 ) { - if ( (equip & (3 << 6)) != (3 << 6) ) { - equip += (1 << 6); - } - } else { - equip |= 1; - equip &= ~(3 << 6); - } + int nflop = (equip & 1) ? (equip >> 6) : 0; + + nflop++; + if ( nflop <= geometry->driveno ) + nflop = geometry->driveno + 1; + + if ( nflop > 4 ) + nflop = 4; + + equip |= 1; + equip &= ~(3 << 6); + equip |= (nflop-1) << 6; wrz_8(BIOS_EQUIP, equip); } |