diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 7e009df13..b1f5ca1ce 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.49 2017/09/28 +# Version: @(#)Makefile.mingw 1.0.49 2017/09/29 # # Authors: Miran Grca, # Fred N. van Kempen, @@ -264,7 +264,7 @@ DEVOBJ := bugger.o lpt.o $(SERIAL) \ tandy_eeprom.o tandy_rom.o \ sio_detect.o \ sio_fdc37c665.o sio_fdc37c669.o sio_fdc37c932fr.o \ - sio_pc87306.o sio_w83877f.o sio_um8669f.o \ + sio_pc87306.o sio_w83877f.o sio_um8669f.o piix.o \ keyboard.o \ keyboard_xt.o keyboard_at.o keyboard_pcjr.o \ keyboard_amstrad.o keyboard_olim24.o \ @@ -279,13 +279,15 @@ FDDOBJ := fdd.o fdc.o fdi2raw.o \ floppy_fdi.o floppy_imd.o floppy_img.o floppy_json.o \ floppy_td0.o +HDDOBJ := hdd.o \ + hdd_image.o hdd_table.o \ + hdc.o \ + hdc_esdi_at.o hdc_esdi_mca.o hdc_ide.o hdc_mfm_at.o \ + hdc_mfm_xt.o hdc_xtide.o + CDROMOBJ := cdrom.o \ cdrom_dosbox.o cdrom_image.o cdrom_ioctl.o cdrom_null.o -HDDOBJ := hdd.o hdd_image.o \ - hdd_mfm_at.o hdd_mfm_xebec.o hdd_esdi_at.o hdd_esdi_mca.o \ - hdd_ide_at.o hdd_ide_xt.o piix.o - ifeq ($(USB), y) USBOBJ := usb.o endif diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index de9a3f9b9..70082af35 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -9,7 +9,7 @@ * Implementation of the CD-ROM drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)cdrom.c 1.0.6 2017/09/24 + * Version: @(#)cdrom.c 1.0.7 2017/09/29 * * Author: Miran Grca, * Copyright 2016,2017 Miran Grca. @@ -26,7 +26,8 @@ #include "../scsi/scsi.h" #include "../timer.h" #include "../nvr.h" -#include "../hdd/hdd_ide_at.h" +#include "../hdd/hdd.h" +#include "../hdd/hdc_ide.h" #include "../win/plat_iodev.h" #include "cdrom.h" diff --git a/src/config.c b/src/config.c index 24ec3806c..4c8b24720 100644 --- a/src/config.c +++ b/src/config.c @@ -8,7 +8,7 @@ * * Configuration file handler. * - * Version: @(#)config.c 1.0.6 2017/09/24 + * Version: @(#)config.c 1.0.7 2017/09/29 * * Authors: Sarah Walker, * Miran Grca, @@ -40,7 +40,8 @@ #include "floppy/fdc.h" #include "floppy/fdd.h" #include "hdd/hdd.h" -#include "hdd/hdd_ide_at.h" +#include "hdd/hdc.h" +#include "hdd/hdc_ide.h" #include "machine/machine.h" #include "mouse.h" #ifdef USE_NETWORK @@ -793,12 +794,17 @@ load_other_peripherals(void) else scsi_card_current = 0; - memset(hdd_controller_name, '\0', sizeof(hdd_controller_name)); - p = config_get_string(cat, "hdd_controller", NULL); - if (p != NULL) - strcpy(hdd_controller_name, p); + memset(hdc_name, '\0', sizeof(hdc_name)); + p = config_get_string(cat, "hdc", NULL); + if (p == NULL) { + p = config_get_string(cat, "hdd_controller", NULL); + if (p != NULL) + config_delete_var(cat, "hdd_controller"); + } + if (p != NULL) + strcpy(hdc_name, p); else - strcpy(hdd_controller_name, "none"); + strcpy(hdc_name, "none"); memset(temp, '\0', sizeof(temp)); for (c = 2; c < 4; c++) @@ -821,8 +827,9 @@ load_other_peripherals(void) /* FIXME: this should be in HDD somewhere. --FvK */ -static int -string_to_bus(char *str, int cdrom) +/* will be moved to hdd.c */ +int +hdd_string_to_bus(char *str, int cdrom) { if (! strcmp(str, "none")) { @@ -929,21 +936,55 @@ no_mfm_cdrom: } -/* FIXME: this should be in HDD. --FvK */ -static int -hard_disk_is_valid(int c) +char * +hdd_bus_to_string(int bus, int cdrom) { - if (hdc[c].bus == HDD_BUS_DISABLED) + switch (bus) + { + case HDD_BUS_DISABLED: + default: + return "none"; + break; + case HDD_BUS_MFM: + return "mfm"; + break; + case HDD_BUS_XTIDE: + return "xtide"; + break; + case HDD_BUS_ESDI: + return "esdi"; + break; + case HDD_BUS_IDE_PIO_ONLY: + return cdrom ? "atapi_pio_only" : "ide_pio_only"; + break; + case HDD_BUS_IDE_PIO_AND_DMA: + return cdrom ? "atapi_pio_and_dma" : "ide_pio_and_dma"; + break; + case HDD_BUS_SCSI: + return "scsi"; + break; + case HDD_BUS_SCSI_REMOVABLE: + return "scsi_removable"; + break; + } +} + + +/* FIXME: this should be in HDD. --FvK */ +int +hdd_is_valid(int c) +{ + if (hdd[c].bus == HDD_BUS_DISABLED) { return 0; } - if ((wcslen(hdc[c].fn) == 0) && (hdc[c].bus != HDD_BUS_SCSI_REMOVABLE)) + if ((wcslen(hdd[c].fn) == 0) && (hdd[c].bus != HDD_BUS_SCSI_REMOVABLE)) { return 0; } - if ((hdc[c].tracks == 0) || (hdc[c].hpc == 0) || (hdc[c].spt == 0)) + if ((hdd[c].tracks == 0) || (hdd[c].hpc == 0) || (hdd[c].spt == 0)) { return 0; } @@ -995,7 +1036,7 @@ load_hard_disks(void) int board = 0, dev = 0; memset(temps, '\0', sizeof(temps)); - for (c = 0; c < HDC_NUM; c++) + for (c = 0; c < HDD_NUM; c++) { sprintf(temps, "hdd_%02i_parameters", c + 1); p = config_get_string(cat, temps, NULL); @@ -1003,17 +1044,19 @@ load_hard_disks(void) p = "0, 0, 0, 0, none"; if (tally_char(p, ',') == 3) { - sscanf(p, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %s", &hdc[c].spt, &hdc[c].hpc, &hdc[c].tracks, s); - hdc[c].wp = 0; + sscanf(p, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %s", + &hdd[c].spt, &hdd[c].hpc, &hdd[c].tracks, s); + hdd[c].wp = 0; } else { - sscanf(p, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %i, %s", &hdc[c].spt, &hdc[c].hpc, &hdc[c].tracks, &hdc[c].wp, s); + sscanf(p, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %i, %s", + &hdd[c].spt, &hdd[c].hpc, &hdd[c].tracks, (int *)&hdd[c].wp, s); } - hdc[c].bus = string_to_bus(s, 0); + hdd[c].bus = hdd_string_to_bus(s, 0); - switch(hdc[c].bus) + switch(hdd[c].bus) { case HDD_BUS_DISABLED: default: @@ -1044,63 +1087,45 @@ load_hard_disks(void) break; } - if (hdc[c].spt > max_spt) - { - hdc[c].spt = max_spt; - } - if (hdc[c].hpc > max_hpc) - { - hdc[c].hpc = max_hpc; - } - if (hdc[c].tracks > max_tracks) - { - hdc[c].tracks = max_tracks; - } + if (hdd[c].spt > max_spt) + hdd[c].spt = max_spt; + if (hdd[c].hpc > max_hpc) + hdd[c].hpc = max_hpc; + if (hdd[c].tracks > max_tracks) + hdd[c].tracks = max_tracks; /* MFM/RLL */ sprintf(temps, "hdd_%02i_mfm_channel", c + 1); - if (hdc[c].bus == HDD_BUS_MFM) - { - hdc[c].mfm_channel = !!config_get_int(cat, temps, c & 1); - } + if (hdd[c].bus == HDD_BUS_MFM) + hdd[c].mfm_channel = !!config_get_int(cat, temps, c & 1); else - { config_delete_var(cat, temps); - } /* XT IDE */ sprintf(temps, "hdd_%02i_xtide_channel", c + 1); - if (hdc[c].bus == HDD_BUS_XTIDE) - { - hdc[c].xtide_channel = !!config_get_int(cat, temps, c & 1); - } + if (hdd[c].bus == HDD_BUS_XTIDE) + hdd[c].xtide_channel = !!config_get_int(cat, temps, c & 1); else - { config_delete_var(cat, temps); - } /* ESDI */ sprintf(temps, "hdd_%02i_esdi_channel", c + 1); - if (hdc[c].bus == HDD_BUS_ESDI) - { - hdc[c].esdi_channel = !!config_get_int(cat, temps, c & 1); - } + if (hdd[c].bus == HDD_BUS_ESDI) + hdd[c].esdi_channel = !!config_get_int(cat, temps, c & 1); else - { config_delete_var(cat, temps); - } /* IDE */ sprintf(temps, "hdd_%02i_ide_channel", c + 1); - if ((hdc[c].bus == HDD_BUS_IDE_PIO_ONLY) || (hdc[c].bus == HDD_BUS_IDE_PIO_AND_DMA)) + if ((hdd[c].bus == HDD_BUS_IDE_PIO_ONLY) || (hdd[c].bus == HDD_BUS_IDE_PIO_AND_DMA)) { sprintf(temps2, "%01u:%01u", c >> 1, c & 1); p = config_get_string(cat, temps, temps2); if (strstr(p, ":") == NULL) { - sscanf(p, "%i", &hdc[c].ide_channel); - hdc[c].ide_channel &= 7; + sscanf(p, "%i", (int *)&hdd[c].ide_channel); + hdd[c].ide_channel &= 7; } else { @@ -1108,13 +1133,11 @@ load_hard_disks(void) board &= 3; dev &= 1; - hdc[c].ide_channel = (board << 1) + dev; + hdd[c].ide_channel = (board << 1) + dev; } - if (hdc[c].ide_channel > 7) - { - hdc[c].ide_channel = 7; - } + if (hdd[c].ide_channel > 7) + hdd[c].ide_channel = 7; } else { @@ -1123,32 +1146,28 @@ load_hard_disks(void) /* SCSI */ sprintf(temps, "hdd_%02i_scsi_location", c + 1); - if ((hdc[c].bus == HDD_BUS_SCSI) || (hdc[c].bus == HDD_BUS_SCSI_REMOVABLE)) + if ((hdd[c].bus == HDD_BUS_SCSI) || (hdd[c].bus == HDD_BUS_SCSI_REMOVABLE)) { sprintf(temps2, "%02u:%02u", c, 0); p = config_get_string(cat, temps, temps2); - sscanf(p, "%02u:%02u", &hdc[c].scsi_id, &hdc[c].scsi_lun); + sscanf(p, "%02u:%02u", (int *)&hdd[c].scsi_id, (int *)&hdd[c].scsi_lun); - if (hdc[c].scsi_id > 15) - { - hdc[c].scsi_id = 15; - } - if (hdc[c].scsi_lun > 7) - { - hdc[c].scsi_lun = 7; - } + if (hdd[c].scsi_id > 15) + hdd[c].scsi_id = 15; + if (hdd[c].scsi_lun > 7) + hdd[c].scsi_lun = 7; } else { config_delete_var(cat, temps); } - memset(hdc[c].fn, 0x00, sizeof(hdc[c].fn)); - memset(hdc[c].prev_fn, 0x00, sizeof(hdc[c].prev_fn)); + memset(hdd[c].fn, 0x00, sizeof(hdd[c].fn)); + memset(hdd[c].prev_fn, 0x00, sizeof(hdd[c].prev_fn)); sprintf(temps, "hdd_%02i_fn", c + 1); wp = config_get_wstring(cat, temps, L""); -#if 1 +#if 0 /* * NOTE: * Temporary hack to remove the absolute @@ -1165,31 +1184,31 @@ load_hard_disks(void) wcscpy((wchar_t *)hdc[c].fn, &wp[wcslen(cfg_path)]); } else #endif - memcpy(hdc[c].fn, wp, (wcslen(wp) << 1) + 2); + memcpy(hdd[c].fn, wp, (wcslen(wp) << 1) + 2); /* If the hard disk is in any way empty or invalid, mark the relevant variables for deletion. */ - if (!hard_disk_is_valid(c)) + if (! hdd_is_valid(c)) { - sprintf(temps, "hdd_%02i_parameters", c + 1); + sprintf(temps, "hdd_%02i_parameters", c+1); config_delete_var(cat, temps); - sprintf(temps, "hdd_%02i_preide_channels", c + 1); + sprintf(temps, "hdd_%02i_preide_channels", c+1); config_delete_var(cat, temps); - sprintf(temps, "hdd_%02i_ide_channels", c + 1); + sprintf(temps, "hdd_%02i_ide_channels", c+1); config_delete_var(cat, temps); - sprintf(temps, "hdd_%02i_scsi_location", c + 1); + sprintf(temps, "hdd_%02i_scsi_location", c+1); config_delete_var(cat, temps); - sprintf(temps, "hdd_%02i_fn", c + 1); + sprintf(temps, "hdd_%02i_fn", c+1); config_delete_var(cat, temps); } - sprintf(temps, "hdd_%02i_mfm_channel", c + 1); + sprintf(temps, "hdd_%02i_mfm_channel", c+1); config_delete_var(cat, temps); - sprintf(temps, "hdd_%02i_ide_channel", c + 1); + sprintf(temps, "hdd_%02i_ide_channel", c+1); config_delete_var(cat, temps); } } @@ -1296,7 +1315,7 @@ load_removable_devices(void) sscanf("0, none", "%u, %s", &cdrom_drives[c].sound_on, s); } - cdrom_drives[c].bus_type = string_to_bus(s, 1); + cdrom_drives[c].bus_type = hdd_string_to_bus(s, 1); sprintf(temps, "cdrom_%02i_ide_channel", c + 1); if ((cdrom_drives[c].bus_type == CDROM_BUS_ATAPI_PIO_ONLY) || (cdrom_drives[c].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA)) @@ -1306,7 +1325,7 @@ load_removable_devices(void) if (strstr(p, ":") == NULL) { - sscanf(p, "%i", &hdc[c].ide_channel); + sscanf(p, "%i", (int *)&hdd[c].ide_channel); cdrom_drives[c].ide_channel &= 7; } else @@ -1427,7 +1446,7 @@ config_load(wchar_t *fn) vid_api = 1; enable_sync = 1; joystick_type = 7; - strcpy(hdd_controller_name, "none"); + strcpy(hdc_name, "none"); serial_enabled[0] = 1; serial_enabled[1] = 1; lpt_enabled = 1; @@ -1979,13 +1998,13 @@ save_other_peripherals(void) config_set_string(cat, "scsicard", scsi_card_get_internal_name(scsi_card_current)); } - if (!strcmp(hdd_controller_name, "none")) + if (!strcmp(hdc_name, "none")) { - config_delete_var(cat, "hdd_controller"); + config_delete_var(cat, "hdc"); } else { - config_set_string(cat, "hdd_controller", hdd_controller_name); + config_set_string(cat, "hdc", hdc_name); } memset(temps, '\0', sizeof(temps)); @@ -2017,40 +2036,6 @@ save_other_peripherals(void) } -static char * -bus_to_string(int bus, int cdrom) -{ - switch (bus) - { - case HDD_BUS_DISABLED: - default: - return "none"; - break; - case HDD_BUS_MFM: - return "mfm"; - break; - case HDD_BUS_XTIDE: - return "xtide"; - break; - case HDD_BUS_ESDI: - return "esdi"; - break; - case HDD_BUS_IDE_PIO_ONLY: - return cdrom ? "atapi_pio_only" : "ide_pio_only"; - break; - case HDD_BUS_IDE_PIO_AND_DMA: - return cdrom ? "atapi_pio_and_dma" : "ide_pio_and_dma"; - break; - case HDD_BUS_SCSI: - return "scsi"; - break; - case HDD_BUS_SCSI_REMOVABLE: - return "scsi_removable"; - break; - } -} - - /* Save "Hard Disks" section. */ static void save_hard_disks(void) @@ -2063,81 +2048,82 @@ save_hard_disks(void) char *p; memset(temps, 0, sizeof(temps)); - for (c = 0; c < HDC_NUM; c++) + for (c = 0; c < HDD_NUM; c++) { - sprintf(temps, "hdd_%02i_parameters", c + 1); + sprintf(temps, "hdd_%02i_parameters", c+1); memset(s, 0, sizeof(s)); - if (!hard_disk_is_valid(c)) + if (! hdd_is_valid(c)) { config_delete_var(cat, temps); } else { - p = bus_to_string(hdc[c].bus, 0); - sprintf(temps2, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %i, %s", hdc[c].spt, hdc[c].hpc, hdc[c].tracks, hdc[c].wp, p); + p = hdd_bus_to_string(hdd[c].bus, 0); + sprintf(temps2, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %i, %s", + hdd[c].spt, hdd[c].hpc, hdd[c].tracks, hdd[c].wp, p); config_set_string(cat, temps, temps2); } - sprintf(temps, "hdd_%02i_mfm_channel", c + 1); - if (!hard_disk_is_valid(c) || (hdc[c].bus != HDD_BUS_MFM)) + sprintf(temps, "hdd_%02i_mfm_channel", c+1); + if (! hdd_is_valid(c) || (hdd[c].bus != HDD_BUS_MFM)) { config_delete_var(cat, temps); } else { - config_set_int(cat, temps, hdc[c].mfm_channel); + config_set_int(cat, temps, hdd[c].mfm_channel); } - sprintf(temps, "hdd_%02i_xtide_channel", c + 1); - if (!hard_disk_is_valid(c) || (hdc[c].bus != HDD_BUS_XTIDE)) + sprintf(temps, "hdd_%02i_xtide_channel", c+1); + if (! hdd_is_valid(c) || (hdd[c].bus != HDD_BUS_XTIDE)) { config_delete_var(cat, temps); } else { - config_set_int(cat, temps, hdc[c].xtide_channel); + config_set_int(cat, temps, hdd[c].xtide_channel); } - sprintf(temps, "hdd_%02i_esdi_channel", c + 1); - if (!hard_disk_is_valid(c) || (hdc[c].bus != HDD_BUS_ESDI)) + sprintf(temps, "hdd_%02i_esdi_channel", c+1); + if (! hdd_is_valid(c) || (hdd[c].bus != HDD_BUS_ESDI)) { config_delete_var(cat, temps); } else { - config_set_int(cat, temps, hdc[c].esdi_channel); + config_set_int(cat, temps, hdd[c].esdi_channel); } sprintf(temps, "hdd_%02i_ide_channel", c + 1); - if (!hard_disk_is_valid(c) || ((hdc[c].bus != HDD_BUS_IDE_PIO_ONLY) && (hdc[c].bus != HDD_BUS_IDE_PIO_AND_DMA))) + if (! hdd_is_valid(c) || ((hdd[c].bus != HDD_BUS_IDE_PIO_ONLY) && (hdd[c].bus != HDD_BUS_IDE_PIO_AND_DMA))) { config_delete_var(cat, temps); } else { - sprintf(temps2, "%01u:%01u", hdc[c].ide_channel >> 1, hdc[c].ide_channel & 1); + sprintf(temps2, "%01u:%01u", hdd[c].ide_channel >> 1, hdd[c].ide_channel & 1); config_set_string(cat, temps, temps2); } sprintf(temps, "hdd_%02i_scsi_location", c + 1); - if (!hard_disk_is_valid(c) || ((hdc[c].bus != HDD_BUS_SCSI) && (hdc[c].bus != HDD_BUS_SCSI_REMOVABLE))) + if (! hdd_is_valid(c) || ((hdd[c].bus != HDD_BUS_SCSI) && (hdd[c].bus != HDD_BUS_SCSI_REMOVABLE))) { config_delete_var(cat, temps); } else { - sprintf(temps2, "%02u:%02u", hdc[c].scsi_id, hdc[c].scsi_lun); + sprintf(temps2, "%02u:%02u", hdd[c].scsi_id, hdd[c].scsi_lun); config_set_string(cat, temps, temps2); } - sprintf(temps, "hdd_%02i_fn", c + 1); - if (!hard_disk_is_valid(c) || (wcslen(hdc[c].fn) == 0)) + sprintf(temps, "hdd_%02i_fn", c+1); + if (! hdd_is_valid(c) || (wcslen(hdd[c].fn) == 0)) { config_delete_var(cat, temps); } else { - config_set_wstring(cat, temps, hdc[c].fn); + config_set_wstring(cat, temps, hdd[c].fn); } } @@ -2233,7 +2219,7 @@ save_removable_devices(void) } else { - sprintf(temps2, "%u, %s", cdrom_drives[c].sound_on, bus_to_string(cdrom_drives[c].bus_type, 1)); + sprintf(temps2, "%u, %s", cdrom_drives[c].sound_on, hdd_bus_to_string(cdrom_drives[c].bus_type, 1)); config_set_string(cat, temps, temps2); } diff --git a/src/hdd/hdc.c b/src/hdd/hdc.c new file mode 100644 index 000000000..647f73187 --- /dev/null +++ b/src/hdd/hdc.c @@ -0,0 +1,149 @@ +/* + * 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. + * + * Common code to handle all sorts of disk controllers. + * + * Version: @(#)hdc.c 1.0.1 2017/09/29 + * + * Authors: Miran Grca, + * Fred N. van Kempen, + * Copyright 2016,2017 Miran Grca. + * Copyright 2017 Fred N. van Kempen. + */ +#include +#include +#include +#include +#include "../ibm.h" +#include "../cpu/cpu.h" +#include "../device.h" +#include "../machine/machine.h" +#include "hdc.h" + + +char hdc_name[16]; +int hdc_current; + + +static void * +null_init(void) +{ + return(NULL); +} + + +static void +null_close(void *priv) +{ +} + + +static device_t null_device = { + "Null HDC", 0, + null_init, null_close, + NULL, NULL, NULL, NULL, NULL +}; + + +static struct { + char name[50]; + char internal_name[16]; + device_t *device; + int is_mfm; +} controllers[] = { + { "None", "none", + &null_device, 0 }, + + { "Internal Controller", "internal", + &null_device, 0 }, + + { "IBM PC Fixed Disk Adapter (MFM,Xebec)", "mfm_xebec", + &mfm_xt_xebec_device, 1 }, + + { "PC DTC-5150X Fixed Disk Adapter (MFM)", "dtc5150x", + &mfm_xt_dtc5150x_device, 1 }, + + { "IBM PC/AT Fixed Disk Adapter (WD1003)", "mfm_at", + &mfm_at_wd1003_device, 1 }, + + { "PC/AT ESDI Fixed Disk Adapter (WD1007V-SE1)", "wd1007vse1", + &esdi_at_wd1007vse1_device, 0 }, + + { "IBM PS/2 ESDI Fixed Disk Adapter (ESDI)","esdi_mca", + &esdi_ps2_device, 1 }, + + { "[IDE] PC/XT XTIDE", "xtide", + &xtide_device , 0 }, + + { "[IDE] PC/AT XTIDE", "xtide_at", + &xtide_at_device, 0 }, + + { "[IDE] PS/2 XTIDE (Acculogic)", "xtide_ps2", + &xtide_ps2_device, 0 }, + + { "[IDE] PS/2 AT XTIDE (1.1.5)", "xtide_at_ps2", + &xtide_at_ps2_device, 0 }, + + { "", "", NULL, 0 } +}; + + +char * +hdc_get_name(int hdc) +{ + return(controllers[hdc].name); +} + + +char * +hdc_get_internal_name(int hdc) +{ + return(controllers[hdc].internal_name); +} + + +int +hdc_get_flags(int hdc) +{ + return(controllers[hdc].device->flags); +} + + +int +hdc_available(int hdc) +{ + return(device_available(controllers[hdc].device)); +} + + +int +hdc_current_is_mfm(void) +{ + return(controllers[hdc_current].is_mfm); +} + + +void +hdc_init(char *name) +{ + int c; + + if (machines[machine].flags & MACHINE_HAS_IDE) return; + + for (c=0; controllers[c].device; c++) { + if (! strcmp(name, controllers[c].internal_name)) { + hdc_current = c; + + if (strcmp(name, "none")) { + device_add(controllers[c].device); + + return; + } + } + } +} diff --git a/src/hdd/hdc.h b/src/hdd/hdc.h new file mode 100644 index 000000000..d73c315d0 --- /dev/null +++ b/src/hdd/hdc.h @@ -0,0 +1,47 @@ +/* + * 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 common disk controller handler. + * + * Version: @(#)hdc.h 1.0.1 2017/09/29 + * + * Authors: Miran Grca, + * Fred N. van Kempen, + * Copyright 2016,2017 Miran Grca. + * Copyright 2017 Fred N. van Kempen. + */ +#ifndef EMU_HDC_H +# define EMU_HDC_H + + +extern char hdc_name[16]; +extern int hdc_current; + + +extern device_t mfm_xt_xebec_device; /* mfm_xt_xebec */ +extern device_t mfm_xt_dtc5150x_device; /* mfm_xt_dtc */ +extern device_t mfm_at_wd1003_device; /* mfm_at_wd1003 */ + +extern device_t esdi_at_wd1007vse1_device; /* esdi_at */ +extern device_t esdi_ps2_device; /* esdi_mca */ + +extern device_t xtide_device; /* xtide_xt */ +extern device_t xtide_at_device; /* xtide_at */ +extern device_t xtide_ps2_device; /* xtide_ps2 */ +extern device_t xtide_at_ps2_device; /* xtide_at_ps2 */ + + +extern char *hdc_get_name(int hdc); +extern char *hdc_get_internal_name(int hdc); +extern int hdc_get_flags(int hdc); +extern int hdc_available(int hdc); +extern int hdc_current_is_mfm(void); +extern void hdc_init(char *internal_name); + + +#endif /*EMU_HDC_H*/ diff --git a/src/hdd/hdc_esdi_at.c b/src/hdd/hdc_esdi_at.c new file mode 100644 index 000000000..eec73f825 --- /dev/null +++ b/src/hdd/hdc_esdi_at.c @@ -0,0 +1,847 @@ +/* + * 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. + * + * Driver for the ESDI controller (WD1007-vse1) for PC/AT. + * + * Version: @(#)hdc_esdi_at.c 1.0.1 2017/09/29 + * + * Authors: Miran Grca, + * Fred N. van Kempen, + * Copyright 2016,2017 Miran Grca. + * Copyright 2017 Fred N. van Kempen. + */ +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include "../ibm.h" +#include "../device.h" +#include "../io.h" +#include "../mem.h" +#include "../pic.h" +#include "../rom.h" +#include "../timer.h" +#include "hdc.h" +#include "hdd.h" + + +#define HDC_TIME (TIMER_USEC*10) +#define BIOS_FILE L"roms/hdd/esdi_at/62-000279-061.bin" + +#define STAT_ERR 0x01 +#define STAT_INDEX 0x02 +#define STAT_CORRECTED_DATA 0x04 +#define STAT_DRQ 0x08 /* Data request */ +#define STAT_DSC 0x10 +#define STAT_SEEK_COMPLETE 0x20 +#define STAT_READY 0x40 +#define STAT_BUSY 0x80 + +#define ERR_DAM_NOT_FOUND 0x01 /*Data Address Mark not found*/ +#define ERR_TR000 0x02 /*Track 0 not found*/ +#define ERR_ABRT 0x04 /*Command aborted*/ +#define ERR_ID_NOT_FOUND 0x10 /*ID not found*/ +#define ERR_DATA_CRC 0x40 /*Data CRC error*/ +#define ERR_BAD_BLOCK 0x80 /*Bad Block detected*/ + +#define CMD_NOP 0x00 +#define CMD_RESTORE 0x10 +#define CMD_READ 0x20 +#define CMD_WRITE 0x30 +#define CMD_VERIFY 0x40 +#define CMD_FORMAT 0x50 +#define CMD_SEEK 0x70 +#define CMD_DIAGNOSE 0x90 +#define CMD_SET_PARAMETERS 0x91 +#define CMD_READ_PARAMETERS 0xec + + +extern char ide_fn[4][512]; + + +typedef struct { + int cfg_spt; + int cfg_hpc; + int current_cylinder; + int real_spt; + int real_hpc; + int real_tracks; + int present; + int hdd_num; +} drive_t; + +typedef struct { + uint8_t status; + uint8_t error; + int secount,sector,cylinder,head,cylprecomp; + uint8_t command; + uint8_t fdisk; + int pos; + + int drive_sel; + int reset; + uint16_t buffer[256]; + int irqstat; + + int callback; + + drive_t drives[2]; + + rom_t bios_rom; +} esdi_t; + + +static inline void +irq_raise(esdi_t *esdi) +{ + if (! (esdi->fdisk&2)) + picint(1<<14); + + esdi->irqstat=1; +} + + +static inline void +irq_lower(esdi_t *esdi) +{ + picintc(1<<14); +} + + +static void +irq_update(esdi_t *esdi) +{ + if (esdi->irqstat && !((pic2.pend|pic2.ins)&0x40) && !(esdi->fdisk & 2)) + picint(1<<14); +} + + +/* Return the sector offset for the current register values. */ +static int +get_sector(esdi_t *esdi, off64_t *addr) +{ + drive_t *drive = &esdi->drives[esdi->drive_sel]; + int heads = drive->cfg_hpc; + int sectors = drive->cfg_spt; + + if (esdi->head > heads) { + pclog("esdi_get_sector: past end of configured heads\n"); + return 1; + } + + if (esdi->sector >= sectors+1) { + pclog("esdi_get_sector: past end of configured sectors\n"); + return 1; + } + + if (drive->cfg_spt==drive->real_spt && drive->cfg_hpc==drive->real_hpc) { + *addr = ((((off64_t) esdi->cylinder * heads) + esdi->head) * + sectors) + (esdi->sector - 1); + } else { + /* + * When performing translation, the firmware seems to leave 1 + * sector per track inaccessible (spare sector) + */ + int c, h, s; + + *addr = ((((off64_t) esdi->cylinder * heads) + esdi->head) * + sectors) + (esdi->sector - 1); + + s = *addr % (drive->real_spt - 1); + h = (*addr / (drive->real_spt - 1)) % drive->real_hpc; + c = (*addr / (drive->real_spt - 1)) / drive->real_hpc; + + *addr = ((((off64_t)c * drive->real_hpc) + h) * drive->real_spt) + s; + } + + return(0); +} + + +/* Move to the next sector using CHS addressing. */ +static void +next_sector(esdi_t *esdi) +{ + drive_t *drive = &esdi->drives[esdi->drive_sel]; + + esdi->sector++; + if (esdi->sector == (drive->cfg_spt + 1)) { + esdi->sector = 1; + if (++esdi->head == drive->cfg_hpc) { + esdi->head = 0; + esdi->cylinder++; + if (drive->current_cylinder < drive->real_tracks) + drive->current_cylinder++; + } + } +} + + +static void +esdi_writew(uint16_t port, uint16_t val, void *priv) +{ + esdi_t *esdi = (esdi_t *)priv; + + esdi->buffer[esdi->pos >> 1] = val; + esdi->pos += 2; + + if (esdi->pos >= 512) { + esdi->pos = 0; + esdi->status = STAT_BUSY; + timer_process(); + esdi->callback = 6*HDC_TIME; + timer_update_outstanding(); + } +} + + +static void +esdi_write(uint16_t port, uint8_t val, void *priv) +{ + esdi_t *esdi = (esdi_t *)priv; + + switch (port) { + case 0x1F0: /* Data */ + esdi_writew(port, val | (val << 8), priv); + return; + + case 0x1F1: /* Write precompenstation */ + esdi->cylprecomp = val; + return; + + case 0x1F2: /* Sector count */ + esdi->secount = val; + return; + + case 0x1F3: /* Sector */ + esdi->sector = val; + return; + + case 0x1F4: /* Cylinder low */ + esdi->cylinder = (esdi->cylinder & 0xFF00) | val; + return; + + case 0x1F5: /* Cylinder high */ + esdi->cylinder = (esdi->cylinder & 0xFF) | (val << 8); + return; + + case 0x1F6: /* Drive/Head */ + esdi->head = val & 0xF; + esdi->drive_sel = (val & 0x10) ? 1 : 0; + if (esdi->drives[esdi->drive_sel].present) + esdi->status = 0; + else + esdi->status = STAT_READY | STAT_DSC; + return; + + case 0x1F7: /* Command register */ + irq_lower(esdi); + esdi->command = val; + esdi->error = 0; + + switch (val & 0xf0) { + case CMD_RESTORE: + esdi->command &= ~0x0f; /*Mask off step rate*/ + esdi->status = STAT_BUSY; + timer_process(); + esdi->callback = 200*HDC_TIME; + timer_update_outstanding(); + break; + + case CMD_SEEK: + esdi->command &= ~0x0f; /*Mask off step rate*/ + esdi->status = STAT_BUSY; + timer_process(); + esdi->callback = 200*HDC_TIME; + timer_update_outstanding(); + break; + + default: + switch (val) { + case CMD_NOP: + esdi->status = STAT_BUSY; + timer_process(); + esdi->callback = 200*HDC_TIME; + timer_update_outstanding(); + break; + + case CMD_READ: + case CMD_READ+1: + case CMD_READ+2: + case CMD_READ+3: + esdi->command &= ~3; + if (val & 2) + fatal("Read with ECC\n"); + + case 0xa0: + esdi->status = STAT_BUSY; + timer_process(); + esdi->callback = 200*HDC_TIME; + timer_update_outstanding(); + break; + + case CMD_WRITE: + case CMD_WRITE+1: + case CMD_WRITE+2: + case CMD_WRITE+3: + esdi->command &= ~3; + if (val & 2) + fatal("Write with ECC\n"); + esdi->status = STAT_DRQ | STAT_DSC; + esdi->pos=0; + break; + + case CMD_VERIFY: + case CMD_VERIFY+1: + esdi->command &= ~1; + esdi->status = STAT_BUSY; + timer_process(); + esdi->callback = 200*HDC_TIME; + timer_update_outstanding(); + break; + + case CMD_FORMAT: + esdi->status = STAT_DRQ; + esdi->pos=0; + break; + + case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ + esdi->status = STAT_BUSY; + timer_process(); + esdi->callback = 30*HDC_TIME; + timer_update_outstanding(); + break; + + case CMD_DIAGNOSE: /* Execute Drive Diagnostics */ + esdi->status = STAT_BUSY; + timer_process(); + esdi->callback = 200*HDC_TIME; + timer_update_outstanding(); + break; + + case 0xe0: /*???*/ + case CMD_READ_PARAMETERS: + esdi->status = STAT_BUSY; + timer_process(); + esdi->callback = 200*HDC_TIME; + timer_update_outstanding(); + break; + + default: + pclog("Bad esdi command %02X\n", val); + case 0xe8: /*???*/ + esdi->status = STAT_BUSY; + timer_process(); + esdi->callback = 200*HDC_TIME; + timer_update_outstanding(); + break; + } + } + break; + + case 0x3F6: /* Device control */ + if ((esdi->fdisk & 4) && !(val & 4)) { + timer_process(); + esdi->callback = 500*HDC_TIME; + timer_update_outstanding(); + esdi->reset = 1; + esdi->status = STAT_BUSY; + } + + if (val & 4) { + /*Drive held in reset*/ + timer_process(); + esdi->callback = 0; + timer_update_outstanding(); + esdi->status = STAT_BUSY; + } + esdi->fdisk = val; + irq_update(esdi); + } +} + + +static uint16_t +esdi_readw(uint16_t port, void *priv) +{ + esdi_t *esdi = (esdi_t *)priv; + uint16_t temp; + + temp = esdi->buffer[esdi->pos >> 1]; + esdi->pos += 2; + + if (esdi->pos >= 512) { + esdi->pos=0; + esdi->status = STAT_READY | STAT_DSC; + if (esdi->command == CMD_READ || esdi->command == 0xa0) { + esdi->secount = (esdi->secount - 1) & 0xff; + if (esdi->secount) { + next_sector(esdi); + esdi->status = STAT_BUSY; + timer_process(); + esdi->callback = 6*HDC_TIME; + timer_update_outstanding(); + } + } + } + + return(temp); +} + + +static uint8_t +esdi_read(uint16_t port, void *priv) +{ + esdi_t *esdi = (esdi_t *)priv; + uint8_t temp = 0xff; + + switch (port) { + case 0x1F0: /* Data */ + temp = esdi_readw(port, esdi) & 0xff; + break; + + case 0x1F1: /* Error */ + temp = esdi->error; + break; + + case 0x1F2: /* Sector count */ + temp = (uint8_t)esdi->secount; + break; + + case 0x1F3: /* Sector */ + temp = (uint8_t)esdi->sector; + break; + + case 0x1F4: /* Cylinder low */ + temp = (uint8_t)(esdi->cylinder&0xFF); + break; + + case 0x1F5: /* Cylinder high */ + temp = (uint8_t)(esdi->cylinder>>8); + break; + + case 0x1F6: /* Drive/Head */ + temp = (uint8_t)(esdi->head | (esdi->drive_sel?0x10:0) | 0xa0); + break; + + case 0x1F7: /* Status */ + irq_lower(esdi); + temp = esdi->status; + break; + } + + return(temp); +} + + +static void +esdi_callback(void *priv) +{ + esdi_t *esdi = (esdi_t *)priv; + drive_t *drive = &esdi->drives[esdi->drive_sel]; + off64_t addr; + + esdi->callback = 0; + if (esdi->reset) { + esdi->status = STAT_READY | STAT_DSC; + esdi->error = 1; + esdi->secount = 1; + esdi->sector = 1; + esdi->head = 0; + esdi->cylinder = 0; + esdi->reset = 0; + + return; + } + + switch (esdi->command) { + case CMD_RESTORE: + if (! drive->present) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + } else { + drive->current_cylinder = 0; + esdi->status = STAT_READY | STAT_DSC; + } + irq_raise(esdi); + break; + + case CMD_SEEK: + if (! drive->present) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + } else { + esdi->status = STAT_READY | STAT_DSC; + } + irq_raise(esdi); + break; + + case CMD_READ: + if (! drive->present) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + irq_raise(esdi); + break; + } + + if (get_sector(esdi, &addr)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + irq_raise(esdi); + break; + } + + if (hdd_image_read_ex(drive->hdd_num, addr, 1, + (uint8_t *)esdi->buffer)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + irq_raise(esdi); + break; + } + + esdi->pos = 0; + esdi->status = STAT_DRQ | STAT_READY | STAT_DSC; + irq_raise(esdi); + update_status_bar_icon(SB_HDD | HDD_BUS_ESDI, 1); + break; + + case CMD_WRITE: + if (! drive->present) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + irq_raise(esdi); + break; + } + + if (get_sector(esdi, &addr)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + irq_raise(esdi); + break; + } + + if (hdd_image_write_ex(drive->hdd_num, addr, 1, + (uint8_t *)esdi->buffer)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + irq_raise(esdi); + break; + } + + irq_raise(esdi); + esdi->secount = (esdi->secount - 1) & 0xff; + if (esdi->secount) { + esdi->status = STAT_DRQ | STAT_READY | STAT_DSC; + esdi->pos = 0; + next_sector(esdi); + } else { + esdi->status = STAT_READY | STAT_DSC; + } + update_status_bar_icon(SB_HDD | HDD_BUS_ESDI, 1); + break; + + case CMD_VERIFY: + if (! drive->present) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + irq_raise(esdi); + break; + } + + if (get_sector(esdi, &addr)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + irq_raise(esdi); + break; + } + + if (hdd_image_read_ex(drive->hdd_num, addr, 1, + (uint8_t *)esdi->buffer)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + irq_raise(esdi); + break; + } + + update_status_bar_icon(SB_HDD | HDD_BUS_ESDI, 1); + next_sector(esdi); + esdi->secount = (esdi->secount - 1) & 0xff; + if (esdi->secount) + esdi->callback = 6*HDC_TIME; + else { + esdi->pos = 0; + esdi->status = STAT_READY | STAT_DSC; + irq_raise(esdi); + } + break; + + case CMD_FORMAT: + if (! drive->present) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + irq_raise(esdi); + break; + } + + if (get_sector(esdi, &addr)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + irq_raise(esdi); + break; + } + if (hdd_image_zero_ex(drive->hdd_num, addr, esdi->secount)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + irq_raise(esdi); + break; + } + esdi->status = STAT_READY | STAT_DSC; + irq_raise(esdi); + update_status_bar_icon(SB_HDD | HDD_BUS_ESDI, 1); + break; + + case CMD_DIAGNOSE: + if (! drive->present) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + } else { + esdi->error = 1; /*No error detected*/ + esdi->status = STAT_READY | STAT_DSC; + } + irq_raise(esdi); + break; + + case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ + if (! drive->present) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + irq_raise(esdi); + break; + } + + drive->cfg_spt = esdi->secount; + drive->cfg_hpc = esdi->head+1; + pclog("Parameters: spt=%i hpc=%i\n", drive->cfg_spt,drive->cfg_hpc); + if (! esdi->secount) + fatal("secount=0\n"); + esdi->status = STAT_READY | STAT_DSC; + irq_raise(esdi); + break; + + case CMD_NOP: + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + irq_raise(esdi); + break; + + case 0xe0: + if (! drive->present) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + irq_raise(esdi); + break; + } + + switch (esdi->cylinder >> 8) { + case 0x31: + esdi->cylinder = drive->real_tracks; + break; + + case 0x33: + esdi->cylinder = drive->real_hpc; + break; + + case 0x35: + esdi->cylinder = 0x200; + break; + + case 0x36: + esdi->cylinder = drive->real_spt; + break; + + default: + pclog("EDSI Bad read config %02x\n", + esdi->cylinder >> 8); + } + esdi->status = STAT_READY | STAT_DSC; + irq_raise(esdi); + break; + + case 0xa0: + if (! drive->present) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + } else { + memset(esdi->buffer, 0, 512); + memset(&esdi->buffer[3], 0xff, 512-6); + esdi->pos = 0; + esdi->status = STAT_DRQ | STAT_READY | STAT_DSC; + } + irq_raise(esdi); + break; + + case CMD_READ_PARAMETERS: + if (! drive->present) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + irq_raise(esdi); + break; + } + + memset(esdi->buffer, 0, 512); + esdi->buffer[0] = 0x44; /* general configuration */ + esdi->buffer[1] = drive->real_tracks; /* number of non-removable cylinders */ + esdi->buffer[2] = 0; /* number of removable cylinders */ + esdi->buffer[3] = drive->real_hpc; /* number of heads */ + esdi->buffer[4] = 600; /* number of unformatted bytes/track */ + esdi->buffer[5] = esdi->buffer[4] * drive->real_spt; /* number of unformatted bytes/sector */ + esdi->buffer[6] = drive->real_spt; /* number of sectors */ + esdi->buffer[7] = 0; /*minimum bytes in inter-sector gap*/ + esdi->buffer[8] = 0; /* minimum bytes in postamble */ + esdi->buffer[9] = 0; /* number of words of vendor status */ + /* controller info */ + esdi->buffer[20] = 2; /* controller type */ + esdi->buffer[21] = 1; /* sector buffer size, in sectors */ + esdi->buffer[22] = 0; /* ecc bytes appended */ + esdi->buffer[27] = 'W' | ('D' << 8); + esdi->buffer[28] = '1' | ('0' << 8); + esdi->buffer[29] = '0' | ('7' << 8); + esdi->buffer[30] = 'V' | ('-' << 8); + esdi->buffer[31] = 'S' | ('E' << 8); + esdi->buffer[32] = '1'; + esdi->buffer[47] = 0; /* sectors per interrupt */ + esdi->buffer[48] = 0;/* can use double word read/write? */ + esdi->pos = 0; + esdi->status = STAT_DRQ | STAT_READY | STAT_DSC; + irq_raise(esdi); + break; + + default: + pclog("ESDI Callback on unknown command %02x\n", esdi->command); + case 0xe8: + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + irq_raise(esdi); + break; + } + + update_status_bar_icon(SB_HDD | HDD_BUS_ESDI, 0); +} + + +static void +esdi_rom_write(uint32_t addr, uint8_t val, void *priv) +{ + rom_t *rom = (rom_t *)priv; + + addr &= rom->mask; + if (addr >= 0x1f00 && addr < 0x2000) + rom->rom[addr] = val; +} + + +static void +loadhd(esdi_t *esdi, int hdd_num, int d, const wchar_t *fn) +{ + drive_t *drive = &esdi->drives[d]; + + if (! hdd_image_load(hdd_num)) { + drive->present = 0; + return; + } + + drive->cfg_spt = drive->real_spt = hdd[hdd_num].spt; + drive->cfg_hpc = drive->real_hpc = hdd[hdd_num].hpc; + drive->real_tracks = hdd[hdd_num].tracks; + drive->hdd_num = hdd_num; + drive->present = 1; +} + + +static void * +wd1007vse1_init(void) +{ + int i, c = 0; + + esdi_t *esdi = malloc(sizeof(esdi_t)); + memset(esdi, 0x00, sizeof(esdi_t)); + + esdi->drives[0].present = esdi->drives[1].present = 0; + + for (i=0; i= ESDI_NUM) break; + } + } + + esdi->status = STAT_READY | STAT_DSC; + esdi->error = 1; + + rom_init(&esdi->bios_rom, + BIOS_FILE, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + mem_mapping_set_handler( + &esdi->bios_rom.mapping, + rom_read, rom_readw, rom_readl, + esdi_rom_write, NULL, NULL); + + io_sethandler(0x01f0, 1, + esdi_read, esdi_readw, NULL, + esdi_write, esdi_writew, NULL, esdi); + io_sethandler(0x01f1, 7, + esdi_read, NULL, NULL, + esdi_write, NULL, NULL, esdi); + io_sethandler(0x03f6, 1, NULL, NULL, NULL, + esdi_write, NULL, NULL, esdi); + + timer_add(esdi_callback, &esdi->callback, &esdi->callback, esdi); + + return(esdi); +} + + +static void +wd1007vse1_close(void *priv) +{ + esdi_t *esdi = (esdi_t *)priv; + drive_t *drive; + int d; + + esdi->drives[0].present = esdi->drives[1].present = 0; + + for (d=0; d<2; d++) { + drive = &esdi->drives[d]; + + hdd_image_close(drive->hdd_num); + } + + free(esdi); +} + + +static int +wd1007vse1_available(void) +{ + return(rom_present(BIOS_FILE)); +} + + +device_t esdi_at_wd1007vse1_device = { + "Western Digital WD1007V-SE1 (ESDI)", + DEVICE_AT, + wd1007vse1_init, + wd1007vse1_close, + wd1007vse1_available, + NULL, NULL, NULL, NULL +}; diff --git a/src/hdd/hdd_esdi_mca.c b/src/hdd/hdc_esdi_mca.c similarity index 96% rename from src/hdd/hdd_esdi_mca.c rename to src/hdd/hdc_esdi_mca.c index 242d4efa6..1f512d384 100644 --- a/src/hdd/hdd_esdi_mca.c +++ b/src/hdd/hdc_esdi_mca.c @@ -52,7 +52,7 @@ * however, are auto-configured by the system software as * shown above. * - * Version: @(#)hdd_esdi_mca.c 1.0.3 2017/09/24 + * Version: @(#)hdc_esdi_mca.c 1.0.4 2017/09/29 * * Authors: Sarah Walker, * Miran Grca, @@ -73,8 +73,8 @@ #include "../pic.h" #include "../rom.h" #include "../timer.h" -#include "hdd_image.h" -#include "hdd_esdi_mca.h" +#include "hdc.h" +#include "hdd.h" /* These are hardwired. */ @@ -82,8 +82,11 @@ #define ESDI_IOADDR_SEC 0x3518 #define ESDI_IRQCHAN 14 +#define BIOS_FILE_L L"roms/hdd/esdi/90x8969.bin" +#define BIOS_FILE_H L"roms/hdd/esdi/90x8970.bin" -#define ESDI_TIME (2000 * TIMER_USEC) + +#define ESDI_TIME (200*TIMER_USEC) #define CMD_ADAPTER 0 @@ -92,8 +95,8 @@ typedef struct esdi_drive { int tracks; int sectors; int present; - int hdc_num; -} esdi_drive_t; + int hdd_num; +} drive_t; typedef struct esdi { uint16_t base; @@ -137,7 +140,7 @@ typedef struct esdi { int req_in_progress; } cmds[3]; - esdi_drive_t drives[2]; + drive_t drives[2]; uint8_t pos_regs[8]; } esdi_t; @@ -271,7 +274,7 @@ static void esdi_callback(void *priv) { esdi_t *dev = (esdi_t *)priv; - esdi_drive_t *drive; + drive_t *drive; int val; dev->callback = 0; @@ -321,7 +324,7 @@ esdi_callback(void *priv) if (! dev->data_pos) { if (dev->rba >= drive->sectors) fatal("Read past end of drive\n"); - hdd_image_read(drive->hdc_num, dev->rba, 1, (uint8_t *)dev->data); + hdd_image_read(drive->hdd_num, dev->rba, 1, (uint8_t *)dev->data); update_status_bar_icon(SB_HDD | HDD_BUS_ESDI, 1); } @@ -400,7 +403,7 @@ esdi_callback(void *priv) if (dev->rba >= drive->sectors) fatal("Write past end of drive\n"); - hdd_image_write(drive->hdc_num, dev->rba, 1, (uint8_t *)dev->data); + hdd_image_write(drive->hdd_num, dev->rba, 1, (uint8_t *)dev->data); dev->rba++; dev->sector_pos++; update_status_bar_icon(SB_HDD | HDD_BUS_ESDI, 1); @@ -969,7 +972,7 @@ esdi_mca_write(int port, uint8_t val, void *priv) static void * esdi_init(void) { - esdi_drive_t *drive; + drive_t *drive; esdi_t *dev; int c, i; @@ -984,17 +987,16 @@ esdi_init(void) dev->irq = ESDI_IRQCHAN; rom_init_interleaved(&dev->bios_rom, - L"roms/hdd/esdi/90x8970.bin", - L"roms/hdd/esdi/90x8969.bin", - 0x00000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + BIOS_FILE_L, BIOS_FILE_H, + 0x00000, 16384, 0x3fff, 0, MEM_MAPPING_EXTERNAL); mem_mapping_disable(&dev->bios_rom.mapping); dev->drives[0].present = dev->drives[1].present = 0; - for (c=0,i=0; idrives[hdc[i].esdi_channel]; + drive = &dev->drives[hdd[i].esdi_channel]; /* Try to load an image for the drive. */ if (! hdd_image_load(i)) { @@ -1004,11 +1006,11 @@ esdi_init(void) } /* OK, so fill in geometry info. */ - drive->spt = hdc[i].spt; - drive->hpc = hdc[i].hpc; - drive->tracks = hdc[i].tracks; - drive->sectors = hdc[i].spt*hdc[i].hpc*hdc[i].tracks; - drive->hdc_num = i; + drive->spt = hdd[i].spt; + drive->hpc = hdd[i].hpc; + drive->tracks = hdd[i].tracks; + drive->sectors = hdd[i].spt*hdd[i].hpc*hdd[i].tracks; + drive->hdd_num = i; /* Mark drive as present. */ drive->present = 1; @@ -1040,7 +1042,7 @@ static void esdi_close(void *priv) { esdi_t *dev = (esdi_t *)priv; - esdi_drive_t *drive; + drive_t *drive; int d; dev->drives[0].present = dev->drives[1].present = 0; @@ -1048,7 +1050,7 @@ esdi_close(void *priv) for (d=0; d<2; d++) { drive = &dev->drives[d]; - hdd_image_close(drive->hdc_num); + hdd_image_close(drive->hdd_num); } free(dev); @@ -1058,20 +1060,13 @@ esdi_close(void *priv) static int esdi_available(void) { - return(rom_present(L"roms/hdd/esdi/90x8969.bin") && - rom_present(L"roms/hdd/esdi/90x8970.bin")); + return(rom_present(BIOS_FILE_L) && rom_present(BIOS_FILE_H)); } -device_t hdd_esdi_device = -{ +device_t esdi_ps2_device = { "IBM ESDI Fixed Disk Adapter (MCA)", DEVICE_MCA, - esdi_init, - esdi_close, - esdi_available, - NULL, - NULL, - NULL, - NULL + esdi_init, esdi_close, esdi_available, + NULL, NULL, NULL, NULL }; diff --git a/src/hdd/hdd_ide_at.c b/src/hdd/hdc_ide.c similarity index 88% rename from src/hdd/hdd_ide_at.c rename to src/hdd/hdc_ide.c index 39a090940..7839743ee 100644 --- a/src/hdd/hdd_ide_at.c +++ b/src/hdd/hdc_ide.c @@ -9,7 +9,7 @@ * Implementation of the IDE emulation for hard disks and ATAPI * CD-ROM devices. * - * Version: @(#)hdd_ide_at.c 1.0.7 2017/09/24 + * Version: @(#)hdc_ide.c 1.0.8 2017/09/29 * * Authors: Sarah Walker, * Miran Grca, @@ -28,10 +28,12 @@ #include "../pic.h" #include "../pci.h" #include "../timer.h" +#include "../device.h" #include "../cdrom/cdrom.h" #include "../scsi/scsi.h" -#include "hdd_image.h" -#include "hdd_ide_at.h" +#include "hdd.h" +#include "hdc.h" +#include "hdc_ide.h" /* Bits of 'atastat' */ @@ -84,23 +86,7 @@ enum IDE_CDROM }; -uint64_t hdt[128][3] = { { 306, 4, 17 }, { 615, 2, 17 }, { 306, 4, 26 }, { 1024, 2, 17 }, { 697, 3, 17 }, { 306, 8, 17 }, { 614, 4, 17 }, { 615, 4, 17 }, /* 000-007 */ - { 670, 4, 17 }, { 697, 4, 17 }, { 987, 3, 17 }, { 820, 4, 17 }, { 670, 5, 17 }, { 697, 5, 17 }, { 733, 5, 17 }, { 615, 6, 17 }, /* 008-015 */ - { 462, 8, 17 }, { 306, 8, 26 }, { 615, 4, 26 }, { 1024, 4, 17 }, { 855, 5, 17 }, { 925, 5, 17 }, { 932, 5, 17 }, { 1024, 2, 40 }, /* 016-023 */ - { 809, 6, 17 }, { 976, 5, 17 }, { 977, 5, 17 }, { 698, 7, 17 }, { 699, 7, 17 }, { 981, 5, 17 }, { 615, 8, 17 }, { 989, 5, 17 }, /* 024-031 */ - { 820, 4, 26 }, { 1024, 5, 17 }, { 733, 7, 17 }, { 754, 7, 17 }, { 733, 5, 26 }, { 940, 6, 17 }, { 615, 6, 26 }, { 462, 8, 26 }, /* 032-039 */ - { 830, 7, 17 }, { 855, 7, 17 }, { 751, 8, 17 }, { 1024, 4, 26 }, { 918, 7, 17 }, { 925, 7, 17 }, { 855, 5, 26 }, { 977, 7, 17 }, /* 040-047 */ - { 987, 7, 17 }, { 1024, 7, 17 }, { 823, 4, 38 }, { 925, 8, 17 }, { 809, 6, 26 }, { 976, 5, 26 }, { 977, 5, 26 }, { 698, 7, 26 }, /* 048-055 */ - { 699, 7, 26 }, { 940, 8, 17 }, { 615, 8, 26 }, { 1024, 5, 26 }, { 733, 7, 26 }, { 1024, 8, 17 }, { 823, 10, 17 }, { 754, 11, 17 }, /* 056-063 */ - { 830, 10, 17 }, { 925, 9, 17 }, { 1224, 7, 17 }, { 940, 6, 26 }, { 855, 7, 26 }, { 751, 8, 26 }, { 1024, 9, 17 }, { 965, 10, 17 }, /* 064-071 */ - { 969, 5, 34 }, { 980, 10, 17 }, { 960, 5, 35 }, { 918, 11, 17 }, { 1024, 10, 17 }, { 977, 7, 26 }, { 1024, 7, 26 }, { 1024, 11, 17 }, /* 072-079 */ - { 940, 8, 26 }, { 776, 8, 33 }, { 755, 16, 17 }, { 1024, 12, 17 }, { 1024, 8, 26 }, { 823, 10, 26 }, { 830, 10, 26 }, { 925, 9, 26 }, /* 080-087 */ - { 960, 9, 26 }, { 1024, 13, 17 }, { 1224, 11, 17 }, { 900, 15, 17 }, { 969, 7, 34 }, { 917, 15, 17 }, { 918, 15, 17 }, { 1524, 4, 39 }, /* 088-095 */ - { 1024, 9, 26 }, { 1024, 14, 17 }, { 965, 10, 26 }, { 980, 10, 26 }, { 1020, 15, 17 }, { 1023, 15, 17 }, { 1024, 15, 17 }, { 1024, 16, 17 }, /* 096-103 */ - { 1224, 15, 17 }, { 755, 16, 26 }, { 903, 8, 46 }, { 984, 10, 34 }, { 900, 15, 26 }, { 917, 15, 26 }, { 1023, 15, 26 }, { 684, 16, 38 }, /* 104-111 */ - { 1930, 4, 62 }, { 967, 16, 31 }, { 1013, 10, 63 }, { 1218, 15, 36 }, { 654, 16, 63 }, { 659, 16, 63 }, { 702, 16, 63 }, { 1002, 13, 63 }, /* 112-119 */ - { 854, 16, 63 }, { 987, 16, 63 }, { 995, 16, 63 }, { 1024, 16, 63 }, { 1036, 16, 63 }, { 1120, 16, 59 }, { 1054, 16, 63 }, { 0, 0, 0 } }; /* 119-127 */ - + IDE ide_drives[IDE_NUM + XTIDE_NUM]; IDE *ext_ide; @@ -341,29 +327,29 @@ static void ide_identify(IDE *ide) uint32_t c, h, s; char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; #if 0 - uint64_t full_size = (hdc[ide->hdc_num].tracks * hdc[ide->hdc_num].hpc * hdc[ide->hdc_num].spt); + uint64_t full_size = (hdd[ide->hdd_num].tracks * hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); #endif - device_identify[6] = (ide->hdc_num / 10) + 0x30; - device_identify[7] = (ide->hdc_num % 10) + 0x30; + device_identify[6] = (ide->hdd_num / 10) + 0x30; + device_identify[7] = (ide->hdd_num % 10) + 0x30; ide_log("IDE Identify: %s\n", device_identify); memset(ide->buffer, 0, 512); - c = hdc[ide->hdc_num].tracks; /* Cylinders */ - h = hdc[ide->hdc_num].hpc; /* Heads */ - s = hdc[ide->hdc_num].spt; /* Sectors */ + c = hdd[ide->hdd_num].tracks; /* Cylinders */ + h = hdd[ide->hdd_num].hpc; /* Heads */ + s = hdd[ide->hdd_num].spt; /* Sectors */ - if (hdc[ide->hdc_num].tracks <= 16383) + if (hdd[ide->hdd_num].tracks <= 16383) { - ide->buffer[1] = hdc[ide->hdc_num].tracks; /* Cylinders */ + ide->buffer[1] = hdd[ide->hdd_num].tracks; /* Cylinders */ } else { ide->buffer[1] = 16383; /* Cylinders */ } - ide->buffer[3] = hdc[ide->hdc_num].hpc; /* Heads */ - ide->buffer[6] = hdc[ide->hdc_num].spt; /* Sectors */ + ide->buffer[3] = hdd[ide->hdd_num].hpc; /* Heads */ + ide->buffer[6] = hdd[ide->hdd_num].spt; /* Sectors */ ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ ide_padstr((char *) (ide->buffer + 23), EMU_VERSION, 8); /* Firmware */ ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ @@ -371,7 +357,7 @@ static void ide_identify(IDE *ide) ide->buffer[21] = 512; /*Buffer size*/ ide->buffer[47] = 16; /*Max sectors on multiple transfer command*/ ide->buffer[48] = 1; /*Dword transfers supported*/ - if (PCI && (ide->board < 2) && (hdc[ide->hdc_num].bus == HDD_BUS_IDE_PIO_AND_DMA)) + if (PCI && (ide->board < 2) && (hdd[ide->hdd_num].bus == HDD_BUS_IDE_PIO_AND_DMA)) { ide->buffer[49] = (1 << 8); /* LBA and DMA supported */ } @@ -404,10 +390,10 @@ static void ide_identify(IDE *ide) ide->buffer[59] = ide->blocksize ? (ide->blocksize | 0x100) : 0; if (ide->buffer[49] & (1 << 9)) { - ide->buffer[60] = (hdc[ide->hdc_num].tracks * hdc[ide->hdc_num].hpc * hdc[ide->hdc_num].spt) & 0xFFFF; /* Total addressable sectors (LBA) */ - ide->buffer[61] = ((hdc[ide->hdc_num].tracks * hdc[ide->hdc_num].hpc * hdc[ide->hdc_num].spt) >> 16) & 0x0FFF; + ide->buffer[60] = (hdd[ide->hdd_num].tracks * hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt) & 0xFFFF; /* Total addressable sectors (LBA) */ + ide->buffer[61] = ((hdd[ide->hdd_num].tracks * hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt) >> 16) & 0x0FFF; } - if (PCI && (ide->board < 2) && (hdc[ide->hdc_num].bus == HDD_BUS_IDE_PIO_AND_DMA)) + if (PCI && (ide->board < 2) && (hdd[ide->hdd_num].bus == HDD_BUS_IDE_PIO_AND_DMA)) { ide->buffer[52] = 2 << 8; /*DMA timing mode*/ @@ -497,21 +483,16 @@ static void ide_next_sector(IDE *ide) static void loadhd(IDE *ide, int d, const wchar_t *fn) { - int ret = 0; - - ret = hdd_image_load(d); - - if (!ret) - { + if (! hdd_image_load(d)) { ide->type = IDE_NONE; return; } - ide->spt = hdc[d].spt; - ide->hpc = hdc[d].hpc; - ide->tracks = hdc[d].tracks; + ide->spt = hdd[d].spt; + ide->hpc = hdd[d].hpc; + ide->tracks = hdd[d].tracks; ide->type = IDE_HDD; - ide->hdc_num = d; + ide->hdd_num = d; ide->hdi = hdd_image_get_type(d); } @@ -588,7 +569,7 @@ static int ide_set_features(IDE *ide) break; case 0x04: /* Multiword DMA mode */ - if (!PCI || (hdc[ide->hdc_num].bus != HDD_BUS_IDE_PIO_AND_DMA) || (ide->board >= 2) || (submode > 2)) + if (!PCI || (hdd[ide->hdd_num].bus != HDD_BUS_IDE_PIO_AND_DMA) || (ide->board >= 2) || (submode > 2)) { return 0; } @@ -617,11 +598,11 @@ void ide_set_sector(IDE *ide, int64_t sector_num) } else { - cyl = sector_num / (hdc[ide->hdc_num].hpc * hdc[ide->hdc_num].spt); - r = sector_num % (hdc[ide->hdc_num].hpc * hdc[ide->hdc_num].spt); + cyl = sector_num / (hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); + r = sector_num % (hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); ide->cylinder = cyl; - ide->head = ((r / hdc[ide->hdc_num].spt) & 0x0f); - ide->sector = (r % hdc[ide->hdc_num].spt) + 1; + ide->head = ((r / hdd[ide->hdd_num].spt) & 0x0f); + ide->sector = (r % hdd[ide->hdd_num].spt) + 1; } } @@ -635,11 +616,11 @@ void resetide(void) build_atapi_cdrom_map(); /* Close hard disk image files (if previously open) */ - for (d = 0; d < (IDE_NUM + XTIDE_NUM); d++) + for (d = 0; d < (IDE_NUM+XTIDE_NUM); d++) { ide_drives[d].channel = d; ide_drives[d].type = IDE_NONE; - hdd_image_close(ide_drives[d].hdc_num); + hdd_image_close(ide_drives[d].hdd_num); if (ide_drive_is_cdrom(&ide_drives[d])) { cdrom[atapi_cdrom_drives[d]].status = READY_STAT | DSC_STAT; @@ -654,21 +635,19 @@ void resetide(void) idecallback[4]=0; c = 0; - for (d = 0; d < HDC_NUM; d++) + for (d = 0; d < HDD_NUM; d++) { - if (((hdc[d].bus == HDD_BUS_IDE_PIO_ONLY) || (hdc[d].bus == HDD_BUS_IDE_PIO_AND_DMA)) && (hdc[d].ide_channel < IDE_NUM)) + if (((hdd[d].bus == HDD_BUS_IDE_PIO_ONLY) || (hdd[d].bus == HDD_BUS_IDE_PIO_AND_DMA)) && (hdd[d].ide_channel < IDE_NUM)) { - ide_log("Found IDE hard disk on channel %i\n", hdc[d].ide_channel); - loadhd(&ide_drives[hdc[d].ide_channel], d, hdc[d].fn); - c++; - if (c >= (IDE_NUM + XTIDE_NUM)) break; + ide_log("Found IDE hard disk on channel %i\n", hdd[d].ide_channel); + loadhd(&ide_drives[hdd[d].ide_channel], d, hdd[d].fn); + if (++c >= (IDE_NUM+XTIDE_NUM)) break; } - if ((hdc[d].bus == HDD_BUS_XTIDE) && (hdc[d].xtide_channel < XTIDE_NUM)) + if ((hdd[d].bus==HDD_BUS_XTIDE) && (hdd[d].xtide_channel < XTIDE_NUM)) { - ide_log("Found XT IDE hard disk on channel %i\n", hdc[d].xtide_channel); - loadhd(&ide_drives[hdc[d].xtide_channel | 8], d, hdc[d].fn); - c++; - if (c >= (IDE_NUM + XTIDE_NUM)) break; + ide_log("Found XT IDE hard disk on channel %i\n", hdd[d].xtide_channel); + loadhd(&ide_drives[hdd[d].xtide_channel | 8], d, hdd[d].fn); + if (++c >= (IDE_NUM+XTIDE_NUM)) break; } } @@ -1317,7 +1296,7 @@ uint32_t ide_read_data(int ide_board, int length) } else { - update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 0); + update_status_bar_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); } } } @@ -1511,7 +1490,7 @@ void callbackide(int ide_board) ide_other = &ide_drives[cur_ide[ide_board] ^ 1]; if (ide->type == IDE_HDD) { - full_size = (hdc[ide->hdc_num].tracks * hdc[ide->hdc_num].hpc * hdc[ide->hdc_num].spt); + full_size = (hdd[ide->hdd_num].tracks * hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); } ext_ide = ide; @@ -1648,11 +1627,11 @@ void callbackide(int ide_board) ide->sector_pos = 0; if (ide->secount) { - hdd_image_read(ide->hdc_num, ide_get_sector(ide), ide->secount, ide->sector_buffer); + hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->secount, ide->sector_buffer); } else { - hdd_image_read(ide->hdc_num, ide_get_sector(ide), 256, ide->sector_buffer); + hdd_image_read(ide->hdd_num, ide_get_sector(ide), 256, ide->sector_buffer); } } @@ -1665,7 +1644,7 @@ void callbackide(int ide_board) ide_irq_raise(ide); - update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 1); + update_status_bar_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); return; case WIN_READ_DMA: @@ -1684,11 +1663,11 @@ void callbackide(int ide_board) ide->sector_pos = 0; if (ide->secount) { - hdd_image_read(ide->hdc_num, ide_get_sector(ide), ide->secount, ide->sector_buffer); + hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->secount, ide->sector_buffer); } else { - hdd_image_read(ide->hdc_num, ide_get_sector(ide), 256, ide->sector_buffer); + hdd_image_read(ide->hdd_num, ide_get_sector(ide), 256, ide->sector_buffer); } } @@ -1712,12 +1691,12 @@ void callbackide(int ide_board) ide_next_sector(ide); ide->atastat = BUSY_STAT; idecallback[ide_board]=6*IDE_TIME; - update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 1); + update_status_bar_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); } else { ide_irq_raise(ide); - update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 0); + update_status_bar_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); } } } @@ -1746,11 +1725,11 @@ void callbackide(int ide_board) ide->sector_pos = 0; if (ide->secount) { - hdd_image_read(ide->hdc_num, ide_get_sector(ide), ide->secount, ide->sector_buffer); + hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->secount, ide->sector_buffer); } else { - hdd_image_read(ide->hdc_num, ide_get_sector(ide), 256, ide->sector_buffer); + hdd_image_read(ide->hdd_num, ide_get_sector(ide), 256, ide->sector_buffer); } } @@ -1770,7 +1749,7 @@ void callbackide(int ide_board) ide->blockcount = 0; } - update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 1); + update_status_bar_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); return; case WIN_WRITE: @@ -1783,7 +1762,7 @@ void callbackide(int ide_board) { goto id_not_found; } - hdd_image_write(ide->hdc_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); + hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); ide_irq_raise(ide); ide->secount = (ide->secount - 1) & 0xff; if (ide->secount) @@ -1791,12 +1770,12 @@ void callbackide(int ide_board) ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; ide->pos=0; ide_next_sector(ide); - update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 1); + update_status_bar_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); } else { ide->atastat = READY_STAT | DSC_STAT; - update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 0); + update_status_bar_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); } return; @@ -1820,7 +1799,7 @@ void callbackide(int ide_board) else { /*DMA successful*/ - hdd_image_write(ide->hdc_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); + hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; @@ -1830,12 +1809,12 @@ void callbackide(int ide_board) ide_next_sector(ide); ide->atastat = BUSY_STAT; idecallback[ide_board]=6*IDE_TIME; - update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 1); + update_status_bar_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); } else { ide_irq_raise(ide); - update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 0); + update_status_bar_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); } } } @@ -1851,7 +1830,7 @@ void callbackide(int ide_board) { goto id_not_found; } - hdd_image_write(ide->hdc_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); + hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); ide->blockcount++; if (ide->blockcount >= ide->blocksize || ide->secount == 1) { @@ -1864,12 +1843,12 @@ void callbackide(int ide_board) ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; ide->pos=0; ide_next_sector(ide); - update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 1); + update_status_bar_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); } else { ide->atastat = READY_STAT | DSC_STAT; - update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 0); + update_status_bar_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); } return; @@ -1886,7 +1865,7 @@ void callbackide(int ide_board) ide->pos=0; ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); - update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 1); + update_status_bar_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); return; case WIN_FORMAT: @@ -1898,12 +1877,12 @@ void callbackide(int ide_board) { goto id_not_found; } - hdd_image_zero(ide->hdc_num, ide_get_sector(ide), ide->secount); + hdd_image_zero(ide->hdd_num, ide_get_sector(ide), ide->secount); ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); - /* update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 1); */ + /* update_status_bar_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); */ return; case WIN_DRIVE_DIAGNOSTICS: @@ -1950,7 +1929,7 @@ void callbackide(int ide_board) full_size /= (ide->head+1); full_size /= ide->secount; ide->specify_success = 1; - hdd_image_specify(ide->hdc_num, ide->head + 1, ide->secount); + hdd_image_specify(ide->hdd_num, ide->head + 1, ide->secount); ide->spt=ide->secount; ide->hpc=ide->head+1; ide->atastat = READY_STAT | DSC_STAT; @@ -2002,9 +1981,9 @@ void callbackide(int ide_board) { goto abort_cmd; } - snum = hdc[ide->hdc_num].spt; - snum *= hdc[ide->hdc_num].hpc; - snum *= hdc[ide->hdc_num].tracks; + snum = hdd[ide->hdd_num].spt; + snum *= hdd[ide->hdd_num].hpc; + snum *= hdd[ide->hdd_num].tracks; ide_set_sector(ide, snum - 1); ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); @@ -2204,7 +2183,8 @@ uint32_t ide_read_qua_l(uint16_t addr, void *priv) static uint16_t ide_base_main[2] = { 0x1f0, 0x170 }; static uint16_t ide_side_main[2] = { 0x3f6, 0x376 }; -void ide_pri_enable() + +void ide_pri_enable(void) { io_sethandler(0x01f0, 0x0008, ide_read_pri, ide_read_pri_w, ide_read_pri_l, ide_write_pri, ide_write_pri_w, ide_write_pri_l, NULL); io_sethandler(0x03f6, 0x0001, ide_read_pri, NULL, NULL, ide_write_pri, NULL, NULL , NULL); @@ -2212,7 +2192,7 @@ void ide_pri_enable() ide_side_main[0] = 0x3f6; } -void ide_pri_enable_ex() +void ide_pri_enable_ex(void) { if (ide_base_main[0] & 0x300) { @@ -2226,13 +2206,13 @@ void ide_pri_enable_ex() } } -void ide_pri_disable() +void ide_pri_disable(void) { io_removehandler(ide_base_main[0], 0x0008, ide_read_pri, ide_read_pri_w, ide_read_pri_l, ide_write_pri, ide_write_pri_w, ide_write_pri_l, NULL); io_removehandler(ide_side_main[0], 0x0001, ide_read_pri, NULL, NULL, ide_write_pri, NULL, NULL , NULL); } -void ide_sec_enable() +void ide_sec_enable(void) { io_sethandler(0x0170, 0x0008, ide_read_sec, ide_read_sec_w, ide_read_sec_l, ide_write_sec, ide_write_sec_w, ide_write_sec_l, NULL); io_sethandler(0x0376, 0x0001, ide_read_sec, NULL, NULL, ide_write_sec, NULL, NULL , NULL); @@ -2240,7 +2220,7 @@ void ide_sec_enable() ide_side_main[1] = 0x376; } -void ide_sec_enable_ex() +void ide_sec_enable_ex(void) { if (ide_base_main[1] & 0x300) { @@ -2252,12 +2232,13 @@ void ide_sec_enable_ex() } } -void ide_sec_disable() +void ide_sec_disable(void) { io_removehandler(ide_base_main[1], 0x0008, ide_read_sec, ide_read_sec_w, ide_read_sec_l, ide_write_sec, ide_write_sec_w, ide_write_sec_l, NULL); io_removehandler(ide_side_main[1], 0x0001, ide_read_sec, NULL, NULL, ide_write_sec, NULL, NULL , NULL); } + void ide_set_base(int controller, uint16_t port) { ide_base_main[controller] = port; @@ -2268,19 +2249,19 @@ void ide_set_side(int controller, uint16_t port) ide_side_main[controller] = port; } -void ide_ter_enable() +void ide_ter_enable(void) { io_sethandler(0x0168, 0x0008, ide_read_ter, ide_read_ter_w, ide_read_ter_l, ide_write_ter, ide_write_ter_w, ide_write_ter_l, NULL); io_sethandler(0x036e, 0x0001, ide_read_ter, NULL, NULL, ide_write_ter, NULL, NULL , NULL); } -void ide_ter_disable() +void ide_ter_disable(void) { io_removehandler(0x0168, 0x0008, ide_read_ter, ide_read_ter_w, ide_read_ter_l, ide_write_ter, ide_write_ter_w, ide_write_ter_l, NULL); io_removehandler(0x036e, 0x0001, ide_read_ter, NULL, NULL, ide_write_ter, NULL, NULL , NULL); } -void ide_ter_disable_cond() +void ide_ter_disable_cond(void) { if ((ide_drives[4].type == IDE_NONE) && (ide_drives[5].type == IDE_NONE)) { @@ -2288,20 +2269,20 @@ void ide_ter_disable_cond() } } -void ide_ter_init() +void ide_ter_init(void) { ide_ter_enable(); timer_add(ide_callback_ter, &idecallback[2], &idecallback[2], NULL); } -void ide_qua_enable() +void ide_qua_enable(void) { io_sethandler(0x01e8, 0x0008, ide_read_qua, ide_read_qua_w, ide_read_qua_l, ide_write_qua, ide_write_qua_w, ide_write_qua_l, NULL); io_sethandler(0x03ee, 0x0001, ide_read_qua, NULL, NULL, ide_write_qua, NULL, NULL , NULL); } -void ide_qua_disable_cond() +void ide_qua_disable_cond(void) { if ((ide_drives[6].type == IDE_NONE) && (ide_drives[7].type == IDE_NONE)) { @@ -2309,20 +2290,21 @@ void ide_qua_disable_cond() } } -void ide_qua_disable() +void ide_qua_disable(void) { io_removehandler(0x01e8, 0x0008, ide_read_qua, ide_read_qua_w, ide_read_qua_l, ide_write_qua, ide_write_qua_w, ide_write_qua_l, NULL); io_removehandler(0x03ee, 0x0001, ide_read_qua, NULL, NULL, ide_write_qua, NULL, NULL , NULL); } -void ide_qua_init() +void ide_qua_init(void) { ide_qua_enable(); timer_add(ide_callback_qua, &idecallback[3], &idecallback[3], NULL); } -void ide_init() + +void ide_init(void) { ide_pri_enable(); ide_sec_enable(); @@ -2332,7 +2314,8 @@ void ide_init() timer_add(ide_callback_sec, &idecallback[1], &idecallback[1], NULL); } -void ide_xtide_init() + +void ide_xtide_init(void) { ide_bus_master_read = ide_bus_master_write = NULL; diff --git a/src/hdd/hdd_ide_at.h b/src/hdd/hdc_ide.h similarity index 96% rename from src/hdd/hdd_ide_at.h rename to src/hdd/hdc_ide.h index 8aa64b944..1260fe54e 100644 --- a/src/hdd/hdd_ide_at.h +++ b/src/hdd/hdc_ide.h @@ -9,7 +9,7 @@ * Implementation of the IDE emulation for hard disks and ATAPI * CD-ROM devices. * - * Version: @(#)hdd_ide_at.h 1.0.2 2017/08/24 + * Version: @(#)hdd_ide.h 1.0.3 2017/09/29 * * Authors: Sarah Walker, * Miran Grca, @@ -21,7 +21,6 @@ # define EMU_IDE_H -#pragma pack(push,1) typedef struct { int type; int board; @@ -47,14 +46,13 @@ typedef struct { int blocksize, blockcount; uint16_t dma_identify_data[3]; int hdi,base; - int hdc_num; + int hdd_num; uint8_t specify_success; int mdma_mode; uint8_t sector_buffer[256*512]; int do_initial_read; int sector_pos; } IDE; -#pragma pack(pop) extern int ideboard; diff --git a/src/hdd/hdd_mfm_at.c b/src/hdd/hdc_mfm_at.c similarity index 92% rename from src/hdd/hdd_mfm_at.c rename to src/hdd/hdc_mfm_at.c index feca7ef2d..1883dbc4f 100644 --- a/src/hdd/hdd_mfm_at.c +++ b/src/hdd/hdc_mfm_at.c @@ -12,7 +12,7 @@ * based design. Most cards were WD1003-WA2 or -WAH, where the * -WA2 cards had a floppy controller as well (to save space.) * - * Version: @(#)hdd_mfm_at.c 1.0.3 2017/09/24 + * Version: @(#)hdd_mfm_at.c 1.0.4 2017/09/29 * * Authors: Sarah Walker, * Miran Grca, @@ -31,8 +31,8 @@ #include "../io.h" #include "../pic.h" #include "../timer.h" -#include "hdd_image.h" -#include "hdd_mfm_at.h" +#include "hdc.h" +#include "hdd.h" #define MFM_TIME (TIMER_USEC*10) @@ -66,7 +66,7 @@ typedef struct { int8_t present, /* drive is present */ - hdc_num, /* drive number in system */ + hdd_num, /* drive number in system */ steprate, /* current servo step rate */ spt, /* physical #sectors per track */ hpc, /* physical #heads per cylinder */ @@ -77,7 +77,7 @@ typedef struct { cfg_hpc; /* configured #heads per track */ int16_t curcyl; /* current track number */ -} mfm_drive_t; +} drive_t; typedef struct { @@ -101,7 +101,7 @@ typedef struct { uint16_t buffer[256]; /* data buffer (16b wide) */ - mfm_drive_t drives[MFM_NUM]; /* attached drives */ + drive_t drives[MFM_NUM]; /* attached drives */ } mfm_t; @@ -152,7 +152,7 @@ static __inline void irq_lower(mfm_t *mfm) static int get_sector(mfm_t *mfm, off64_t *addr) { - mfm_drive_t *drive = &mfm->drives[mfm->drvsel]; + drive_t *drive = &mfm->drives[mfm->drvsel]; if (drive->curcyl != mfm->cylinder) { pclog("WD1003(%d) sector: wrong cylinder\n"); @@ -195,7 +195,7 @@ get_sector(mfm_t *mfm, off64_t *addr) static void next_sector(mfm_t *mfm) { - mfm_drive_t *drive = &mfm->drives[mfm->drvsel]; + drive_t *drive = &mfm->drives[mfm->drvsel]; if (++mfm->sector == (drive->cfg_spt+1)) { mfm->sector = 1; @@ -212,7 +212,7 @@ next_sector(mfm_t *mfm) static void mfm_cmd(mfm_t *mfm, uint8_t val) { - mfm_drive_t *drive = &mfm->drives[mfm->drvsel]; + drive_t *drive = &mfm->drives[mfm->drvsel]; if (! drive->present) { /* This happens if sofware polls all drives. */ @@ -526,7 +526,7 @@ mfm_read(uint16_t port, void *priv) static void do_seek(mfm_t *mfm) { - mfm_drive_t *drive = &mfm->drives[mfm->drvsel]; + drive_t *drive = &mfm->drives[mfm->drvsel]; #if MFM_DEBUG pclog("WD1003(%d) seek(%d) max=%d\n", @@ -543,7 +543,7 @@ static void do_callback(void *priv) { mfm_t *mfm = (mfm_t *)priv; - mfm_drive_t *drive = &mfm->drives[mfm->drvsel]; + drive_t *drive = &mfm->drives[mfm->drvsel]; off64_t addr; mfm->callback = 0; @@ -592,7 +592,7 @@ do_callback(void *priv) break; } - hdd_image_read(drive->hdc_num, addr, 1, (uint8_t *)mfm->buffer); + hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *)mfm->buffer); mfm->pos = 0; mfm->status = STAT_DRQ|STAT_READY|STAT_DSC; @@ -613,7 +613,7 @@ do_callback(void *priv) break; } - hdd_image_write(drive->hdc_num, addr, 1,(uint8_t *)mfm->buffer); + hdd_image_write(drive->hdd_num, addr, 1,(uint8_t *)mfm->buffer); mfm->status = STAT_READY|STAT_DSC; mfm->secount = (mfm->secount - 1) & 0xff; @@ -654,7 +654,7 @@ do_callback(void *priv) break; } - hdd_image_zero(drive->hdc_num, addr, mfm->secount); + hdd_image_zero(drive->hdd_num, addr, mfm->secount); mfm->status = STAT_READY|STAT_DSC; irq_raise(mfm); @@ -685,7 +685,7 @@ do_callback(void *priv) static void loadhd(mfm_t *mfm, int c, int d, const wchar_t *fn) { - mfm_drive_t *drive = &mfm->drives[c]; + drive_t *drive = &mfm->drives[c]; if (! hdd_image_load(d)) { drive->present = 0; @@ -693,10 +693,10 @@ loadhd(mfm_t *mfm, int c, int d, const wchar_t *fn) return; } - drive->spt = hdc[d].spt; - drive->hpc = hdc[d].hpc; - drive->tracks = hdc[d].tracks; - drive->hdc_num = d; + drive->spt = hdd[d].spt; + drive->hpc = hdd[d].hpc; + drive->tracks = hdd[d].tracks; + drive->hdd_num = d; drive->present = 1; } @@ -712,12 +712,12 @@ mfm_init(void) memset(mfm, 0x00, sizeof(mfm_t)); c = 0; - for (d=0; d= MFM_NUM) break; } @@ -748,9 +748,9 @@ mfm_close(void *priv) int d; for (d=0; d<2; d++) { - mfm_drive_t *drive = &mfm->drives[d]; + drive_t *drive = &mfm->drives[d]; - hdd_image_close(drive->hdc_num); + hdd_image_close(drive->hdd_num); } free(mfm); @@ -759,15 +759,9 @@ mfm_close(void *priv) } -device_t mfm_at_device = -{ +device_t mfm_at_wd1003_device = { "WD1003 AT MFM/RLL Controller", DEVICE_AT, - mfm_init, - mfm_close, - NULL, - NULL, - NULL, - NULL, - NULL + mfm_init, mfm_close, NULL, + NULL, NULL, NULL, NULL }; diff --git a/src/hdd/hdc_mfm_xt.c b/src/hdd/hdc_mfm_xt.c new file mode 100644 index 000000000..6259aaa60 --- /dev/null +++ b/src/hdd/hdc_mfm_xt.c @@ -0,0 +1,888 @@ +/* + * 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. + * + * Driver for the IBM PC-XT MFM/RLL Fixed Disk controller. + * + * The original controller shipped by IBM was made by Xebec, and + * several variations had been made. + * + * + * Since all controllers (including the ones made by DTC) we do + * keep them all in this module. + * + * Version: @(#)hdd_mfm_xt.c 1.0.5 2017/09/29 + * + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016,2017 Miran Grca. + * Copyright 2017 Fred N. van Kempen. + */ +#include +#include +#include +#include +#include +#include "../ibm.h" +#include "../device.h" +#include "../dma.h" +#include "../io.h" +#include "../mem.h" +#include "../pic.h" +#include "../rom.h" +#include "../timer.h" +#include "hdc.h" +#include "hdd.h" + + +#define MFM_TIME (2000*TIMER_USEC) +#define XEBEC_BIOS_FILE L"roms/hdd/mfm_xebec/ibm_xebec_62x0822_1985.bin" +#define DTC_BIOS_FILE L"roms/hdd/mfm_xebec/dtc_cxd21a.bin" + + +enum { + STATE_IDLE, + STATE_RECEIVE_COMMAND, + STATE_START_COMMAND, + STATE_RECEIVE_DATA, + STATE_RECEIVED_DATA, + STATE_SEND_DATA, + STATE_SENT_DATA, + STATE_COMPLETION_BYTE, + STATE_DUNNO +}; + + +typedef struct { + int spt, hpc; + int tracks; + int cfg_spt; + int cfg_hpc; + int cfg_cyl; + int current_cylinder; + int present; + int hdd_num; +} drive_t; + +typedef struct { + rom_t bios_rom; + int callback; + int state; + uint8_t status; + uint8_t command[6]; + int command_pos; + uint8_t data[512]; + int data_pos, data_len; + uint8_t sector_buf[512]; + uint8_t irq_dma_mask; + uint8_t completion_byte; + uint8_t error; + int drive_sel; + drive_t drives[2]; + int sector, head, cylinder; + int sector_count; + uint8_t switches; +} mfm_t; + +#define STAT_IRQ 0x20 +#define STAT_DRQ 0x10 +#define STAT_BSY 0x08 +#define STAT_CD 0x04 +#define STAT_IO 0x02 +#define STAT_REQ 0x01 + +#define IRQ_ENA 0x02 +#define DMA_ENA 0x01 + +#define CMD_TEST_DRIVE_READY 0x00 +#define CMD_RECALIBRATE 0x01 +#define CMD_READ_STATUS 0x03 +#define CMD_VERIFY_SECTORS 0x05 +#define CMD_FORMAT_TRACK 0x06 +#define CMD_READ_SECTORS 0x08 +#define CMD_WRITE_SECTORS 0x0a +#define CMD_SEEK 0x0b +#define CMD_INIT_DRIVE_PARAMS 0x0c +#define CMD_WRITE_SECTOR_BUFFER 0x0f +#define CMD_BUFFER_DIAGNOSTIC 0xe0 +#define CMD_CONTROLLER_DIAGNOSTIC 0xe4 +#define CMD_DTC_GET_DRIVE_PARAMS 0xfb +#define CMD_DTC_SET_STEP_RATE 0xfc +#define CMD_DTC_SET_GEOMETRY 0xfe +#define CMD_DTC_GET_GEOMETRY 0xff + +#define ERR_NOT_READY 0x04 +#define ERR_SEEK_ERROR 0x15 +#define ERR_ILLEGAL_SECTOR_ADDRESS 0x21 + + +static uint8_t +mfm_read(uint16_t port, void *priv) +{ + mfm_t *mfm = (mfm_t *)priv; + uint8_t temp = 0xff; + + switch (port) { + case 0x320: /*Read data*/ + mfm->status &= ~STAT_IRQ; + switch (mfm->state) { + case STATE_COMPLETION_BYTE: + if ((mfm->status & 0xf) != (STAT_CD | STAT_IO | STAT_REQ | STAT_BSY)) + fatal("Read data STATE_COMPLETION_BYTE, status=%02x\n", mfm->status); + + temp = mfm->completion_byte; + mfm->status = 0; + mfm->state = STATE_IDLE; + break; + + case STATE_SEND_DATA: + if ((mfm->status & 0xf) != (STAT_IO | STAT_REQ | STAT_BSY)) + fatal("Read data STATE_COMPLETION_BYTE, status=%02x\n", mfm->status); + if (mfm->data_pos >= mfm->data_len) + fatal("Data write with full data!\n"); + temp = mfm->data[mfm->data_pos++]; + if (mfm->data_pos == mfm->data_len) { + mfm->status = STAT_BSY; + mfm->state = STATE_SENT_DATA; + mfm->callback = MFM_TIME; + } + break; + + default: + fatal("Read data register - %i, %02x\n", mfm->state, mfm->status); + } + break; + + case 0x321: /*Read status*/ + temp = mfm->status; + break; + + case 0x322: /*Read option jumpers*/ + temp = mfm->switches; + break; + } + + return(temp); +} + + +static void +mfm_write(uint16_t port, uint8_t val, void *priv) +{ + mfm_t *mfm = (mfm_t *)priv; + + switch (port) { + case 0x320: /*Write data*/ + switch (mfm->state) { + case STATE_RECEIVE_COMMAND: + if ((mfm->status & 0xf) != (STAT_BSY | STAT_CD | STAT_REQ)) + fatal("Bad write data state - STATE_START_COMMAND, status=%02x\n", mfm->status); + if (mfm->command_pos >= 6) + fatal("Command write with full command!\n"); + /*Command data*/ + mfm->command[mfm->command_pos++] = val; + if (mfm->command_pos == 6) { + mfm->status = STAT_BSY; + mfm->state = STATE_START_COMMAND; + mfm->callback = MFM_TIME; + } + break; + + case STATE_RECEIVE_DATA: + if ((mfm->status & 0xf) != (STAT_BSY | STAT_REQ)) + fatal("Bad write data state - STATE_RECEIVE_DATA, status=%02x\n", mfm->status); + if (mfm->data_pos >= mfm->data_len) + fatal("Data write with full data!\n"); + /*Command data*/ + mfm->data[mfm->data_pos++] = val; + if (mfm->data_pos == mfm->data_len) { + mfm->status = STAT_BSY; + mfm->state = STATE_RECEIVED_DATA; + mfm->callback = MFM_TIME; + } + break; + + default: + fatal("Write data unknown state - %i %02x\n", mfm->state, mfm->status); + } + break; + + case 0x321: /*Controller reset*/ + mfm->status = 0; + break; + + case 0x322: /*Generate controller-select-pulse*/ + mfm->status = STAT_BSY | STAT_CD | STAT_REQ; + mfm->command_pos = 0; + mfm->state = STATE_RECEIVE_COMMAND; + break; + + case 0x323: /*DMA/IRQ mask register*/ + mfm->irq_dma_mask = val; + break; + } +} + + +static void mfm_complete(mfm_t *mfm) +{ + mfm->status = STAT_REQ | STAT_CD | STAT_IO | STAT_BSY; + mfm->state = STATE_COMPLETION_BYTE; + + if (mfm->irq_dma_mask & IRQ_ENA) { + mfm->status |= STAT_IRQ; + picint(1 << 5); + } +} + + +static void +mfm_error(mfm_t *mfm, uint8_t error) +{ + mfm->completion_byte |= 0x02; + mfm->error = error; + + pclog("mfm_error - %02x\n", mfm->error); +} + + +static int +get_sector(mfm_t *mfm, off64_t *addr) +{ + drive_t *drive = &mfm->drives[mfm->drive_sel]; + int heads = drive->cfg_hpc; + + if (drive->current_cylinder != mfm->cylinder) { + pclog("mfm_get_sector: wrong cylinder\n"); + mfm->error = ERR_ILLEGAL_SECTOR_ADDRESS; + return(1); + } + if (mfm->head > heads) { + pclog("mfm_get_sector: past end of configured heads\n"); + mfm->error = ERR_ILLEGAL_SECTOR_ADDRESS; + return(1); + } + if (mfm->head > drive->hpc) { + pclog("mfm_get_sector: past end of heads\n"); + mfm->error = ERR_ILLEGAL_SECTOR_ADDRESS; + return(1); + } + if (mfm->sector >= 17) { + pclog("mfm_get_sector: past end of sectors\n"); + mfm->error = ERR_ILLEGAL_SECTOR_ADDRESS; + return(1); + } + + *addr = ((((off64_t) mfm->cylinder * heads) + mfm->head) * + 17) + mfm->sector; + + return(0); +} + + +static void +next_sector(mfm_t *mfm) +{ + drive_t *drive = &mfm->drives[mfm->drive_sel]; + + mfm->sector++; + if (mfm->sector >= 17) { + mfm->sector = 0; + mfm->head++; + if (mfm->head >= drive->cfg_hpc) { + mfm->head = 0; + mfm->cylinder++; + drive->current_cylinder++; + if (drive->current_cylinder >= drive->cfg_cyl) + drive->current_cylinder = drive->cfg_cyl-1; + } + } +} + + +static void +mfm_callback(void *priv) +{ + mfm_t *mfm = (mfm_t *)priv; + drive_t *drive; + off64_t addr; + + mfm->callback = 0; + + mfm->drive_sel = (mfm->command[1] & 0x20) ? 1 : 0; + mfm->completion_byte = mfm->drive_sel & 0x20; + drive = &mfm->drives[mfm->drive_sel]; + + switch (mfm->command[0]) { + case CMD_TEST_DRIVE_READY: + if (!drive->present) + mfm_error(mfm, ERR_NOT_READY); + mfm_complete(mfm); + break; + + case CMD_RECALIBRATE: + if (!drive->present) + mfm_error(mfm, ERR_NOT_READY); + else { + mfm->cylinder = 0; + drive->current_cylinder = 0; + } + mfm_complete(mfm); + break; + + case CMD_READ_STATUS: + switch (mfm->state) { + case STATE_START_COMMAND: + mfm->state = STATE_SEND_DATA; + mfm->data_pos = 0; + mfm->data_len = 4; + mfm->status = STAT_BSY | STAT_IO | STAT_REQ; + mfm->data[0] = mfm->error; + mfm->data[1] = mfm->drive_sel ? 0x20 : 0; + mfm->data[2] = mfm->data[3] = 0; + mfm->error = 0; + break; + + case STATE_SENT_DATA: + mfm_complete(mfm); + break; + } + break; + + case CMD_VERIFY_SECTORS: + switch (mfm->state) { + case STATE_START_COMMAND: + mfm->cylinder = mfm->command[3] | ((mfm->command[2] & 0xc0) << 2); + drive->current_cylinder = (mfm->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl-1 : mfm->cylinder; + mfm->head = mfm->command[1] & 0x1f; + mfm->sector = mfm->command[2] & 0x1f; + mfm->sector_count = mfm->command[4]; + do { + if (get_sector(mfm, &addr)) { + pclog("get_sector failed\n"); + mfm_error(mfm, mfm->error); + mfm_complete(mfm); + return; + } + + next_sector(mfm); + + mfm->sector_count = (mfm->sector_count-1) & 0xff; + } while (mfm->sector_count); + + mfm_complete(mfm); + + update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); + break; + + default: + fatal("CMD_VERIFY_SECTORS: bad state %i\n", mfm->state); + } + break; + + case CMD_FORMAT_TRACK: + mfm->cylinder = mfm->command[3] | ((mfm->command[2] & 0xc0) << 2); + drive->current_cylinder = (mfm->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl-1 : mfm->cylinder; + mfm->head = mfm->command[1] & 0x1f; + + if (get_sector(mfm, &addr)) { + pclog("get_sector failed\n"); + mfm_error(mfm, mfm->error); + mfm_complete(mfm); + return; + } + + hdd_image_zero(drive->hdd_num, addr, 17); + + mfm_complete(mfm); + break; + + case CMD_READ_SECTORS: + switch (mfm->state) { + case STATE_START_COMMAND: + mfm->cylinder = mfm->command[3] | ((mfm->command[2] & 0xc0) << 2); + drive->current_cylinder = (mfm->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl-1 : mfm->cylinder; + mfm->head = mfm->command[1] & 0x1f; + mfm->sector = mfm->command[2] & 0x1f; + mfm->sector_count = mfm->command[4]; + mfm->state = STATE_SEND_DATA; + mfm->data_pos = 0; + mfm->data_len = 512; + + if (get_sector(mfm, &addr)) { + mfm_error(mfm, mfm->error); + mfm_complete(mfm); + return; + } + + hdd_image_read(drive->hdd_num, addr, 1, + (uint8_t *) mfm->sector_buf); + update_status_bar_icon(SB_HDD|HDD_BUS_MFM, 1); + + if (mfm->irq_dma_mask & DMA_ENA) + mfm->callback = MFM_TIME; + else { + mfm->status = STAT_BSY | STAT_IO | STAT_REQ; + memcpy(mfm->data, mfm->sector_buf, 512); + } + break; + + case STATE_SEND_DATA: + mfm->status = STAT_BSY; + if (mfm->irq_dma_mask & DMA_ENA) { + for (; mfm->data_pos < 512; mfm->data_pos++) { + int val = dma_channel_write(3, mfm->sector_buf[mfm->data_pos]); + + if (val == DMA_NODATA) { + pclog("CMD_READ_SECTORS out of data!\n"); + mfm->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ; + mfm->callback = MFM_TIME; + return; + } + } + mfm->state = STATE_SENT_DATA; + mfm->callback = MFM_TIME; + } else + fatal("Read sectors no DMA! - shouldn't get here\n"); + break; + + case STATE_SENT_DATA: + next_sector(mfm); + + mfm->data_pos = 0; + + mfm->sector_count = (mfm->sector_count-1) & 0xff; + + if (mfm->sector_count) { + if (get_sector(mfm, &addr)) { + mfm_error(mfm, mfm->error); + mfm_complete(mfm); + return; + } + + hdd_image_read(drive->hdd_num, addr, 1, + (uint8_t *) mfm->sector_buf); + update_status_bar_icon(SB_HDD|HDD_BUS_MFM, 1); + + mfm->state = STATE_SEND_DATA; + + if (mfm->irq_dma_mask & DMA_ENA) + mfm->callback = MFM_TIME; + else { + mfm->status = STAT_BSY | STAT_IO | STAT_REQ; + memcpy(mfm->data, mfm->sector_buf, 512); + } + } else { + mfm_complete(mfm); + update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 0); + } + break; + + default: + fatal("CMD_READ_SECTORS: bad state %i\n", mfm->state); + } + break; + + case CMD_WRITE_SECTORS: + switch (mfm->state) { + case STATE_START_COMMAND: + mfm->cylinder = mfm->command[3] | ((mfm->command[2] & 0xc0) << 2); + drive->current_cylinder = (mfm->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl-1 : mfm->cylinder; + mfm->head = mfm->command[1] & 0x1f; + mfm->sector = mfm->command[2] & 0x1f; + mfm->sector_count = mfm->command[4]; + mfm->state = STATE_RECEIVE_DATA; + mfm->data_pos = 0; + mfm->data_len = 512; + if (mfm->irq_dma_mask & DMA_ENA) + mfm->callback = MFM_TIME; + else + mfm->status = STAT_BSY | STAT_REQ; + break; + + case STATE_RECEIVE_DATA: + mfm->status = STAT_BSY; + if (mfm->irq_dma_mask & DMA_ENA) { + for (; mfm->data_pos < 512; mfm->data_pos++) { + int val = dma_channel_read(3); + + if (val == DMA_NODATA) { + pclog("CMD_WRITE_SECTORS out of data!\n"); + mfm->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ; + mfm->callback = MFM_TIME; + return; + } + + mfm->sector_buf[mfm->data_pos] = val & 0xff; + } + + mfm->state = STATE_RECEIVED_DATA; + mfm->callback = MFM_TIME; + } else + fatal("Write sectors no DMA! - should never get here\n"); + break; + + case STATE_RECEIVED_DATA: + if (! (mfm->irq_dma_mask & DMA_ENA)) + memcpy(mfm->sector_buf, mfm->data, 512); + + if (get_sector(mfm, &addr)) + { + mfm_error(mfm, mfm->error); + mfm_complete(mfm); + return; + } + + hdd_image_write(drive->hdd_num, addr, 1, + (uint8_t *) mfm->sector_buf); + update_status_bar_icon(SB_HDD|HDD_BUS_MFM, 1); + + next_sector(mfm); + mfm->data_pos = 0; + mfm->sector_count = (mfm->sector_count-1) & 0xff; + + if (mfm->sector_count) { + mfm->state = STATE_RECEIVE_DATA; + if (mfm->irq_dma_mask & DMA_ENA) + mfm->callback = MFM_TIME; + else + mfm->status = STAT_BSY | STAT_REQ; + } else + mfm_complete(mfm); + break; + + default: + fatal("CMD_WRITE_SECTORS: bad state %i\n", mfm->state); + } + break; + + case CMD_SEEK: + if (! drive->present) + mfm_error(mfm, ERR_NOT_READY); + else { + int cylinder = mfm->command[3] | ((mfm->command[2] & 0xc0) << 2); + + drive->current_cylinder = (cylinder >= drive->cfg_cyl) ? drive->cfg_cyl-1 : cylinder; + + if (cylinder != drive->current_cylinder) + mfm_error(mfm, ERR_SEEK_ERROR); + } + mfm_complete(mfm); + break; + + case CMD_INIT_DRIVE_PARAMS: + switch (mfm->state) { + case STATE_START_COMMAND: + mfm->state = STATE_RECEIVE_DATA; + mfm->data_pos = 0; + mfm->data_len = 8; + mfm->status = STAT_BSY | STAT_REQ; + break; + + case STATE_RECEIVED_DATA: + drive->cfg_cyl = mfm->data[1] | (mfm->data[0] << 8); + drive->cfg_hpc = mfm->data[2]; + pclog("Drive %i: cylinders=%i, heads=%i\n", mfm->drive_sel, drive->cfg_cyl, drive->cfg_hpc); + mfm_complete(mfm); + break; + + default: + fatal("CMD_INIT_DRIVE_PARAMS bad state %i\n", mfm->state); + } + break; + + case CMD_WRITE_SECTOR_BUFFER: + switch (mfm->state) { + case STATE_START_COMMAND: + mfm->state = STATE_RECEIVE_DATA; + mfm->data_pos = 0; + mfm->data_len = 512; + if (mfm->irq_dma_mask & DMA_ENA) + mfm->callback = MFM_TIME; + else + mfm->status = STAT_BSY | STAT_REQ; + break; + + case STATE_RECEIVE_DATA: + if (mfm->irq_dma_mask & DMA_ENA) { + mfm->status = STAT_BSY; + + for (; mfm->data_pos < 512; mfm->data_pos++) { + int val = dma_channel_read(3); + + if (val == DMA_NODATA) { + pclog("CMD_WRITE_SECTOR_BUFFER out of data!\n"); + mfm->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ; + mfm->callback = MFM_TIME; + return; + } + + mfm->data[mfm->data_pos] = val & 0xff; + } + + mfm->state = STATE_RECEIVED_DATA; + mfm->callback = MFM_TIME; + } else + fatal("CMD_WRITE_SECTOR_BUFFER - should never get here!\n"); + break; + + case STATE_RECEIVED_DATA: + memcpy(mfm->sector_buf, mfm->data, 512); + mfm_complete(mfm); + break; + + default: + fatal("CMD_WRITE_SECTOR_BUFFER bad state %i\n", mfm->state); + } + break; + + case CMD_BUFFER_DIAGNOSTIC: + case CMD_CONTROLLER_DIAGNOSTIC: + mfm_complete(mfm); + break; + + case 0xfa: + mfm_complete(mfm); + break; + + case CMD_DTC_SET_STEP_RATE: + mfm_complete(mfm); + break; + + case CMD_DTC_GET_DRIVE_PARAMS: + switch (mfm->state) { + case STATE_START_COMMAND: + mfm->state = STATE_SEND_DATA; + mfm->data_pos = 0; + mfm->data_len = 4; + mfm->status = STAT_BSY | STAT_IO | STAT_REQ; + memset(mfm->data, 0, 4); + mfm->data[0] = drive->tracks & 0xff; + mfm->data[1] = 17 | ((drive->tracks >> 2) & 0xc0); + mfm->data[2] = drive->hpc-1; + pclog("Get drive params %02x %02x %02x %i\n", mfm->data[0], mfm->data[1], mfm->data[2], drive->tracks); + break; + + case STATE_SENT_DATA: + mfm_complete(mfm); + break; + + default: + fatal("CMD_INIT_DRIVE_PARAMS bad state %i\n", mfm->state); + } + break; + + case CMD_DTC_GET_GEOMETRY: + switch (mfm->state) { + case STATE_START_COMMAND: + mfm->state = STATE_SEND_DATA; + mfm->data_pos = 0; + mfm->data_len = 16; + mfm->status = STAT_BSY | STAT_IO | STAT_REQ; + memset(mfm->data, 0, 16); + mfm->data[0x4] = drive->tracks & 0xff; + mfm->data[0x5] = (drive->tracks >> 8) & 0xff; + mfm->data[0xa] = drive->hpc; + break; + + case STATE_SENT_DATA: + mfm_complete(mfm); + break; + } + break; + + case CMD_DTC_SET_GEOMETRY: + switch (mfm->state) { + case STATE_START_COMMAND: + mfm->state = STATE_RECEIVE_DATA; + mfm->data_pos = 0; + mfm->data_len = 16; + mfm->status = STAT_BSY | STAT_REQ; + break; + + case STATE_RECEIVED_DATA: + /*Bit of a cheat here - we always report the actual geometry of the drive in use*/ + mfm_complete(mfm); + break; + } + break; + + default: + fatal("Unknown Xebec command - %02x %02x %02x %02x %02x %02x\n", + mfm->command[0], mfm->command[1], + mfm->command[2], mfm->command[3], + mfm->command[4], mfm->command[5]); + } +} + + +static void +loadhd(mfm_t *mfm, int c, int d, const wchar_t *fn) +{ + drive_t *drive = &mfm->drives[d]; + + if (! hdd_image_load(d)) { + drive->present = 0; + return; + } + + drive->spt = hdd[c].spt; + drive->hpc = hdd[c].hpc; + drive->tracks = hdd[c].tracks; + drive->hdd_num = c; + drive->present = 1; +} + + +static struct { + int tracks, hpc; +} hd_types[4] = { + { 306, 4 }, /* Type 0 */ + { 612, 4 }, /* Type 16 */ + { 615, 4 }, /* Type 2 */ + { 306, 8 } /* Type 13 */ +}; + + +static void +mfm_set_switches(mfm_t *mfm) +{ + int c, d; + + mfm->switches = 0; + + for (d=0; d<2; d++) { + drive_t *drive = &mfm->drives[d]; + + if (! drive->present) continue; + + for (c=0; c<4; c++) { + if (drive->spt == 17 && + drive->hpc == hd_types[c].hpc && + drive->tracks == hd_types[c].tracks) { + mfm->switches |= (c << (d ? 0 : 2)); + break; + } + } + + if (c == 4) + pclog("WARNING: Drive %c: has format not supported by Fixed Disk Adapter", d ? 'D' : 'C'); + } +} + + +static void * +xebec_init(void) +{ + int i, c = 0; + + mfm_t *xebec = malloc(sizeof(mfm_t)); + memset(xebec, 0x00, sizeof(mfm_t)); + + for (i=0; i MFM_NUM) break; + } + } + + mfm_set_switches(xebec); + + rom_init(&xebec->bios_rom, XEBEC_BIOS_FILE, + 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + io_sethandler(0x0320, 4, + mfm_read, NULL, NULL, mfm_write, NULL, NULL, xebec); + + timer_add(mfm_callback, &xebec->callback, &xebec->callback, xebec); + + return(xebec); +} + + +static void +mfm_close(void *priv) +{ + mfm_t *mfm = (mfm_t *)priv; + int d; + + for (d=0; d<2; d++) { + drive_t *drive = &mfm->drives[d]; + + hdd_image_close(drive->hdd_num); + } + + free(mfm); +} + + +static int +xebec_available(void) +{ + return(rom_present(XEBEC_BIOS_FILE)); +} + + +device_t mfm_xt_xebec_device = { + "IBM PC Fixed Disk Adapter", + 0, + xebec_init, mfm_close, xebec_available, + NULL, NULL, NULL, NULL +}; + + +static void * +dtc5150x_init(void) +{ + int i, c = 0; + + mfm_t *dtc = malloc(sizeof(mfm_t)); + memset(dtc, 0x00, sizeof(mfm_t)); + + for (i=0; i MFM_NUM) break; + } + } + + dtc->switches = 0xff; + + dtc->drives[0].cfg_cyl = dtc->drives[0].tracks; + dtc->drives[0].cfg_hpc = dtc->drives[0].hpc; + dtc->drives[1].cfg_cyl = dtc->drives[1].tracks; + dtc->drives[1].cfg_hpc = dtc->drives[1].hpc; + + rom_init(&dtc->bios_rom, DTC_BIOS_FILE, + 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + io_sethandler(0x0320, 4, + mfm_read, NULL, NULL, mfm_write, NULL, NULL, dtc); + + timer_add(mfm_callback, &dtc->callback, &dtc->callback, dtc); + + return(dtc); +} + + +static int +dtc5150x_available(void) +{ + return(rom_present(DTC_BIOS_FILE)); +} + + +device_t mfm_xt_dtc5150x_device = { + "DTC 5150X", + 0, + dtc5150x_init, mfm_close, dtc5150x_available, + NULL, NULL, NULL, NULL +}; diff --git a/src/hdd/hdc_xtide.c b/src/hdd/hdc_xtide.c new file mode 100644 index 000000000..349b39e7c --- /dev/null +++ b/src/hdd/hdc_xtide.c @@ -0,0 +1,257 @@ +/* + * 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. + * + * XT-IDE controller emulation. + * + * The XT-IDE project is intended to allow 8-bit ("XT") systems + * to use regular IDE drives. IDE is a standard based on the + * 16b PC/AT design, and so a special board (with its own BIOS) + * had to be created for this. + * + * XT-IDE is *NOT* the same as XTA, or X-IDE, which is an older + * standard where the actual MFM/RLL controller for the PC/XT + * was placed on the hard drive (hard drives where its drive + * type would end in "X" or "XT", such as the 8425XT.) This was + * more or less the original IDE, but since those systems were + * already on their way out, the newer IDE standard based on the + * PC/AT controller and 16b design became the IDE we now know. + * + * Version: @(#)xtide.c 1.0.5 2017/09/29 + * + * Authors: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016,2017 Miran Grca. + */ +#include +#include +#include +#include +#include +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" +#include "hdd.h" +#include "hdc.h" +#include "hdc_ide.h" + + +#define XT_ROM_PATH L"roms/hdd/xtide/ide_xt.bin" +#define AT_ROM_PATH L"roms/hdd/xtide/ide_at.bin" +#define PS2_ROM_PATH L"roms/hdd/xtide/SIDE1V12.BIN" +#define PS2AT_ROM_PATH L"roms/hdd/xtide/ide_at_1_1_5.bin" + + +typedef struct { + uint8_t data_high; + rom_t bios_rom; +} xtide_t; + + +static void +xtide_write(uint16_t port, uint8_t val, void *priv) +{ + xtide_t *xtide = (xtide_t *)priv; + + switch (port & 0xf) { + case 0x0: + writeidew(4, val | (xtide->data_high << 8)); + return; + + case 0x1: + case 0x2: + case 0x3: + case 0x4: + case 0x5: + case 0x6: + case 0x7: + writeide(4, (port & 0xf) | 0x1f0, val); + return; + + case 0x8: + xtide->data_high = val; + return; + + case 0xe: + writeide(4, 0x3f6, val); + return; + } +} + + +static uint8_t +xtide_read(uint16_t port, void *priv) +{ + xtide_t *xtide = (xtide_t *)priv; + uint16_t tempw; + + switch (port & 0xf) { + case 0x0: + tempw = readidew(4); + xtide->data_high = tempw >> 8; + return(tempw & 0xff); + + case 0x1: + case 0x2: + case 0x3: + case 0x4: + case 0x5: + case 0x6: + case 0x7: + return(readide(4, (port & 0xf) | 0x1f0)); + + case 0x8: + return(xtide->data_high); + + case 0xe: + return(readide(4, 0x3f6)); + + default: + return(0xff); + } +} + + +static void * +xtide_init(void) +{ + xtide_t *xtide = malloc(sizeof(xtide_t)); + + memset(xtide, 0x00, sizeof(xtide_t)); + + rom_init(&xtide->bios_rom, XT_ROM_PATH, + 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + ide_xtide_init(); + + io_sethandler(0x0300, 16, + xtide_read, NULL, NULL, + xtide_write, NULL, NULL, xtide); + + return(xtide); +} + + +static int +xtide_available(void) +{ + return(rom_present(XT_ROM_PATH)); +} + + +static void * +xtide_at_init(void) +{ + xtide_t *xtide = malloc(sizeof(xtide_t)); + + memset(xtide, 0x00, sizeof(xtide_t)); + + rom_init(&xtide->bios_rom, AT_ROM_PATH, + 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + ide_init(); + + return(xtide); +} + + +static int +xtide_at_available(void) +{ + return(rom_present(AT_ROM_PATH)); +} + + +static void * +xtide_ps2_init(void) +{ + xtide_t *xtide = malloc(sizeof(xtide_t)); + + memset(xtide, 0x00, sizeof(xtide_t)); + + rom_init(&xtide->bios_rom, PS2_ROM_PATH, + 0xc8000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + + ide_xtide_init(); + + io_sethandler(0x0360, 16, + xtide_read, NULL, NULL, + xtide_write, NULL, NULL, xtide); + + return(xtide); +} + + +static int +xtide_ps2_available(void) +{ + return(rom_present(PS2_ROM_PATH)); +} + + +static void * +xtide_at_ps2_init(void) +{ + xtide_t *xtide = malloc(sizeof(xtide_t)); + + memset(xtide, 0x00, sizeof(xtide_t)); + + rom_init(&xtide->bios_rom, PS2AT_ROM_PATH, + 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + ide_init(); + + return(xtide); +} + + +static int +xtide_at_ps2_available(void) +{ + return(rom_present(PS2AT_ROM_PATH)); +} + + +static void +xtide_close(void *priv) +{ + xtide_t *xtide = (xtide_t *)priv; + + free(xtide); +} + + +device_t xtide_device = { + "XTIDE", + 0, + xtide_init, xtide_close, xtide_available, + NULL, NULL, NULL, NULL +}; + +device_t xtide_at_device = { + "XTIDE (AT)", + DEVICE_AT, + xtide_at_init, xtide_close, xtide_at_available, + NULL, NULL, NULL, NULL +}; + +device_t xtide_ps2_device = { + "XTIDE (Acculogic)", + 0, + xtide_ps2_init, xtide_close, xtide_ps2_available, + NULL, NULL, NULL, NULL +}; + +device_t xtide_at_ps2_device = { + "XTIDE (AT) (1.1.5)", + DEVICE_PS2, + xtide_at_ps2_init, xtide_close, xtide_at_ps2_available, + NULL, NULL, NULL, NULL +}; diff --git a/src/hdd/hdd.c b/src/hdd/hdd.c index 626ebdb7d..23c9ed38f 100644 --- a/src/hdd/hdd.c +++ b/src/hdd/hdd.c @@ -1,3 +1,20 @@ +/* + * 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. + * + * Common code to handle all sorts of hard disk images. + * + * Version: @(#)hdd.c 1.0.1 2017/09/29 + * + * Authors: Miran Grca, + * Fred N. van Kempen, + * Copyright 2016,2017 Miran Grca. + * Copyright 2017 Fred N. van Kempen. + */ #include #include #include @@ -7,107 +24,6 @@ #include "../device.h" #include "../machine/machine.h" #include "hdd.h" -#include "hdd_esdi_at.h" -#include "hdd_esdi_mca.h" -#include "hdd_mfm_at.h" -#include "hdd_mfm_xebec.h" -#include "hdd_ide_xt.h" -char hdd_controller_name[16]; -hard_disk_t hdc[HDC_NUM]; - -static device_t null_hdd_device; -static int hdd_controller_current; - - -static struct -{ - char name[50]; - char internal_name[16]; - device_t *device; - int is_mfm; -} hdd_controllers[] = -{ - {"None", "none", &null_hdd_device, 0}, - {"[MFM] AT Fixed Disk Adapter", "mfm_at", &mfm_at_device, 1}, - {"[MFM] DTC 5150X", "dtc5150x", &dtc_5150x_device, 1}, - {"[MFM] Fixed Disk Adapter (Xebec)", "mfm_xebec", &mfm_xebec_device, 1}, - {"[ESDI] IBM ESDI Fixed Disk Adapter", "esdi_mca", &hdd_esdi_device, 1}, - {"[ESDI] Western Digital WD1007V-SE1", "wd1007vse1", &wd1007vse1_device, 0}, - {"[IDE] XTIDE", "xtide", &xtide_device, 0}, - {"[IDE] XTIDE (Acculogic)", "xtide_ps2", &xtide_ps2_device, 0}, - {"[IDE] XTIDE (AT)", "xtide_at", &xtide_at_device, 0}, - {"[IDE] XTIDE (AT) (1.1.5)", "xtide_at_ps2", &xtide_at_ps2_device, 0}, - {"", "", NULL, 0} -}; - -char *hdd_controller_get_name(int hdd) -{ - return hdd_controllers[hdd].name; -} - -char *hdd_controller_get_internal_name(int hdd) -{ - return hdd_controllers[hdd].internal_name; -} - -int hdd_controller_get_flags(int hdd) -{ - return hdd_controllers[hdd].device->flags; -} - -int hdd_controller_available(int hdd) -{ - return device_available(hdd_controllers[hdd].device); -} - -int hdd_controller_current_is_mfm() -{ - return hdd_controllers[hdd_controller_current].is_mfm; -} - -void hdd_controller_init(char *internal_name) -{ - int c = 0; - - if (machines[machine].flags & MACHINE_HAS_IDE) - { - return; - } - - while (hdd_controllers[c].device) - { - if (!strcmp(internal_name, hdd_controllers[c].internal_name)) - { - hdd_controller_current = c; - if (strcmp(internal_name, "none")) - device_add(hdd_controllers[c].device); - return; - } - c++; - } -} - - -static void *null_hdd_init() -{ - return NULL; -} - -static void null_hdd_close(void *p) -{ -} - -static device_t null_hdd_device = -{ - "Null HDD controller", - 0, - null_hdd_init, - null_hdd_close, - NULL, - NULL, - NULL, - NULL, - NULL -}; +hard_disk_t hdd[HDD_NUM]; diff --git a/src/hdd/hdd.h b/src/hdd/hdd.h index ff42de816..758c3e72b 100644 --- a/src/hdd/hdd.h +++ b/src/hdd/hdd.h @@ -1,16 +1,97 @@ +/* + * 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. + * + * Version: @(#)hdd.h 1.0.1 2017/09/29 + * + * Authors: Miran Grca, + * Fred N. van Kempen, + * Copyright 2016,2017 Miran Grca. + * Copyright 2017 Fred N. van Kempen. + */ #ifndef EMU_HDD_H # define EMU_HDD_H -extern char hdd_controller_name[16]; +#define HDD_NUM 30 /* total of 30 images supported */ +#define MFM_NUM 2 /* 2 drives per controller supported */ +#define ESDI_NUM 2 /* 2 drives per controller supported */ +#define XTIDE_NUM 2 /* 2 drives per controller supported */ +#define IDE_NUM 8 +#define SCSI_NUM 16 /* theoretically the controller can have at + * least 7 devices, with each device being + * able to support 8 units, but hey... */ + +/* Hard Disk bus types. */ +enum { + HDD_BUS_DISABLED = 0, + HDD_BUS_MFM, + HDD_BUS_XTIDE, + HDD_BUS_ESDI, + HDD_BUS_IDE_PIO_ONLY, + HDD_BUS_IDE_PIO_AND_DMA, + HDD_BUS_SCSI, + HDD_BUS_SCSI_REMOVABLE, + HDD_BUS_USB +}; -extern char *hdd_controller_get_name(int hdd); -extern char *hdd_controller_get_internal_name(int hdd); -extern int hdd_controller_get_flags(int hdd); -extern int hdd_controller_available(int hdd); -extern int hdd_controller_current_is_mfm(void); -extern void hdd_controller_init(char *internal_name); +/* Define the virtual Hard Disk. */ +typedef struct { + int8_t is_hdi; /* image type (should rename) */ + int8_t wp; /* disk has been mounted READ-ONLY */ + + uint8_t bus; + + uint8_t mfm_channel; /* should rename and/or unionize */ + uint8_t esdi_channel; + uint8_t xtide_channel; + uint8_t ide_channel; + uint8_t scsi_id; + uint8_t scsi_lun; + + uint32_t base; + + uint64_t spt, + hpc, /* physical geometry parameters */ + tracks; + + uint64_t at_spt, /* [Translation] parameters */ + at_hpc; + + FILE *f; /* current file handle to image */ + + wchar_t fn[260]; /* name of current image file */ + wchar_t prev_fn[260]; /* name of previous image file */ +} hard_disk_t; + + +extern hard_disk_t hdd[HDD_NUM]; +extern uint64_t hdd_table[128][3]; + + +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 uint8_t hdd_image_get_type(uint8_t id); +extern void hdd_image_specify(uint8_t id, uint64_t hpc, uint64_t spt); +extern void hdd_image_unload(uint8_t id, int fn_preserve); +extern void hdd_image_close(uint8_t id); + +extern int image_is_hdi(const wchar_t *s); +extern int image_is_hdx(const wchar_t *s, int check_signature); #endif /*EMU_HDD_H*/ diff --git a/src/hdd/hdd_esdi_at.c b/src/hdd/hdd_esdi_at.c deleted file mode 100644 index 9be45fd85..000000000 --- a/src/hdd/hdd_esdi_at.c +++ /dev/null @@ -1,849 +0,0 @@ -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include "../ibm.h" -#include "../device.h" -#include "../io.h" -#include "../mem.h" -#include "../pic.h" -#include "../rom.h" -#include "../timer.h" -#include "hdd_image.h" -#include "hdd_esdi_at.h" - - -#define IDE_TIME (TIMER_USEC*10) - -#define STAT_ERR 0x01 -#define STAT_INDEX 0x02 -#define STAT_CORRECTED_DATA 0x04 -#define STAT_DRQ 0x08 /* Data request */ -#define STAT_DSC 0x10 -#define STAT_SEEK_COMPLETE 0x20 -#define STAT_READY 0x40 -#define STAT_BUSY 0x80 - -#define ERR_DAM_NOT_FOUND 0x01 /*Data Address Mark not found*/ -#define ERR_TR000 0x02 /*Track 0 not found*/ -#define ERR_ABRT 0x04 /*Command aborted*/ -#define ERR_ID_NOT_FOUND 0x10 /*ID not found*/ -#define ERR_DATA_CRC 0x40 /*Data CRC error*/ -#define ERR_BAD_BLOCK 0x80 /*Bad Block detected*/ - -#define CMD_NOP 0x00 -#define CMD_RESTORE 0x10 -#define CMD_READ 0x20 -#define CMD_WRITE 0x30 -#define CMD_VERIFY 0x40 -#define CMD_FORMAT 0x50 -#define CMD_SEEK 0x70 -#define CMD_DIAGNOSE 0x90 -#define CMD_SET_PARAMETERS 0x91 -#define CMD_READ_PARAMETERS 0xec - -extern char ide_fn[4][512]; - -typedef struct esdi_drive_t -{ - int cfg_spt; - int cfg_hpc; - int current_cylinder; - int real_spt; - int real_hpc; - int real_tracks; - int present; - int hdc_num; -} esdi_drive_t; - -typedef struct esdi_t -{ - uint8_t status; - uint8_t error; - int secount,sector,cylinder,head,cylprecomp; - uint8_t command; - uint8_t fdisk; - int pos; - - int drive_sel; - int reset; - uint16_t buffer[256]; - int irqstat; - - int callback; - - esdi_drive_t drives[2]; - - rom_t bios_rom; -} esdi_t; - -uint16_t esdi_readw(uint16_t port, void *p); -void esdi_writew(uint16_t port, uint16_t val, void *p); - -static inline void esdi_irq_raise(esdi_t *esdi) -{ - if (!(esdi->fdisk&2)) - picint(1 << 14); - - esdi->irqstat=1; -} - -static inline void esdi_irq_lower(esdi_t *esdi) -{ - picintc(1 << 14); -} - -void esdi_irq_update(esdi_t *esdi) -{ - if (esdi->irqstat && !((pic2.pend|pic2.ins)&0x40) && !(esdi->fdisk & 2)) - picint(1 << 14); -} - -/* - * Return the sector offset for the current register values - */ -int esdi_get_sector(esdi_t *esdi, off64_t *addr) -{ - esdi_drive_t *drive = &esdi->drives[esdi->drive_sel]; - int heads = drive->cfg_hpc; - int sectors = drive->cfg_spt; - - if (esdi->head > heads) - { - pclog("esdi_get_sector: past end of configured heads\n"); - return 1; - } - if (esdi->sector >= sectors+1) - { - pclog("esdi_get_sector: past end of configured sectors\n"); - return 1; - } - - if (drive->cfg_spt == drive->real_spt && drive->cfg_hpc == drive->real_hpc) - { - *addr = ((((off64_t) esdi->cylinder * heads) + esdi->head) * - sectors) + (esdi->sector - 1); - } - else - { - /*When performing translation, the firmware seems to leave 1 - sector per track inaccessible (spare sector)*/ - int c, h, s; - *addr = ((((off64_t) esdi->cylinder * heads) + esdi->head) * - sectors) + (esdi->sector - 1); - - s = *addr % (drive->real_spt - 1); - h = (*addr / (drive->real_spt - 1)) % drive->real_hpc; - c = (*addr / (drive->real_spt - 1)) / drive->real_hpc; - - *addr = ((((off64_t) c * drive->real_hpc) + h) * - drive->real_spt) + s; - } - - return 0; -} - -/** - * Move to the next sector using CHS addressing - */ -void esdi_next_sector(esdi_t *esdi) -{ - esdi_drive_t *drive = &esdi->drives[esdi->drive_sel]; - - esdi->sector++; - if (esdi->sector == (drive->cfg_spt + 1)) - { - esdi->sector = 1; - esdi->head++; - if (esdi->head == drive->cfg_hpc) - { - esdi->head = 0; - esdi->cylinder++; - if (drive->current_cylinder < drive->real_tracks) - drive->current_cylinder++; - } - } -} - -void esdi_write(uint16_t port, uint8_t val, void *p) -{ - esdi_t *esdi = (esdi_t *)p; - - switch (port) - { - case 0x1F0: /* Data */ - esdi_writew(port, val | (val << 8), p); - return; - - case 0x1F1: /* Write precompenstation */ - esdi->cylprecomp = val; - return; - - case 0x1F2: /* Sector count */ - esdi->secount = val; - return; - - case 0x1F3: /* Sector */ - esdi->sector = val; - return; - - case 0x1F4: /* Cylinder low */ - esdi->cylinder = (esdi->cylinder & 0xFF00) | val; - return; - - case 0x1F5: /* Cylinder high */ - esdi->cylinder = (esdi->cylinder & 0xFF) | (val << 8); - return; - - case 0x1F6: /* Drive/Head */ - esdi->head = val & 0xF; - esdi->drive_sel = (val & 0x10) ? 1 : 0; - if (esdi->drives[esdi->drive_sel].present) - esdi->status = 0; - else - esdi->status = STAT_READY | STAT_DSC; - return; - - case 0x1F7: /* Command register */ - esdi_irq_lower(esdi); - esdi->command = val; - esdi->error = 0; - - switch (val & 0xf0) - { - case CMD_RESTORE: - esdi->command &= ~0x0f; /*Mask off step rate*/ - esdi->status = STAT_BUSY; - timer_process(); - esdi->callback = 200*IDE_TIME; - timer_update_outstanding(); - break; - - case CMD_SEEK: - esdi->command &= ~0x0f; /*Mask off step rate*/ - esdi->status = STAT_BUSY; - timer_process(); - esdi->callback = 200*IDE_TIME; - timer_update_outstanding(); - break; - - default: - switch (val) - { - case CMD_NOP: - esdi->status = STAT_BUSY; - timer_process(); - esdi->callback = 200*IDE_TIME; - timer_update_outstanding(); - break; - - case CMD_READ: case CMD_READ+1: - case CMD_READ+2: case CMD_READ+3: - esdi->command &= ~3; - if (val & 2) - fatal("Read with ECC\n"); - case 0xa0: - esdi->status = STAT_BUSY; - timer_process(); - esdi->callback = 200*IDE_TIME; - timer_update_outstanding(); - break; - - case CMD_WRITE: case CMD_WRITE+1: - case CMD_WRITE+2: case CMD_WRITE+3: - esdi->command &= ~3; - if (val & 2) - fatal("Write with ECC\n"); - esdi->status = STAT_DRQ | STAT_DSC; - esdi->pos=0; - break; - - case CMD_VERIFY: case CMD_VERIFY+1: - esdi->command &= ~1; - esdi->status = STAT_BUSY; - timer_process(); - esdi->callback = 200 * IDE_TIME; - timer_update_outstanding(); - break; - - case CMD_FORMAT: - esdi->status = STAT_DRQ; - esdi->pos=0; - break; - - case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ - esdi->status = STAT_BUSY; - timer_process(); - esdi->callback = 30*IDE_TIME; - timer_update_outstanding(); - break; - - case CMD_DIAGNOSE: /* Execute Drive Diagnostics */ - esdi->status = STAT_BUSY; - timer_process(); - esdi->callback = 200*IDE_TIME; - timer_update_outstanding(); - break; - - case 0xe0: /*???*/ - case CMD_READ_PARAMETERS: - esdi->status = STAT_BUSY; - timer_process(); - esdi->callback = 200*IDE_TIME; - timer_update_outstanding(); - break; - - default: - pclog("Bad esdi command %02X\n", val); - case 0xe8: /*???*/ - esdi->status = STAT_BUSY; - timer_process(); - esdi->callback = 200*IDE_TIME; - timer_update_outstanding(); - break; - } - } - break; - - case 0x3F6: /* Device control */ - if ((esdi->fdisk & 4) && !(val & 4)) - { - timer_process(); - esdi->callback = 500*IDE_TIME; - timer_update_outstanding(); - esdi->reset = 1; - esdi->status = STAT_BUSY; - } - if (val & 4) - { - /*Drive held in reset*/ - timer_process(); - esdi->callback = 0; - timer_update_outstanding(); - esdi->status = STAT_BUSY; - } - esdi->fdisk = val; - esdi_irq_update(esdi); - return; - } -} - -void esdi_writew(uint16_t port, uint16_t val, void *p) -{ - esdi_t *esdi = (esdi_t *)p; - - esdi->buffer[esdi->pos >> 1] = val; - esdi->pos += 2; - - if (esdi->pos >= 512) - { - esdi->pos = 0; - esdi->status = STAT_BUSY; - timer_process(); - esdi->callback = 6*IDE_TIME; - timer_update_outstanding(); - } -} - -uint8_t esdi_read(uint16_t port, void *p) -{ - esdi_t *esdi = (esdi_t *)p; - uint8_t temp = 0xff; - - switch (port) - { - case 0x1F0: /* Data */ - temp = esdi_readw(port, esdi) & 0xff; - break; - - case 0x1F1: /* Error */ - temp = esdi->error; - break; - - case 0x1F2: /* Sector count */ - temp = (uint8_t)esdi->secount; - break; - - case 0x1F3: /* Sector */ - temp = (uint8_t)esdi->sector; - break; - - case 0x1F4: /* Cylinder low */ - temp = (uint8_t)(esdi->cylinder&0xFF); - break; - - case 0x1F5: /* Cylinder high */ - temp = (uint8_t)(esdi->cylinder>>8); - break; - - case 0x1F6: /* Drive/Head */ - temp = (uint8_t)(esdi->head | (esdi->drive_sel ? 0x10 : 0) | 0xa0); - break; - - case 0x1F7: /* Status */ - esdi_irq_lower(esdi); - temp = esdi->status; - break; - } - - return temp; -} - -uint16_t esdi_readw(uint16_t port, void *p) -{ - esdi_t *esdi = (esdi_t *)p; - uint16_t temp; - - temp = esdi->buffer[esdi->pos >> 1]; - esdi->pos += 2; - - if (esdi->pos >= 512) - { - esdi->pos=0; - esdi->status = STAT_READY | STAT_DSC; - if (esdi->command == CMD_READ || esdi->command == 0xa0) - { - esdi->secount = (esdi->secount - 1) & 0xff; - if (esdi->secount) - { - esdi_next_sector(esdi); - esdi->status = STAT_BUSY; - timer_process(); - esdi->callback = 6*IDE_TIME; - timer_update_outstanding(); - } - } - } - - return temp; -} - -void esdi_callback(void *p) -{ - esdi_t *esdi = (esdi_t *)p; - esdi_drive_t *drive = &esdi->drives[esdi->drive_sel]; - off64_t addr; - - esdi->callback = 0; - if (esdi->reset) - { - esdi->status = STAT_READY | STAT_DSC; - esdi->error = 1; - esdi->secount = 1; - esdi->sector = 1; - esdi->head = 0; - esdi->cylinder = 0; - esdi->reset = 0; - return; - } - switch (esdi->command) - { - case CMD_RESTORE: - if (!drive->present) - { - esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - } - else - { - drive->current_cylinder = 0; - esdi->status = STAT_READY | STAT_DSC; - esdi_irq_raise(esdi); - } - break; - - case CMD_SEEK: - if (!drive->present) - { - esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - } - else - { - esdi->status = STAT_READY | STAT_DSC; - esdi_irq_raise(esdi); - } - break; - - case CMD_READ: - if (!drive->present) - { - esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - } - else - { - if (esdi_get_sector(esdi, &addr)) - { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY | STAT_DSC | STAT_ERR; - esdi_irq_raise(esdi); - break; - } - if (hdd_image_read_ex(drive->hdc_num, addr, 1, (uint8_t *) esdi->buffer)) - { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY | STAT_DSC | STAT_ERR; - esdi_irq_raise(esdi); - break; - } - esdi->pos = 0; - esdi->status = STAT_DRQ | STAT_READY | STAT_DSC; - esdi_irq_raise(esdi); - update_status_bar_icon(SB_HDD | HDD_BUS_ESDI, 1); - } - break; - - case CMD_WRITE: - if (!drive->present) - { - esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - } - else - { - if (esdi_get_sector(esdi, &addr)) - { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY | STAT_DSC | STAT_ERR; - esdi_irq_raise(esdi); - break; - } - if (hdd_image_write_ex(drive->hdc_num, addr, 1, (uint8_t *) esdi->buffer)) - { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY | STAT_DSC | STAT_ERR; - esdi_irq_raise(esdi); - break; - } - esdi_irq_raise(esdi); - esdi->secount = (esdi->secount - 1) & 0xff; - if (esdi->secount) - { - esdi->status = STAT_DRQ | STAT_READY | STAT_DSC; - esdi->pos = 0; - esdi_next_sector(esdi); - } - else - esdi->status = STAT_READY | STAT_DSC; - update_status_bar_icon(SB_HDD | HDD_BUS_ESDI, 1); - } - break; - - case CMD_VERIFY: - if (!drive->present) - { - esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - } - else - { - if (esdi_get_sector(esdi, &addr)) - { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY | STAT_DSC | STAT_ERR; - esdi_irq_raise(esdi); - break; - } - if (hdd_image_read_ex(drive->hdc_num, addr, 1, (uint8_t *) esdi->buffer)) - { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY | STAT_DSC | STAT_ERR; - esdi_irq_raise(esdi); - break; - } - update_status_bar_icon(SB_HDD | HDD_BUS_ESDI, 1); - esdi_next_sector(esdi); - esdi->secount = (esdi->secount - 1) & 0xff; - if (esdi->secount) - esdi->callback = 6*IDE_TIME; - else - { - esdi->pos = 0; - esdi->status = STAT_READY | STAT_DSC; - esdi_irq_raise(esdi); - } - } - break; - - case CMD_FORMAT: - if (!drive->present) - { - esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - } - else - { - if (esdi_get_sector(esdi, &addr)) - { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY | STAT_DSC | STAT_ERR; - esdi_irq_raise(esdi); - break; - } - if (hdd_image_zero_ex(drive->hdc_num, addr, esdi->secount)) - { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY | STAT_DSC | STAT_ERR; - esdi_irq_raise(esdi); - break; - } - esdi->status = STAT_READY | STAT_DSC; - esdi_irq_raise(esdi); - update_status_bar_icon(SB_HDD | HDD_BUS_ESDI, 1); - } - break; - - case CMD_DIAGNOSE: - if (!drive->present) - { - esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - } - else - { - esdi->error = 1; /*No error detected*/ - esdi->status = STAT_READY | STAT_DSC; - esdi_irq_raise(esdi); - } - break; - - case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ - if (!drive->present) - { - esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - } - else - { - drive->cfg_spt = esdi->secount; - drive->cfg_hpc = esdi->head+1; - pclog("Parameters: spt=%i hpc=%i\n", drive->cfg_spt,drive->cfg_hpc); - if (!esdi->secount) - fatal("secount=0\n"); - esdi->status = STAT_READY | STAT_DSC; - esdi_irq_raise(esdi); - } - break; - - case CMD_NOP: - esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - break; - - case 0xe0: - if (!drive->present) - { - esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - } - else - { - switch (esdi->cylinder >> 8) - { - case 0x31: - esdi->cylinder = drive->real_tracks; - break; - case 0x33: - esdi->cylinder = drive->real_hpc; - break; - case 0x35: - esdi->cylinder = 0x200; - break; - case 0x36: - esdi->cylinder = drive->real_spt; - break; - default: - pclog("EDSI Bad read config %02x\n", esdi->cylinder >> 8); - } - esdi->status = STAT_READY | STAT_DSC; - esdi_irq_raise(esdi); - } - break; - - case 0xa0: - if (!drive->present) - { - esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - } - else - { - memset(esdi->buffer, 0, 512); - memset(&esdi->buffer[3], 0xff, 512-6); - esdi->pos = 0; - esdi->status = STAT_DRQ | STAT_READY | STAT_DSC; - esdi_irq_raise(esdi); - } - break; - - case CMD_READ_PARAMETERS: - if (!drive->present) - { - esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - } - else - { - memset(esdi->buffer, 0, 512); - - esdi->buffer[0] = 0x44; /* general configuration */ - esdi->buffer[1] = drive->real_tracks; /* number of non-removable cylinders */ - esdi->buffer[2] = 0; /* number of removable cylinders */ - esdi->buffer[3] = drive->real_hpc; /* number of heads */ - esdi->buffer[5] = esdi->buffer[4] * drive->real_spt; /* number of unformatted bytes/sector */ - esdi->buffer[4] = 600; /* number of unformatted bytes/track */ - esdi->buffer[6] = drive->real_spt; /* number of sectors */ - esdi->buffer[7] = 0; /*minimum bytes in inter-sector gap*/ - esdi->buffer[8] = 0; /* minimum bytes in postamble */ - esdi->buffer[9] = 0; /* number of words of vendor status */ - /* controller info */ - esdi->buffer[20] = 2; /* controller type */ - esdi->buffer[21] = 1; /* sector buffer size, in sectors */ - esdi->buffer[22] = 0; /* ecc bytes appended */ - esdi->buffer[27] = 'W' | ('D' << 8); - esdi->buffer[28] = '1' | ('0' << 8); - esdi->buffer[29] = '0' | ('7' << 8); - esdi->buffer[30] = 'V' | ('-' << 8); - esdi->buffer[31] = 'S' | ('E' << 8); - esdi->buffer[32] = '1'; - esdi->buffer[47] = 0; /* sectors per interrupt */ - esdi->buffer[48] = 0;/* can use double word read/write? */ - esdi->pos = 0; - esdi->status = STAT_DRQ | STAT_READY | STAT_DSC; - esdi_irq_raise(esdi); - } - break; - - default: - pclog("ESDI Callback on unknown command %02x\n", esdi->command); - case 0xe8: - esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - break; - } - - update_status_bar_icon(SB_HDD | HDD_BUS_ESDI, 0); -} - -static void esdi_rom_write(uint32_t addr, uint8_t val, void *p) -{ - rom_t *rom = (rom_t *)p; - - addr &= rom->mask; - - if (addr >= 0x1f00 && addr < 0x2000) - rom->rom[addr] = val; -} - -static void loadhd(esdi_t *esdi, int hdc_num, int d, const wchar_t *fn) -{ - esdi_drive_t *drive = &esdi->drives[d]; - int ret = 0; - - ret = hdd_image_load(hdc_num); - - if (!ret) - { - drive->present = 0; - return; - } - - drive->cfg_spt = drive->real_spt = hdc[hdc_num].spt; - drive->cfg_hpc = drive->real_hpc = hdc[hdc_num].hpc; - drive->real_tracks = hdc[hdc_num].tracks; - drive->hdc_num = hdc_num; - drive->present = 1; -} - -void *wd1007vse1_init() -{ - int i = 0; - int c = 0; - - esdi_t *esdi = malloc(sizeof(esdi_t)); - memset(esdi, 0, sizeof(esdi_t)); - - esdi->drives[0].present = esdi->drives[1].present = 0; - - for (i = 0; i < HDC_NUM; i++) - { - if ((hdc[i].bus == HDD_BUS_ESDI) && (hdc[i].esdi_channel < ESDI_NUM)) - { - loadhd(esdi, i, hdc[i].esdi_channel, hdc[i].fn); - c++; - if (c >= ESDI_NUM) break; - } - } - - esdi->status = STAT_READY | STAT_DSC; - esdi->error = 1; /*No errors*/ - - rom_init(&esdi->bios_rom, L"roms/hdd/esdi_at/62-000279-061.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - mem_mapping_set_handler(&esdi->bios_rom.mapping, - rom_read, rom_readw, rom_readl, - esdi_rom_write, NULL, NULL); - - io_sethandler(0x01f0, 0x0001, esdi_read, esdi_readw, NULL, esdi_write, esdi_writew, NULL, esdi); - io_sethandler(0x01f1, 0x0007, esdi_read, NULL, NULL, esdi_write, NULL, NULL, esdi); - io_sethandler(0x03f6, 0x0001, NULL, NULL, NULL, esdi_write, NULL, NULL, esdi); - - timer_add(esdi_callback, &esdi->callback, &esdi->callback, esdi); - - return esdi; -} - -void wd1007vse1_close(void *p) -{ - esdi_t *esdi = (esdi_t *)p; - esdi_drive_t *drive; - - int d; - - esdi->drives[0].present = esdi->drives[1].present = 0; - - for (d = 0; d < 2; d++) - { - drive = &esdi->drives[d]; - - hdd_image_close(drive->hdc_num); - } - - free(esdi); -} - -static int wd1007vse1_available() -{ - return rom_present(L"roms/hdd/esdi_at/62-000279-061.bin"); -} - -device_t wd1007vse1_device = -{ - "Western Digital WD1007V-SE1 (ESDI)", - DEVICE_AT, - wd1007vse1_init, - wd1007vse1_close, - wd1007vse1_available, - NULL, - NULL, - NULL, - NULL -}; diff --git a/src/hdd/hdd_esdi_at.h b/src/hdd/hdd_esdi_at.h deleted file mode 100644 index fa66ace21..000000000 --- a/src/hdd/hdd_esdi_at.h +++ /dev/null @@ -1 +0,0 @@ -extern device_t wd1007vse1_device; diff --git a/src/hdd/hdd_esdi_mca.h b/src/hdd/hdd_esdi_mca.h deleted file mode 100644 index 4fea361bd..000000000 --- a/src/hdd/hdd_esdi_mca.h +++ /dev/null @@ -1 +0,0 @@ -extern device_t hdd_esdi_device; diff --git a/src/hdd/hdd_ide_xt.c b/src/hdd/hdd_ide_xt.c deleted file mode 100644 index 7c1515961..000000000 --- a/src/hdd/hdd_ide_xt.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * 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. - * - * XT IDE controller emulation. - * - * Version: @(#)xtide.c 1.0.4 2017/09/24 - * - * Authors: Sarah Walker, - * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../ibm.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "hdd_ide_at.h" -#include "hdd_ide_xt.h" - - -#define XTIDE_ROM_PATH L"roms/hdd/xtide/ide_xt.bin" -#define ATIDE_ROM_PATH L"roms/hdd/xtide/ide_at.bin" - - -typedef struct xtide_t -{ - uint8_t data_high; - rom_t bios_rom; -} xtide_t; - - -static void xtide_write(uint16_t port, uint8_t val, void *p) -{ - xtide_t *xtide = (xtide_t *)p; - - switch (port & 0xf) - { - case 0x0: - writeidew(4, val | (xtide->data_high << 8)); - return; - - case 0x1: case 0x2: case 0x3: - case 0x4: case 0x5: case 0x6: case 0x7: - writeide(4, (port & 0xf) | 0x1f0, val); - return; - - case 0x8: - xtide->data_high = val; - return; - - case 0xe: - writeide(4, 0x3f6, val); - return; - } -} - - -static uint8_t xtide_read(uint16_t port, void *p) -{ - xtide_t *xtide = (xtide_t *)p; - uint16_t tempw; - - switch (port & 0xf) - { - case 0x0: - tempw = readidew(4); - xtide->data_high = tempw >> 8; - return tempw & 0xff; - - case 0x1: case 0x2: case 0x3: - case 0x4: case 0x5: case 0x6: case 0x7: - return readide(4, (port & 0xf) | 0x1f0); - - case 0x8: - return xtide->data_high; - - case 0xe: - return readide(4, 0x3f6); - - default: - return 0xff; - } -} - - -static void *xtide_init(void) -{ - xtide_t *xtide = malloc(sizeof(xtide_t)); - memset(xtide, 0, sizeof(xtide_t)); - - rom_init(&xtide->bios_rom, XTIDE_ROM_PATH, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - ide_xtide_init(); - io_sethandler(0x0300, 0x0010, xtide_read, NULL, NULL, xtide_write, NULL, NULL, xtide); - - return xtide; -} - - -static void *xtide_at_init(void) -{ - xtide_t *xtide = malloc(sizeof(xtide_t)); - memset(xtide, 0, sizeof(xtide_t)); - - rom_init(&xtide->bios_rom, ATIDE_ROM_PATH, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - ide_init(); - - return xtide; -} - - -static void *xtide_ps2_init(void) -{ - xtide_t *xtide = malloc(sizeof(xtide_t)); - memset(xtide, 0, sizeof(xtide_t)); - - rom_init(&xtide->bios_rom, L"roms/hdd/xtide/SIDE1V12.BIN", 0xc8000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - ide_xtide_init(); - io_sethandler(0x0360, 0x0010, xtide_read, NULL, NULL, xtide_write, NULL, NULL, xtide); - - return xtide; -} - - -static void *xtide_at_ps2_init(void) -{ - xtide_t *xtide = malloc(sizeof(xtide_t)); - memset(xtide, 0, sizeof(xtide_t)); - - rom_init(&xtide->bios_rom, L"roms/hdd/xtide/ide_at_1_1_5.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - ide_init(); - - return xtide; -} - - -static void xtide_close(void *p) -{ - xtide_t *xtide = (xtide_t *)p; - - free(xtide); -} - - -static int xtide_available(void) -{ - return rom_present(L"roms/hdd/xtide/ide_xt.bin"); -} - - -static int xtide_at_available(void) -{ - return rom_present(L"roms/hdd/xtide/ide_at.bin"); -} - - -static int xtide_ps2_available(void) -{ - return rom_present(L"roms/hdd/xtide/SIDE1V12.BIN"); -} - - -static int xtide_at_ps2_available(void) -{ - return rom_present(L"roms/hdd/xtide/ide_at_1_1_5.bin"); -} - - -device_t xtide_device = -{ - "XTIDE", - 0, - xtide_init, - xtide_close, - xtide_available, - NULL, - NULL, - NULL, - NULL -}; -device_t xtide_at_device = -{ - "XTIDE (AT)", - DEVICE_AT, - xtide_at_init, - xtide_close, - xtide_at_available, - NULL, - NULL, - NULL, - NULL -}; - -device_t xtide_ps2_device = -{ - "XTIDE (Acculogic)", - 0, - xtide_ps2_init, - xtide_close, - xtide_ps2_available, - NULL, - NULL, - NULL, - NULL -}; - -device_t xtide_at_ps2_device = -{ - "XTIDE (AT) (1.1.5)", - DEVICE_PS2, - xtide_at_ps2_init, - xtide_close, - xtide_at_ps2_available, - NULL, - NULL, - NULL, - NULL -}; diff --git a/src/hdd/hdd_ide_xt.h b/src/hdd/hdd_ide_xt.h deleted file mode 100644 index 8137cbbb0..000000000 --- a/src/hdd/hdd_ide_xt.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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. - * - * XT IDE controller emulation. - * - * Version: @(#)xtide.h 1.0.2 2017/08/23 - * - * Authors: Sarah Walker, - * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. - */ -#ifndef EMU_XTIDE_H -# define EMU_XTIDE_H - - -extern device_t xtide_device; -extern device_t xtide_at_device; -extern device_t xtide_ps2_device; -extern device_t xtide_at_ps2_device; - - -#endif /*EMU_XTIDE_H*/ diff --git a/src/hdd/hdd_image.c b/src/hdd/hdd_image.c index 8c56fae30..7b7bbf32f 100644 --- a/src/hdd/hdd_image.c +++ b/src/hdd/hdd_image.c @@ -9,8 +9,8 @@ #include #include #include "../ibm.h" -#include "hdd_image.h" -#include "hdd_ide_at.h" +#include "hdd.h" +//#include "hdc_ide.h" typedef struct @@ -22,11 +22,13 @@ typedef struct uint8_t loaded; } hdd_image_t; -hdd_image_t hdd_images[HDC_NUM]; + +hdd_image_t hdd_images[HDD_NUM]; static char empty_sector[512]; static char *empty_sector_1mb; + int hdd_image_do_log = 0; void hdd_image_log(const char *format, ...) @@ -43,6 +45,7 @@ void hdd_image_log(const char *format, ...) #endif } + int image_is_hdi(const wchar_t *s) { int len; @@ -64,7 +67,9 @@ int image_is_hdi(const wchar_t *s) } } -int image_is_hdx(const wchar_t *s, int check_signature) + +int +image_is_hdx(const wchar_t *s, int check_signature) { int len; FILE *f; @@ -116,6 +121,7 @@ int image_is_hdx(const wchar_t *s, int check_signature) } } + int hdd_image_load(int id) { uint32_t sector_size = 512; @@ -125,7 +131,7 @@ int hdd_image_load(int id) uint64_t spt = 0, hpc = 0, tracks = 0; int c; uint64_t i = 0, s = 0, t = 0; - wchar_t *fn = hdc[id].fn; + wchar_t *fn = hdd[id].fn; int is_hdx[2] = { 0, 0 }; memset(empty_sector, 0, sizeof(empty_sector)); @@ -146,7 +152,7 @@ int hdd_image_load(int id) if (fn[0] == '.') { hdd_image_log("File name starts with .\n"); - memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); return 0; } hdd_images[id].file = _wfopen(fn, L"rb+"); @@ -157,10 +163,10 @@ int hdd_image_load(int id) { /* Failed because it does not exist, so try to create new file */ - if (hdc[id].wp) + if (hdd[id].wp) { hdd_image_log("A write-protected image must exist\n"); - memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); return 0; } @@ -168,23 +174,23 @@ int hdd_image_load(int id) if (hdd_images[id].file == NULL) { hdd_image_log("Unable to open image\n"); - memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); return 0; } else { if (image_is_hdi(fn)) { - full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; + full_size = hdd[id].spt * hdd[id].hpc * hdd[id].tracks * 512; hdd_images[id].base = 0x1000; fwrite(&zero, 1, 4, hdd_images[id].file); fwrite(&zero, 1, 4, hdd_images[id].file); fwrite(&(hdd_images[id].base), 1, 4, hdd_images[id].file); fwrite(&full_size, 1, 4, hdd_images[id].file); fwrite(§or_size, 1, 4, hdd_images[id].file); - fwrite(&(hdc[id].spt), 1, 4, hdd_images[id].file); - fwrite(&(hdc[id].hpc), 1, 4, hdd_images[id].file); - fwrite(&(hdc[id].tracks), 1, 4, hdd_images[id].file); + fwrite(&(hdd[id].spt), 1, 4, hdd_images[id].file); + fwrite(&(hdd[id].hpc), 1, 4, hdd_images[id].file); + fwrite(&(hdd[id].tracks), 1, 4, hdd_images[id].file); for (c = 0; c < 0x3f8; c++) { fwrite(&zero, 1, 4, hdd_images[id].file); @@ -193,14 +199,14 @@ int hdd_image_load(int id) } else if (is_hdx[0]) { - full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; + full_size = hdd[id].spt * hdd[id].hpc * hdd[id].tracks * 512; hdd_images[id].base = 0x28; fwrite(&signature, 1, 8, hdd_images[id].file); fwrite(&full_size, 1, 8, hdd_images[id].file); fwrite(§or_size, 1, 4, hdd_images[id].file); - fwrite(&(hdc[id].spt), 1, 4, hdd_images[id].file); - fwrite(&(hdc[id].hpc), 1, 4, hdd_images[id].file); - fwrite(&(hdc[id].tracks), 1, 4, hdd_images[id].file); + fwrite(&(hdd[id].spt), 1, 4, hdd_images[id].file); + fwrite(&(hdd[id].hpc), 1, 4, hdd_images[id].file); + fwrite(&(hdd[id].tracks), 1, 4, hdd_images[id].file); fwrite(&zero, 1, 4, hdd_images[id].file); fwrite(&zero, 1, 4, hdd_images[id].file); hdd_images[id].type = 2; @@ -212,7 +218,7 @@ int hdd_image_load(int id) hdd_images[id].last_sector = 0; } - s = full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; + s = full_size = hdd[id].spt * hdd[id].hpc * hdd[id].tracks * 512; goto prepare_new_hard_disk; } @@ -220,7 +226,7 @@ int hdd_image_load(int id) { /* Failed for another reason */ hdd_image_log("Failed for another reason\n"); - memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); return 0; } } @@ -241,26 +247,26 @@ int hdd_image_load(int id) hdd_image_log("HDI: Sector size is not 512\n"); fclose(hdd_images[id].file); hdd_images[id].file = NULL; - memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); return 0; } fread(&spt, 1, 4, hdd_images[id].file); fread(&hpc, 1, 4, hdd_images[id].file); fread(&tracks, 1, 4, hdd_images[id].file); - if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) + if (hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) { - if ((spt != hdc[id].spt) || (hpc != hdc[id].hpc) || (tracks != hdc[id].tracks)) + if ((spt != hdd[id].spt) || (hpc != hdd[id].hpc) || (tracks != hdd[id].tracks)) { hdd_image_log("HDI: Geometry mismatch\n"); fclose(hdd_images[id].file); hdd_images[id].file = NULL; - memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); return 0; } } - hdc[id].spt = spt; - hdc[id].hpc = hpc; - hdc[id].tracks = tracks; + hdd[id].spt = spt; + hdd[id].hpc = hpc; + hdd[id].tracks = tracks; hdd_images[id].type = 1; } else if (is_hdx[1]) @@ -276,33 +282,33 @@ int hdd_image_load(int id) hdd_image_log("HDX: Sector size is not 512\n"); fclose(hdd_images[id].file); hdd_images[id].file = NULL; - memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); return 0; } fread(&spt, 1, 4, hdd_images[id].file); fread(&hpc, 1, 4, hdd_images[id].file); fread(&tracks, 1, 4, hdd_images[id].file); - if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) + if (hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) { - if ((spt != hdc[id].spt) || (hpc != hdc[id].hpc) || (tracks != hdc[id].tracks)) + if ((spt != hdd[id].spt) || (hpc != hdd[id].hpc) || (tracks != hdd[id].tracks)) { hdd_image_log("HDX: Geometry mismatch\n"); fclose(hdd_images[id].file); hdd_images[id].file = NULL; - memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); return 0; } } - hdc[id].spt = spt; - hdc[id].hpc = hpc; - hdc[id].tracks = tracks; - fread(&(hdc[id].at_spt), 1, 4, hdd_images[id].file); - fread(&(hdc[id].at_hpc), 1, 4, hdd_images[id].file); + hdd[id].spt = spt; + hdd[id].hpc = hpc; + hdd[id].tracks = tracks; + fread(&(hdd[id].at_spt), 1, 4, hdd_images[id].file); + fread(&(hdd[id].at_hpc), 1, 4, hdd_images[id].file); hdd_images[id].type = 2; } else { - full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; + full_size = hdd[id].spt * hdd[id].hpc * hdd[id].tracks * 512; hdd_images[id].type = 0; } } @@ -341,8 +347,14 @@ prepare_new_hard_disk: hdd_images[id].last_sector = (uint32_t) (full_size >> 9) - 1; +#ifdef WALTJE + hdd_images[id].loaded = 1; +pclog("HDD: disk %d image '%S' file 0x%08lx\n", id, hdd[id].fn, hdd_images[id].file); + return 1; +#else return 1; hdd_images[id].loaded = 1; +#endif } void hdd_image_seek(uint8_t id, uint32_t sector) @@ -358,6 +370,7 @@ void hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer { count <<= 9; +pclog("HDD: read_image(id=%d sector=%lu cnt=%d, bufp=%08lx) fp=%08lx\n",id,sector,count,buffer,hdd_images[id].file); hdd_image_seek(id, sector); memset(buffer, 0, count); fread(buffer, 1, count, hdd_images[id].file); @@ -479,17 +492,17 @@ void hdd_image_specify(uint8_t id, uint64_t hpc, uint64_t spt) { if (hdd_images[id].type == 2) { - hdc[id].at_hpc = hpc; - hdc[id].at_spt = spt; + hdd[id].at_hpc = hpc; + hdd[id].at_spt = spt; fseeko64(hdd_images[id].file, 0x20, SEEK_SET); - fwrite(&(hdc[id].at_spt), 1, 4, hdd_images[id].file); - fwrite(&(hdc[id].at_hpc), 1, 4, hdd_images[id].file); + fwrite(&(hdd[id].at_spt), 1, 4, hdd_images[id].file); + fwrite(&(hdd[id].at_hpc), 1, 4, hdd_images[id].file); } } void hdd_image_unload(uint8_t id, int fn_preserve) { - if (wcslen(hdc[id].fn) == 0) + if (wcslen(hdd[id].fn) == 0) { return; } @@ -505,13 +518,13 @@ void hdd_image_unload(uint8_t id, int fn_preserve) hdd_images[id].last_sector = -1; - memset(hdc[id].prev_fn, 0, sizeof(hdc[id].prev_fn)); + memset(hdd[id].prev_fn, 0, sizeof(hdd[id].prev_fn)); if (fn_preserve) { - wcscpy(hdc[id].prev_fn, hdc[id].fn); + wcscpy(hdd[id].prev_fn, hdd[id].fn); } - memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); } void hdd_image_close(uint8_t id) diff --git a/src/hdd/hdd_image.h b/src/hdd/hdd_image.h deleted file mode 100644 index d04710999..000000000 --- a/src/hdd/hdd_image.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef EMU_HDD_IMAGE_H -# define EMU_HDD_IMAGE_H - - -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 uint8_t hdd_image_get_type(uint8_t id); -extern void hdd_image_specify(uint8_t id, uint64_t hpc, uint64_t spt); -extern void hdd_image_unload(uint8_t id, int fn_preserve); -extern void hdd_image_close(uint8_t id); - - -#endif /*EMU_HDD_IMAGE_H*/ diff --git a/src/hdd/hdd_mfm_at.h b/src/hdd/hdd_mfm_at.h deleted file mode 100644 index 67907af23..000000000 --- a/src/hdd/hdd_mfm_at.h +++ /dev/null @@ -1 +0,0 @@ -extern device_t mfm_at_device; diff --git a/src/hdd/hdd_mfm_xebec.c b/src/hdd/hdd_mfm_xebec.c deleted file mode 100644 index b5a8993b6..000000000 --- a/src/hdd/hdd_mfm_xebec.c +++ /dev/null @@ -1,919 +0,0 @@ -#include -#include -#include -#include -#include -#include "../ibm.h" -#include "../device.h" -#include "../dma.h" -#include "../io.h" -#include "../mem.h" -#include "../pic.h" -#include "../rom.h" -#include "../timer.h" -#include "hdd_image.h" -#include "hdd_mfm_xebec.h" - - -#define XEBEC_TIME (2000 * TIMER_USEC) - -enum -{ - STATE_IDLE, - STATE_RECEIVE_COMMAND, - STATE_START_COMMAND, - STATE_RECEIVE_DATA, - STATE_RECEIVED_DATA, - STATE_SEND_DATA, - STATE_SENT_DATA, - STATE_COMPLETION_BYTE, - STATE_DUNNO -}; - -typedef struct mfm_drive_t -{ - int spt, hpc; - int tracks; - int cfg_spt; - int cfg_hpc; - int cfg_cyl; - int current_cylinder; - int present; - int hdc_num; -} mfm_drive_t; - -typedef struct xebec_t -{ - rom_t bios_rom; - - int callback; - - int state; - - uint8_t status; - - uint8_t command[6]; - int command_pos; - - uint8_t data[512]; - int data_pos, data_len; - - uint8_t sector_buf[512]; - - uint8_t irq_dma_mask; - - uint8_t completion_byte; - uint8_t error; - - int drive_sel; - - mfm_drive_t drives[2]; - - int sector, head, cylinder; - int sector_count; - - uint8_t switches; -} xebec_t; - -#define STAT_IRQ 0x20 -#define STAT_DRQ 0x10 -#define STAT_BSY 0x08 -#define STAT_CD 0x04 -#define STAT_IO 0x02 -#define STAT_REQ 0x01 - -#define IRQ_ENA 0x02 -#define DMA_ENA 0x01 - -#define CMD_TEST_DRIVE_READY 0x00 -#define CMD_RECALIBRATE 0x01 -#define CMD_READ_STATUS 0x03 -#define CMD_VERIFY_SECTORS 0x05 -#define CMD_FORMAT_TRACK 0x06 -#define CMD_READ_SECTORS 0x08 -#define CMD_WRITE_SECTORS 0x0a -#define CMD_SEEK 0x0b -#define CMD_INIT_DRIVE_PARAMS 0x0c -#define CMD_WRITE_SECTOR_BUFFER 0x0f -#define CMD_BUFFER_DIAGNOSTIC 0xe0 -#define CMD_CONTROLLER_DIAGNOSTIC 0xe4 -#define CMD_DTC_GET_DRIVE_PARAMS 0xfb -#define CMD_DTC_SET_STEP_RATE 0xfc -#define CMD_DTC_SET_GEOMETRY 0xfe -#define CMD_DTC_GET_GEOMETRY 0xff - -#define ERR_NOT_READY 0x04 -#define ERR_SEEK_ERROR 0x15 -#define ERR_ILLEGAL_SECTOR_ADDRESS 0x21 - -static uint8_t xebec_read(uint16_t port, void *p) -{ - xebec_t *xebec = (xebec_t *)p; - uint8_t temp = 0xff; - - switch (port) - { - case 0x320: /*Read data*/ - xebec->status &= ~STAT_IRQ; - switch (xebec->state) - { - case STATE_COMPLETION_BYTE: - if ((xebec->status & 0xf) != (STAT_CD | STAT_IO | STAT_REQ | STAT_BSY)) - fatal("Read data STATE_COMPLETION_BYTE, status=%02x\n", xebec->status); - - temp = xebec->completion_byte; - xebec->status = 0; - xebec->state = STATE_IDLE; - break; - - case STATE_SEND_DATA: - if ((xebec->status & 0xf) != (STAT_IO | STAT_REQ | STAT_BSY)) - fatal("Read data STATE_COMPLETION_BYTE, status=%02x\n", xebec->status); - if (xebec->data_pos >= xebec->data_len) - fatal("Data write with full data!\n"); - temp = xebec->data[xebec->data_pos++]; - if (xebec->data_pos == xebec->data_len) - { - xebec->status = STAT_BSY; - xebec->state = STATE_SENT_DATA; - xebec->callback = XEBEC_TIME; - } - break; - - default: - fatal("Read data register - %i, %02x\n", xebec->state, xebec->status); - } - break; - - case 0x321: /*Read status*/ - temp = xebec->status; - break; - - case 0x322: /*Read option jumpers*/ - temp = xebec->switches; - break; - } - - return temp; -} - -static void xebec_write(uint16_t port, uint8_t val, void *p) -{ - xebec_t *xebec = (xebec_t *)p; - - switch (port) - { - case 0x320: /*Write data*/ - switch (xebec->state) - { - case STATE_RECEIVE_COMMAND: - if ((xebec->status & 0xf) != (STAT_BSY | STAT_CD | STAT_REQ)) - fatal("Bad write data state - STATE_START_COMMAND, status=%02x\n", xebec->status); - if (xebec->command_pos >= 6) - fatal("Command write with full command!\n"); - /*Command data*/ - xebec->command[xebec->command_pos++] = val; - if (xebec->command_pos == 6) - { - xebec->status = STAT_BSY; - xebec->state = STATE_START_COMMAND; - xebec->callback = XEBEC_TIME; - } - break; - - case STATE_RECEIVE_DATA: - if ((xebec->status & 0xf) != (STAT_BSY | STAT_REQ)) - fatal("Bad write data state - STATE_RECEIVE_DATA, status=%02x\n", xebec->status); - if (xebec->data_pos >= xebec->data_len) - fatal("Data write with full data!\n"); - /*Command data*/ - xebec->data[xebec->data_pos++] = val; - if (xebec->data_pos == xebec->data_len) - { - xebec->status = STAT_BSY; - xebec->state = STATE_RECEIVED_DATA; - xebec->callback = XEBEC_TIME; - } - break; - - default: - fatal("Write data unknown state - %i %02x\n", xebec->state, xebec->status); - } - break; - - case 0x321: /*Controller reset*/ - xebec->status = 0; - break; - - case 0x322: /*Generate controller-select-pulse*/ - xebec->status = STAT_BSY | STAT_CD | STAT_REQ; - xebec->command_pos = 0; - xebec->state = STATE_RECEIVE_COMMAND; - break; - - case 0x323: /*DMA/IRQ mask register*/ - xebec->irq_dma_mask = val; - break; - } -} - -static void xebec_complete(xebec_t *xebec) -{ - xebec->status = STAT_REQ | STAT_CD | STAT_IO | STAT_BSY; - xebec->state = STATE_COMPLETION_BYTE; - if (xebec->irq_dma_mask & IRQ_ENA) - { - xebec->status |= STAT_IRQ; - picint(1 << 5); - } -} - -static void xebec_error(xebec_t *xebec, uint8_t error) -{ - xebec->completion_byte |= 0x02; - xebec->error = error; - pclog("xebec_error - %02x\n", xebec->error); -} - -static int xebec_get_sector(xebec_t *xebec, off64_t *addr) -{ - mfm_drive_t *drive = &xebec->drives[xebec->drive_sel]; - int heads = drive->cfg_hpc; - - if (drive->current_cylinder != xebec->cylinder) - { - pclog("mfm_get_sector: wrong cylinder\n"); - xebec->error = ERR_ILLEGAL_SECTOR_ADDRESS; - return 1; - } - if (xebec->head > heads) - { - pclog("mfm_get_sector: past end of configured heads\n"); - xebec->error = ERR_ILLEGAL_SECTOR_ADDRESS; - return 1; - } - if (xebec->head > drive->hpc) - { - pclog("mfm_get_sector: past end of heads\n"); - xebec->error = ERR_ILLEGAL_SECTOR_ADDRESS; - return 1; - } - if (xebec->sector >= 17) - { - pclog("mfm_get_sector: past end of sectors\n"); - xebec->error = ERR_ILLEGAL_SECTOR_ADDRESS; - return 1; - } - - *addr = ((((off64_t) xebec->cylinder * heads) + xebec->head) * - 17) + xebec->sector; - - return 0; -} - -static void xebec_next_sector(xebec_t *xebec) -{ - mfm_drive_t *drive = &xebec->drives[xebec->drive_sel]; - - xebec->sector++; - if (xebec->sector >= 17) - { - xebec->sector = 0; - xebec->head++; - if (xebec->head >= drive->cfg_hpc) - { - xebec->head = 0; - xebec->cylinder++; - drive->current_cylinder++; - if (drive->current_cylinder >= drive->cfg_cyl) - drive->current_cylinder = drive->cfg_cyl-1; - } - } -} - -static void xebec_callback(void *p) -{ - off64_t addr; - - xebec_t *xebec = (xebec_t *)p; - mfm_drive_t *drive; - - xebec->callback = 0; - - xebec->drive_sel = (xebec->command[1] & 0x20) ? 1 : 0; - xebec->completion_byte = xebec->drive_sel & 0x20; - - drive = &xebec->drives[xebec->drive_sel]; - - switch (xebec->command[0]) - { - case CMD_TEST_DRIVE_READY: - if (!drive->present) - xebec_error(xebec, ERR_NOT_READY); - xebec_complete(xebec); - break; - - case CMD_RECALIBRATE: - if (!drive->present) - xebec_error(xebec, ERR_NOT_READY); - else - { - xebec->cylinder = 0; - drive->current_cylinder = 0; - } - xebec_complete(xebec); - break; - - case CMD_READ_STATUS: - switch (xebec->state) - { - case STATE_START_COMMAND: - xebec->state = STATE_SEND_DATA; - xebec->data_pos = 0; - xebec->data_len = 4; - xebec->status = STAT_BSY | STAT_IO | STAT_REQ; - xebec->data[0] = xebec->error; - xebec->data[1] = xebec->drive_sel ? 0x20 : 0; - xebec->data[2] = xebec->data[3] = 0; - xebec->error = 0; - break; - - case STATE_SENT_DATA: - xebec_complete(xebec); - break; - } - break; - - case CMD_VERIFY_SECTORS: - switch (xebec->state) - { - case STATE_START_COMMAND: - xebec->cylinder = xebec->command[3] | ((xebec->command[2] & 0xc0) << 2); - drive->current_cylinder = (xebec->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl-1 : xebec->cylinder; - xebec->head = xebec->command[1] & 0x1f; - xebec->sector = xebec->command[2] & 0x1f; - xebec->sector_count = xebec->command[4]; - do - { - if (xebec_get_sector(xebec, &addr)) - { - pclog("xebec_get_sector failed\n"); - xebec_error(xebec, xebec->error); - xebec_complete(xebec); - return; - } - - xebec_next_sector(xebec); - - xebec->sector_count = (xebec->sector_count-1) & 0xff; - } while (xebec->sector_count); - - xebec_complete(xebec); - - update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); - break; - - default: - fatal("CMD_VERIFY_SECTORS: bad state %i\n", xebec->state); - } - break; - - case CMD_FORMAT_TRACK: - { - xebec->cylinder = xebec->command[3] | ((xebec->command[2] & 0xc0) << 2); - drive->current_cylinder = (xebec->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl-1 : xebec->cylinder; - xebec->head = xebec->command[1] & 0x1f; - - if (xebec_get_sector(xebec, &addr)) - { - pclog("xebec_get_sector failed\n"); - xebec_error(xebec, xebec->error); - xebec_complete(xebec); - return; - } - - hdd_image_zero(drive->hdc_num, addr, 17); - - xebec_complete(xebec); - } - break; - - case CMD_READ_SECTORS: - switch (xebec->state) - { - case STATE_START_COMMAND: - xebec->cylinder = xebec->command[3] | ((xebec->command[2] & 0xc0) << 2); - drive->current_cylinder = (xebec->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl-1 : xebec->cylinder; - xebec->head = xebec->command[1] & 0x1f; - xebec->sector = xebec->command[2] & 0x1f; - xebec->sector_count = xebec->command[4]; - xebec->state = STATE_SEND_DATA; - xebec->data_pos = 0; - xebec->data_len = 512; - { - if (xebec_get_sector(xebec, &addr)) - { - xebec_error(xebec, xebec->error); - xebec_complete(xebec); - return; - } - - hdd_image_read(drive->hdc_num, addr, 1, (uint8_t *) xebec->sector_buf); - update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); - } - if (xebec->irq_dma_mask & DMA_ENA) - xebec->callback = XEBEC_TIME; - else - { - xebec->status = STAT_BSY | STAT_IO | STAT_REQ; - memcpy(xebec->data, xebec->sector_buf, 512); - } - break; - - case STATE_SEND_DATA: - xebec->status = STAT_BSY; - if (xebec->irq_dma_mask & DMA_ENA) - { - for (; xebec->data_pos < 512; xebec->data_pos++) - { - int val = dma_channel_write(3, xebec->sector_buf[xebec->data_pos]); - - if (val == DMA_NODATA) - { - pclog("CMD_READ_SECTORS out of data!\n"); - xebec->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ; - xebec->callback = XEBEC_TIME; - return; - } - } - xebec->state = STATE_SENT_DATA; - xebec->callback = XEBEC_TIME; - } - else - fatal("Read sectors no DMA! - shouldn't get here\n"); - break; - - case STATE_SENT_DATA: - xebec_next_sector(xebec); - - xebec->data_pos = 0; - - xebec->sector_count = (xebec->sector_count-1) & 0xff; - - if (xebec->sector_count) - { - if (xebec_get_sector(xebec, &addr)) - { - xebec_error(xebec, xebec->error); - xebec_complete(xebec); - return; - } - - hdd_image_read(drive->hdc_num, addr, 1, (uint8_t *) xebec->sector_buf); - update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); - - xebec->state = STATE_SEND_DATA; - - if (xebec->irq_dma_mask & DMA_ENA) - xebec->callback = XEBEC_TIME; - else - { - xebec->status = STAT_BSY | STAT_IO | STAT_REQ; - memcpy(xebec->data, xebec->sector_buf, 512); - } - } - else - { - xebec_complete(xebec); - update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 0); - } - break; - - - default: - fatal("CMD_READ_SECTORS: bad state %i\n", xebec->state); - } - break; - - case CMD_WRITE_SECTORS: - switch (xebec->state) - { - case STATE_START_COMMAND: - xebec->cylinder = xebec->command[3] | ((xebec->command[2] & 0xc0) << 2); - drive->current_cylinder = (xebec->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl-1 : xebec->cylinder; - xebec->head = xebec->command[1] & 0x1f; - xebec->sector = xebec->command[2] & 0x1f; - xebec->sector_count = xebec->command[4]; - xebec->state = STATE_RECEIVE_DATA; - xebec->data_pos = 0; - xebec->data_len = 512; - if (xebec->irq_dma_mask & DMA_ENA) - xebec->callback = XEBEC_TIME; - else - xebec->status = STAT_BSY | STAT_REQ; - break; - - case STATE_RECEIVE_DATA: - xebec->status = STAT_BSY; - if (xebec->irq_dma_mask & DMA_ENA) - { - for (; xebec->data_pos < 512; xebec->data_pos++) - { - int val = dma_channel_read(3); - - if (val == DMA_NODATA) - { - pclog("CMD_WRITE_SECTORS out of data!\n"); - xebec->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ; - xebec->callback = XEBEC_TIME; - return; - } - - xebec->sector_buf[xebec->data_pos] = val & 0xff; - } - - xebec->state = STATE_RECEIVED_DATA; - xebec->callback = XEBEC_TIME; - } - else - fatal("Write sectors no DMA! - should never get here\n"); - break; - - case STATE_RECEIVED_DATA: - if (!(xebec->irq_dma_mask & DMA_ENA)) - memcpy(xebec->sector_buf, xebec->data, 512); - - { - if (xebec_get_sector(xebec, &addr)) - { - xebec_error(xebec, xebec->error); - xebec_complete(xebec); - return; - } - - hdd_image_write(drive->hdc_num, addr, 1, (uint8_t *) xebec->sector_buf); - } - - update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); - - xebec_next_sector(xebec); - xebec->data_pos = 0; - xebec->sector_count = (xebec->sector_count-1) & 0xff; - - if (xebec->sector_count) - { - xebec->state = STATE_RECEIVE_DATA; - if (xebec->irq_dma_mask & DMA_ENA) - xebec->callback = XEBEC_TIME; - else - xebec->status = STAT_BSY | STAT_REQ; - } - else - xebec_complete(xebec); - break; - - default: - fatal("CMD_WRITE_SECTORS: bad state %i\n", xebec->state); - } - break; - - case CMD_SEEK: - if (!drive->present) - xebec_error(xebec, ERR_NOT_READY); - else - { - int cylinder = xebec->command[3] | ((xebec->command[2] & 0xc0) << 2); - - drive->current_cylinder = (cylinder >= drive->cfg_cyl) ? drive->cfg_cyl-1 : cylinder; - - if (cylinder != drive->current_cylinder) - xebec_error(xebec, ERR_SEEK_ERROR); - } - xebec_complete(xebec); - break; - - case CMD_INIT_DRIVE_PARAMS: - switch (xebec->state) - { - case STATE_START_COMMAND: - xebec->state = STATE_RECEIVE_DATA; - xebec->data_pos = 0; - xebec->data_len = 8; - xebec->status = STAT_BSY | STAT_REQ; - break; - - case STATE_RECEIVED_DATA: - drive->cfg_cyl = xebec->data[1] | (xebec->data[0] << 8); - drive->cfg_hpc = xebec->data[2]; - pclog("Drive %i: cylinders=%i, heads=%i\n", xebec->drive_sel, drive->cfg_cyl, drive->cfg_hpc); - xebec_complete(xebec); - break; - - default: - fatal("CMD_INIT_DRIVE_PARAMS bad state %i\n", xebec->state); - } - break; - - case CMD_WRITE_SECTOR_BUFFER: - switch (xebec->state) - { - case STATE_START_COMMAND: - xebec->state = STATE_RECEIVE_DATA; - xebec->data_pos = 0; - xebec->data_len = 512; - if (xebec->irq_dma_mask & DMA_ENA) - xebec->callback = XEBEC_TIME; - else - xebec->status = STAT_BSY | STAT_REQ; - break; - - case STATE_RECEIVE_DATA: - if (xebec->irq_dma_mask & DMA_ENA) - { - xebec->status = STAT_BSY; - - for (; xebec->data_pos < 512; xebec->data_pos++) - { - int val = dma_channel_read(3); - - if (val == DMA_NODATA) - { - pclog("CMD_WRITE_SECTOR_BUFFER out of data!\n"); - xebec->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ; - xebec->callback = XEBEC_TIME; - return; - } - - xebec->data[xebec->data_pos] = val & 0xff; - } - - xebec->state = STATE_RECEIVED_DATA; - xebec->callback = XEBEC_TIME; - } - else - fatal("CMD_WRITE_SECTOR_BUFFER - should never get here!\n"); - break; - case STATE_RECEIVED_DATA: - memcpy(xebec->sector_buf, xebec->data, 512); - xebec_complete(xebec); - break; - - default: - fatal("CMD_WRITE_SECTOR_BUFFER bad state %i\n", xebec->state); - } - break; - - case CMD_BUFFER_DIAGNOSTIC: - case CMD_CONTROLLER_DIAGNOSTIC: - xebec_complete(xebec); - break; - - case 0xfa: - xebec_complete(xebec); - break; - - case CMD_DTC_SET_STEP_RATE: - xebec_complete(xebec); - break; - - case CMD_DTC_GET_DRIVE_PARAMS: - switch (xebec->state) - { - case STATE_START_COMMAND: - xebec->state = STATE_SEND_DATA; - xebec->data_pos = 0; - xebec->data_len = 4; - xebec->status = STAT_BSY | STAT_IO | STAT_REQ; - memset(xebec->data, 0, 4); - xebec->data[0] = drive->tracks & 0xff; - xebec->data[1] = 17 | ((drive->tracks >> 2) & 0xc0); - xebec->data[2] = drive->hpc-1; - pclog("Get drive params %02x %02x %02x %i\n", xebec->data[0], xebec->data[1], xebec->data[2], drive->tracks); - break; - - case STATE_SENT_DATA: - xebec_complete(xebec); - break; - - default: - fatal("CMD_INIT_DRIVE_PARAMS bad state %i\n", xebec->state); - } - break; - - case CMD_DTC_GET_GEOMETRY: - switch (xebec->state) - { - case STATE_START_COMMAND: - xebec->state = STATE_SEND_DATA; - xebec->data_pos = 0; - xebec->data_len = 16; - xebec->status = STAT_BSY | STAT_IO | STAT_REQ; - memset(xebec->data, 0, 16); - xebec->data[0x4] = drive->tracks & 0xff; - xebec->data[0x5] = (drive->tracks >> 8) & 0xff; - xebec->data[0xa] = drive->hpc; - break; - - case STATE_SENT_DATA: - xebec_complete(xebec); - break; - } - break; - - case CMD_DTC_SET_GEOMETRY: - switch (xebec->state) - { - case STATE_START_COMMAND: - xebec->state = STATE_RECEIVE_DATA; - xebec->data_pos = 0; - xebec->data_len = 16; - xebec->status = STAT_BSY | STAT_REQ; - break; - - case STATE_RECEIVED_DATA: - /*Bit of a cheat here - we always report the actual geometry of the drive in use*/ - xebec_complete(xebec); - break; - } - break; - - default: - fatal("Unknown Xebec command - %02x %02x %02x %02x %02x %02x\n", - xebec->command[0], xebec->command[1], - xebec->command[2], xebec->command[3], - xebec->command[4], xebec->command[5]); - } -} - -static void loadhd(xebec_t *xebec, int c, int d, const wchar_t *fn) -{ - mfm_drive_t *drive = &xebec->drives[d]; - int ret = 0; - - ret = hdd_image_load(d); - - if (!ret) - { - drive->present = 0; - return; - } - - drive->spt = hdc[c].spt; - drive->hpc = hdc[c].hpc; - drive->tracks = hdc[c].tracks; - drive->hdc_num = c; - drive->present = 1; -} - -static struct -{ - int tracks, hpc; -} xebec_hd_types[4] = -{ - {306, 4}, /*Type 0*/ - {612, 4}, /*Type 16*/ - {615, 4}, /*Type 2*/ - {306, 8} /*Type 13*/ -}; - -static void xebec_set_switches(xebec_t *xebec) -{ - int c, d; - - xebec->switches = 0; - - for (d = 0; d < 2; d++) - { - mfm_drive_t *drive = &xebec->drives[d]; - - if (!drive->present) - continue; - - for (c = 0; c < 4; c++) - { - if (drive->spt == 17 && - drive->hpc == xebec_hd_types[c].hpc && - drive->tracks == xebec_hd_types[c].tracks) - { - xebec->switches |= (c << (d ? 0 : 2)); - break; - } - } - - if (c == 4) - pclog("WARNING: Drive %c: has format not supported by Fixed Disk Adapter", d ? 'D' : 'C'); - } -} - -static void *xebec_init() -{ - int i = 0; - int c = 0; - - xebec_t *xebec = malloc(sizeof(xebec_t)); - memset(xebec, 0, sizeof(xebec_t)); - - for (i = 0; i < HDC_NUM; i++) - { - if ((hdc[i].bus == HDD_BUS_MFM) && (hdc[i].mfm_channel < MFM_NUM)) - { - loadhd(xebec, i, hdc[i].mfm_channel, hdc[i].fn); - c++; - if (c > MFM_NUM) break; - } - } - - xebec_set_switches(xebec); - - rom_init(&xebec->bios_rom, L"roms/hdd/mfm_xebec/ibm_xebec_62x0822_1985.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - io_sethandler(0x0320, 0x0004, xebec_read, NULL, NULL, xebec_write, NULL, NULL, xebec); - - timer_add(xebec_callback, &xebec->callback, &xebec->callback, xebec); - - return xebec; -} - -static void xebec_close(void *p) -{ - xebec_t *xebec = (xebec_t *)p; - int d; - - for (d = 0; d < 2; d++) - { - mfm_drive_t *drive = &xebec->drives[d]; - - hdd_image_close(drive->hdc_num); - } - - free(xebec); -} - -static int xebec_available() -{ - return rom_present(L"roms/hdd/mfm_xebec/ibm_xebec_62x0822_1985.bin"); -} - -device_t mfm_xebec_device = -{ - "IBM PC Fixed Disk Adapter", - 0, - xebec_init, - xebec_close, - xebec_available, - NULL, - NULL, - NULL, - NULL -}; - -static void *dtc_5150x_init() -{ - int i = 0; - int c = 0; - - xebec_t *xebec = malloc(sizeof(xebec_t)); - memset(xebec, 0, sizeof(xebec_t)); - - for (i = 0; i < HDC_NUM; i++) - { - if ((hdc[i].bus == HDD_BUS_MFM) && (hdc[i].mfm_channel < MFM_NUM)) - { - loadhd(xebec, i, hdc[i].mfm_channel, hdc[i].fn); - c++; - if (c > MFM_NUM) break; - } - } - - xebec->switches = 0xff; - - xebec->drives[0].cfg_cyl = xebec->drives[0].tracks; - xebec->drives[0].cfg_hpc = xebec->drives[0].hpc; - xebec->drives[1].cfg_cyl = xebec->drives[1].tracks; - xebec->drives[1].cfg_hpc = xebec->drives[1].hpc; - - rom_init(&xebec->bios_rom, L"roms/hdd/mfm_xebec/dtc_cxd21a.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - io_sethandler(0x0320, 0x0004, xebec_read, NULL, NULL, xebec_write, NULL, NULL, xebec); - - timer_add(xebec_callback, &xebec->callback, &xebec->callback, xebec); - - return xebec; -} -static int dtc_5150x_available() -{ - return rom_present(L"roms/hdd/mfm_xebec/dtc_cxd21a.bin"); -} - -device_t dtc_5150x_device = -{ - "DTC 5150X", - 0, - dtc_5150x_init, - xebec_close, - dtc_5150x_available, - NULL, - NULL, - NULL, - NULL -}; diff --git a/src/hdd/hdd_mfm_xebec.h b/src/hdd/hdd_mfm_xebec.h deleted file mode 100644 index e6bafff17..000000000 --- a/src/hdd/hdd_mfm_xebec.h +++ /dev/null @@ -1,2 +0,0 @@ -extern device_t mfm_xebec_device; -extern device_t dtc_5150x_device; diff --git a/src/hdd/hdd_table.c b/src/hdd/hdd_table.c new file mode 100644 index 000000000..8a5bf9cd5 --- /dev/null +++ b/src/hdd/hdd_table.c @@ -0,0 +1,178 @@ +/* + * 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. + * + * Implementation of the IDE emulation for hard disks and ATAPI + * CD-ROM devices. + * + * Version: @(#)hdd_table.c 1.0.2 2017/09/29 + * + * Authors: Sarah Walker, + * Miran Grca, + * TheCollector1995, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016,2017 Miran Grca. + */ +#include +#include +#include +#include +#include +#include "../86box.h" +#include "../ibm.h" +#include "../io.h" +#include "../pic.h" +#include "../pci.h" +#include "../timer.h" +#include "hdd.h" + + +uint64_t hdd_table[128][3] = { + { 306, 4, 17 }, /* 0 - 7 */ + { 615, 2, 17 }, + { 306, 4, 26 }, + { 1024, 2, 17 }, + { 697, 3, 17 }, + { 306, 8, 17 }, + { 614, 4, 17 }, + { 615, 4, 17 }, + + { 670, 4, 17 }, /* 8 - 15 */ + { 697, 4, 17 }, + { 987, 3, 17 }, + { 820, 4, 17 }, + { 670, 5, 17 }, + { 697, 5, 17 }, + { 733, 5, 17 }, + { 615, 6, 17 }, + + { 462, 8, 17 }, /* 016-023 */ + { 306, 8, 26 }, + { 615, 4, 26 }, + { 1024, 4, 17 }, + { 855, 5, 17 }, + { 925, 5, 17 }, + { 932, 5, 17 }, + { 1024, 2, 40 }, + + { 809, 6, 17 }, /* 024-031 */ + { 976, 5, 17 }, + { 977, 5, 17 }, + { 698, 7, 17 }, + { 699, 7, 17 }, + { 981, 5, 17 }, + { 615, 8, 17 }, + { 989, 5, 17 }, + + { 820, 4, 26 }, /* 032-039 */ + { 1024, 5, 17 }, + { 733, 7, 17 }, + { 754, 7, 17 }, + { 733, 5, 26 }, + { 940, 6, 17 }, + { 615, 6, 26 }, + { 462, 8, 26 }, + + { 830, 7, 17 }, /* 040-047 */ + { 855, 7, 17 }, + { 751, 8, 17 }, + { 1024, 4, 26 }, + { 918, 7, 17 }, + { 925, 7, 17 }, + { 855, 5, 26 }, + { 977, 7, 17 }, + + { 987, 7, 17 }, /* 048-055 */ + { 1024, 7, 17 }, + { 823, 4, 38 }, + { 925, 8, 17 }, + { 809, 6, 26 }, + { 976, 5, 26 }, + { 977, 5, 26 }, + { 698, 7, 26 }, + + { 699, 7, 26 }, /* 056-063 */ + { 940, 8, 17 }, + { 615, 8, 26 }, + { 1024, 5, 26 }, + { 733, 7, 26 }, + { 1024, 8, 17 }, + { 823, 10, 17 }, + { 754, 11, 17 }, + + { 830, 10, 17 }, /* 064-071 */ + { 925, 9, 17 }, + { 1224, 7, 17 }, + { 940, 6, 26 }, + { 855, 7, 26 }, + { 751, 8, 26 }, + { 1024, 9, 17 }, + { 965, 10, 17 }, + + { 969, 5, 34 }, /* 072-079 */ + { 980, 10, 17 }, + { 960, 5, 35 }, + { 918, 11, 17 }, + { 1024, 10, 17 }, + { 977, 7, 26 }, + { 1024, 7, 26 }, + { 1024, 11, 17 }, + + { 940, 8, 26 }, /* 080-087 */ + { 776, 8, 33 }, + { 755, 16, 17 }, + { 1024, 12, 17 }, + { 1024, 8, 26 }, + { 823, 10, 26 }, + { 830, 10, 26 }, + { 925, 9, 26 }, + + { 960, 9, 26 }, /* 088-095 */ + { 1024, 13, 17 }, + { 1224, 11, 17 }, + { 900, 15, 17 }, + { 969, 7, 34 }, + { 917, 15, 17 }, + { 918, 15, 17 }, + { 1524, 4, 39 }, + + { 1024, 9, 26 }, /* 096-103 */ + { 1024, 14, 17 }, + { 965, 10, 26 }, + { 980, 10, 26 }, + { 1020, 15, 17 }, + { 1023, 15, 17 }, + { 1024, 15, 17 }, + { 1024, 16, 17 }, + + { 1224, 15, 17 }, /* 104-111 */ + { 755, 16, 26 }, + { 903, 8, 46 }, + { 984, 10, 34 }, + { 900, 15, 26 }, + { 917, 15, 26 }, + { 1023, 15, 26 }, + { 684, 16, 38 }, + + { 1930, 4, 62 }, /* 112-119 */ + { 967, 16, 31 }, + { 1013, 10, 63 }, + { 1218, 15, 36 }, + { 654, 16, 63 }, + { 659, 16, 63 }, + { 702, 16, 63 }, + { 1002, 13, 63 }, + + { 854, 16, 63 }, /* 119-127 */ + { 987, 16, 63 }, + { 995, 16, 63 }, + { 1024, 16, 63 }, + { 1036, 16, 63 }, + { 1120, 16, 59 }, + { 1054, 16, 63 }, + { 0, 0, 0 } +}; diff --git a/src/ibm.h b/src/ibm.h index a052f3a1e..d8831cc89 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -8,7 +8,9 @@ * * General include file. * - * Version: @(#)ibm.h 1.0.5 2017/09/24 + * !!!NOTE!!! The goal is to GET RID of this file. Do NOT add stuff !! + * + * Version: @(#)ibm.h 1.0.6 2017/09/29 * * Authors: Sarah Walker, * Miran Grca, @@ -481,57 +483,6 @@ extern wchar_t cfg_path[1024]; extern wchar_t nvr_path[1024]; -/*Hard disk*/ -enum -{ - HDD_BUS_DISABLED = 0, - HDD_BUS_MFM, - HDD_BUS_XTIDE, - HDD_BUS_ESDI, - HDD_BUS_IDE_PIO_ONLY, - HDD_BUS_IDE_PIO_AND_DMA, - HDD_BUS_SCSI, - HDD_BUS_SCSI_REMOVABLE, - HDD_BUS_USB -}; - -#define HDC_NUM 30 -#define MFM_NUM 2 -#define ESDI_NUM 2 -#define XTIDE_NUM 2 -#define IDE_NUM 8 -#define SCSI_NUM 16 /* Theoretically the controller can have at least 64 devices, or even 128 in case of a wide bus, but - let's not exaggerate with them - 16 ought to be enough for everyone. */ - -#pragma pack(push,1) -typedef struct { - FILE *f; - uint64_t spt,hpc; /*Sectors per track, heads per cylinder*/ - uint64_t tracks; - int is_hdi; - int wp; - uint32_t base; - uint64_t at_spt,at_hpc; /*[Translation] Sectors per track, heads per cylinder*/ - unsigned int bus; - unsigned int mfm_channel; - unsigned int esdi_channel; - unsigned int xtide_channel; - unsigned int ide_channel; - unsigned int scsi_id; - unsigned int scsi_lun; - wchar_t fn[260]; - wchar_t prev_fn[260]; -} hard_disk_t; -#pragma pack(pop) - -extern hard_disk_t hdc[HDC_NUM]; - -uint64_t hdt[128][3]; -uint64_t hdt_mfm[128][3]; - -int image_is_hdi(const wchar_t *s); -int image_is_hdx(const wchar_t *s, int check_signature); - /*Keyboard*/ extern int keybsenddelay; diff --git a/src/machine/machine_at.c b/src/machine/machine_at.c index 86d6ae051..611ed3802 100644 --- a/src/machine/machine_at.c +++ b/src/machine/machine_at.c @@ -13,7 +13,8 @@ #include "../gameport.h" #include "../keyboard_at.h" #include "../lpt.h" -#include "../hdd/hdd_ide_at.h" +#include "../hdd/hdd.h" +#include "../hdd/hdc_ide.h" #include "machine_common.h" #include "machine_at.h" diff --git a/src/machine/machine_at_ali1429.c b/src/machine/machine_at_ali1429.c index 2a5328b7f..2892c17dd 100644 --- a/src/machine/machine_at_ali1429.c +++ b/src/machine/machine_at_ali1429.c @@ -9,7 +9,8 @@ #include "../cpu/cpu.h" #include "../io.h" #include "../mem.h" -#include "../hdd/hdd_ide_at.h" +#include "../hdd/hdd.h" +#include "../hdd/hdc_ide.h" #include "machine_at.h" #include "machine_at_ali1429.h" diff --git a/src/machine/machine_at_sis_85c471.c b/src/machine/machine_at_sis_85c471.c index cde72f6d6..51efb03a1 100644 --- a/src/machine/machine_at_sis_85c471.c +++ b/src/machine/machine_at_sis_85c471.c @@ -9,7 +9,7 @@ * SiS sis85c471 Super I/O Chip * Used by DTK PKM-0038S E-2 * - * Version: @(#)sis85c471.c 1.0.5 2017/09/24 + * Version: @(#)sis85c471.c 1.0.6 2017/09/29 * * Author: Miran Grca, * Copyright 2017 Miran Grca. @@ -26,7 +26,8 @@ #include "../floppy/floppy.h" #include "../floppy/fdc.h" #include "../floppy/fdd.h" -#include "../hdd/hdd_ide_at.h" +#include "../hdd/hdd.h" +#include "../hdd/hdc_ide.h" #include "machine_at.h" #include "machine_at_sis_85c471.h" diff --git a/src/machine/machine_ps1.c b/src/machine/machine_ps1.c index f0f95f98f..b63354c22 100644 --- a/src/machine/machine_ps1.c +++ b/src/machine/machine_ps1.c @@ -22,7 +22,8 @@ #include "../floppy/floppy.h" #include "../floppy/fdd.h" #include "../floppy/fdc.h" -#include "../hdd/hdd_ide_at.h" +#include "../hdd/hdd.h" +#include "../hdd/hdc_ide.h" #include "../sound/snd_ps1.h" #include "machine_common.h" #include "machine_ps1.h" diff --git a/src/pc.c b/src/pc.c index 6712527bf..8f949b000 100644 --- a/src/pc.c +++ b/src/pc.c @@ -8,7 +8,7 @@ * * Emulation core dispatcher. * - * Version: @(#)pc.c 1.0.12 2017/09/24 + * Version: @(#)pc.c 1.0.13 2017/09/29 * * Authors: Sarah Walker, * Miran Grca, @@ -45,7 +45,8 @@ #include "cdrom/cdrom_ioctl.h" #include "cdrom/cdrom_null.h" #include "hdd/hdd.h" -#include "hdd/hdd_ide_at.h" +#include "hdd/hdc.h" +#include "hdd/hdc_ide.h" #include "keyboard.h" #include "keyboard_at.h" #include "lpt.h" @@ -401,6 +402,7 @@ usage: append_filename_w(config_file_default, cfg_path, config_file, 511); + config_file = NULL; } else { append_filename_w(config_file_default, cfg_path, CONFIG_FILE_W, 511); } @@ -473,7 +475,9 @@ void initmodules(void) loadnvr(); sound_init(); +#if 0 resetide(); +#endif scsi_card_init(); fullspeed(); @@ -562,6 +566,7 @@ void resetpchard_init(void) fdc_init(); floppy_reset(); + hdc_init(hdc_name); #ifndef WALTJE serial_init(); #endif @@ -583,7 +588,9 @@ void resetpchard_init(void) ide_qua_init(); } +#if 0 resetide(); +#endif scsi_card_init(); #ifdef USE_NETWORK network_reset(); @@ -600,7 +607,6 @@ void resetpchard_init(void) device_add(&ssi2001_device); if (voodoo_enabled) device_add(&voodoo_device); - hdd_controller_init(hdd_controller_name); pc_reset(); mouse_emu_init(); diff --git a/src/pci.c b/src/pci.c index 174ff22f9..6bbccd225 100644 --- a/src/pci.c +++ b/src/pci.c @@ -11,7 +11,8 @@ #include "keyboard_at.h" #include "floppy/floppy.h" #include "floppy/fdc.h" -#include "hdd/hdd_ide_at.h" +#include "hdd/hdd.h" +#include "hdd/hdc_ide.h" #include "cdrom/cdrom.h" diff --git a/src/piix.c b/src/piix.c index 039ca5aae..c37d05a1b 100644 --- a/src/piix.c +++ b/src/piix.c @@ -12,7 +12,7 @@ * word 0 - base address * word 1 - bits 1 - 15 = byte count, bit 31 = end of transfer * - * Version: @(#)piix.c 1.0.3 2017/09/24 + * Version: @(#)piix.c 1.0.4 2017/09/29 * * Authors: Sarah Walker, * Miran Grca, @@ -29,7 +29,8 @@ #include "keyboard_at.h" #include "mem.h" #include "pci.h" -#include "hdd/hdd_ide_at.h" +#include "hdd/hdd.h" +#include "hdd/hdc_ide.h" #include "piix.h" diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index 2781ed45c..0bde9090b 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -8,7 +8,7 @@ * * Handling of the SCSI controllers. * - * Version: @(#)scsi.c 1.0.5 2017/09/24 + * Version: @(#)scsi.c 1.0.6 2017/09/29 * * Authors: TheCollector1995, * Miran Grca, @@ -26,6 +26,7 @@ #include "../timer.h" #include "../device.h" #include "../cdrom/cdrom.h" +#include "../hdd/hdd.h" #include "scsi.h" #include "scsi_aha154x.h" #include "scsi_buslogic.h" diff --git a/src/scsi/scsi_device.c b/src/scsi/scsi_device.c index dadcab4d5..d4eaef583 100644 --- a/src/scsi/scsi_device.c +++ b/src/scsi/scsi_device.c @@ -8,7 +8,7 @@ * * The generic SCSI device command handler. * - * Version: @(#)scsi_device.c 1.0.3 2017/09/24 + * Version: @(#)scsi_device.c 1.0.4 2017/09/29 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -21,6 +21,7 @@ #include #include "../ibm.h" #include "../cdrom/cdrom.h" +#include "../hdd/hdd.h" #include "scsi.h" #include "scsi_disk.h" @@ -174,7 +175,7 @@ void scsi_device_type_data(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *type, uin case SCSI_DISK: id = scsi_hard_disks[scsi_id][scsi_lun]; *type = 0x00; - *rmb = (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? 0x80 : 0x00; + *rmb = (hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) ? 0x80 : 0x00; break; case SCSI_CDROM: *type = 0x05; diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 4985e37f9..aa6add9f4 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -6,7 +6,7 @@ * * Emulation of SCSI fixed and removable disks. * - * Version: @(#)scsi_disk.c 1.0.8 2017/09/24 + * Version: @(#)scsi_disk.c 1.0.9 2017/09/29 * * Author: Miran Grca, * Copyright 2017 Miran Grca. @@ -22,8 +22,8 @@ #include "../timer.h" #include "../piix.h" #include "../cdrom/cdrom.h" -#include "../hdd/hdd_image.h" -#include "../hdd/hdd_ide_at.h" +#include "../hdd/hdd.h" +#include "../hdd/hdc_ide.h" #include "../win/plat_iodev.h" #include "scsi.h" #include "scsi_disk.h" @@ -49,8 +49,8 @@ #define scsi_hd_ascq shdc[id].sense[13] -scsi_hard_disk_t shdc[HDC_NUM]; -FILE *shdf[HDC_NUM]; +scsi_hard_disk_t shdc[HDD_NUM]; +FILE *shdf[HDD_NUM]; uint8_t scsi_hard_disks[16][8] = { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, @@ -190,21 +190,21 @@ int scsi_hd_phase_to_scsi(uint8_t id) } -int find_hdc_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun) +int find_hdd_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun) { uint8_t i = 0; - for (i = 0; i < HDC_NUM; i++) + for (i = 0; i < HDD_NUM; i++) { - if ((wcslen(hdc[i].fn) == 0) && (hdc[i].bus != HDD_BUS_SCSI_REMOVABLE)) + if ((wcslen(hdd[i].fn) == 0) && (hdd[i].bus != HDD_BUS_SCSI_REMOVABLE)) { continue; } - if (((hdc[i].spt == 0) || (hdc[i].hpc == 0) || (hdc[i].tracks == 0)) && (hdc[i].bus != HDD_BUS_SCSI_REMOVABLE)) + if (((hdd[i].spt == 0) || (hdd[i].hpc == 0) || (hdd[i].tracks == 0)) && (hdd[i].bus != HDD_BUS_SCSI_REMOVABLE)) { continue; } - if (((hdc[i].bus == HDD_BUS_SCSI) || (hdc[i].bus == HDD_BUS_SCSI_REMOVABLE)) && (hdc[i].scsi_id == scsi_id) && (hdc[i].scsi_lun == scsi_lun)) + if (((hdd[i].bus == HDD_BUS_SCSI) || (hdd[i].bus == HDD_BUS_SCSI_REMOVABLE)) && (hdd[i].scsi_id == scsi_id) && (hdd[i].scsi_lun == scsi_lun)) { return i; } @@ -215,19 +215,14 @@ int find_hdc_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun) void scsi_disk_insert(uint8_t id) { - shdc[id].unit_attention = (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? 1 : 0; + shdc[id].unit_attention = (hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) ? 1 : 0; } void scsi_loadhd(int scsi_id, int scsi_lun, int id) { - int ret = 0; - - ret = hdd_image_load(id); - - if (!ret) - { - if (hdc[id].bus != HDD_BUS_SCSI_REMOVABLE) + if (! hdd_image_load(id)) { + if (hdd[id].bus != HDD_BUS_SCSI_REMOVABLE) { scsi_hard_disks[scsi_id][scsi_lun] = 0xff; } @@ -243,14 +238,14 @@ void scsi_reloadhd(int id) { int ret = 0; - if(wcslen(hdc[id].prev_fn) == 0) + if (wcslen(hdd[id].prev_fn) == 0) { return; } else { - wcscpy(hdc[id].fn, hdc[id].prev_fn); - memset(hdc[id].prev_fn, 0, sizeof(hdc[id].prev_fn)); + wcscpy(hdd[id].fn, hdd[id].prev_fn); + memset(hdd[id].prev_fn, 0, sizeof(hdd[id].prev_fn)); } ret = hdd_image_load(id); @@ -282,11 +277,11 @@ void build_scsi_hd_map(void) { for (j = 0; j < 8; j++) { - scsi_hard_disks[i][j] = find_hdc_for_scsi_id(i, j); + scsi_hard_disks[i][j] = find_hdd_for_scsi_id(i, j); if (scsi_hard_disks[i][j] != 0xff) { memset(&(shdc[scsi_hard_disks[i][j]]), 0, sizeof(shdc[scsi_hard_disks[i][j]])); - if (wcslen(hdc[scsi_hard_disks[i][j]].fn) > 0) + if (wcslen(hdd[scsi_hard_disks[i][j]].fn) > 0) { scsi_loadhd(i, j, scsi_hard_disks[i][j]); } @@ -414,14 +409,14 @@ void scsi_hd_data_command_finish(uint8_t id, int len, int block_len, int alloc_l } if (len == 0) { - SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength = 0; + SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].InitLength = 0; scsi_hd_command_complete(id); } else { if (direction == 0) { - SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength = alloc_len; + SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].InitLength = alloc_len; scsi_hd_command_read_dma(id); } else @@ -548,7 +543,7 @@ int scsi_hd_pre_execution_check(uint8_t id, uint8_t *cdb) { int ready = 1; - if (((shdc[id].request_length >> 5) & 7) != hdc[id].scsi_lun) + if (((shdc[id].request_length >> 5) & 7) != hdd[id].scsi_lun) { scsi_hd_log("SCSI HD %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", id, ((shdc[id].request_length >> 5) & 7)); scsi_hd_invalid_lun(id); @@ -563,10 +558,10 @@ int scsi_hd_pre_execution_check(uint8_t id, uint8_t *cdb) return 0; } - if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) + if (hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) { /* Removable disk, set ready state. */ - if (wcslen(hdc[id].fn) > 0) + if (wcslen(hdd[id].fn) > 0) { ready = 1; } @@ -697,10 +692,10 @@ void scsi_hd_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_l { int ready = 1; - if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) + if (hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) { /* Removable disk, set ready state. */ - if (wcslen(hdc[id].fn) > 0) + if (wcslen(hdd[id].fn) > 0) { ready = 1; } @@ -732,7 +727,7 @@ void scsi_hd_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_l void scsi_hd_command(uint8_t id, uint8_t *cdb) { /* uint8_t *hdbufferb = (uint8_t *) shdc[id].buffer; */ - uint8_t *hdbufferb = SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].CmdBuffer; + uint8_t *hdbufferb = SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].CmdBuffer; uint32_t len; int pos=0; int max_len; @@ -764,7 +759,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) device_identify_ex[12] = EMU_VERSION[2]; device_identify_ex[13] = EMU_VERSION[3]; - if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) + if (hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) { device_identify[4] = 'R'; @@ -814,9 +809,9 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) case GPCMD_REQUEST_SENSE: /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE should forget about the not ready, and report unit attention straight away. */ - if (SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength < cdb[4]) + if (SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].InitLength < cdb[4]) { - cdb[4] = SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength; + cdb[4] = SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].InitLength; } scsi_hd_request_sense(id, hdbufferb, cdb[4]); scsi_hd_data_command_finish(id, 18, 18, cdb[4], 0); @@ -856,7 +851,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) return; } - if ((!shdc[id].sector_len) || (SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength == 0)) + if ((!shdc[id].sector_len) || (SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].InitLength == 0)) { /* scsi_hd_log("SCSI HD %i: All done - callback set\n", id); */ shdc[id].packet_status = CDROM_PHASE_COMPLETE; @@ -869,11 +864,11 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) alloc_length = shdc[id].packet_len = max_len << 9; - if ((shdc[id].requested_blocks > 0) && (SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength > 0)) + if ((shdc[id].requested_blocks > 0) && (SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].InitLength > 0)) { - if (alloc_length > SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength) + if (alloc_length > SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].InitLength) { - hdd_image_read(id, shdc[id].sector_pos, SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength >> 9, hdbufferb); + hdd_image_read(id, shdc[id].sector_pos, SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].InitLength >> 9, hdbufferb); } else { @@ -892,18 +887,18 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) shdc[id].all_blocks_total = shdc[id].block_total; if (shdc[id].packet_status != CDROM_PHASE_COMPLETE) { - update_status_bar_icon((hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 1); + update_status_bar_icon((hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 1); } else { - update_status_bar_icon((hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); + update_status_bar_icon((hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); } return; case GPCMD_WRITE_6: case GPCMD_WRITE_10: case GPCMD_WRITE_12: - if ((hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) && hdc[id].wp) + if ((hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) && hdd[id].wp) { scsi_hd_write_protected(id); return; @@ -932,7 +927,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) return; } - if ((!shdc[id].sector_len) || (SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength == 0)) + if ((!shdc[id].sector_len) || (SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].InitLength == 0)) { /* scsi_hd_log("SCSI HD %i: All done - callback set\n", id); */ shdc[id].packet_status = CDROM_PHASE_COMPLETE; @@ -945,11 +940,11 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) alloc_length = shdc[id].packet_len = max_len << 9; - if ((shdc[id].requested_blocks > 0) && (SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength > 0)) + if ((shdc[id].requested_blocks > 0) && (SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].InitLength > 0)) { - if (alloc_length > SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength) + if (alloc_length > SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].InitLength) { - hdd_image_write(id, shdc[id].sector_pos, SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength >> 9, hdbufferb); + hdd_image_write(id, shdc[id].sector_pos, SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].InitLength >> 9, hdbufferb); } else { @@ -968,16 +963,16 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) shdc[id].all_blocks_total = shdc[id].block_total; if (shdc[id].packet_status != CDROM_PHASE_COMPLETE) { - update_status_bar_icon((hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 1); + update_status_bar_icon((hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 1); } else { - update_status_bar_icon((hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); + update_status_bar_icon((hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); } return; case GPCMD_START_STOP_UNIT: - if (hdc[id].bus != HDD_BUS_SCSI_REMOVABLE) + if (hdd[id].bus != HDD_BUS_SCSI_REMOVABLE) { scsi_hd_illegal_opcode(id); break; @@ -1004,7 +999,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) max_len <<= 8; max_len |= cdb[4]; - if ((!max_len) || (SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength == 0)) + if ((!max_len) || (SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].InitLength == 0)) { /* scsi_hd_log("SCSI HD %i: All done - callback set\n", id); */ shdc[id].packet_status = CDROM_PHASE_COMPLETE; @@ -1073,7 +1068,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) memset(tempbuffer, 0, 8); tempbuffer[0] = 0; /*SCSI HD*/ - if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) + if (hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) { tempbuffer[1] = 0x80; /*Removable*/ } @@ -1100,9 +1095,9 @@ atapi_out: len = max_len; } - if (len > SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength) + if (len > SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].InitLength) { - len = SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength; + len = SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].InitLength; } memcpy(hdbufferb, tempbuffer, len); @@ -1166,7 +1161,7 @@ void scsi_hd_callback(uint8_t id) shdc[id].status = READY_STAT; shdc[id].phase = 3; shdc[id].packet_status = 0xFF; - update_status_bar_icon((hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); + update_status_bar_icon((hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); return; case CDROM_PHASE_DATA_OUT: scsi_hd_log("SCSI HD %i: PHASE_DATA_OUT\n", id); @@ -1178,7 +1173,7 @@ void scsi_hd_callback(uint8_t id) shdc[id].packet_status = CDROM_PHASE_COMPLETE; shdc[id].status = READY_STAT; shdc[id].phase = 3; - update_status_bar_icon((hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); + update_status_bar_icon((hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); return; case CDROM_PHASE_DATA_IN: scsi_hd_log("SCSI HD %i: PHASE_DATA_IN\n", id); @@ -1190,7 +1185,7 @@ void scsi_hd_callback(uint8_t id) shdc[id].packet_status = CDROM_PHASE_COMPLETE; shdc[id].status = READY_STAT; shdc[id].phase = 3; - update_status_bar_icon((hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); + update_status_bar_icon((hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); return; case CDROM_PHASE_ERROR: scsi_hd_log("SCSI HD %i: PHASE_ERROR\n", id); diff --git a/src/scsi/scsi_disk.h b/src/scsi/scsi_disk.h index c6c8991ad..453b019e3 100644 --- a/src/scsi/scsi_disk.h +++ b/src/scsi/scsi_disk.h @@ -6,13 +6,13 @@ * * Emulation of SCSI fixed and removable disks. * - * Version: @(#)scsi_disk.h 1.0.1 2017/08/23 + * Version: @(#)scsi_disk.h 1.0.2 2017/09/29 * * Author: Miran Grca, * Copyright 2017 Miran Grca. */ -#pragma pack(push,1) + typedef struct { /* Stuff for SCSI hard disks. */ uint8_t cdb[16]; @@ -42,15 +42,15 @@ typedef struct { int request_pos; uint8_t hd_cdb[16]; } scsi_hard_disk_t; -#pragma pack(pop) -extern scsi_hard_disk_t shdc[HDC_NUM]; + +extern scsi_hard_disk_t shdc[HDD_NUM]; +extern FILE *shdf[HDD_NUM]; + extern void scsi_disk_insert(uint8_t id); extern void scsi_loadhd(int scsi_id, int scsi_lun, int id); extern void scsi_reloadhd(int id); extern void scsi_unloadhd(int scsi_id, int scsi_lun, int id); -extern FILE *shdf[HDC_NUM]; - int scsi_hd_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len); diff --git a/src/sio_fdc37c665.c b/src/sio_fdc37c665.c index e7e88fa9e..7f441fc35 100644 --- a/src/sio_fdc37c665.c +++ b/src/sio_fdc37c665.c @@ -8,7 +8,7 @@ * * Implementation of the SMC FDC37C665 Super I/O Chip. * - * Version: @(#)sio_fdc37c665.c 1.0.5 2017/09/24 + * Version: @(#)sio_fdc37c665.c 1.0.6 2017/09/29 * * Authors: Sarah Walker, * Miran Grca, @@ -26,7 +26,8 @@ #include "floppy/floppy.h" #include "floppy/fdc.h" #include "floppy/fdd.h" -#include "hdd/hdd_ide_at.h" +#include "hdd/hdd.h" +#include "hdd/hdc_ide.h" #include "sio.h" diff --git a/src/sio_fdc37c669.c b/src/sio_fdc37c669.c index 239d0bbcc..fdcf085e2 100644 --- a/src/sio_fdc37c669.c +++ b/src/sio_fdc37c669.c @@ -8,7 +8,7 @@ * * Implementation of the SMC FDC37C669 Super I/O Chip. * - * Version: @(#)sio_fdc37c669.c 1.0.3 2017/09/24 + * Version: @(#)sio_fdc37c669.c 1.0.4 2017/09/29 * * Author: Miran Grca, * Copyright 2016,2017 Miran Grca. @@ -24,7 +24,8 @@ #include "floppy/floppy.h" #include "floppy/fdc.h" #include "floppy/fdd.h" -#include "hdd/hdd_ide_at.h" +#include "hdd/hdd.h" +#include "hdd/hdc_ide.h" #include "sio.h" diff --git a/src/sio_fdc37c932fr.c b/src/sio_fdc37c932fr.c index 936890b44..dfc1aead2 100644 --- a/src/sio_fdc37c932fr.c +++ b/src/sio_fdc37c932fr.c @@ -8,7 +8,7 @@ * * Implementation of the SMC FDC37C932FR Super I/O Chip. * - * Version: @(#)sio_fdc37c932fr.c 1.0.4 2017/09/24 + * Version: @(#)sio_fdc37c932fr.c 1.0.5 2017/09/29 * * Author: Miran Grca, * Copyright 2016,2017 Miran Grca. @@ -24,7 +24,8 @@ #include "floppy/floppy.h" #include "floppy/fdc.h" #include "floppy/fdd.h" -#include "hdd/hdd_ide_at.h" +#include "hdd/hdd.h" +#include "hdd/hdc_ide.h" #include "sio.h" diff --git a/src/sio_pc87306.c b/src/sio_pc87306.c index 1e5df2574..772d637aa 100644 --- a/src/sio_pc87306.c +++ b/src/sio_pc87306.c @@ -8,7 +8,7 @@ * * Emulation of the NatSemi PC87306 Super I/O chip. * - * Version: @(#)sio_pc87306.c 1.0.4 2017/09/24 + * Version: @(#)sio_pc87306.c 1.0.5 2017/09/29 * * Author: Miran Grca, * Copyright 2016,2017 Miran Grca. @@ -24,7 +24,8 @@ #include "floppy/floppy.h" #include "floppy/fdc.h" #include "floppy/fdd.h" -#include "hdd/hdd_ide_at.h" +#include "hdd/hdd.h" +#include "hdd/hdc_ide.h" #include "sio.h" diff --git a/src/win/win.c b/src/win/win.c index 3aeefc73b..9e97896c3 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -8,7 +8,7 @@ * * The Emulator's Windows core. * - * Version: @(#)win.c 1.0.12 2017/09/25 + * Version: @(#)win.c 1.0.13 2017/09/29 * * Authors: Sarah Walker, * Miran Grca, @@ -46,7 +46,8 @@ #include "../floppy/floppy.h" #include "../floppy/fdd.h" #include "../hdd/hdd.h" -#include "../hdd/hdd_ide_at.h" +#include "../hdd/hdc.h" +#include "../hdd/hdc_ide.h" #include "../scsi/scsi.h" #include "../scsi/scsi_disk.h" #ifdef USE_NETWORK @@ -731,15 +732,17 @@ int fdd_type_to_icon(int type) } } -int count_hard_disks(int bus) + +/* FIXME: should be hdd_count() in hdd.c */ +int hdd_count(int bus) { int i = 0; int c = 0; - for (i = 0; i < HDC_NUM; i++) + for (i = 0; i < HDD_NUM; i++) { - if (hdc[i].bus == bus) + if (hdd[i].bus == bus) { c++; } @@ -748,6 +751,7 @@ int count_hard_disks(int bus) return c; } + int find_status_bar_part(int tag) { int i = 0; @@ -900,13 +904,13 @@ void create_removable_hd_tip(int part) int drive = sb_part_meanings[part] & 0x1f; - if (wcslen(hdc[drive].fn) == 0) + if (wcslen(hdd[drive].fn) == 0) { _swprintf(tempTip, win_language_get_string_from_id(IDS_4115), drive, win_language_get_string_from_id(IDS_2057)); } else { - _swprintf(tempTip, win_language_get_string_from_id(IDS_4115), drive, hdc[drive].fn); + _swprintf(tempTip, win_language_get_string_from_id(IDS_4115), drive, hdd[drive].fn); } if (sbTips[part] != NULL) @@ -1122,12 +1126,12 @@ void update_status_bar_panes(HWND hwnds) sb_ready = 0; - c_mfm = count_hard_disks(HDD_BUS_MFM); - c_esdi = count_hard_disks(HDD_BUS_ESDI); - c_xtide = count_hard_disks(HDD_BUS_XTIDE); - c_ide_pio = count_hard_disks(HDD_BUS_IDE_PIO_ONLY); - c_ide_dma = count_hard_disks(HDD_BUS_IDE_PIO_AND_DMA); - c_scsi = count_hard_disks(HDD_BUS_SCSI); + c_mfm = hdd_count(HDD_BUS_MFM); + c_esdi = hdd_count(HDD_BUS_ESDI); + c_xtide = hdd_count(HDD_BUS_XTIDE); + c_ide_pio = hdd_count(HDD_BUS_IDE_PIO_ONLY); + c_ide_dma = hdd_count(HDD_BUS_IDE_PIO_AND_DMA); + c_scsi = hdd_count(HDD_BUS_SCSI); #ifdef USE_NETWORK do_net = display_network_icon(); @@ -1195,22 +1199,22 @@ void update_status_bar_panes(HWND hwnds) sb_parts++; } } - for (i = 0; i < HDC_NUM; i++) + for (i = 0; i < HDD_NUM; i++) { - if ((hdc[i].bus == HDD_BUS_SCSI_REMOVABLE) && (scsi_card_current != 0)) + if ((hdd[i].bus == HDD_BUS_SCSI_REMOVABLE) && (scsi_card_current != 0)) { sb_parts++; } } - if (c_mfm && !(machines[machine].flags & MACHINE_HAS_IDE) && !!memcmp(hdd_controller_name, "none", 4) && !!memcmp(hdd_controller_name, "xtide", 5) && !!memcmp(hdd_controller_name, "esdi", 4)) + if (c_mfm && !(machines[machine].flags & MACHINE_HAS_IDE) && !!memcmp(hdc_name, "none", 4) && !!memcmp(hdc_name, "xtide", 5) && !!memcmp(hdc_name, "esdi", 4)) { sb_parts++; } - if (c_esdi && !memcmp(hdd_controller_name, "esdi", 4)) + if (c_esdi && !memcmp(hdc_name, "esdi", 4)) { sb_parts++; } - if (c_xtide && !memcmp(hdd_controller_name, "xtide", 5)) + if (c_xtide && !memcmp(hdc_name, "xtide", 5)) { sb_parts++; } @@ -1283,9 +1287,9 @@ void update_status_bar_panes(HWND hwnds) sb_parts++; } } - for (i = 0; i < HDC_NUM; i++) + for (i = 0; i < HDD_NUM; i++) { - if ((hdc[i].bus == HDD_BUS_SCSI_REMOVABLE) && (scsi_card_current != 0)) + if ((hdd[i].bus == HDD_BUS_SCSI_REMOVABLE) && (scsi_card_current != 0)) { edge += SB_ICON_WIDTH; iStatusWidths[sb_parts] = edge; @@ -1293,21 +1297,21 @@ void update_status_bar_panes(HWND hwnds) sb_parts++; } } - if (c_mfm && !(machines[machine].flags & MACHINE_HAS_IDE) && !!memcmp(hdd_controller_name, "none", 4) && !!memcmp(hdd_controller_name, "xtide", 5) && !!memcmp(hdd_controller_name, "esdi", 4)) + if (c_mfm && !(machines[machine].flags & MACHINE_HAS_IDE) && !!memcmp(hdc_name, "none", 4) && !!memcmp(hdc_name, "xtide", 5) && !!memcmp(hdc_name, "esdi", 4)) { edge += SB_ICON_WIDTH; iStatusWidths[sb_parts] = edge; sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_MFM; sb_parts++; } - if (c_esdi && !memcmp(hdd_controller_name, "esdi", 4)) + if (c_esdi && !memcmp(hdc_name, "esdi", 4)) { edge += SB_ICON_WIDTH; iStatusWidths[sb_parts] = edge; sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_ESDI; sb_parts++; } - if (c_xtide && !memcmp(hdd_controller_name, "xtide", 5)) + if (c_xtide && !memcmp(hdc_name, "xtide", 5)) { edge += SB_ICON_WIDTH; iStatusWidths[sb_parts] = edge; @@ -1390,7 +1394,7 @@ void update_status_bar_panes(HWND hwnds) break; case SB_RDISK: /* Removable hard disk */ - sb_icon_flags[i] = (wcslen(hdc[sb_part_meanings[i] & 0x1f].fn) == 0) ? 256 : 0; + sb_icon_flags[i] = (wcslen(hdd[sb_part_meanings[i] & 0x1f].fn) == 0) ? 256 : 0; sb_part_icons[i] = 176 + sb_icon_flags[i]; sb_menu_handles[i] = create_popup_menu(i); create_removable_disk_submenu(sb_menu_handles[i], sb_part_meanings[i] & 0x1f); @@ -2755,16 +2759,16 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR case IDM_RDISK_IMAGE: case IDM_RDISK_IMAGE_WP: id = item_params & 0x001f; - ret = file_dlg_w_st(hwnd, IDS_4106, hdc[id].fn, id); + ret = file_dlg_w_st(hwnd, IDS_4106, hdd[id].fn, id); if (!ret) { removable_disk_unload(id); - memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); - wcscpy(hdc[id].fn, wopenfilestring); - hdc[id].wp = (item_id == IDM_RDISK_IMAGE_WP) ? 1 : 0; - scsi_loadhd(hdc[id].scsi_id, hdc[id].scsi_lun, id); + memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); + wcscpy(hdd[id].fn, wopenfilestring); + hdd[id].wp = (item_id == IDM_RDISK_IMAGE_WP) ? 1 : 0; + scsi_loadhd(hdd[id].scsi_id, hdd[id].scsi_lun, id); scsi_disk_insert(id); - if (wcslen(hdc[id].fn) > 0) + if (wcslen(hdd[id].fn) > 0) { update_status_bar_icon_state(SB_RDISK | id, 0); EnableMenuItem(sb_menu_handles[part], IDM_RDISK_EJECT | id, MF_BYCOMMAND | MF_ENABLED); diff --git a/src/win/win_iodev.c b/src/win/win_iodev.c index 2365bc99d..c04415a6d 100644 --- a/src/win/win_iodev.c +++ b/src/win/win_iodev.c @@ -8,7 +8,7 @@ * * Windows IO device menu handler. * - * Version: @(#)win_iodev.c 1.0.3 2017/09/24 + * Version: @(#)win_iodev.c 1.0.4 2017/09/29 * * Author: Miran Grca, * Copyright 2016,2017 Miran Grca. @@ -36,6 +36,7 @@ #include "../cdrom/cdrom_image.h" #include "../cdrom/cdrom_ioctl.h" #include "../cdrom/cdrom_null.h" +#include "../hdd/hdd.h" #include "../scsi/scsi_disk.h" #include "plat_iodev.h" #include "win.h" @@ -146,12 +147,12 @@ void cdrom_reload(uint8_t id) void removable_disk_unload(uint8_t id) { - if (wcslen(hdc[id].fn) == 0) + if (wcslen(hdd[id].fn) == 0) { /* Switch from empty to empty. Do nothing. */ return; } - scsi_unloadhd(hdc[id].scsi_id, hdc[id].scsi_lun, id); + scsi_unloadhd(hdd[id].scsi_id, hdd[id].scsi_lun, id); scsi_disk_insert(id); } @@ -186,17 +187,17 @@ void removable_disk_reload(uint8_t id) return; } - if (wcslen(hdc[id].fn) != 0) + if (wcslen(hdd[id].fn) != 0) { /* Attempting to reload while an image is already loaded. Do nothing. */ return; } scsi_reloadhd(id); /* scsi_disk_insert(id); */ - update_status_bar_icon_state(SB_RDISK | id, wcslen(hdc[id].fn) ? 0 : 1); - EnableMenuItem(sb_menu_handles[part], IDM_RDISK_EJECT | id, MF_BYCOMMAND | (wcslen(hdc[id].fn) ? MF_ENABLED : MF_GRAYED)); + update_status_bar_icon_state(SB_RDISK | id, wcslen(hdd[id].fn) ? 0 : 1); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_EJECT | id, MF_BYCOMMAND | (wcslen(hdd[id].fn) ? MF_ENABLED : MF_GRAYED)); EnableMenuItem(sb_menu_handles[part], IDM_RDISK_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(sb_menu_handles[part], IDM_RDISK_SEND_CHANGE | id, MF_BYCOMMAND | (wcslen(hdc[id].fn) ? MF_ENABLED : MF_GRAYED)); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_SEND_CHANGE | id, MF_BYCOMMAND | (wcslen(hdd[id].fn) ? MF_ENABLED : MF_GRAYED)); update_tip(SB_RDISK | id); config_save(); } diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 29b775a4a..a4f234c6a 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -8,7 +8,7 @@ * * Windows 86Box Settings dialog handler. * - * Version: @(#)win_settings.c 1.0.13 2017/09/24 + * Version: @(#)win_settings.c 1.0.14 2017/09/29 * * Author: Miran Grca, * Copyright 2016,2017 Miran Grca. @@ -39,7 +39,8 @@ #include "../floppy/floppy.h" #include "../floppy/fdd.h" #include "../hdd/hdd.h" -#include "../hdd/hdd_ide_at.h" +#include "../hdd/hdc.h" +#include "../hdd/hdc_ide.h" #include "../scsi/scsi.h" #ifdef USE_NETWORK #include "../network/network.h" @@ -82,11 +83,10 @@ static int temp_serial[2], temp_lpt; /* Peripherals category */ static int temp_scsi_card, hdc_ignore, temp_ide_ter, temp_ide_ter_irq, temp_ide_qua, temp_ide_qua_irq; static int temp_bugger; - static char temp_hdc_name[16]; /* Hard disks category */ -static hard_disk_t temp_hdc[HDC_NUM]; +static hard_disk_t temp_hdd[HDD_NUM]; /* Removable devices category */ static int temp_fdd_types[FDD_NUM]; @@ -109,7 +109,7 @@ static int settings_scsi_to_list[20], settings_list_to_scsi[20]; #ifdef USE_NETWORK static int settings_network_to_list[20], settings_list_to_network[20]; #endif -static char *hdd_names[16]; +static char *hdc_names[16]; /* This does the initial read of global variables into the temporary ones. */ @@ -164,7 +164,7 @@ static void win_settings_init(void) /* Peripherals category */ temp_scsi_card = scsi_card_current; - strncpy(temp_hdc_name, hdd_controller_name, sizeof(temp_hdc_name) - 1); + strncpy(temp_hdc_name, hdc_name, sizeof(temp_hdc_name) - 1); temp_ide_ter = ide_enable[2]; temp_ide_ter_irq = ide_irq[2]; temp_ide_qua = ide_enable[3]; @@ -172,7 +172,7 @@ static void win_settings_init(void) temp_bugger = bugger_enabled; /* Hard disks category */ - memcpy(temp_hdc, hdc, HDC_NUM * sizeof(hard_disk_t)); + memcpy(temp_hdd, hdd, HDD_NUM * sizeof(hard_disk_t)); /* Removable devices category */ for (i = 0; i < FDD_NUM; i++) @@ -236,7 +236,7 @@ static int win_settings_changed(void) /* Peripherals category */ i = i || (scsi_card_current != temp_scsi_card); - i = i || strncmp(temp_hdc_name, hdd_controller_name, sizeof(temp_hdc_name) - 1); + i = i || strncmp(temp_hdc_name, hdc_name, sizeof(temp_hdc_name) - 1); i = i || (temp_ide_ter != ide_enable[2]); i = i || (temp_ide_ter_irq != ide_irq[2]); i = i || (temp_ide_qua != ide_enable[3]); @@ -244,7 +244,7 @@ static int win_settings_changed(void) i = i || (temp_bugger != bugger_enabled); /* Hard disks category */ - i = i || memcmp(hdc, temp_hdc, HDC_NUM * sizeof(hard_disk_t)); + i = i || memcmp(hdd, temp_hdd, HDD_NUM * sizeof(hard_disk_t)); /* Removable devices category */ for (j = 0; j < FDD_NUM; j++) @@ -345,7 +345,7 @@ static void win_settings_save(void) /* Peripherals category */ scsi_card_current = temp_scsi_card; - strncpy(hdd_controller_name, temp_hdc_name, sizeof(temp_hdc_name) - 1); + strncpy(hdc_name, temp_hdc_name, sizeof(temp_hdc_name) - 1); ide_enable[2] = temp_ide_ter; ide_irq[2] = temp_ide_ter_irq; ide_enable[3] = temp_ide_qua; @@ -353,7 +353,7 @@ static void win_settings_save(void) bugger_enabled = temp_bugger; /* Hard disks category */ - memcpy(hdc, temp_hdc, HDC_NUM * sizeof(hard_disk_t)); + memcpy(hdd, temp_hdd, HDD_NUM * sizeof(hard_disk_t)); /* Removable devices category */ for (i = 0; i < FDD_NUM; i++) @@ -1385,7 +1385,7 @@ static BOOL CALLBACK win_settings_ports_proc(HWND hdlg, UINT message, WPARAM wPa } -static void recalc_hdd_list(HWND hdlg, int machine, int use_selected_hdd) +static void recalc_hdd_list(HWND hdlg, int machine, int use_selected_hdc) { HWND h; @@ -1415,13 +1415,13 @@ static void recalc_hdd_list(HWND hdlg, int machine, int use_selected_hdd) valid = 0; - if (use_selected_hdd) + if (use_selected_hdc) { c = SendMessage(h, CB_GETCURSEL, 0, 0); - if (c != -1 && hdd_names[c]) + if (c != -1 && hdc_names[c]) { - strncpy(old_name, hdd_names[c], sizeof(old_name) - 1); + strncpy(old_name, hdc_names[c], sizeof(old_name) - 1); } else { @@ -1437,27 +1437,27 @@ static void recalc_hdd_list(HWND hdlg, int machine, int use_selected_hdd) c = d = 0; while (1) { - s = hdd_controller_get_name(c); + s = hdc_get_name(c); if (s[0] == 0) { break; } - if ((hdd_controller_get_flags(c) & DEVICE_AT) && !(machines[machine].flags & MACHINE_AT)) + if ((hdc_get_flags(c) & DEVICE_AT) && !(machines[machine].flags & MACHINE_AT)) { c++; continue; } - if ((hdd_controller_get_flags(c) & DEVICE_PS2) && !(machines[machine].flags & MACHINE_PS2_HDD)) + if ((hdc_get_flags(c) & DEVICE_PS2) && !(machines[machine].flags & MACHINE_PS2_HDD)) { c++; continue; } - if ((hdd_controller_get_flags(c) & DEVICE_MCA) && !(machines[machine].flags & MACHINE_MCA)) + if ((hdc_get_flags(c) & DEVICE_MCA) && !(machines[machine].flags & MACHINE_MCA)) { c++; continue; } - if (!hdd_controller_available(c)) + if (!hdc_available(c)) { c++; continue; @@ -1471,8 +1471,8 @@ static void recalc_hdd_list(HWND hdlg, int machine, int use_selected_hdd) mbstowcs(lptsTemp, s, strlen(s) + 1); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); } - hdd_names[d] = hdd_controller_get_internal_name(c); - if (!strcmp(old_name, hdd_names[d])) + hdc_names[d] = hdc_get_internal_name(c); + if (!strcmp(old_name, hdc_names[d])) { SendMessage(h, CB_SETCURSEL, d, 0); valid = 1; @@ -1650,9 +1650,9 @@ static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPAR { h = GetDlgItem(hdlg, IDC_COMBO_HDC); c = SendMessage(h, CB_GETCURSEL, 0, 0); - if (hdd_names[c]) + if (hdc_names[c]) { - strncpy(temp_hdc_name, hdd_names[c], sizeof(temp_hdc_name) - 1); + strncpy(temp_hdc_name, hdc_names[c], sizeof(temp_hdc_name) - 1); } else { @@ -1921,28 +1921,28 @@ int next_free_id = 0; static void normalize_hd_list() { - hard_disk_t ihdc[HDC_NUM]; + hard_disk_t ihdd[HDD_NUM]; int i, j; j = 0; - memset(ihdc, 0, HDC_NUM * sizeof(hard_disk_t)); + memset(ihdd, 0, HDD_NUM * sizeof(hard_disk_t)); - for (i = 0; i < HDC_NUM; i++) + for (i = 0; i < HDD_NUM; i++) { - if (temp_hdc[i].bus != HDD_BUS_DISABLED) + if (temp_hdd[i].bus != HDD_BUS_DISABLED) { - memcpy(&(ihdc[j]), &(temp_hdc[i]), sizeof(hard_disk_t)); + memcpy(&(ihdd[j]), &(temp_hdd[i]), sizeof(hard_disk_t)); j++; } } - memcpy(temp_hdc, ihdc, HDC_NUM * sizeof(hard_disk_t)); + memcpy(temp_hdd, ihdd, HDD_NUM * sizeof(hard_disk_t)); } -int hdc_id_to_listview_index[HDC_NUM]; +int hdc_id_to_listview_index[HDD_NUM]; int hd_listview_items; -hard_disk_t new_hdc; +hard_disk_t new_hdd; int hdlv_current_sel; static int get_selected_hard_disk(HWND hdlg) @@ -2060,7 +2060,7 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.mfm_channel : temp_hdc[hdlv_current_sel].mfm_channel, 0); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.mfm_channel : temp_hdd[hdlv_current_sel].mfm_channel, 0); break; case HDD_BUS_XTIDE: /* XT IDE */ h = GetDlgItem(hdlg, IDT_1722); @@ -2070,7 +2070,7 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.xtide_channel : temp_hdc[hdlv_current_sel].xtide_channel, 0); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.xtide_channel : temp_hdd[hdlv_current_sel].xtide_channel, 0); break; case HDD_BUS_ESDI: /* ESDI */ h = GetDlgItem(hdlg, IDT_1722); @@ -2080,7 +2080,7 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.esdi_channel : temp_hdc[hdlv_current_sel].esdi_channel, 0); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.esdi_channel : temp_hdd[hdlv_current_sel].esdi_channel, 0); break; case HDD_BUS_IDE_PIO_ONLY: /* IDE (PIO-only) */ case HDD_BUS_IDE_PIO_AND_DMA: /* IDE (PIO and DMA) */ @@ -2091,7 +2091,7 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.ide_channel : temp_hdc[hdlv_current_sel].ide_channel, 0); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.ide_channel : temp_hdd[hdlv_current_sel].ide_channel, 0); break; case HDD_BUS_SCSI: /* SCSI */ case HDD_BUS_SCSI_REMOVABLE: /* SCSI (removable) */ @@ -2105,12 +2105,12 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.scsi_id : temp_hdc[hdlv_current_sel].scsi_id, 0); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.scsi_id : temp_hdd[hdlv_current_sel].scsi_id, 0); h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.scsi_lun : temp_hdc[hdlv_current_sel].scsi_lun, 0); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.scsi_lun : temp_hdd[hdlv_current_sel].scsi_lun, 0); break; } } @@ -2151,41 +2151,41 @@ static void recalc_next_free_id(HWND hdlg) next_free_id = -1; - for (i = 0; i < HDC_NUM; i++) + for (i = 0; i < HDD_NUM; i++) { - if (temp_hdc[i].bus == HDD_BUS_MFM) + if (temp_hdd[i].bus == HDD_BUS_MFM) { c_mfm++; } - else if (temp_hdc[i].bus == HDD_BUS_ESDI) + else if (temp_hdd[i].bus == HDD_BUS_ESDI) { c_esdi++; } - else if (temp_hdc[i].bus == HDD_BUS_XTIDE) + else if (temp_hdd[i].bus == HDD_BUS_XTIDE) { c_xtide++; } - else if (temp_hdc[i].bus == HDD_BUS_IDE_PIO_ONLY) + else if (temp_hdd[i].bus == HDD_BUS_IDE_PIO_ONLY) { c_ide_pio++; } - else if (temp_hdc[i].bus == HDD_BUS_IDE_PIO_AND_DMA) + else if (temp_hdd[i].bus == HDD_BUS_IDE_PIO_AND_DMA) { c_ide_dma++; } - else if (temp_hdc[i].bus == HDD_BUS_SCSI) + else if (temp_hdd[i].bus == HDD_BUS_SCSI) { c_scsi++; } - else if (temp_hdc[i].bus == HDD_BUS_SCSI_REMOVABLE) + else if (temp_hdd[i].bus == HDD_BUS_SCSI_REMOVABLE) { c_scsi++; } } - for (i = 0; i < HDC_NUM; i++) + for (i = 0; i < HDD_NUM; i++) { - if (temp_hdc[i].bus == HDD_BUS_DISABLED) + if (temp_hdd[i].bus == HDD_BUS_DISABLED) { next_free_id = i; break; @@ -2246,59 +2246,59 @@ static void win_settings_hard_disks_update_item(HWND hwndList, int i, int column if (column == 0) { - switch(temp_hdc[i].bus) + switch(temp_hdd[i].bus) { case HDD_BUS_MFM: - wsprintf(szText, win_language_get_string_from_id(IDS_4608), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1); + wsprintf(szText, win_language_get_string_from_id(IDS_4608), temp_hdd[i].mfm_channel >> 1, temp_hdd[i].mfm_channel & 1); break; case HDD_BUS_XTIDE: - wsprintf(szText, win_language_get_string_from_id(IDS_4609), temp_hdc[i].xtide_channel >> 1, temp_hdc[i].xtide_channel & 1); + wsprintf(szText, win_language_get_string_from_id(IDS_4609), temp_hdd[i].xtide_channel >> 1, temp_hdd[i].xtide_channel & 1); break; case HDD_BUS_ESDI: - wsprintf(szText, win_language_get_string_from_id(IDS_4610), temp_hdc[i].esdi_channel >> 1, temp_hdc[i].esdi_channel & 1); + wsprintf(szText, win_language_get_string_from_id(IDS_4610), temp_hdd[i].esdi_channel >> 1, temp_hdd[i].esdi_channel & 1); break; case HDD_BUS_IDE_PIO_ONLY: - wsprintf(szText, win_language_get_string_from_id(IDS_4611), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + wsprintf(szText, win_language_get_string_from_id(IDS_4611), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1); break; case HDD_BUS_IDE_PIO_AND_DMA: - wsprintf(szText, win_language_get_string_from_id(IDS_4612), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + wsprintf(szText, win_language_get_string_from_id(IDS_4612), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1); break; case HDD_BUS_SCSI: - wsprintf(szText, win_language_get_string_from_id(IDS_4613), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); + wsprintf(szText, win_language_get_string_from_id(IDS_4613), temp_hdd[i].scsi_id, temp_hdd[i].scsi_lun); break; case HDD_BUS_SCSI_REMOVABLE: - wsprintf(szText, win_language_get_string_from_id(IDS_4614), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); + wsprintf(szText, win_language_get_string_from_id(IDS_4614), temp_hdd[i].scsi_id, temp_hdd[i].scsi_lun); break; } lvI.pszText = szText; - lvI.iImage = (temp_hdc[i].bus == HDD_BUS_SCSI_REMOVABLE) ? 1 : 0; + lvI.iImage = (temp_hdd[i].bus == HDD_BUS_SCSI_REMOVABLE) ? 1 : 0; } else if (column == 1) { - lvI.pszText = temp_hdc[i].fn; + lvI.pszText = temp_hdd[i].fn; lvI.iImage = 0; } else if (column == 2) { - wsprintf(szText, win_language_get_string_from_id(IDS_4098), temp_hdc[i].tracks); + wsprintf(szText, win_language_get_string_from_id(IDS_4098), temp_hdd[i].tracks); lvI.pszText = szText; lvI.iImage = 0; } else if (column == 3) { - wsprintf(szText, win_language_get_string_from_id(IDS_4098), temp_hdc[i].hpc); + wsprintf(szText, win_language_get_string_from_id(IDS_4098), temp_hdd[i].hpc); lvI.pszText = szText; lvI.iImage = 0; } else if (column == 4) { - wsprintf(szText, win_language_get_string_from_id(IDS_4098), temp_hdc[i].spt); + wsprintf(szText, win_language_get_string_from_id(IDS_4098), temp_hdd[i].spt); lvI.pszText = szText; lvI.iImage = 0; } else if (column == 5) { - wsprintf(szText, win_language_get_string_from_id(IDS_4098), (temp_hdc[i].tracks * temp_hdc[i].hpc * temp_hdc[i].spt) >> 11); + wsprintf(szText, win_language_get_string_from_id(IDS_4098), (temp_hdd[i].tracks * temp_hdd[i].hpc * temp_hdd[i].spt) >> 11); lvI.pszText = szText; lvI.iImage = 0; } @@ -2324,39 +2324,39 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; lvI.stateMask = lvI.iSubItem = lvI.state = 0; - for (i = 0; i < HDC_NUM; i++) + for (i = 0; i < HDD_NUM; i++) { - if (temp_hdc[i].bus > 0) + if (temp_hdd[i].bus > 0) { hdc_id_to_listview_index[i] = j; lvI.iSubItem = 0; - switch(temp_hdc[i].bus) + switch(temp_hdd[i].bus) { case HDD_BUS_MFM: - wsprintf(szText, win_language_get_string_from_id(IDS_4608), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1); + wsprintf(szText, win_language_get_string_from_id(IDS_4608), temp_hdd[i].mfm_channel >> 1, temp_hdd[i].mfm_channel & 1); break; case HDD_BUS_XTIDE: - wsprintf(szText, win_language_get_string_from_id(IDS_4609), temp_hdc[i].xtide_channel >> 1, temp_hdc[i].xtide_channel & 1); + wsprintf(szText, win_language_get_string_from_id(IDS_4609), temp_hdd[i].xtide_channel >> 1, temp_hdd[i].xtide_channel & 1); break; case HDD_BUS_ESDI: - wsprintf(szText, win_language_get_string_from_id(IDS_4610), temp_hdc[i].esdi_channel >> 1, temp_hdc[i].esdi_channel & 1); + wsprintf(szText, win_language_get_string_from_id(IDS_4610), temp_hdd[i].esdi_channel >> 1, temp_hdd[i].esdi_channel & 1); break; case HDD_BUS_IDE_PIO_ONLY: - wsprintf(szText, win_language_get_string_from_id(IDS_4611), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + wsprintf(szText, win_language_get_string_from_id(IDS_4611), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1); break; case HDD_BUS_IDE_PIO_AND_DMA: - wsprintf(szText, win_language_get_string_from_id(IDS_4612), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + wsprintf(szText, win_language_get_string_from_id(IDS_4612), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1); break; case HDD_BUS_SCSI: - wsprintf(szText, win_language_get_string_from_id(IDS_4613), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); + wsprintf(szText, win_language_get_string_from_id(IDS_4613), temp_hdd[i].scsi_id, temp_hdd[i].scsi_lun); break; case HDD_BUS_SCSI_REMOVABLE: - wsprintf(szText, win_language_get_string_from_id(IDS_4614), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); + wsprintf(szText, win_language_get_string_from_id(IDS_4614), temp_hdd[i].scsi_id, temp_hdd[i].scsi_lun); break; } lvI.pszText = szText; lvI.iItem = j; - lvI.iImage = (temp_hdc[i].bus == HDD_BUS_SCSI_REMOVABLE) ? 1 : 0; + lvI.iImage = (temp_hdd[i].bus == HDD_BUS_SCSI_REMOVABLE) ? 1 : 0; if (ListView_InsertItem(hwndList, &lvI) == -1) { @@ -2364,7 +2364,7 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) } lvI.iSubItem = 1; - lvI.pszText = temp_hdc[i].fn; + lvI.pszText = temp_hdd[i].fn; lvI.iItem = j; lvI.iImage = 0; @@ -2374,7 +2374,7 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) } lvI.iSubItem = 2; - wsprintf(szText, win_language_get_string_from_id(IDS_4098), temp_hdc[i].tracks); + wsprintf(szText, win_language_get_string_from_id(IDS_4098), temp_hdd[i].tracks); lvI.pszText = szText; lvI.iItem = j; lvI.iImage = 0; @@ -2385,7 +2385,7 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) } lvI.iSubItem = 3; - wsprintf(szText, win_language_get_string_from_id(IDS_4098), temp_hdc[i].hpc); + wsprintf(szText, win_language_get_string_from_id(IDS_4098), temp_hdd[i].hpc); lvI.pszText = szText; lvI.iItem = j; lvI.iImage = 0; @@ -2396,7 +2396,7 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) } lvI.iSubItem = 4; - wsprintf(szText, win_language_get_string_from_id(IDS_4098), temp_hdc[i].spt); + wsprintf(szText, win_language_get_string_from_id(IDS_4098), temp_hdd[i].spt); lvI.pszText = szText; lvI.iItem = j; lvI.iImage = 0; @@ -2407,7 +2407,7 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) } lvI.iSubItem = 5; - wsprintf(szText, win_language_get_string_from_id(IDS_4098), (temp_hdc[i].tracks * temp_hdc[i].hpc * temp_hdc[i].spt) >> 11); + wsprintf(szText, win_language_get_string_from_id(IDS_4098), (temp_hdd[i].tracks * temp_hdd[i].hpc * temp_hdd[i].spt) >> 11); lvI.pszText = szText; lvI.iItem = j; lvI.iImage = 0; @@ -2523,7 +2523,7 @@ uint64_t selection = 127; uint64_t spt, hpc, tracks, size; wchar_t hd_file_name[512]; -static hard_disk_t *hdc_ptr; +static hard_disk_t *hdd_ptr; static int hdconf_initialize_hdt_combo(HWND hdlg) { @@ -2538,11 +2538,11 @@ static int hdconf_initialize_hdt_combo(HWND hdlg) h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); for (i = 0; i < 127; i++) { - temp_size = hdt[i][0] * hdt[i][1] * hdt[i][2]; + temp_size = hdd_table[i][0] * hdd_table[i][1] * hdd_table[i][2]; size_mb = temp_size >> 11; - wsprintf(szText, win_language_get_string_from_id(IDS_2157), size_mb, hdt[i][0], hdt[i][1], hdt[i][2]); + wsprintf(szText, win_language_get_string_from_id(IDS_2157), size_mb, hdd_table[i][0], hdd_table[i][1], hdd_table[i][2]); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); - if ((tracks == hdt[i][0]) && (hpc == hdt[i][1]) && (spt == hdt[i][2])) + if ((tracks == hdd_table[i][0]) && (hpc == hdd_table[i][1]) && (spt == hdd_table[i][2])) { selection = i; } @@ -2562,7 +2562,7 @@ static void recalc_selection(HWND hdlg) h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); for (i = 0; i < 127; i++) { - if ((tracks == hdt[i][0]) && (hpc == hdt[i][1]) && (spt == hdt[i][2])) + if ((tracks == hdd_table[i][0]) && (hpc == hdd_table[i][1]) && (spt == hdd_table[i][2])) { selection = i; } @@ -2599,11 +2599,11 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W if (existing & 2) { next_free_id = (existing >> 3) & 0x1f; - hdc_ptr = &(hdc[next_free_id]); + hdd_ptr = &(hdd[next_free_id]); } else { - hdc_ptr = &(temp_hdc[next_free_id]); + hdd_ptr = &(temp_hdd[next_free_id]); } SetWindowText(hdlg, win_language_get_string_from_id((existing & 1) ? IDS_4103 : IDS_4102)); @@ -2640,17 +2640,17 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); if (existing & 2) { - hdc_ptr->bus = HDD_BUS_SCSI_REMOVABLE; + hdd_ptr->bus = HDD_BUS_SCSI_REMOVABLE; max_spt = 99; max_hpc = 255; } else { - hdc_ptr->bus = HDD_BUS_IDE_PIO_ONLY; + hdd_ptr->bus = HDD_BUS_IDE_PIO_ONLY; max_spt = 63; max_hpc = 16; } - SendMessage(h, CB_SETCURSEL, hdc_ptr->bus, 0); + SendMessage(h, CB_SETCURSEL, hdd_ptr->bus, 0); max_tracks = 266305; recalc_location_controls(hdlg, 1); if (existing & 2) @@ -2675,7 +2675,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W /* Set the file name edit box contents to our existing parameters. */ h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); - SendMessage(h, WM_SETTEXT, 0, (LPARAM) hdc[next_free_id].fn); + SendMessage(h, WM_SETTEXT, 0, (LPARAM) hdd[next_free_id].fn); } else { @@ -2700,73 +2700,73 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W if (!(existing & 2)) { h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - hdc_ptr->bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; + hdd_ptr->bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; } /* Make sure no file name is allowed with removable SCSI hard disks. */ - if ((wcslen(hd_file_name) == 0) && (hdc_ptr->bus != HDD_BUS_SCSI_REMOVABLE)) + if ((wcslen(hd_file_name) == 0) && (hdd_ptr->bus != HDD_BUS_SCSI_REMOVABLE)) { - hdc_ptr->bus = HDD_BUS_DISABLED; + hdd_ptr->bus = HDD_BUS_DISABLED; msgbox_error(hwndParentDialog, IDS_4112); return TRUE; } - else if ((wcslen(hd_file_name) == 0) && (hdc_ptr->bus == HDD_BUS_SCSI_REMOVABLE)) + else if ((wcslen(hd_file_name) == 0) && (hdd_ptr->bus == HDD_BUS_SCSI_REMOVABLE)) { /* Mark hard disk added but return empty - it will signify the disk was ejected. */ - hdc_ptr->spt = hdc_ptr->hpc = hdc_ptr->tracks = 0; - memset(hdc_ptr->fn, 0, sizeof(hdc_ptr->fn)); + hdd_ptr->spt = hdd_ptr->hpc = hdd_ptr->tracks = 0; + memset(hdd_ptr->fn, 0, sizeof(hdd_ptr->fn)); goto hd_add_ok_common; } - get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &(hdc_ptr->spt)); - get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &(hdc_ptr->hpc)); - get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &(hdc_ptr->tracks)); - spt = hdc_ptr->spt; - hpc = hdc_ptr->hpc; - tracks = hdc_ptr->tracks; + get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &(hdd_ptr->spt)); + get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &(hdd_ptr->hpc)); + get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &(hdd_ptr->tracks)); + spt = hdd_ptr->spt; + hpc = hdd_ptr->hpc; + tracks = hdd_ptr->tracks; if (existing & 2) { - if (hdc_ptr->bus == HDD_BUS_SCSI_REMOVABLE) + if (hdd_ptr->bus == HDD_BUS_SCSI_REMOVABLE) { - memset(hdc_ptr->prev_fn, 0, sizeof(hdc_ptr->prev_fn)); - wcscpy(hdc_ptr->prev_fn, hdc_ptr->fn); + memset(hdd_ptr->prev_fn, 0, sizeof(hdd_ptr->prev_fn)); + wcscpy(hdd_ptr->prev_fn, hdd_ptr->fn); } } else { - switch(hdc_ptr->bus) + switch(hdd_ptr->bus) { case HDD_BUS_MFM: h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - hdc_ptr->mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + hdd_ptr->mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); break; case HDD_BUS_ESDI: h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - hdc_ptr->esdi_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + hdd_ptr->esdi_channel = SendMessage(h, CB_GETCURSEL, 0, 0); break; case HDD_BUS_XTIDE: h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - hdc_ptr->xtide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + hdd_ptr->xtide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); break; case HDD_BUS_IDE_PIO_ONLY: case HDD_BUS_IDE_PIO_AND_DMA: h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - hdc_ptr->ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + hdd_ptr->ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); break; case HDD_BUS_SCSI: case HDD_BUS_SCSI_REMOVABLE: h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - hdc_ptr->scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); + hdd_ptr->scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - hdc_ptr->scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); + hdd_ptr->scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); break; } } - memset(hdc_ptr->fn, 0, sizeof(hdc_ptr->fn)); - wcscpy(hdc_ptr->fn, hd_file_name); + memset(hdd_ptr->fn, 0, sizeof(hdd_ptr->fn)); + wcscpy(hdd_ptr->fn, hd_file_name); sector_size = 512; @@ -2854,7 +2854,7 @@ hd_add_ok_common: hard_disk_added = 0; if (!(existing & 2)) { - hdc_ptr->bus = HDD_BUS_DISABLED; + hdd_ptr->bus = HDD_BUS_DISABLED; } EndDialog(hdlg, 0); return TRUE; @@ -3103,9 +3103,9 @@ hdd_add_file_open_error: if ((temp != selection) && (temp != 127) && (temp != 128)) { selection = temp; - tracks = hdt[selection][0]; - hpc = hdt[selection][1]; - spt = hdt[selection][2]; + tracks = hdd_table[selection][0]; + hpc = hdd_table[selection][1]; + spt = hdd_table[selection][2]; size = (tracks * hpc * spt) << 9; set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); @@ -3167,14 +3167,14 @@ hdd_add_file_open_error: recalc_location_controls(hdlg, 1); h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); b = SendMessage(h,CB_GETCURSEL,0,0) + 1; - if (b == hdc_ptr->bus) + if (b == hdd_ptr->bus) { goto hd_add_bus_skip; } - hdc_ptr->bus = b; + hdd_ptr->bus = b; - switch(hdc_ptr->bus) + switch(hdd_ptr->bus) { case HDD_BUS_DISABLED: default: @@ -3226,7 +3226,7 @@ hdd_add_file_open_error: break; } - if ((hdc_ptr->bus == HDD_BUS_SCSI_REMOVABLE) && !chs_enabled) + if ((hdd_ptr->bus == HDD_BUS_SCSI_REMOVABLE) && !chs_enabled) { h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); EnableWindow(h, TRUE); @@ -3239,7 +3239,7 @@ hdd_add_file_open_error: h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); EnableWindow(h, TRUE); } - else if ((hdc_ptr->bus != HDD_BUS_SCSI_REMOVABLE) && !chs_enabled) + else if ((hdd_ptr->bus != HDD_BUS_SCSI_REMOVABLE) && !chs_enabled) { h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); EnableWindow(h, FALSE); @@ -3330,7 +3330,7 @@ static BOOL CALLBACK win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARA ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); hdlv_current_sel = 0; h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - SendMessage(h, CB_SETCURSEL, temp_hdc[0].bus - 1, 0); + SendMessage(h, CB_SETCURSEL, temp_hdd[0].bus - 1, 0); } else { @@ -3365,7 +3365,7 @@ static BOOL CALLBACK win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARA } ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - SendMessage(h, CB_SETCURSEL, temp_hdc[hdlv_current_sel].bus - 1, 0); + SendMessage(h, CB_SETCURSEL, temp_hdd[hdlv_current_sel].bus - 1, 0); recalc_location_controls(hdlg, 0); ignore_change = 0; } @@ -3383,11 +3383,11 @@ static BOOL CALLBACK win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARA ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); b = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; - if (b == temp_hdc[hdlv_current_sel].bus) + if (b == temp_hdd[hdlv_current_sel].bus) { goto hd_bus_skip; } - temp_hdc[hdlv_current_sel].bus = b; + temp_hdd[hdlv_current_sel].bus = b; recalc_location_controls(hdlg, 0); h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); @@ -3403,17 +3403,17 @@ hd_bus_skip: ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - if (temp_hdc[hdlv_current_sel].bus == HDD_BUS_MFM) + if (temp_hdd[hdlv_current_sel].bus == HDD_BUS_MFM) { - temp_hdc[hdlv_current_sel].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + temp_hdd[hdlv_current_sel].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); } - else if (temp_hdc[hdlv_current_sel].bus == HDD_BUS_ESDI) + else if (temp_hdd[hdlv_current_sel].bus == HDD_BUS_ESDI) { - temp_hdc[hdlv_current_sel].esdi_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + temp_hdd[hdlv_current_sel].esdi_channel = SendMessage(h, CB_GETCURSEL, 0, 0); } - else if (temp_hdc[hdlv_current_sel].bus == HDD_BUS_XTIDE) + else if (temp_hdd[hdlv_current_sel].bus == HDD_BUS_XTIDE) { - temp_hdc[hdlv_current_sel].xtide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + temp_hdd[hdlv_current_sel].xtide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); } h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); @@ -3428,7 +3428,7 @@ hd_bus_skip: ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - temp_hdc[hdlv_current_sel].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + temp_hdd[hdlv_current_sel].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); ignore_change = 0; @@ -3442,7 +3442,7 @@ hd_bus_skip: ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - temp_hdc[hdlv_current_sel].scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); + temp_hdd[hdlv_current_sel].scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); ignore_change = 0; @@ -3456,7 +3456,7 @@ hd_bus_skip: ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - temp_hdc[hdlv_current_sel].scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); + temp_hdd[hdlv_current_sel].scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); ignore_change = 0; @@ -3487,8 +3487,8 @@ hd_bus_skip: return FALSE; case IDC_BUTTON_HDD_REMOVE: - memcpy(temp_hdc[hdlv_current_sel].fn, L"", 4); - temp_hdc[hdlv_current_sel].bus = HDD_BUS_DISABLED; /* Only set the bus to zero, the list normalize code below will take care of turning this entire entry to a complete zero. */ + memcpy(temp_hdd[hdlv_current_sel].fn, L"", 4); + temp_hdd[hdlv_current_sel].bus = HDD_BUS_DISABLED; /* Only set the bus to zero, the list normalize code below will take care of turning this entire entry to a complete zero. */ normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. */ ignore_change = 1; h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); @@ -3499,7 +3499,7 @@ hd_bus_skip: ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); hdlv_current_sel = 0; h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - SendMessage(h, CB_SETCURSEL, temp_hdc[0].bus - 1, 0); + SendMessage(h, CB_SETCURSEL, temp_hdd[0].bus - 1, 0); } else {