mirror of
https://github.com/qemu/qemu.git
synced 2024-11-23 19:03:38 +08:00
fdc: move floppy geometry guessing to block.c
Other geometry guessing functions already reside in block.c. Remove some unused or debugging only fields. Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
This commit is contained in:
parent
9b13ef9f4c
commit
5bbdbb4676
103
block.c
103
block.c
@ -1319,6 +1319,109 @@ void bdrv_get_geometry_hint(BlockDriverState *bs,
|
||||
*psecs = bs->secs;
|
||||
}
|
||||
|
||||
/* Recognize floppy formats */
|
||||
typedef struct FDFormat {
|
||||
FDriveType drive;
|
||||
uint8_t last_sect;
|
||||
uint8_t max_track;
|
||||
uint8_t max_head;
|
||||
} FDFormat;
|
||||
|
||||
static const FDFormat fd_formats[] = {
|
||||
/* First entry is default format */
|
||||
/* 1.44 MB 3"1/2 floppy disks */
|
||||
{ FDRIVE_DRV_144, 18, 80, 1, },
|
||||
{ FDRIVE_DRV_144, 20, 80, 1, },
|
||||
{ FDRIVE_DRV_144, 21, 80, 1, },
|
||||
{ FDRIVE_DRV_144, 21, 82, 1, },
|
||||
{ FDRIVE_DRV_144, 21, 83, 1, },
|
||||
{ FDRIVE_DRV_144, 22, 80, 1, },
|
||||
{ FDRIVE_DRV_144, 23, 80, 1, },
|
||||
{ FDRIVE_DRV_144, 24, 80, 1, },
|
||||
/* 2.88 MB 3"1/2 floppy disks */
|
||||
{ FDRIVE_DRV_288, 36, 80, 1, },
|
||||
{ FDRIVE_DRV_288, 39, 80, 1, },
|
||||
{ FDRIVE_DRV_288, 40, 80, 1, },
|
||||
{ FDRIVE_DRV_288, 44, 80, 1, },
|
||||
{ FDRIVE_DRV_288, 48, 80, 1, },
|
||||
/* 720 kB 3"1/2 floppy disks */
|
||||
{ FDRIVE_DRV_144, 9, 80, 1, },
|
||||
{ FDRIVE_DRV_144, 10, 80, 1, },
|
||||
{ FDRIVE_DRV_144, 10, 82, 1, },
|
||||
{ FDRIVE_DRV_144, 10, 83, 1, },
|
||||
{ FDRIVE_DRV_144, 13, 80, 1, },
|
||||
{ FDRIVE_DRV_144, 14, 80, 1, },
|
||||
/* 1.2 MB 5"1/4 floppy disks */
|
||||
{ FDRIVE_DRV_120, 15, 80, 1, },
|
||||
{ FDRIVE_DRV_120, 18, 80, 1, },
|
||||
{ FDRIVE_DRV_120, 18, 82, 1, },
|
||||
{ FDRIVE_DRV_120, 18, 83, 1, },
|
||||
{ FDRIVE_DRV_120, 20, 80, 1, },
|
||||
/* 720 kB 5"1/4 floppy disks */
|
||||
{ FDRIVE_DRV_120, 9, 80, 1, },
|
||||
{ FDRIVE_DRV_120, 11, 80, 1, },
|
||||
/* 360 kB 5"1/4 floppy disks */
|
||||
{ FDRIVE_DRV_120, 9, 40, 1, },
|
||||
{ FDRIVE_DRV_120, 9, 40, 0, },
|
||||
{ FDRIVE_DRV_120, 10, 41, 1, },
|
||||
{ FDRIVE_DRV_120, 10, 42, 1, },
|
||||
/* 320 kB 5"1/4 floppy disks */
|
||||
{ FDRIVE_DRV_120, 8, 40, 1, },
|
||||
{ FDRIVE_DRV_120, 8, 40, 0, },
|
||||
/* 360 kB must match 5"1/4 better than 3"1/2... */
|
||||
{ FDRIVE_DRV_144, 9, 80, 0, },
|
||||
/* end */
|
||||
{ FDRIVE_DRV_NONE, -1, -1, 0, },
|
||||
};
|
||||
|
||||
void bdrv_get_floppy_geometry_hint(BlockDriverState *bs, int *nb_heads,
|
||||
int *max_track, int *last_sect,
|
||||
FDriveType drive_in, FDriveType *drive)
|
||||
{
|
||||
const FDFormat *parse;
|
||||
uint64_t nb_sectors, size;
|
||||
int i, first_match, match;
|
||||
|
||||
bdrv_get_geometry_hint(bs, nb_heads, max_track, last_sect);
|
||||
if (*nb_heads != 0 && *max_track != 0 && *last_sect != 0) {
|
||||
/* User defined disk */
|
||||
} else {
|
||||
bdrv_get_geometry(bs, &nb_sectors);
|
||||
match = -1;
|
||||
first_match = -1;
|
||||
for (i = 0; ; i++) {
|
||||
parse = &fd_formats[i];
|
||||
if (parse->drive == FDRIVE_DRV_NONE) {
|
||||
break;
|
||||
}
|
||||
if (drive_in == parse->drive ||
|
||||
drive_in == FDRIVE_DRV_NONE) {
|
||||
size = (parse->max_head + 1) * parse->max_track *
|
||||
parse->last_sect;
|
||||
if (nb_sectors == size) {
|
||||
match = i;
|
||||
break;
|
||||
}
|
||||
if (first_match == -1) {
|
||||
first_match = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (match == -1) {
|
||||
if (first_match == -1) {
|
||||
match = 1;
|
||||
} else {
|
||||
match = first_match;
|
||||
}
|
||||
parse = &fd_formats[match];
|
||||
}
|
||||
*nb_heads = parse->max_head + 1;
|
||||
*max_track = parse->max_track;
|
||||
*last_sect = parse->last_sect;
|
||||
*drive = parse->drive;
|
||||
}
|
||||
}
|
||||
|
||||
int bdrv_get_type_hint(BlockDriverState *bs)
|
||||
{
|
||||
return bs->type;
|
||||
|
10
block.h
10
block.h
@ -166,6 +166,16 @@ 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);
|
||||
typedef enum FDriveType {
|
||||
FDRIVE_DRV_144 = 0x00, /* 1.44 MB 3"5 drive */
|
||||
FDRIVE_DRV_288 = 0x01, /* 2.88 MB 3"5 drive */
|
||||
FDRIVE_DRV_120 = 0x02, /* 1.2 MB 5"25 drive */
|
||||
FDRIVE_DRV_NONE = 0x03, /* No drive connected */
|
||||
} FDriveType;
|
||||
|
||||
void bdrv_get_floppy_geometry_hint(BlockDriverState *bs, int *nb_heads,
|
||||
int *max_track, int *last_sect,
|
||||
FDriveType drive_in, FDriveType *drive);
|
||||
int bdrv_get_type_hint(BlockDriverState *bs);
|
||||
int bdrv_get_translation_hint(BlockDriverState *bs);
|
||||
void bdrv_set_on_error(BlockDriverState *bs, BlockErrorAction on_read_error,
|
||||
|
114
hw/fdc.c
114
hw/fdc.c
@ -63,21 +63,6 @@
|
||||
#define FD_RESET_SENSEI_COUNT 4 /* Number of sense interrupts on RESET */
|
||||
|
||||
/* Floppy disk drive emulation */
|
||||
typedef enum FDiskType {
|
||||
FDRIVE_DISK_288 = 0x01, /* 2.88 MB disk */
|
||||
FDRIVE_DISK_144 = 0x02, /* 1.44 MB disk */
|
||||
FDRIVE_DISK_720 = 0x03, /* 720 kB disk */
|
||||
FDRIVE_DISK_USER = 0x04, /* User defined geometry */
|
||||
FDRIVE_DISK_NONE = 0x05, /* No disk */
|
||||
} FDiskType;
|
||||
|
||||
typedef enum FDriveType {
|
||||
FDRIVE_DRV_144 = 0x00, /* 1.44 MB 3"5 drive */
|
||||
FDRIVE_DRV_288 = 0x01, /* 2.88 MB 3"5 drive */
|
||||
FDRIVE_DRV_120 = 0x02, /* 1.2 MB 5"25 drive */
|
||||
FDRIVE_DRV_NONE = 0x03, /* No drive connected */
|
||||
} FDriveType;
|
||||
|
||||
typedef enum FDiskFlags {
|
||||
FDISK_DBL_SIDES = 0x01,
|
||||
} FDiskFlags;
|
||||
@ -178,111 +163,23 @@ static void fd_recalibrate(FDrive *drv)
|
||||
drv->sect = 1;
|
||||
}
|
||||
|
||||
/* Recognize floppy formats */
|
||||
typedef struct FDFormat {
|
||||
FDriveType drive;
|
||||
FDiskType disk;
|
||||
uint8_t last_sect;
|
||||
uint8_t max_track;
|
||||
uint8_t max_head;
|
||||
const char *str;
|
||||
} FDFormat;
|
||||
|
||||
static const FDFormat fd_formats[] = {
|
||||
/* First entry is default format */
|
||||
/* 1.44 MB 3"1/2 floppy disks */
|
||||
{ FDRIVE_DRV_144, FDRIVE_DISK_144, 18, 80, 1, "1.44 MB 3\"1/2", },
|
||||
{ FDRIVE_DRV_144, FDRIVE_DISK_144, 20, 80, 1, "1.6 MB 3\"1/2", },
|
||||
{ FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 80, 1, "1.68 MB 3\"1/2", },
|
||||
{ FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 82, 1, "1.72 MB 3\"1/2", },
|
||||
{ FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 83, 1, "1.74 MB 3\"1/2", },
|
||||
{ FDRIVE_DRV_144, FDRIVE_DISK_144, 22, 80, 1, "1.76 MB 3\"1/2", },
|
||||
{ FDRIVE_DRV_144, FDRIVE_DISK_144, 23, 80, 1, "1.84 MB 3\"1/2", },
|
||||
{ FDRIVE_DRV_144, FDRIVE_DISK_144, 24, 80, 1, "1.92 MB 3\"1/2", },
|
||||
/* 2.88 MB 3"1/2 floppy disks */
|
||||
{ FDRIVE_DRV_288, FDRIVE_DISK_288, 36, 80, 1, "2.88 MB 3\"1/2", },
|
||||
{ FDRIVE_DRV_288, FDRIVE_DISK_288, 39, 80, 1, "3.12 MB 3\"1/2", },
|
||||
{ FDRIVE_DRV_288, FDRIVE_DISK_288, 40, 80, 1, "3.2 MB 3\"1/2", },
|
||||
{ FDRIVE_DRV_288, FDRIVE_DISK_288, 44, 80, 1, "3.52 MB 3\"1/2", },
|
||||
{ FDRIVE_DRV_288, FDRIVE_DISK_288, 48, 80, 1, "3.84 MB 3\"1/2", },
|
||||
/* 720 kB 3"1/2 floppy disks */
|
||||
{ FDRIVE_DRV_144, FDRIVE_DISK_720, 9, 80, 1, "720 kB 3\"1/2", },
|
||||
{ FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 80, 1, "800 kB 3\"1/2", },
|
||||
{ FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 82, 1, "820 kB 3\"1/2", },
|
||||
{ FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 83, 1, "830 kB 3\"1/2", },
|
||||
{ FDRIVE_DRV_144, FDRIVE_DISK_720, 13, 80, 1, "1.04 MB 3\"1/2", },
|
||||
{ FDRIVE_DRV_144, FDRIVE_DISK_720, 14, 80, 1, "1.12 MB 3\"1/2", },
|
||||
/* 1.2 MB 5"1/4 floppy disks */
|
||||
{ FDRIVE_DRV_120, FDRIVE_DISK_288, 15, 80, 1, "1.2 kB 5\"1/4", },
|
||||
{ FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 80, 1, "1.44 MB 5\"1/4", },
|
||||
{ FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 82, 1, "1.48 MB 5\"1/4", },
|
||||
{ FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 83, 1, "1.49 MB 5\"1/4", },
|
||||
{ FDRIVE_DRV_120, FDRIVE_DISK_288, 20, 80, 1, "1.6 MB 5\"1/4", },
|
||||
/* 720 kB 5"1/4 floppy disks */
|
||||
{ FDRIVE_DRV_120, FDRIVE_DISK_288, 9, 80, 1, "720 kB 5\"1/4", },
|
||||
{ FDRIVE_DRV_120, FDRIVE_DISK_288, 11, 80, 1, "880 kB 5\"1/4", },
|
||||
/* 360 kB 5"1/4 floppy disks */
|
||||
{ FDRIVE_DRV_120, FDRIVE_DISK_288, 9, 40, 1, "360 kB 5\"1/4", },
|
||||
{ FDRIVE_DRV_120, FDRIVE_DISK_288, 9, 40, 0, "180 kB 5\"1/4", },
|
||||
{ FDRIVE_DRV_120, FDRIVE_DISK_288, 10, 41, 1, "410 kB 5\"1/4", },
|
||||
{ FDRIVE_DRV_120, FDRIVE_DISK_288, 10, 42, 1, "420 kB 5\"1/4", },
|
||||
/* 320 kB 5"1/4 floppy disks */
|
||||
{ FDRIVE_DRV_120, FDRIVE_DISK_288, 8, 40, 1, "320 kB 5\"1/4", },
|
||||
{ FDRIVE_DRV_120, FDRIVE_DISK_288, 8, 40, 0, "160 kB 5\"1/4", },
|
||||
/* 360 kB must match 5"1/4 better than 3"1/2... */
|
||||
{ FDRIVE_DRV_144, FDRIVE_DISK_720, 9, 80, 0, "360 kB 3\"1/2", },
|
||||
/* end */
|
||||
{ FDRIVE_DRV_NONE, FDRIVE_DISK_NONE, -1, -1, 0, NULL, },
|
||||
};
|
||||
|
||||
/* Revalidate a disk drive after a disk change */
|
||||
static void fd_revalidate(FDrive *drv)
|
||||
{
|
||||
const FDFormat *parse;
|
||||
uint64_t nb_sectors, size;
|
||||
int i, first_match, match;
|
||||
int nb_heads, max_track, last_sect, ro;
|
||||
FDriveType drive;
|
||||
|
||||
FLOPPY_DPRINTF("revalidate\n");
|
||||
if (drv->bs != NULL && bdrv_is_inserted(drv->bs)) {
|
||||
ro = bdrv_is_read_only(drv->bs);
|
||||
bdrv_get_geometry_hint(drv->bs, &nb_heads, &max_track, &last_sect);
|
||||
bdrv_get_floppy_geometry_hint(drv->bs, &nb_heads, &max_track,
|
||||
&last_sect, drv->drive, &drive);
|
||||
if (nb_heads != 0 && max_track != 0 && last_sect != 0) {
|
||||
FLOPPY_DPRINTF("User defined disk (%d %d %d)",
|
||||
nb_heads - 1, max_track, last_sect);
|
||||
} else {
|
||||
bdrv_get_geometry(drv->bs, &nb_sectors);
|
||||
match = -1;
|
||||
first_match = -1;
|
||||
for (i = 0;; i++) {
|
||||
parse = &fd_formats[i];
|
||||
if (parse->drive == FDRIVE_DRV_NONE)
|
||||
break;
|
||||
if (drv->drive == parse->drive ||
|
||||
drv->drive == FDRIVE_DRV_NONE) {
|
||||
size = (parse->max_head + 1) * parse->max_track *
|
||||
parse->last_sect;
|
||||
if (nb_sectors == size) {
|
||||
match = i;
|
||||
break;
|
||||
}
|
||||
if (first_match == -1)
|
||||
first_match = i;
|
||||
}
|
||||
}
|
||||
if (match == -1) {
|
||||
if (first_match == -1)
|
||||
match = 1;
|
||||
else
|
||||
match = first_match;
|
||||
parse = &fd_formats[match];
|
||||
}
|
||||
nb_heads = parse->max_head + 1;
|
||||
max_track = parse->max_track;
|
||||
last_sect = parse->last_sect;
|
||||
drv->drive = parse->drive;
|
||||
FLOPPY_DPRINTF("%s floppy disk (%d h %d t %d s) %s\n", parse->str,
|
||||
nb_heads, max_track, last_sect, ro ? "ro" : "rw");
|
||||
FLOPPY_DPRINTF("Floppy disk (%d h %d t %d s) %s\n", nb_heads,
|
||||
max_track, last_sect, ro ? "ro" : "rw");
|
||||
}
|
||||
if (nb_heads == 1) {
|
||||
drv->flags &= ~FDISK_DBL_SIDES;
|
||||
@ -292,6 +189,7 @@ static void fd_revalidate(FDrive *drv)
|
||||
drv->max_track = max_track;
|
||||
drv->last_sect = last_sect;
|
||||
drv->ro = ro;
|
||||
drv->drive = drive;
|
||||
} else {
|
||||
FLOPPY_DPRINTF("No disk in drive\n");
|
||||
drv->last_sect = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user