diff -ruN /qemu-0.6.1/work/qemu-0.6.1/Changelog qemu-snapshot-2004-11-26_23/Changelog
--- /qemu-0.6.1/work/qemu-0.6.1/Changelog	2004-11-14 21:51:33.000000000 +0100
+++ qemu-snapshot-2004-11-26_23/Changelog	2004-11-24 20:31:21.000000000 +0100
@@ -1,3 +1,9 @@
+version 0.6.2:
+
+  - better BIOS translation and HDD geometry auto-detection
+  - user mode networking bug fix
+  - undocumented FPU ops support
+
 version 0.6.1:
 
   - Mac OS X port (Pierre d'Herbemont)
diff -ruN /qemu-0.6.1/work/qemu-0.6.1/Makefile qemu-snapshot-2004-11-26_23/Makefile
--- /qemu-0.6.1/work/qemu-0.6.1/Makefile	2004-11-14 21:51:33.000000000 +0100
+++ qemu-snapshot-2004-11-26_23/Makefile	2004-11-16 02:44:03.000000000 +0100
@@ -10,18 +10,18 @@
 LDFLAGS=-g
 LIBS=
 DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
-TOOLS=qemu-img
+TOOLS=qemu-img$(EXESUF)
 ifdef CONFIG_STATIC
 LDFLAGS+=-static
 endif
-DOCS=qemu-doc.html qemu-tech.html qemu.1
+DOCS=qemu-doc.html qemu-tech.html qemu.1 qemu-img.1
 
 all: dyngen$(EXESUF) $(TOOLS) $(DOCS)
 	for d in $(TARGET_DIRS); do \
 	$(MAKE) -C $$d $@ || exit 1 ; \
         done
 
-qemu-img: qemu-img.c block.c block-cow.c block-qcow.c aes.c block-vmdk.c block-cloop.c
+qemu-img$(EXESUF): qemu-img.c block.c block-cow.c block-qcow.c aes.c block-vmdk.c block-cloop.c
 	$(CC) -DQEMU_TOOL $(CFLAGS) $(LDFLAGS) $(DEFINES) -o $@ $^ -lz $(LIBS)
 
 dyngen$(EXESUF): dyngen.c
@@ -30,7 +30,7 @@
 clean:
 # avoid old build problems by removing potentially incorrect old files
 	rm -f config.mak config.h op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h 
-	rm -f *.o *.a $(TOOLS) dyngen$(EXESUF) TAGS qemu.pod *~ */*~
+	rm -f *.o *.a $(TOOLS) dyngen$(EXESUF) TAGS *.pod *~ */*~
 	$(MAKE) -C tests clean
 	for d in $(TARGET_DIRS); do \
 	$(MAKE) -C $$d $@ || exit 1 ; \
@@ -44,9 +44,7 @@
 
 install: all 
 	mkdir -p "$(bindir)"
-ifndef CONFIG_WIN32
 	install -m 755 -s $(TOOLS) "$(bindir)"
-endif
 	mkdir -p "$(datadir)"
 	install -m 644 pc-bios/bios.bin pc-bios/vgabios.bin \
                        pc-bios/vgabios-cirrus.bin \
@@ -57,7 +55,7 @@
 	install -m 644 qemu-doc.html  qemu-tech.html "$(docdir)"
 ifndef CONFIG_WIN32
 	mkdir -p "$(mandir)/man1"
-	install qemu.1 qemu-mkcow.1 "$(mandir)/man1"
+	install qemu.1 qemu-img.1 "$(mandir)/man1"
 endif
 	for d in $(TARGET_DIRS); do \
 	$(MAKE) -C $$d $@ || exit 1 ; \
@@ -78,6 +76,10 @@
 	./texi2pod.pl $< qemu.pod
 	pod2man --section=1 --center=" " --release=" " qemu.pod > $@
 
+qemu-img.1: qemu-img.texi
+	./texi2pod.pl $< qemu-img.pod
+	pod2man --section=1 --center=" " --release=" " qemu-img.pod > $@
+
 FILE=qemu-$(shell cat VERSION)
 
 # tar release (use 'make -k tar' on a checkouted tree)
@@ -92,6 +94,7 @@
 	( cd / ; tar zcvf ~/qemu-$(VERSION)-i386.tar.gz \
 	$(bindir)/qemu $(bindir)/qemu-fast \
 	$(bindir)/qemu-system-ppc \
+	$(bindir)/qemu-system-sparc \
 	$(bindir)/qemu-i386 \
         $(bindir)/qemu-arm \
         $(bindir)/qemu-sparc \
@@ -105,7 +108,7 @@
 	$(datadir)/linux_boot.bin \
 	$(docdir)/qemu-doc.html \
 	$(docdir)/qemu-tech.html \
-	$(mandir)/man1/qemu.1 $(mandir)/man1/qemu-mkcow.1 )
+	$(mandir)/man1/qemu.1 $(mandir)/man1/qemu-img.1 )
 
 ifneq ($(wildcard .depend),)
 include .depend
diff -ruN /qemu-0.6.1/work/qemu-0.6.1/VERSION qemu-snapshot-2004-11-26_23/VERSION
--- /qemu-0.6.1/work/qemu-0.6.1/VERSION	2004-11-14 21:51:33.000000000 +0100
+++ qemu-snapshot-2004-11-26_23/VERSION	2004-11-24 20:31:52.000000000 +0100
@@ -1 +1 @@
-0.6.1
\ No newline at end of file
+0.6.2
\ No newline at end of file
diff -ruN /qemu-0.6.1/work/qemu-0.6.1/block.c qemu-snapshot-2004-11-26_23/block.c
--- /qemu-0.6.1/work/qemu-0.6.1/block.c	2004-11-14 21:51:33.000000000 +0100
+++ qemu-snapshot-2004-11-26_23/block.c	2004-11-16 02:45:27.000000000 +0100
@@ -348,6 +348,11 @@
                       type == BDRV_TYPE_FLOPPY));
 }
 
+void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
+{
+    bs->translation = translation;
+}
+
 void bdrv_get_geometry_hint(BlockDriverState *bs, 
                             int *pcyls, int *pheads, int *psecs)
 {
@@ -361,6 +366,11 @@
     return bs->type;
 }
 
+int bdrv_get_translation_hint(BlockDriverState *bs)
+{
+    return bs->translation;
+}
+
 int bdrv_is_removable(BlockDriverState *bs)
 {
     return bs->removable;
diff -ruN /qemu-0.6.1/work/qemu-0.6.1/block_int.h qemu-snapshot-2004-11-26_23/block_int.h
--- /qemu-0.6.1/work/qemu-0.6.1/block_int.h	2004-11-14 21:51:33.000000000 +0100
+++ qemu-snapshot-2004-11-26_23/block_int.h	2004-11-16 02:45:27.000000000 +0100
@@ -68,7 +68,7 @@
     
     /* NOTE: the following infos are only hints for real hardware
        drivers. They are not used by the block driver */
-    int cyls, heads, secs;
+    int cyls, heads, secs, translation;
     int type;
     char device_name[32];
     BlockDriverState *next;
diff -ruN /qemu-0.6.1/work/qemu-0.6.1/hw/cirrus_vga.c qemu-snapshot-2004-11-26_23/hw/cirrus_vga.c
--- /qemu-0.6.1/work/qemu-0.6.1/hw/cirrus_vga.c	2004-11-14 21:51:33.000000000 +0100
+++ qemu-snapshot-2004-11-26_23/hw/cirrus_vga.c	2004-11-15 22:43:57.000000000 +0100
@@ -737,7 +737,8 @@
             else
                 s->cirrus_blt_srcpitch = ((w + 7) >> 3);
 	} else {
-	    s->cirrus_blt_srcpitch = s->cirrus_blt_width;
+            /* always align input size to 32 bits */
+	    s->cirrus_blt_srcpitch = (s->cirrus_blt_width + 3) & ~3;
 	}
         s->cirrus_srccounter = s->cirrus_blt_srcpitch * s->cirrus_blt_height;
     }
diff -ruN /qemu-0.6.1/work/qemu-0.6.1/hw/ide.c qemu-snapshot-2004-11-26_23/hw/ide.c
--- /qemu-0.6.1/work/qemu-0.6.1/hw/ide.c	2004-11-14 21:51:33.000000000 +0100
+++ qemu-snapshot-2004-11-26_23/hw/ide.c	2004-11-17 23:35:32.000000000 +0100
@@ -1826,37 +1826,45 @@
 	uint32_t nr_sects;		/* nr of sectors in partition */
 } __attribute__((packed));
 
-/* try to guess the IDE geometry from the MSDOS partition table */
-static void ide_guess_geometry(IDEState *s)
+/* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
+static int guess_disk_lchs(IDEState *s, 
+                           int *pcylinders, int *pheads, int *psectors)
 {
     uint8_t buf[512];
-    int ret, i;
+    int ret, i, heads, sectors, cylinders;
     struct partition *p;
     uint32_t nr_sects;
 
-    if (s->cylinders != 0)
-        return;
     ret = bdrv_read(s->bs, 0, buf, 1);
     if (ret < 0)
-        return;
+        return -1;
     /* test msdos magic */
     if (buf[510] != 0x55 || buf[511] != 0xaa)
-        return;
+        return -1;
     for(i = 0; i < 4; i++) {
         p = ((struct partition *)(buf + 0x1be)) + i;
         nr_sects = le32_to_cpu(p->nr_sects);
         if (nr_sects && p->end_head) {
             /* We make the assumption that the partition terminates on
                a cylinder boundary */
-            s->heads = p->end_head + 1;
-            s->sectors = p->end_sector & 63;
-            s->cylinders = s->nb_sectors / (s->heads * s->sectors);
+            heads = p->end_head + 1;
+            sectors = p->end_sector & 63;
+            if (sectors == 0)
+                continue;
+            cylinders = s->nb_sectors / (heads * sectors);
+            if (cylinders < 1 || cylinders > 16383)
+                continue;
+            *pheads = heads;
+            *psectors = sectors;
+            *pcylinders = cylinders;
 #if 0
-            printf("guessed partition: CHS=%d %d %d\n", 
-                   s->cylinders, s->heads, s->sectors);
+            printf("guessed geometry: LCHS=%d %d %d\n", 
+                   cylinders, heads, sectors);
 #endif
+            return 0;
         }
     }
+    return -1;
 }
 
 static void ide_init2(IDEState *ide_state, int irq,
@@ -1864,7 +1872,7 @@
 {
     IDEState *s;
     static int drive_serial = 1;
-    int i, cylinders, heads, secs;
+    int i, cylinders, heads, secs, translation;
     int64_t nb_sectors;
 
     for(i = 0; i < 2; i++) {
@@ -1883,9 +1891,27 @@
                 s->heads = heads;
                 s->sectors = secs;
             } else {
-                ide_guess_geometry(s);
-                if (s->cylinders == 0) {
-                    /* if no geometry, use a LBA compatible one */
+                if (guess_disk_lchs(s, &cylinders, &heads, &secs) == 0) {
+                    if (heads > 16) {
+                        /* if heads > 16, it means that a BIOS LBA
+                           translation was active, so the default
+                           hardware geometry is OK */
+                        goto default_geometry;
+                    } else {
+                        s->cylinders = cylinders;
+                        s->heads = heads;
+                        s->sectors = secs;
+                        /* disable any translation to be in sync with
+                           the logical geometry */
+                        translation = bdrv_get_translation_hint(s->bs);
+                        if (translation == BIOS_ATA_TRANSLATION_AUTO) {
+                            bdrv_set_translation_hint(s->bs,
+                                                      BIOS_ATA_TRANSLATION_NONE);
+                        }
+                    }
+                } else {
+                default_geometry:
+                    /* if no geometry, use a standard physical disk geometry */
                     cylinders = nb_sectors / (16 * 63);
                     if (cylinders > 16383)
                         cylinders = 16383;
diff -ruN /qemu-0.6.1/work/qemu-0.6.1/hw/pc.c qemu-snapshot-2004-11-26_23/hw/pc.c
--- /qemu-0.6.1/work/qemu-0.6.1/hw/pc.c	2004-11-14 21:51:33.000000000 +0100
+++ qemu-snapshot-2004-11-26_23/hw/pc.c	2004-11-16 02:45:27.000000000 +0100
@@ -217,19 +217,23 @@
     val = 0;
     for (i = 0; i < 4; i++) {
         if (hd_table[i]) {
-            int cylinders, heads, sectors;
-            uint8_t translation;
-            /* NOTE: bdrv_get_geometry_hint() returns the geometry
-               that the hard disk returns. It is always such that: 1 <=
-               sects <= 63, 1 <= heads <= 16, 1 <= cylinders <=
-               16383. The BIOS geometry can be different. */
-            bdrv_get_geometry_hint(hd_table[i], &cylinders, &heads, &sectors);
-            if (cylinders <= 1024 && heads <= 16 && sectors <= 63) {
-                /* No translation. */
-                translation = 0;
+            int cylinders, heads, sectors, translation;
+            /* NOTE: bdrv_get_geometry_hint() returns the physical
+                geometry.  It is always such that: 1 <= sects <= 63, 1
+                <= heads <= 16, 1 <= cylinders <= 16383. The BIOS
+                geometry can be different if a translation is done. */
+            translation = bdrv_get_translation_hint(hd_table[i]);
+            if (translation == BIOS_ATA_TRANSLATION_AUTO) {
+                bdrv_get_geometry_hint(hd_table[i], &cylinders, &heads, &sectors);
+                if (cylinders <= 1024 && heads <= 16 && sectors <= 63) {
+                    /* No translation. */
+                    translation = 0;
+                } else {
+                    /* LBA translation. */
+                    translation = 1;
+                }
             } else {
-                /* LBA translation. */
-                translation = 1;
+                translation--;
             }
             val |= translation << (i * 2);
         }
diff -ruN /qemu-0.6.1/work/qemu-0.6.1/qemu-doc.texi qemu-snapshot-2004-11-26_23/qemu-doc.texi
--- /qemu-0.6.1/work/qemu-0.6.1/qemu-doc.texi	2004-11-14 21:51:33.000000000 +0100
+++ qemu-snapshot-2004-11-26_23/qemu-doc.texi	2004-11-16 02:45:27.000000000 +0100
@@ -343,6 +343,12 @@
 Do not start CPU at startup (you must type 'c' in the monitor).
 @item -d             
 Output log in /tmp/qemu.log
+@item -hdachs c,h,s,[,t]
+Force hard disk 0 physical geometry (1 <= @var{c} <= 16383, 1 <=
+@var{h} <= 16, 1 <= @var{s} <= 63) and optionally force the BIOS
+translation mode (@var{t}=none, lba or auto). Usually QEMU can guess
+all thoses parameters. This option is useful for old MS-DOS disk
+images.
 @item -isa
 Simulate an ISA-only system (default is PCI system).
 @item -std-vga
@@ -584,81 +590,34 @@
 @node disk_images
 @section Disk Images
 
-@subsection Raw disk images
+Since version 0.6.1, QEMU supports many disk image formats, including
+growable disk images (their size increase as non empty sectors are
+written), compressed and encrypted disk images.
 
-The disk images can simply be raw images of the hard disk. You can
-create them with the command:
+@subsection Quick start for disk image creation
+
+You can create a disk image with the command:
 @example
-dd of=myimage bs=1024 seek=mysize count=0
+qemu-img create myimage.img mysize
 @end example
-where @var{myimage} is the image filename and @var{mysize} is its size
-in kilobytes.
+where @var{myimage.img} is the disk image filename and @var{mysize} is its
+size in kilobytes. You can add an @code{M} suffix to give the size in
+megabytes and a @code{G} suffix for gigabytes.
+
+@xref{qemu_img_invocation} for more information.
 
 @subsection Snapshot mode
 
 If you use the option @option{-snapshot}, all disk images are
 considered as read only. When sectors in written, they are written in
 a temporary file created in @file{/tmp}. You can however force the
-write back to the raw disk images by pressing @key{C-a s}.
-
-NOTE: The snapshot mode only works with raw disk images.
-
-@subsection Copy On Write disk images
-
-QEMU also supports user mode Linux
-(@url{http://user-mode-linux.sourceforge.net/}) Copy On Write (COW)
-disk images. The COW disk images are much smaller than normal images
-as they store only modified sectors. They also permit the use of the
-same disk image template for many users.
-
-To create a COW disk images, use the command:
-
-@example
-qemu-mkcow -f myrawimage.bin mycowimage.cow
-@end example
-
-@file{myrawimage.bin} is a raw image you want to use as original disk
-image. It will never be written to.
-
-@file{mycowimage.cow} is the COW disk image which is created by
-@code{qemu-mkcow}. You can use it directly with the @option{-hdx}
-options. You must not modify the original raw disk image if you use
-COW images, as COW images only store the modified sectors from the raw
-disk image. QEMU stores the original raw disk image name and its
-modified time in the COW disk image so that chances of mistakes are
-reduced.
-
-If the raw disk image is not read-only, by pressing @key{C-a s} you
-can flush the COW disk image back into the raw disk image, as in
-snapshot mode.
+write back to the raw disk images by using the @code{commit} monitor
+command (or @key{C-a s} in the serial console).
 
-COW disk images can also be created without a corresponding raw disk
-image. It is useful to have a big initial virtual disk image without
-using much disk space. Use:
+@node qemu_img_invocation
+@subsection @code{qemu-img} Invocation
 
-@example
-qemu-mkcow mycowimage.cow 1024
-@end example
-
-to create a 1 gigabyte empty COW disk image.
-
-NOTES: 
-@enumerate
-@item
-COW disk images must be created on file systems supporting
-@emph{holes} such as ext2 or ext3.
-@item 
-Since holes are used, the displayed size of the COW disk image is not
-the real one. To know it, use the @code{ls -ls} command.
-@end enumerate
-
-@subsection Convert VMware disk images to raw disk images
-
-You can use the tool @file{vmdk2raw} to convert VMware disk images to
-raw disk images directly usable by QEMU. The syntax is:
-@example
-vmdk2raw vmware_image output_image
-@end example
+@include qemu-img.texi
 
 @section Network emulation
 
diff -ruN /qemu-0.6.1/work/qemu-0.6.1/qemu-img.texi qemu-snapshot-2004-11-26_23/qemu-img.texi
--- /qemu-0.6.1/work/qemu-0.6.1/qemu-img.texi	1970-01-01 01:00:00.000000000 +0100
+++ qemu-snapshot-2004-11-26_23/qemu-img.texi	2004-11-15 23:57:26.000000000 +0100
@@ -0,0 +1,127 @@
+@example
+@c man begin SYNOPSIS
+usage: qemu-img command [command options]
+@c man end
+@end example
+
+@c man begin OPTIONS
+
+The following commands are supported:
+@table @option
+@item create [-e] [-b @var{base_image}] [-f @var{fmt}] @var{filename} [@var{size}]
+@item commit [-f @var{fmt}] @var{filename}
+@item convert [-c] [-e] [-f @var{fmt}] @var{filename} [-O @var{output_fmt}] @var{output_filename}
+@item info [-f @var{fmt}] @var{filename}
+@end table
+
+Command parameters:
+@table @var
+@item filename
+ is a disk image filename
+@item base_image 
+is the read-only disk image which is used as base for a copy on
+    write image; the copy on write image only stores the modified data
+
+@item fmt 
+is the disk image format. It is guessed automatically in most cases. The following formats are supported:
+
+@table @code
+@item raw
+
+Raw disk image format (default). This format has the advantage of
+being simple and easily exportable to all other emulators. If your file
+system supports @emph{holes} (for example in ext2 or ext3 on Linux),
+then only the written sectors will reserve space. Use @code{qemu-img
+info} to know the real size used by the image or @code{ls -ls} on
+Unix/Linux.
+
+@item qcow
+QEMU image format, the most versatile format. Use it to have smaller
+images (useful if your filesystem does not supports holes, for example
+on Windows), optional AES encryption and zlib based compression.
+@item cow
+User Mode Linux Copy On Write image format. Used to be the only growable
+image format in QEMU. It is supported only for compatibility with
+previous versions. It does not work on win32.
+@item vmdk
+VMware 3 and 4 compatible image format. Currently only supported as
+read-only.
+@item cloop
+Linux Compressed Loop image, useful only to reuse directly compressed
+CD-ROM images present for example in the Knoppix CD-ROMs.
+@end table
+
+@item size 
+is the disk image size in kilobytes. Optional suffixes @code{M}
+(megabyte) and @code{G} (gigabyte) are supported 
+
+@item output_filename
+is the destination disk image filename 
+
+@item output_fmt
+ is the destination format
+
+@item -c
+indicates that target image must be compressed (qcow format only)
+@item -e 
+indicates that the target image must be encrypted (qcow format only)
+@end table
+
+Command description:
+
+@table @option
+@item create [-e] [-b @var{base_image}] [-f @var{fmt}] @var{filename} [@var{size}]
+
+Create the new disk image @var{filename} of size @var{size} and format
+@var{fmt}. 
+
+If @var{base_image} is specified, then the image will record only the
+differences from @var{base_image}. No size needs to be specified in
+this case. @var{base_image} will never be modified unless you use the
+@code{commit} monitor command.
+
+@item commit [-f @var{fmt}] @var{filename}
+
+Commit the changes recorded in @var{filename} in its base image.
+
+@item convert [-c] [-e] [-f @var{fmt}] @var{filename} [-O @var{output_fmt}] @var{output_filename}
+
+Convert the disk image @var{filename} to disk image @var{output_filename}
+using format @var{output_fmt}. It can be optionnaly encrypted
+(@code{-e} option) or compressed (@code{-c} option).
+
+Only the format @code{qcow} supports encryption or compression. The
+compression is read-only. It means that if a compressed sector is
+rewritten, then it is rewritten as uncompressed data.
+
+Encryption uses the AES format which is very secure (128 bit keys). Use
+a long password (16 characters) to get maximum protection.
+
+Image conversion is also useful to get smaller image when using a
+growable format such as @code{qcow} or @code{cow}: the empty sectors
+are detected and suppressed from the destination image.
+
+@item info [-f @var{fmt}] @var{filename}
+
+Give information about the disk image @var{filename}. Use it in
+particular to know the size reserved on disk which can be different
+from the displayed size.
+@end table
+
+@c man end
+
+@ignore
+
+@setfilename qemu-img
+@settitle QEMU disk image utility
+
+@c man begin SEEALSO
+The HTML documentation of QEMU for more precise information and Linux
+user mode emulator invocation.
+@c man end
+
+@c man begin AUTHOR
+Fabrice Bellard
+@c man end
+
+@end ignore
diff -ruN /qemu-0.6.1/work/qemu-0.6.1/slirp/socket.c qemu-snapshot-2004-11-26_23/slirp/socket.c
--- /qemu-0.6.1/work/qemu-0.6.1/slirp/socket.c	2004-11-14 21:51:33.000000000 +0100
+++ qemu-snapshot-2004-11-26_23/slirp/socket.c	2004-11-24 21:39:26.000000000 +0100
@@ -175,8 +175,12 @@
 	 * a close will be detected on next iteration.
 	 * A return of -1 wont (shouldn't) happen, since it didn't happen above
 	 */
-	if (n == 2 && nn == iov[0].iov_len)
-	   nn += recv(so->s, iov[1].iov_base, iov[1].iov_len,0);
+	if (n == 2 && nn == iov[0].iov_len) {
+            int ret;
+            ret = recv(so->s, iov[1].iov_base, iov[1].iov_len,0);
+            if (ret > 0)
+                nn += ret;
+        }
 	
 	DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
 #endif
@@ -348,8 +352,12 @@
 	}
 	
 #ifndef HAVE_READV
-	if (n == 2 && nn == iov[0].iov_len)
-	   nn += send(so->s, iov[1].iov_base, iov[1].iov_len,0);
+	if (n == 2 && nn == iov[0].iov_len) {
+            int ret;
+            ret = send(so->s, iov[1].iov_base, iov[1].iov_len,0);
+            if (ret > 0)
+                nn += ret;
+        }
         DEBUG_MISC((dfd, "  ... wrote nn = %d bytes\n", nn));
 #endif
 	
diff -ruN /qemu-0.6.1/work/qemu-0.6.1/target-i386/translate.c qemu-snapshot-2004-11-26_23/target-i386/translate.c
--- /qemu-0.6.1/work/qemu-0.6.1/target-i386/translate.c	2004-11-14 21:51:33.000000000 +0100
+++ qemu-snapshot-2004-11-26_23/target-i386/translate.c	2004-11-24 20:28:52.000000000 +0100
@@ -2958,6 +2958,8 @@
                 gen_op_fmov_ST0_STN((opreg + 1) & 7);
                 break;
             case 0x09: /* fxchg sti */
+            case 0x29: /* fxchg4 sti, undocumented op */
+            case 0x39: /* fxchg7 sti, undocumented op */
                 gen_op_fxchg_ST0_STN(opreg);
                 break;
             case 0x0a: /* grp d9/2 */
@@ -3104,10 +3106,13 @@
                 }
                 break;
             case 0x02: /* fcom */
+            case 0x22: /* fcom2, undocumented op */
                 gen_op_fmov_FT0_STN(opreg);
                 gen_op_fcom_ST0_FT0();
                 break;
             case 0x03: /* fcomp */
+            case 0x23: /* fcomp3, undocumented op */
+            case 0x32: /* fcomp5, undocumented op */
                 gen_op_fmov_FT0_STN(opreg);
                 gen_op_fcom_ST0_FT0();
                 gen_op_fpop();
@@ -3163,6 +3168,9 @@
                 gen_op_fmov_STN_ST0(opreg);
                 break;
             case 0x2b: /* fstp sti */
+            case 0x0b: /* fstp1 sti, undocumented op */
+            case 0x3a: /* fstp8 sti, undocumented op */
+            case 0x3b: /* fstp9 sti, undocumented op */
                 gen_op_fmov_STN_ST0(opreg);
                 gen_op_fpop();
                 break;
@@ -3187,6 +3195,10 @@
                     goto illegal_op;
                 }
                 break;
+            case 0x38: /* ffreep sti, undocumented op */
+                gen_op_ffree_STN(opreg);
+                gen_op_fpop();
+                break;
             case 0x3c: /* df/4 */
                 switch(rm) {
                 case 0:
diff -ruN /qemu-0.6.1/work/qemu-0.6.1/vl.c qemu-snapshot-2004-11-26_23/vl.c
--- /qemu-0.6.1/work/qemu-0.6.1/vl.c	2004-11-14 21:51:33.000000000 +0100
+++ qemu-snapshot-2004-11-26_23/vl.c	2004-11-16 02:45:27.000000000 +0100
@@ -2537,7 +2537,8 @@
            "-s              wait gdb connection to port %d\n"
            "-p port         change gdb connection port\n"
            "-d item1,...    output log to %s (use -d ? for a list of log items)\n"
-           "-hdachs c,h,s   force hard disk 0 geometry (usually qemu can guess it)\n"
+           "-hdachs c,h,s[,t]  force hard disk 0 physical geometry and the optional BIOS\n"
+           "                translation (t=none or lba) (usually qemu can guess them)\n"
            "-L path         set the directory for the BIOS and VGA BIOS\n"
 #ifdef USE_CODE_COPY
            "-no-code-copy   disable code copy acceleration\n"
@@ -2753,7 +2754,7 @@
     const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
     const char *kernel_filename, *kernel_cmdline;
     DisplayState *ds = &display_state;
-    int cyls, heads, secs;
+    int cyls, heads, secs, translation;
     int start_emulation = 1;
     uint8_t macaddr[6];
     int net_if_type, nb_tun_fds, tun_fds[MAX_NICS];
@@ -2788,6 +2789,7 @@
     kernel_cmdline = "";
     has_cdrom = 1;
     cyls = heads = secs = 0;
+    translation = BIOS_ATA_TRANSLATION_AUTO;
     pstrcpy(monitor_device, sizeof(monitor_device), "vc");
 
     pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
@@ -2857,17 +2859,34 @@
                     const char *p;
                     p = optarg;
                     cyls = strtol(p, (char **)&p, 0);
+                    if (cyls < 1 || cyls > 16383)
+                        goto chs_fail;
                     if (*p != ',')
                         goto chs_fail;
                     p++;
                     heads = strtol(p, (char **)&p, 0);
+                    if (heads < 1 || heads > 16)
+                        goto chs_fail;
                     if (*p != ',')
                         goto chs_fail;
                     p++;
                     secs = strtol(p, (char **)&p, 0);
-                    if (*p != '\0') {
+                    if (secs < 1 || secs > 63)
+                        goto chs_fail;
+                    if (*p == ',') {
+                        p++;
+                        if (!strcmp(p, "none"))
+                            translation = BIOS_ATA_TRANSLATION_NONE;
+                        else if (!strcmp(p, "lba"))
+                            translation = BIOS_ATA_TRANSLATION_LBA;
+                        else if (!strcmp(p, "auto"))
+                            translation = BIOS_ATA_TRANSLATION_AUTO;
+                        else
+                            goto chs_fail;
+                    } else if (*p != '\0') {
                     chs_fail:
-                        cyls = 0;
+                        fprintf(stderr, "qemu: invalid physical CHS format\n");
+                        exit(1);
                     }
                 }
                 break;
@@ -3230,8 +3249,10 @@
                         hd_filename[i]);
                 exit(1);
             }
-            if (i == 0 && cyls != 0) 
+            if (i == 0 && cyls != 0) {
                 bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
+                bdrv_set_translation_hint(bs_table[i], translation);
+            }
         }
     }
 
diff -ruN /qemu-0.6.1/work/qemu-0.6.1/vl.h qemu-snapshot-2004-11-26_23/vl.h
--- /qemu-0.6.1/work/qemu-0.6.1/vl.h	2004-11-14 21:51:33.000000000 +0100
+++ qemu-snapshot-2004-11-26_23/vl.h	2004-11-16 02:45:27.000000000 +0100
@@ -383,13 +383,18 @@
 #define BDRV_TYPE_HD     0
 #define BDRV_TYPE_CDROM  1
 #define BDRV_TYPE_FLOPPY 2
+#define BIOS_ATA_TRANSLATION_AUTO 0
+#define BIOS_ATA_TRANSLATION_NONE 1
+#define BIOS_ATA_TRANSLATION_LBA  2
 
 void bdrv_set_geometry_hint(BlockDriverState *bs, 
                             int cyls, int heads, int secs);
 void bdrv_set_type_hint(BlockDriverState *bs, int type);
+void bdrv_set_translation_hint(BlockDriverState *bs, int translation);
 void bdrv_get_geometry_hint(BlockDriverState *bs, 
                             int *pcyls, int *pheads, int *psecs);
 int bdrv_get_type_hint(BlockDriverState *bs);
+int bdrv_get_translation_hint(BlockDriverState *bs);
 int bdrv_is_removable(BlockDriverState *bs);
 int bdrv_is_read_only(BlockDriverState *bs);
 int bdrv_is_inserted(BlockDriverState *bs);