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:
parent
b55c952aea
commit
08388273a3
17
hw/fdc.c
17
hw/fdc.c
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue