diff -ur 2.4.0.4/linux/drivers/block/floppy.c linux/drivers/block/floppy.c
--- 2.4.0.4/linux/drivers/block/floppy.c	Fri Jul 14 20:41:51 2000
+++ linux/drivers/block/floppy.c	Sat Jul 15 08:38:41 2000
@@ -2229,6 +2229,10 @@
 			}
 		}
 	}
+	if(_floppy->stretch & FD_ZEROBASED) {
+	    for(count = 0; count < F_SECT_PER_TRACK; count++)
+		here[count].sect--;
+	}
 }
 
 static void redo_format(void)
@@ -2638,7 +2642,8 @@
 	}
 	HEAD = sector_t / _floppy->sect;
 
-	if (((_floppy->stretch & FD_SWAPSIDES) || TESTF(FD_NEED_TWADDLE)) &&
+	if (( (_floppy->stretch & (FD_SWAPSIDES | FD_ZEROBASED)) || 
+	      TESTF(FD_NEED_TWADDLE)) &&
 	    sector_t < _floppy->sect)
 		max_sector = _floppy->sect;
 
@@ -2668,7 +2673,8 @@
 	GAP = _floppy->gap;
 	CODE2SIZE;
 	SECT_PER_TRACK = _floppy->sect << 2 >> SIZECODE;
-	SECTOR = ((sector_t % _floppy->sect) << 2 >> SIZECODE) + 1;
+	SECTOR = ((sector_t % _floppy->sect) << 2 >> SIZECODE) + 
+	    ((_floppy->stretch & FD_ZEROBASED) ? 0 : 1);
 
 	/* tracksize describes the size which can be filled up with sectors
 	 * of size ssize.
@@ -3305,7 +3311,7 @@
 	    g->track <= 0 ||
 	    g->track > UDP->tracks>>STRETCH(g) ||
 	    /* check if reserved bits are set */
-	    (g->stretch&~(FD_STRETCH|FD_SWAPSIDES)) != 0)
+	    (g->stretch&~(FD_STRETCH|FD_SWAPSIDES|FD_ZEROBASED)) != 0)
 		return -EINVAL;
 	if (type){
 		if (!capable(CAP_SYS_ADMIN))
@@ -3330,11 +3336,13 @@
 					      drive_state[cnt].fd_device));
 		}
 	} else {
+		int oldStretch;
 		LOCK_FDC(drive,1);
 		if (cmd != FDDEFPRM)
 			/* notice a disk change immediately, else
 			 * we lose our settings immediately*/
 			CALL(poll_drive(1, FD_RAW_NEED_DISK));
+		oldStretch = g->stretch;
 		user_params[drive] = *g;
 		if (buffer_drive == drive)
 			SUPBOUND(buffer_max, user_params[drive].sect);
@@ -3349,7 +3357,10 @@
 		 * whose number will change. This is useful, because
 		 * mtools often changes the geometry of the disk after
 		 * looking at the boot block */
-		if (DRS->maxblock > user_params[drive].sect || DRS->maxtrack)
+		if (DRS->maxblock > user_params[drive].sect || 
+		    DRS->maxtrack ||
+		    ((user_params[drive].sect ^ oldStretch) &
+		     FD_SWAPSIDES | FD_ZEROBASED))
 			invalidate_drive(device);
 		else
 			process_fd_request();
diff -ur 2.4.0.4/linux/include/linux/fd.h linux/include/linux/fd.h
--- 2.4.0.4/linux/include/linux/fd.h	Fri Aug 13 21:16:16 1999
+++ linux/include/linux/fd.h	Fri Jul 14 23:54:46 2000
@@ -17,6 +17,7 @@
 			stretch;	/* !=0 means double track steps */
 #define FD_STRETCH 1
 #define FD_SWAPSIDES 2
+#define FD_ZEROBASED 4
 
 	unsigned char	gap,		/* gap1 size */
 
