228 lines
6.7 KiB
C
228 lines
6.7 KiB
C
/*
|
|
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
|
* running old operating systems and software designed for IBM
|
|
* PC systems and compatibles from 1981 through fairly recent
|
|
* system designs based on the PCI bus.
|
|
*
|
|
* This file is part of the 86Box distribution.
|
|
*
|
|
* Definitions for the hard disk image handler.
|
|
*
|
|
*
|
|
*
|
|
* Authors: Miran Grca, <mgrca8@gmail.com>
|
|
* Fred N. van Kempen, <decwiz@yahoo.com>
|
|
*
|
|
* Copyright 2016-2018 Miran Grca.
|
|
* Copyright 2017-2018 Fred N. van Kempen.
|
|
*/
|
|
#ifndef EMU_HDD_H
|
|
#define EMU_HDD_H
|
|
|
|
#define IMG_FMT_RAW 0
|
|
#define IMG_FMT_HDI 1
|
|
#define IMG_FMT_HDX 2
|
|
#define IMG_FMT_VHD_FIXED 3
|
|
#define IMG_FMT_VHD_DYNAMIC 4
|
|
#define IMG_FMT_VHD_DIFF 5
|
|
|
|
#define HDD_NUM 88 /* total of 88 images supported */
|
|
|
|
/* Hard Disk bus types. */
|
|
#if 0
|
|
/* Bit 4 = DMA supported (0 = no, 1 yes) - used for IDE and ATAPI only;
|
|
Bit 5 = Removable (0 = no, 1 yes). */
|
|
|
|
enum {
|
|
BUS_DISABLED = 0x00,
|
|
|
|
BUS_MFM = 0x01, /* These four are for hard disk only. */
|
|
BUS_XIDE = 0x02,
|
|
BUS_XTA = 0x03,
|
|
BUS_ESDI = 0x04,
|
|
|
|
BUS_PANASONIC = 0x21, / These four are for CD-ROM only. */
|
|
BUS_PHILIPS = 0x22,
|
|
BUS_SONY = 0x23,
|
|
BUS_MITSUMI = 0x24,
|
|
|
|
BUS_IDE_PIO_ONLY = 0x05,
|
|
BUS_IDE_PIO_AND_DMA = 0x15,
|
|
BUS_IDE_R_PIO_ONLY = 0x25,
|
|
BUS_IDE_R_PIO_AND_DMA = 0x35,
|
|
|
|
BUS_ATAPI_PIO_ONLY = 0x06,
|
|
BUS_ATAPI_PIO_AND_DMA = 0x16,
|
|
BUS_ATAPI_R_PIO_ONLY = 0x26,
|
|
BUS_ATAPI_R_PIO_AND_DMA = 0x36,
|
|
|
|
BUS_SASI = 0x07,
|
|
BUS_SASI_R = 0x27,
|
|
|
|
BUS_SCSI = 0x08,
|
|
BUS_SCSI_R = 0x28,
|
|
|
|
BUS_USB = 0x09,
|
|
BUS_USB_R = 0x29
|
|
};
|
|
#else
|
|
enum {
|
|
HDD_BUS_DISABLED = 0,
|
|
HDD_BUS_MFM = 1,
|
|
HDD_BUS_XTA = 2,
|
|
HDD_BUS_ESDI = 3,
|
|
HDD_BUS_IDE = 4,
|
|
HDD_BUS_ATAPI = 5,
|
|
HDD_BUS_SCSI = 6,
|
|
HDD_BUS_USB = 7
|
|
};
|
|
#endif
|
|
|
|
enum {
|
|
HDD_OP_SEEK = 0,
|
|
HDD_OP_READ = 2,
|
|
HDD_OP_WRITE = 3
|
|
};
|
|
|
|
#define HDD_MAX_ZONES 16
|
|
#define HDD_MAX_CACHE_SEG 16
|
|
|
|
typedef struct hdd_preset_t {
|
|
const char *name;
|
|
const char *internal_name;
|
|
uint32_t zones;
|
|
uint32_t avg_spt;
|
|
uint32_t heads;
|
|
uint32_t rpm;
|
|
uint32_t rcache_num_seg;
|
|
uint32_t rcache_seg_size;
|
|
uint32_t max_multiple;
|
|
double full_stroke_ms;
|
|
double track_seek_ms;
|
|
} hdd_preset_t;
|
|
|
|
typedef struct hdd_cache_seg_t {
|
|
uint32_t id;
|
|
uint32_t lba_addr;
|
|
uint32_t ra_addr;
|
|
uint32_t host_addr;
|
|
uint8_t lru;
|
|
uint8_t valid;
|
|
} hdd_cache_seg_t;
|
|
|
|
typedef struct hdd_cache_t {
|
|
// Read cache
|
|
hdd_cache_seg_t segments[HDD_MAX_CACHE_SEG];
|
|
uint32_t num_segments;
|
|
uint32_t segment_size;
|
|
uint32_t ra_segment;
|
|
uint8_t ra_ongoing;
|
|
uint64_t ra_start_time;
|
|
|
|
// Write cache
|
|
uint32_t write_addr;
|
|
uint32_t write_pending;
|
|
uint32_t write_size;
|
|
uint64_t write_start_time;
|
|
} hdd_cache_t;
|
|
|
|
typedef struct hdd_zone_t {
|
|
uint32_t cylinders;
|
|
uint32_t sectors_per_track;
|
|
double sector_time_usec;
|
|
uint32_t start_sector;
|
|
uint32_t end_sector;
|
|
uint32_t start_track;
|
|
} hdd_zone_t;
|
|
|
|
/* Define the virtual Hard Disk. */
|
|
typedef struct hard_disk_t {
|
|
uint8_t id;
|
|
union {
|
|
uint8_t channel; /* Needed for Settings to reduce the number of if's */
|
|
|
|
uint8_t mfm_channel; /* Should rename and/or unionize */
|
|
uint8_t esdi_channel;
|
|
uint8_t xta_channel;
|
|
uint8_t ide_channel;
|
|
uint8_t scsi_id;
|
|
};
|
|
uint8_t bus;
|
|
uint8_t bus_mode; /* Bit 0 = PIO suported;
|
|
Bit 1 = DMA supportd. */
|
|
uint8_t wp; /* Disk has been mounted READ-ONLY */
|
|
uint8_t pad;
|
|
uint8_t pad0;
|
|
|
|
void *priv;
|
|
|
|
char fn[1024]; /* Name of current image file */
|
|
char vhd_parent[1041]; /* Differential VHD parent file */
|
|
|
|
uint32_t seek_pos;
|
|
uint32_t seek_len;
|
|
uint32_t base;
|
|
uint32_t spt;
|
|
uint32_t hpc; /* Physical geometry parameters */
|
|
uint32_t tracks;
|
|
|
|
hdd_zone_t zones[HDD_MAX_ZONES];
|
|
uint32_t num_zones;
|
|
hdd_cache_t cache;
|
|
uint32_t phy_cyl;
|
|
uint32_t phy_heads;
|
|
uint32_t rpm;
|
|
uint8_t max_multiple_block;
|
|
|
|
uint32_t cur_cylinder;
|
|
uint32_t cur_track;
|
|
uint32_t cur_addr;
|
|
|
|
uint32_t speed_preset;
|
|
uint32_t vhd_blocksize;
|
|
|
|
double avg_rotation_lat_usec;
|
|
double full_stroke_usec;
|
|
double head_switch_usec;
|
|
double cyl_switch_usec;
|
|
} hard_disk_t;
|
|
|
|
extern hard_disk_t hdd[HDD_NUM];
|
|
extern unsigned int hdd_table[128][3];
|
|
|
|
extern int hdd_init(void);
|
|
extern int hdd_string_to_bus(char *str, int cdrom);
|
|
extern char *hdd_bus_to_string(int bus, int cdrom);
|
|
extern int hdd_is_valid(int c);
|
|
|
|
extern void hdd_image_init(void);
|
|
extern int hdd_image_load(int id);
|
|
extern void hdd_image_seek(uint8_t id, uint32_t sector);
|
|
extern void hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer);
|
|
extern int hdd_image_read_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer);
|
|
extern void hdd_image_write(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer);
|
|
extern int hdd_image_write_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer);
|
|
extern void hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count);
|
|
extern int hdd_image_zero_ex(uint8_t id, uint32_t sector, uint32_t count);
|
|
extern uint32_t hdd_image_get_last_sector(uint8_t id);
|
|
extern uint32_t hdd_image_get_pos(uint8_t id);
|
|
extern uint8_t hdd_image_get_type(uint8_t id);
|
|
extern void hdd_image_unload(uint8_t id, int fn_preserve);
|
|
extern void hdd_image_close(uint8_t id);
|
|
extern void hdd_image_calc_chs(uint32_t *c, uint32_t *h, uint32_t *s, uint32_t size);
|
|
|
|
extern int image_is_hdi(const char *s);
|
|
extern int image_is_hdx(const char *s, int check_signature);
|
|
extern int image_is_vhd(const char *s, int check_signature);
|
|
|
|
extern double hdd_timing_write(hard_disk_t *hdd, uint32_t addr, uint32_t len);
|
|
extern double hdd_timing_read(hard_disk_t *hdd, uint32_t addr, uint32_t len);
|
|
extern double hdd_seek_get_time(hard_disk_t *hdd, uint32_t dst_addr, uint8_t operation, uint8_t continuous, double max_seek_time);
|
|
int hdd_preset_get_num(void);
|
|
const char *hdd_preset_getname(int preset);
|
|
extern const char *hdd_preset_get_internal_name(int preset);
|
|
extern int hdd_preset_get_from_internal_name(char *s);
|
|
extern void hdd_preset_apply(int hdd_id);
|
|
|
|
#endif /*EMU_HDD_H*/
|