From: Marcelo Tosatti <marcelo.tosatti@cyclades.com>

From: Alain Knaff <alain.knaff@lll.lu>

This patch adds support for floppy disks whose sectors are numbered
starting at 0 rather than 1 as usual disks would be.  This format is used
for some CP/M disks, and also for certain music samplers (such as Ensoniq
Ensoniq EPS 16plus).

In order to use it, you need an fdutils with the current patch from
http://fdutils.linux.lu as well, and then do setfdrpm /dev/fd0 dd zerobased
sect=10 or setfdprm /dev/fd0 hd zerobased sect.

In addtion, the patch also fixes my email addresses.  I no longer use
pobox.com.


---

 25-akpm/drivers/block/floppy.c |   19 +++++++++++++++----
 25-akpm/include/linux/fd.h     |    1 +
 2 files changed, 16 insertions(+), 4 deletions(-)

diff -puN drivers/block/floppy.c~support-zerobased-floppies drivers/block/floppy.c
--- 25/drivers/block/floppy.c~support-zerobased-floppies	Mon Mar 29 15:53:38 2004
+++ 25-akpm/drivers/block/floppy.c	Mon Mar 29 15:53:38 2004
@@ -2258,6 +2258,10 @@ static void setup_format_params(int trac
 			}
 		}
 	}
+	if(_floppy->stretch & FD_ZEROBASED) {
+	    for(count = 0; count < F_SECT_PER_TRACK; count++)
+		here[count].sect--;
+	}
 }
 
 static void redo_format(void)
@@ -2679,7 +2683,8 @@ static int make_raw_rw_request(void)
 	}
 	HEAD = fsector_t / _floppy->sect;
 
-	if (((_floppy->stretch & FD_SWAPSIDES) || TESTF(FD_NEED_TWADDLE)) &&
+	if (((_floppy->stretch & (FD_SWAPSIDES | FD_ZEROBASED)) ||
+	     TESTF(FD_NEED_TWADDLE)) &&
 	    fsector_t < _floppy->sect)
 		max_sector = _floppy->sect;
 
@@ -2709,7 +2714,8 @@ static int make_raw_rw_request(void)
 	GAP = _floppy->gap;
 	CODE2SIZE;
 	SECT_PER_TRACK = _floppy->sect << 2 >> SIZECODE;
-	SECTOR = ((fsector_t % _floppy->sect) << 2 >> SIZECODE) + 1;
+	SECTOR = ((fsector_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.
@@ -3346,7 +3352,7 @@ static inline int set_geometry(unsigned 
 	    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))
@@ -3367,11 +3373,13 @@ static inline int set_geometry(unsigned 
 		}
 		up(&open_lock);
 	} 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);
@@ -3386,7 +3394,10 @@ static inline int set_geometry(unsigned 
 		 * 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(bdev);
 		else
 			process_fd_request();
diff -puN include/linux/fd.h~support-zerobased-floppies include/linux/fd.h
--- 25/include/linux/fd.h~support-zerobased-floppies	Mon Mar 29 15:53:38 2004
+++ 25-akpm/include/linux/fd.h	Mon Mar 29 15:53:38 2004
@@ -17,6 +17,7 @@ struct floppy_struct {
 			stretch;	/* !=0 means double track steps */
 #define FD_STRETCH 1
 #define FD_SWAPSIDES 2
+#define FD_ZEROBASED 4
 
 	unsigned char	gap,		/* gap1 size */
 

_