fdc: take side count into account

Floppies can be simple or double-sided. However, current code
was only taking the common case into account (ie 2 sides).

This repairs single-sided floppies, which where totally broken
before this patch : for track > 0, wrong sector number was
calculated, and data was read/written at wrong place on
underlying device.

Fortunately, only some 360 kB floppies are single-sided, so
this bug was probably not seen much.

Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Hervé Poussineau 2012-02-06 22:29:02 +01:00 committed by Kevin Wolf
parent b55c952aea
commit 08388273a3

View File

@ -95,16 +95,19 @@ static void fd_init(FDrive *drv)
drv->max_track = 0;
}
#define NUM_SIDES(drv) ((drv)->flags & FDISK_DBL_SIDES ? 2 : 1)
static int fd_sector_calc(uint8_t head, uint8_t track, uint8_t sect,
uint8_t last_sect)
uint8_t last_sect, uint8_t num_sides)
{
return (((track * 2) + head) * last_sect) + sect - 1;
return (((track * num_sides) + head) * last_sect) + sect - 1;
}
/* Returns current position, in sectors, for given drive */
static int fd_sector(FDrive *drv)
{
return fd_sector_calc(drv->head, drv->track, drv->sect, drv->last_sect);
return fd_sector_calc(drv->head, drv->track, drv->sect, drv->last_sect,
NUM_SIDES(drv));
}
/* Seek to a new position:
@ -135,7 +138,7 @@ static int fd_seek(FDrive *drv, uint8_t head, uint8_t track, uint8_t sect,
drv->max_track, drv->last_sect);
return 3;
}
sector = fd_sector_calc(head, track, sect, drv->last_sect);
sector = fd_sector_calc(head, track, sect, drv->last_sect, NUM_SIDES(drv));
ret = 0;
if (sector != fd_sector(drv)) {
#if 0
@ -1019,7 +1022,8 @@ static void fdctrl_start_transfer(FDCtrl *fdctrl, int direction)
ks = fdctrl->fifo[4];
FLOPPY_DPRINTF("Start transfer at %d %d %02x %02x (%d)\n",
GET_CUR_DRV(fdctrl), kh, kt, ks,
fd_sector_calc(kh, kt, ks, cur_drv->last_sect));
fd_sector_calc(kh, kt, ks, cur_drv->last_sect,
NUM_SIDES(cur_drv)));
switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & FD_CONFIG_EIS)) {
case 2:
/* sect too big */
@ -1289,7 +1293,8 @@ static void fdctrl_format_sector(FDCtrl *fdctrl)
ks = fdctrl->fifo[8];
FLOPPY_DPRINTF("format sector at %d %d %02x %02x (%d)\n",
GET_CUR_DRV(fdctrl), kh, kt, ks,
fd_sector_calc(kh, kt, ks, cur_drv->last_sect));
fd_sector_calc(kh, kt, ks, cur_drv->last_sect,
NUM_SIDES(cur_drv)));
switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & FD_CONFIG_EIS)) {
case 2:
/* sect too big */