/* * 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, * Fred N. van Kempen, * * 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*/