summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--memdisk/Makefile3
-rw-r--r--memdisk/memdisk.asm15
-rw-r--r--memdisk/memdisk.doc23
-rw-r--r--memdisk/setup.c41
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);
}