Changes to remove XT-IDE as a separate bus. They are just IDE now.
Rename MFM (and RLL) to ST506 all over. Config files will be updated. XT-IDE driver rework. Cleanups in the HDC drivers. This commit requires a new romset, HDC roms have been moved!
This commit is contained in:
78
src/config.c
78
src/config.c
@@ -12,7 +12,7 @@
|
||||
* it on Windows XP, and possibly also Vista. Use the
|
||||
* -DANSI_CFG for use on these systems.
|
||||
*
|
||||
* Version: @(#)config.c 1.0.15 2018/04/19
|
||||
* Version: @(#)config.c 1.0.16 2018/04/23
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -947,14 +947,13 @@ load_disks(const char *cat)
|
||||
max_spt = max_hpc = max_tracks = 0;
|
||||
break;
|
||||
|
||||
case HDD_BUS_MFM:
|
||||
max_spt = 17; /* 26 for RLL */
|
||||
case HDD_BUS_ST506:
|
||||
max_spt = 26; /* 17=MFM, 26=RLL */
|
||||
max_hpc = 15;
|
||||
max_tracks = 1023;
|
||||
break;
|
||||
|
||||
case HDD_BUS_ESDI:
|
||||
case HDD_BUS_XTIDE:
|
||||
max_spt = 63;
|
||||
max_hpc = 16;
|
||||
max_tracks = 1023;
|
||||
@@ -982,24 +981,28 @@ load_disks(const char *cat)
|
||||
if (hdd[c].tracks > max_tracks)
|
||||
hdd[c].tracks = max_tracks;
|
||||
|
||||
/* MFM/RLL */
|
||||
sprintf(temp, "hdd_%02i_mfm_channel", c+1);
|
||||
if (hdd[c].bus == HDD_BUS_MFM)
|
||||
hdd[c].mfm_channel = !!config_get_int(cat, temp, c & 1);
|
||||
else
|
||||
config_delete_var(cat, temp);
|
||||
/* ST506 */
|
||||
sprintf(temp, "hdd_%02i_st506_channel", c+1);
|
||||
if (hdd[c].bus == HDD_BUS_ST506) {
|
||||
/* Try new syntax. */
|
||||
dev = config_get_int(cat, temp, -1);
|
||||
if (dev < 0) {
|
||||
/* Re-try with old syntax. */
|
||||
// FIXME: remove by 01-JUL-2018 --FvK
|
||||
sprintf(temp, "hdd_%02i_mfm_channel", c+1);
|
||||
dev = config_get_int(cat, temp, c & 1);
|
||||
config_delete_var(cat, temp);
|
||||
|
||||
/* XT IDE */
|
||||
sprintf(temp, "hdd_%02i_xtide_channel", c+1);
|
||||
if (hdd[c].bus == HDD_BUS_XTIDE)
|
||||
hdd[c].xtide_channel = !!config_get_int(cat, temp, c & 1);
|
||||
else
|
||||
/* Set value either way. */
|
||||
hdd[c].id.st506_channel = dev;
|
||||
}
|
||||
} else
|
||||
config_delete_var(cat, temp);
|
||||
|
||||
/* ESDI */
|
||||
sprintf(temp, "hdd_%02i_esdi_channel", c+1);
|
||||
if (hdd[c].bus == HDD_BUS_ESDI)
|
||||
hdd[c].esdi_channel = !!config_get_int(cat, temp, c & 1);
|
||||
hdd[c].id.esdi_channel = !!config_get_int(cat, temp, c & 1);
|
||||
else
|
||||
config_delete_var(cat, temp);
|
||||
|
||||
@@ -1012,10 +1015,10 @@ load_disks(const char *cat)
|
||||
sscanf(p, "%01u:%01u", &board, &dev);
|
||||
board &= 3;
|
||||
dev &= 1;
|
||||
hdd[c].ide_channel = (board<<1) + dev;
|
||||
hdd[c].id.ide_channel = (board<<1) + dev;
|
||||
|
||||
if (hdd[c].ide_channel > 7)
|
||||
hdd[c].ide_channel = 7;
|
||||
if (hdd[c].id.ide_channel > 7)
|
||||
hdd[c].id.ide_channel = 7;
|
||||
} else {
|
||||
config_delete_var(cat, temp);
|
||||
}
|
||||
@@ -1028,12 +1031,12 @@ load_disks(const char *cat)
|
||||
p = config_get_string(cat, temp, tmp2);
|
||||
|
||||
sscanf(p, "%02u:%02u",
|
||||
(int *)&hdd[c].scsi_id, (int *)&hdd[c].scsi_lun);
|
||||
(int *)&hdd[c].id.scsi.id, (int *)&hdd[c].id.scsi.lun);
|
||||
|
||||
if (hdd[c].scsi_id > 15)
|
||||
hdd[c].scsi_id = 15;
|
||||
if (hdd[c].scsi_lun > 7)
|
||||
hdd[c].scsi_lun = 7;
|
||||
if (hdd[c].id.scsi.id > 15)
|
||||
hdd[c].id.scsi.id = 15;
|
||||
if (hdd[c].id.scsi.lun > 7)
|
||||
hdd[c].id.scsi.lun = 7;
|
||||
} else {
|
||||
config_delete_var(cat, temp);
|
||||
}
|
||||
@@ -1051,9 +1054,6 @@ load_disks(const char *cat)
|
||||
sprintf(temp, "hdd_%02i_parameters", c+1);
|
||||
config_delete_var(cat, temp);
|
||||
|
||||
sprintf(temp, "hdd_%02i_preide_channels", c+1);
|
||||
config_delete_var(cat, temp);
|
||||
|
||||
sprintf(temp, "hdd_%02i_ide_channels", c+1);
|
||||
config_delete_var(cat, temp);
|
||||
|
||||
@@ -1063,12 +1063,6 @@ load_disks(const char *cat)
|
||||
sprintf(temp, "hdd_%02i_fn", c+1);
|
||||
config_delete_var(cat, temp);
|
||||
}
|
||||
|
||||
sprintf(temp, "hdd_%02i_mfm_channel", c+1);
|
||||
config_delete_var(cat, temp);
|
||||
|
||||
sprintf(temp, "hdd_%02i_ide_channel", c+1);
|
||||
config_delete_var(cat, temp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1092,21 +1086,15 @@ save_disks(const char *cat)
|
||||
config_delete_var(cat, temp);
|
||||
}
|
||||
|
||||
sprintf(temp, "hdd_%02i_mfm_channel", c+1);
|
||||
if (hdd_is_valid(c) && (hdd[c].bus == HDD_BUS_MFM))
|
||||
config_set_int(cat, temp, hdd[c].mfm_channel);
|
||||
else
|
||||
config_delete_var(cat, temp);
|
||||
|
||||
sprintf(temp, "hdd_%02i_xtide_channel", c+1);
|
||||
if (hdd_is_valid(c) && (hdd[c].bus == HDD_BUS_XTIDE))
|
||||
config_set_int(cat, temp, hdd[c].xtide_channel);
|
||||
sprintf(temp, "hdd_%02i_st506_channel", c+1);
|
||||
if (hdd_is_valid(c) && (hdd[c].bus == HDD_BUS_ST506))
|
||||
config_set_int(cat, temp, hdd[c].id.st506_channel);
|
||||
else
|
||||
config_delete_var(cat, temp);
|
||||
|
||||
sprintf(temp, "hdd_%02i_esdi_channel", c+1);
|
||||
if (hdd_is_valid(c) && (hdd[c].bus == HDD_BUS_ESDI))
|
||||
config_set_int(cat, temp, hdd[c].esdi_channel);
|
||||
config_set_int(cat, temp, hdd[c].id.esdi_channel);
|
||||
else
|
||||
config_delete_var(cat, temp);
|
||||
|
||||
@@ -1114,7 +1102,7 @@ save_disks(const char *cat)
|
||||
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, temp);
|
||||
} else {
|
||||
sprintf(tmp2, "%01u:%01u", hdd[c].ide_channel >> 1, hdd[c].ide_channel & 1);
|
||||
sprintf(tmp2, "%01u:%01u", hdd[c].id.ide_channel >> 1, hdd[c].id.ide_channel & 1);
|
||||
config_set_string(cat, temp, tmp2);
|
||||
}
|
||||
|
||||
@@ -1122,7 +1110,7 @@ save_disks(const char *cat)
|
||||
if (! hdd_is_valid(c) || ((hdd[c].bus != HDD_BUS_SCSI) && (hdd[c].bus != HDD_BUS_SCSI_REMOVABLE))) {
|
||||
config_delete_var(cat, temp);
|
||||
} else {
|
||||
sprintf(tmp2, "%02u:%02u", hdd[c].scsi_id, hdd[c].scsi_lun);
|
||||
sprintf(tmp2, "%02u:%02u", hdd[c].id.scsi.id, hdd[c].id.scsi.lun);
|
||||
config_set_string(cat, temp, tmp2);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Common code to handle all sorts of disk controllers.
|
||||
*
|
||||
* Version: @(#)hdc.c 1.0.9 2018/04/20
|
||||
* Version: @(#)hdc.c 1.0.10 2018/04/23
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -68,7 +68,8 @@ null_close(void *priv)
|
||||
static const device_t null_device = {
|
||||
"Null HDC", 0, 0,
|
||||
null_init, null_close, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
@@ -88,7 +89,8 @@ inthdc_close(void *priv)
|
||||
static const device_t inthdc_device = {
|
||||
"Internal Controller", 0, 0,
|
||||
inthdc_init, inthdc_close, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
@@ -96,7 +98,7 @@ static const struct {
|
||||
const char *name;
|
||||
const char *internal_name;
|
||||
const device_t *device;
|
||||
int is_mfm;
|
||||
int is_st506;
|
||||
} controllers[] = {
|
||||
{ "Disabled", "none",
|
||||
&null_device, 0 },
|
||||
@@ -104,17 +106,11 @@ static const struct {
|
||||
{ "Internal Controller", "internal",
|
||||
&inthdc_device, 0 },
|
||||
|
||||
{ "[ISA] [MFM] IBM PC Fixed Disk Adapter", "mfm_xt",
|
||||
&mfm_xt_xebec_device, 1 },
|
||||
{ "[ISA] [ST506] IBM PC Fixed Disk Adapter", "st506_xt",
|
||||
&st506_xt_xebec_device, 1 },
|
||||
|
||||
{ "[ISA] [MFM] DTC-5150X Fixed Disk Adapter", "mfm_dtc5150x",
|
||||
&mfm_xt_dtc5150x_device, 1 },
|
||||
|
||||
{ "[ISA] [MFM] IBM PC/AT Fixed Disk Adapter", "mfm_at",
|
||||
&mfm_at_wd1003_device, 1 },
|
||||
|
||||
{ "[ISA] [ESDI] PC/AT ESDI Fixed Disk Adapter", "esdi_at",
|
||||
&esdi_at_wd1007vse1_device, 0 },
|
||||
{ "[ISA] [ST506] DTC-5150X Fixed Disk Adapter", "st506_dtc5150x",
|
||||
&st506_xt_dtc5150x_device, 1 },
|
||||
|
||||
#ifdef USE_XTA
|
||||
{ "[ISA] [IDE] PC/XT IDE (XTA) Adapter", "xta_isa",
|
||||
@@ -127,6 +123,12 @@ static const struct {
|
||||
{ "[ISA] [IDE] PC/XT Acculogic XT IDE", "xtide_acculogic",
|
||||
&xtide_acculogic_device, 0 },
|
||||
|
||||
{ "[ISA] [ST506] IBM PC/AT Fixed Disk Adapter", "st506_at",
|
||||
&st506_at_wd1003_device, 1 },
|
||||
|
||||
{ "[ISA] [ESDI] PC/AT ESDI Fixed Disk Adapter", "esdi_at",
|
||||
&esdi_at_wd1007vse1_device, 0 },
|
||||
|
||||
{ "[ISA] [IDE] PC/AT IDE (ATA) Adapter", "ide_isa",
|
||||
&ide_isa_device, 0 },
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Definitions for the common disk controller handler.
|
||||
*
|
||||
* Version: @(#)hdc.h 1.0.9 2018/04/20
|
||||
* Version: @(#)hdc.h 1.0.10 2018/04/23
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -38,9 +38,8 @@
|
||||
# define EMU_HDC_H
|
||||
|
||||
|
||||
#define MFM_NUM 2 /* 2 drives per controller supported */
|
||||
#define ST506_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
|
||||
@@ -55,9 +54,10 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t mfm_xt_xebec_device; /* mfm_xt_xebec */
|
||||
extern const device_t mfm_xt_dtc5150x_device; /* mfm_xt_dtc */
|
||||
extern const device_t mfm_at_wd1003_device; /* mfm_at_wd1003 */
|
||||
extern const device_t st506_xt_xebec_device; /* st506_xt_xebec */
|
||||
extern const device_t st506_xt_dtc5150x_device; /* st506_xt_dtc */
|
||||
|
||||
extern const device_t st506_at_wd1003_device; /* st506_at_wd1003 */
|
||||
|
||||
extern const device_t esdi_at_wd1007vse1_device; /* esdi_at */
|
||||
extern const device_t esdi_ps2_device; /* esdi_mca */
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Driver for the ESDI controller (WD1007-vse1) for PC/AT.
|
||||
*
|
||||
* Version: @(#)hdc_esdi_at.c 1.0.6 2018/04/02
|
||||
* Version: @(#)hdc_esdi_at.c 1.0.7 2018/04/23
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -60,7 +60,9 @@
|
||||
|
||||
|
||||
#define HDC_TIME (TIMER_USEC*10LL)
|
||||
#define ESDI_BIOS_FILE L"hdd/esdi_at/62-000279-061.bin"
|
||||
|
||||
#define ESDI_BIOS_FILE L"disk/esdi/at/62-000279-061.bin"
|
||||
|
||||
|
||||
#define STAT_ERR 0x01
|
||||
#define STAT_INDEX 0x02
|
||||
@@ -119,77 +121,77 @@ typedef struct {
|
||||
drive_t drives[2];
|
||||
|
||||
rom_t bios_rom;
|
||||
} esdi_t;
|
||||
} hdc_t;
|
||||
|
||||
|
||||
static __inline void
|
||||
irq_raise(esdi_t *esdi)
|
||||
irq_raise(hdc_t *dev)
|
||||
{
|
||||
/* If not already pending.. */
|
||||
if (! esdi->irqstat) {
|
||||
if (! dev->irqstat) {
|
||||
/* If enabled in the control register.. */
|
||||
if (! (esdi->fdisk & 0x02)) {
|
||||
if (! (dev->fdisk & 0x02)) {
|
||||
/* .. raise IRQ14. */
|
||||
picint(1<<14);
|
||||
}
|
||||
|
||||
/* Remember this. */
|
||||
esdi->irqstat = 1;
|
||||
dev->irqstat = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static __inline void
|
||||
irq_lower(esdi_t *esdi)
|
||||
irq_lower(hdc_t *dev)
|
||||
{
|
||||
/* If raised.. */
|
||||
if (esdi->irqstat) {
|
||||
if (dev->irqstat) {
|
||||
/* If enabled in the control register.. */
|
||||
if (! (esdi->fdisk & 0x02)) {
|
||||
if (! (dev->fdisk & 0x02)) {
|
||||
/* .. drop IRQ14. */
|
||||
picintc(1<<14);
|
||||
}
|
||||
|
||||
/* Remember this. */
|
||||
esdi->irqstat = 0;
|
||||
dev->irqstat = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Return the sector offset for the current register values. */
|
||||
static int
|
||||
get_sector(esdi_t *esdi, off64_t *addr)
|
||||
get_sector(hdc_t *dev, off64_t *addr)
|
||||
{
|
||||
drive_t *drive = &esdi->drives[esdi->drive_sel];
|
||||
drive_t *drive = &dev->drives[dev->drive_sel];
|
||||
int heads = drive->cfg_hpc;
|
||||
int sectors = drive->cfg_spt;
|
||||
int c, h, s;
|
||||
|
||||
if (esdi->head > heads) {
|
||||
if (dev->head > heads) {
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("esdi_get_sector: past end of configured heads\n");
|
||||
hdc_log("dev_get_sector: past end of configured heads\n");
|
||||
#endif
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (esdi->sector >= sectors+1) {
|
||||
if (dev->sector >= sectors+1) {
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("esdi_get_sector: past end of configured sectors\n");
|
||||
hdc_log("dev_get_sector: past end of configured sectors\n");
|
||||
#endif
|
||||
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);
|
||||
*addr = ((((off64_t) dev->cylinder * heads) + dev->head) *
|
||||
sectors) + (dev->sector - 1);
|
||||
} else {
|
||||
/*
|
||||
* When performing translation, the firmware seems to leave 1
|
||||
* sector per track inaccessible (spare sector)
|
||||
*/
|
||||
|
||||
*addr = ((((off64_t) esdi->cylinder * heads) + esdi->head) *
|
||||
sectors) + (esdi->sector - 1);
|
||||
*addr = ((((off64_t) dev->cylinder * heads) + dev->head) *
|
||||
sectors) + (dev->sector - 1);
|
||||
|
||||
s = *addr % (drive->real_spt - 1);
|
||||
h = (*addr / (drive->real_spt - 1)) % drive->real_hpc;
|
||||
@@ -204,16 +206,16 @@ get_sector(esdi_t *esdi, off64_t *addr)
|
||||
|
||||
/* Move to the next sector using CHS addressing. */
|
||||
static void
|
||||
next_sector(esdi_t *esdi)
|
||||
next_sector(hdc_t *dev)
|
||||
{
|
||||
drive_t *drive = &esdi->drives[esdi->drive_sel];
|
||||
drive_t *drive = &dev->drives[dev->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++;
|
||||
dev->sector++;
|
||||
if (dev->sector == (drive->cfg_spt + 1)) {
|
||||
dev->sector = 1;
|
||||
if (++dev->head == drive->cfg_hpc) {
|
||||
dev->head = 0;
|
||||
dev->cylinder++;
|
||||
if (drive->current_cylinder < drive->real_tracks)
|
||||
drive->current_cylinder++;
|
||||
}
|
||||
@@ -222,27 +224,27 @@ next_sector(esdi_t *esdi)
|
||||
|
||||
|
||||
static void
|
||||
esdi_writew(uint16_t port, uint16_t val, void *priv)
|
||||
hdc_writew(uint16_t port, uint16_t val, void *priv)
|
||||
{
|
||||
esdi_t *esdi = (esdi_t *)priv;
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
|
||||
esdi->buffer[esdi->pos >> 1] = val;
|
||||
esdi->pos += 2;
|
||||
dev->buffer[dev->pos >> 1] = val;
|
||||
dev->pos += 2;
|
||||
|
||||
if (esdi->pos >= 512) {
|
||||
esdi->pos = 0;
|
||||
esdi->status = STAT_BUSY;
|
||||
if (dev->pos >= 512) {
|
||||
dev->pos = 0;
|
||||
dev->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
esdi->callback = 6LL*HDC_TIME;
|
||||
dev->callback = 6LL*HDC_TIME;
|
||||
timer_update_outstanding();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
esdi_write(uint16_t port, uint8_t val, void *priv)
|
||||
hdc_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
esdi_t *esdi = (esdi_t *)priv;
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1007 write(%04x, %02x)\n", port, val);
|
||||
@@ -250,70 +252,70 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
||||
|
||||
switch (port) {
|
||||
case 0x1f0: /* data */
|
||||
esdi_writew(port, val | (val << 8), priv);
|
||||
hdc_writew(port, val | (val << 8), priv);
|
||||
return;
|
||||
|
||||
case 0x1f1: /* write precompensation */
|
||||
esdi->cylprecomp = val;
|
||||
dev->cylprecomp = val;
|
||||
return;
|
||||
|
||||
case 0x1f2: /* sector count */
|
||||
esdi->secount = val;
|
||||
dev->secount = val;
|
||||
return;
|
||||
|
||||
case 0x1f3: /* sector */
|
||||
esdi->sector = val;
|
||||
dev->sector = val;
|
||||
return;
|
||||
|
||||
case 0x1f4: /* cylinder low */
|
||||
esdi->cylinder = (esdi->cylinder & 0xFF00) | val;
|
||||
dev->cylinder = (dev->cylinder & 0xFF00) | val;
|
||||
return;
|
||||
|
||||
case 0x1f5: /* cylinder high */
|
||||
esdi->cylinder = (esdi->cylinder & 0xFF) | (val << 8);
|
||||
dev->cylinder = (dev->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 = STAT_READY|STAT_DSC;
|
||||
dev->head = val & 0xF;
|
||||
dev->drive_sel = (val & 0x10) ? 1 : 0;
|
||||
if (dev->drives[dev->drive_sel].present) {
|
||||
dev->status = STAT_READY|STAT_DSC;
|
||||
} else {
|
||||
esdi->status = 0;
|
||||
dev->status = 0;
|
||||
}
|
||||
return;
|
||||
|
||||
case 0x1f7: /* command register */
|
||||
irq_lower(esdi);
|
||||
esdi->command = val;
|
||||
esdi->error = 0;
|
||||
irq_lower(dev);
|
||||
dev->command = val;
|
||||
dev->error = 0;
|
||||
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1007: command %02x\n", val & 0xf0);
|
||||
#endif
|
||||
switch (val & 0xf0) {
|
||||
case CMD_RESTORE:
|
||||
esdi->command &= ~0x0f; /*mask off step rate*/
|
||||
esdi->status = STAT_BUSY;
|
||||
dev->command &= ~0x0f; /*mask off step rate*/
|
||||
dev->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
esdi->callback = 200LL*HDC_TIME;
|
||||
dev->callback = 200LL*HDC_TIME;
|
||||
timer_update_outstanding();
|
||||
break;
|
||||
|
||||
case CMD_SEEK:
|
||||
esdi->command &= ~0x0f; /*mask off step rate*/
|
||||
esdi->status = STAT_BUSY;
|
||||
dev->command &= ~0x0f; /*mask off step rate*/
|
||||
dev->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
esdi->callback = 200LL*HDC_TIME;
|
||||
dev->callback = 200LL*HDC_TIME;
|
||||
timer_update_outstanding();
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (val) {
|
||||
case CMD_NOP:
|
||||
esdi->status = STAT_BUSY;
|
||||
dev->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
esdi->callback = 200LL*HDC_TIME;
|
||||
dev->callback = 200LL*HDC_TIME;
|
||||
timer_update_outstanding();
|
||||
break;
|
||||
|
||||
@@ -321,14 +323,14 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
||||
case CMD_READ+1:
|
||||
case CMD_READ+2:
|
||||
case CMD_READ+3:
|
||||
esdi->command &= ~0x03;
|
||||
dev->command &= ~0x03;
|
||||
if (val & 0x02)
|
||||
fatal("Read with ECC\n");
|
||||
|
||||
case 0xa0:
|
||||
esdi->status = STAT_BUSY;
|
||||
dev->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
esdi->callback = 200LL*HDC_TIME;
|
||||
dev->callback = 200LL*HDC_TIME;
|
||||
timer_update_outstanding();
|
||||
break;
|
||||
|
||||
@@ -336,46 +338,46 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
||||
case CMD_WRITE+1:
|
||||
case CMD_WRITE+2:
|
||||
case CMD_WRITE+3:
|
||||
esdi->command &= ~0x03;
|
||||
dev->command &= ~0x03;
|
||||
if (val & 0x02)
|
||||
fatal("Write with ECC\n");
|
||||
esdi->status = STAT_DRQ | STAT_DSC;
|
||||
esdi->pos = 0;
|
||||
dev->status = STAT_DRQ | STAT_DSC;
|
||||
dev->pos = 0;
|
||||
break;
|
||||
|
||||
case CMD_VERIFY:
|
||||
case CMD_VERIFY+1:
|
||||
esdi->command &= ~0x01;
|
||||
esdi->status = STAT_BUSY;
|
||||
dev->command &= ~0x01;
|
||||
dev->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
esdi->callback = 200LL*HDC_TIME;
|
||||
dev->callback = 200LL*HDC_TIME;
|
||||
timer_update_outstanding();
|
||||
break;
|
||||
|
||||
case CMD_FORMAT:
|
||||
esdi->status = STAT_DRQ;
|
||||
esdi->pos = 0;
|
||||
dev->status = STAT_DRQ;
|
||||
dev->pos = 0;
|
||||
break;
|
||||
|
||||
case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */
|
||||
esdi->status = STAT_BUSY;
|
||||
dev->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
esdi->callback = 30LL*HDC_TIME;
|
||||
dev->callback = 30LL*HDC_TIME;
|
||||
timer_update_outstanding();
|
||||
break;
|
||||
|
||||
case CMD_DIAGNOSE: /* Execute Drive Diagnostics */
|
||||
esdi->status = STAT_BUSY;
|
||||
dev->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
esdi->callback = 200LL*HDC_TIME;
|
||||
dev->callback = 200LL*HDC_TIME;
|
||||
timer_update_outstanding();
|
||||
break;
|
||||
|
||||
case 0xe0: /*???*/
|
||||
case CMD_READ_PARAMETERS:
|
||||
esdi->status = STAT_BUSY;
|
||||
dev->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
esdi->callback = 200LL*HDC_TIME;
|
||||
dev->callback = 200LL*HDC_TIME;
|
||||
timer_update_outstanding();
|
||||
break;
|
||||
|
||||
@@ -384,9 +386,9 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
||||
hdc_log("WD1007: bad command %02X\n", val);
|
||||
#endif
|
||||
case 0xe8: /*???*/
|
||||
esdi->status = STAT_BUSY;
|
||||
dev->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
esdi->callback = 200LL*HDC_TIME;
|
||||
dev->callback = 200LL*HDC_TIME;
|
||||
timer_update_outstanding();
|
||||
break;
|
||||
}
|
||||
@@ -394,46 +396,46 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case 0x3f6: /* Device control */
|
||||
if ((esdi->fdisk & 0x04) && !(val & 0x04)) {
|
||||
if ((dev->fdisk & 0x04) && !(val & 0x04)) {
|
||||
timer_clock();
|
||||
esdi->callback = 500LL*HDC_TIME;
|
||||
dev->callback = 500LL*HDC_TIME;
|
||||
timer_update_outstanding();
|
||||
esdi->reset = 1;
|
||||
esdi->status = STAT_BUSY;
|
||||
dev->reset = 1;
|
||||
dev->status = STAT_BUSY;
|
||||
}
|
||||
|
||||
if (val & 0x04) {
|
||||
/*Drive held in reset*/
|
||||
timer_clock();
|
||||
esdi->callback = 0LL;
|
||||
dev->callback = 0LL;
|
||||
timer_update_outstanding();
|
||||
esdi->status = STAT_BUSY;
|
||||
dev->status = STAT_BUSY;
|
||||
}
|
||||
esdi->fdisk = val;
|
||||
dev->fdisk = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint16_t
|
||||
esdi_readw(uint16_t port, void *priv)
|
||||
hdc_readw(uint16_t port, void *priv)
|
||||
{
|
||||
esdi_t *esdi = (esdi_t *)priv;
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
uint16_t temp;
|
||||
|
||||
temp = esdi->buffer[esdi->pos >> 1];
|
||||
esdi->pos += 2;
|
||||
temp = dev->buffer[dev->pos >> 1];
|
||||
dev->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;
|
||||
if (dev->pos >= 512) {
|
||||
dev->pos=0;
|
||||
dev->status = STAT_READY | STAT_DSC;
|
||||
if (dev->command == CMD_READ || dev->command == 0xa0) {
|
||||
dev->secount = (dev->secount - 1) & 0xff;
|
||||
if (dev->secount) {
|
||||
next_sector(dev);
|
||||
dev->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
esdi->callback = 6LL*HDC_TIME;
|
||||
dev->callback = 6LL*HDC_TIME;
|
||||
timer_update_outstanding();
|
||||
} else {
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
|
||||
@@ -446,43 +448,43 @@ esdi_readw(uint16_t port, void *priv)
|
||||
|
||||
|
||||
static uint8_t
|
||||
esdi_read(uint16_t port, void *priv)
|
||||
hdc_read(uint16_t port, void *priv)
|
||||
{
|
||||
esdi_t *esdi = (esdi_t *)priv;
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
uint8_t temp = 0xff;
|
||||
|
||||
switch (port) {
|
||||
case 0x1f0: /* data */
|
||||
temp = esdi_readw(port, esdi) & 0xff;
|
||||
temp = hdc_readw(port, dev) & 0xff;
|
||||
break;
|
||||
|
||||
case 0x1f1: /* error */
|
||||
temp = esdi->error;
|
||||
temp = dev->error;
|
||||
break;
|
||||
|
||||
case 0x1f2: /* sector count */
|
||||
temp = esdi->secount;
|
||||
temp = dev->secount;
|
||||
break;
|
||||
|
||||
case 0x1f3: /* sector */
|
||||
temp = esdi->sector;
|
||||
temp = dev->sector;
|
||||
break;
|
||||
|
||||
case 0x1f4: /* cylinder low */
|
||||
temp = (uint8_t)(esdi->cylinder&0xff);
|
||||
temp = (uint8_t)(dev->cylinder&0xff);
|
||||
break;
|
||||
|
||||
case 0x1f5: /* cylinder high */
|
||||
temp = (uint8_t)(esdi->cylinder>>8);
|
||||
temp = (uint8_t)(dev->cylinder>>8);
|
||||
break;
|
||||
|
||||
case 0x1f6: /* drive/Head */
|
||||
temp = (uint8_t)(0xa0|esdi->head|(esdi->drive_sel?0x10:0));
|
||||
temp = (uint8_t)(0xa0|dev->head|(dev->drive_sel?0x10:0));
|
||||
break;
|
||||
|
||||
case 0x1f7: /* status */
|
||||
irq_lower(esdi);
|
||||
temp = esdi->status;
|
||||
irq_lower(dev);
|
||||
temp = dev->status;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -495,21 +497,21 @@ esdi_read(uint16_t port, void *priv)
|
||||
|
||||
|
||||
static void
|
||||
esdi_callback(void *priv)
|
||||
hdc_callback(void *priv)
|
||||
{
|
||||
esdi_t *esdi = (esdi_t *)priv;
|
||||
drive_t *drive = &esdi->drives[esdi->drive_sel];
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
drive_t *drive = &dev->drives[dev->drive_sel];
|
||||
off64_t addr;
|
||||
|
||||
esdi->callback = 0LL;
|
||||
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;
|
||||
dev->callback = 0LL;
|
||||
if (dev->reset) {
|
||||
dev->status = STAT_READY|STAT_DSC;
|
||||
dev->error = 1;
|
||||
dev->secount = 1;
|
||||
dev->sector = 1;
|
||||
dev->head = 0;
|
||||
dev->cylinder = 0;
|
||||
dev->reset = 0;
|
||||
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
|
||||
|
||||
@@ -517,263 +519,263 @@ esdi_callback(void *priv)
|
||||
}
|
||||
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1007: command %02x\n", esdi->command);
|
||||
hdc_log("WD1007: command %02x\n", dev->command);
|
||||
#endif
|
||||
|
||||
switch (esdi->command) {
|
||||
switch (dev->command) {
|
||||
case CMD_RESTORE:
|
||||
if (! drive->present) {
|
||||
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
esdi->error = ERR_ABRT;
|
||||
dev->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
dev->error = ERR_ABRT;
|
||||
} else {
|
||||
drive->current_cylinder = 0;
|
||||
esdi->status = STAT_READY|STAT_DSC;
|
||||
dev->status = STAT_READY|STAT_DSC;
|
||||
}
|
||||
irq_raise(esdi);
|
||||
irq_raise(dev);
|
||||
break;
|
||||
|
||||
case CMD_SEEK:
|
||||
if (! drive->present) {
|
||||
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
esdi->error = ERR_ABRT;
|
||||
dev->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
dev->error = ERR_ABRT;
|
||||
} else {
|
||||
esdi->status = STAT_READY|STAT_DSC;
|
||||
dev->status = STAT_READY|STAT_DSC;
|
||||
}
|
||||
irq_raise(esdi);
|
||||
irq_raise(dev);
|
||||
break;
|
||||
|
||||
case CMD_READ:
|
||||
if (! drive->present) {
|
||||
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
esdi->error = ERR_ABRT;
|
||||
irq_raise(esdi);
|
||||
dev->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
dev->error = ERR_ABRT;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
if (get_sector(esdi, &addr)) {
|
||||
esdi->error = ERR_ID_NOT_FOUND;
|
||||
esdi->status = STAT_READY|STAT_DSC|STAT_ERR;
|
||||
irq_raise(esdi);
|
||||
if (get_sector(dev, &addr)) {
|
||||
dev->error = ERR_ID_NOT_FOUND;
|
||||
dev->status = STAT_READY|STAT_DSC|STAT_ERR;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
hdd_image_read(drive->hdd_num, addr, 1,
|
||||
(uint8_t *)esdi->buffer);
|
||||
(uint8_t *)dev->buffer);
|
||||
|
||||
esdi->pos = 0;
|
||||
esdi->status = STAT_DRQ|STAT_READY|STAT_DSC;
|
||||
irq_raise(esdi);
|
||||
dev->pos = 0;
|
||||
dev->status = STAT_DRQ|STAT_READY|STAT_DSC;
|
||||
irq_raise(dev);
|
||||
ui_sb_update_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);
|
||||
dev->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
dev->error = ERR_ABRT;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
if (get_sector(esdi, &addr)) {
|
||||
esdi->error = ERR_ID_NOT_FOUND;
|
||||
esdi->status = STAT_READY|STAT_DSC|STAT_ERR;
|
||||
irq_raise(esdi);
|
||||
if (get_sector(dev, &addr)) {
|
||||
dev->error = ERR_ID_NOT_FOUND;
|
||||
dev->status = STAT_READY|STAT_DSC|STAT_ERR;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
hdd_image_write(drive->hdd_num, addr, 1,
|
||||
(uint8_t *)esdi->buffer);
|
||||
(uint8_t *)dev->buffer);
|
||||
|
||||
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);
|
||||
irq_raise(dev);
|
||||
dev->secount = (dev->secount - 1) & 0xff;
|
||||
if (dev->secount) {
|
||||
dev->status = STAT_DRQ|STAT_READY|STAT_DSC;
|
||||
dev->pos = 0;
|
||||
next_sector(dev);
|
||||
} else {
|
||||
esdi->status = STAT_READY|STAT_DSC;
|
||||
dev->status = STAT_READY|STAT_DSC;
|
||||
}
|
||||
ui_sb_update_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);
|
||||
dev->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
dev->error = ERR_ABRT;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
if (get_sector(esdi, &addr)) {
|
||||
esdi->error = ERR_ID_NOT_FOUND;
|
||||
esdi->status = STAT_READY|STAT_DSC|STAT_ERR;
|
||||
irq_raise(esdi);
|
||||
if (get_sector(dev, &addr)) {
|
||||
dev->error = ERR_ID_NOT_FOUND;
|
||||
dev->status = STAT_READY|STAT_DSC|STAT_ERR;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
hdd_image_read(drive->hdd_num, addr, 1,
|
||||
(uint8_t *)esdi->buffer);
|
||||
(uint8_t *)dev->buffer);
|
||||
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1);
|
||||
next_sector(esdi);
|
||||
esdi->secount = (esdi->secount - 1) & 0xff;
|
||||
if (esdi->secount)
|
||||
esdi->callback = 6LL*HDC_TIME;
|
||||
next_sector(dev);
|
||||
dev->secount = (dev->secount - 1) & 0xff;
|
||||
if (dev->secount)
|
||||
dev->callback = 6LL*HDC_TIME;
|
||||
else {
|
||||
esdi->pos = 0;
|
||||
esdi->status = STAT_READY|STAT_DSC;
|
||||
irq_raise(esdi);
|
||||
dev->pos = 0;
|
||||
dev->status = STAT_READY|STAT_DSC;
|
||||
irq_raise(dev);
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_FORMAT:
|
||||
if (! drive->present) {
|
||||
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
esdi->error = ERR_ABRT;
|
||||
irq_raise(esdi);
|
||||
dev->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
dev->error = ERR_ABRT;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
if (get_sector(esdi, &addr)) {
|
||||
esdi->error = ERR_ID_NOT_FOUND;
|
||||
esdi->status = STAT_READY|STAT_DSC|STAT_ERR;
|
||||
irq_raise(esdi);
|
||||
if (get_sector(dev, &addr)) {
|
||||
dev->error = ERR_ID_NOT_FOUND;
|
||||
dev->status = STAT_READY|STAT_DSC|STAT_ERR;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
hdd_image_zero(drive->hdd_num, addr, esdi->secount);
|
||||
hdd_image_zero(drive->hdd_num, addr, dev->secount);
|
||||
|
||||
esdi->status = STAT_READY|STAT_DSC;
|
||||
irq_raise(esdi);
|
||||
dev->status = STAT_READY|STAT_DSC;
|
||||
irq_raise(dev);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1);
|
||||
break;
|
||||
|
||||
case CMD_DIAGNOSE:
|
||||
esdi->error = 1; /*no error detected*/
|
||||
esdi->status = STAT_READY|STAT_DSC;
|
||||
irq_raise(esdi);
|
||||
dev->error = 1; /*no error detected*/
|
||||
dev->status = STAT_READY|STAT_DSC;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
|
||||
case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */
|
||||
if (drive->present == 0) {
|
||||
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
esdi->error = ERR_ABRT;
|
||||
irq_raise(esdi);
|
||||
dev->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
dev->error = ERR_ABRT;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
drive->cfg_spt = esdi->secount;
|
||||
drive->cfg_hpc = esdi->head+1;
|
||||
drive->cfg_spt = dev->secount;
|
||||
drive->cfg_hpc = dev->head+1;
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1007: parameters: spt=%i hpc=%i\n", drive->cfg_spt,drive->cfg_hpc);
|
||||
#endif
|
||||
if (! esdi->secount)
|
||||
if (! dev->secount)
|
||||
fatal("WD1007: secount=0\n");
|
||||
esdi->status = STAT_READY|STAT_DSC;
|
||||
irq_raise(esdi);
|
||||
dev->status = STAT_READY|STAT_DSC;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
|
||||
case CMD_NOP:
|
||||
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
esdi->error = ERR_ABRT;
|
||||
irq_raise(esdi);
|
||||
dev->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
dev->error = ERR_ABRT;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
|
||||
case 0xe0:
|
||||
if (! drive->present) {
|
||||
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
esdi->error = ERR_ABRT;
|
||||
irq_raise(esdi);
|
||||
dev->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
dev->error = ERR_ABRT;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (esdi->cylinder >> 8) {
|
||||
switch (dev->cylinder >> 8) {
|
||||
case 0x31:
|
||||
esdi->cylinder = drive->real_tracks;
|
||||
dev->cylinder = drive->real_tracks;
|
||||
break;
|
||||
|
||||
case 0x33:
|
||||
esdi->cylinder = drive->real_hpc;
|
||||
dev->cylinder = drive->real_hpc;
|
||||
break;
|
||||
|
||||
case 0x35:
|
||||
esdi->cylinder = 0x200;
|
||||
dev->cylinder = 0x200;
|
||||
break;
|
||||
|
||||
case 0x36:
|
||||
esdi->cylinder = drive->real_spt;
|
||||
dev->cylinder = drive->real_spt;
|
||||
break;
|
||||
|
||||
default:
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1007: bad read config %02x\n",
|
||||
esdi->cylinder >> 8);
|
||||
dev->cylinder >> 8);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
esdi->status = STAT_READY|STAT_DSC;
|
||||
irq_raise(esdi);
|
||||
dev->status = STAT_READY|STAT_DSC;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
|
||||
case 0xa0:
|
||||
if (! drive->present) {
|
||||
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
esdi->error = ERR_ABRT;
|
||||
dev->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
dev->error = ERR_ABRT;
|
||||
} else {
|
||||
memset(esdi->buffer, 0x00, 512);
|
||||
memset(&esdi->buffer[3], 0xff, 512-6);
|
||||
esdi->pos = 0;
|
||||
esdi->status = STAT_DRQ|STAT_READY|STAT_DSC;
|
||||
memset(dev->buffer, 0x00, 512);
|
||||
memset(&dev->buffer[3], 0xff, 512-6);
|
||||
dev->pos = 0;
|
||||
dev->status = STAT_DRQ|STAT_READY|STAT_DSC;
|
||||
}
|
||||
irq_raise(esdi);
|
||||
irq_raise(dev);
|
||||
break;
|
||||
|
||||
case CMD_READ_PARAMETERS:
|
||||
if (! drive->present) {
|
||||
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
esdi->error = ERR_ABRT;
|
||||
irq_raise(esdi);
|
||||
dev->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
dev->error = ERR_ABRT;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
memset(esdi->buffer, 0x00, 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 */
|
||||
memset(dev->buffer, 0x00, 512);
|
||||
dev->buffer[0] = 0x44; /* general configuration */
|
||||
dev->buffer[1] = drive->real_tracks; /* number of non-removable cylinders */
|
||||
dev->buffer[2] = 0; /* number of removable cylinders */
|
||||
dev->buffer[3] = drive->real_hpc; /* number of heads */
|
||||
dev->buffer[4] = 600; /* number of unformatted bytes/track */
|
||||
dev->buffer[5] = dev->buffer[4] * drive->real_spt; /* number of unformatted bytes/sector */
|
||||
dev->buffer[6] = drive->real_spt; /* number of sectors */
|
||||
dev->buffer[7] = 0; /*minimum bytes in inter-sector gap*/
|
||||
dev->buffer[8] = 0; /* minimum bytes in postamble */
|
||||
dev->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);
|
||||
dev->buffer[20] = 2; /* controller type */
|
||||
dev->buffer[21] = 1; /* sector buffer size, in sectors */
|
||||
dev->buffer[22] = 0; /* ecc bytes appended */
|
||||
dev->buffer[27] = 'W' | ('D' << 8);
|
||||
dev->buffer[28] = '1' | ('0' << 8);
|
||||
dev->buffer[29] = '0' | ('7' << 8);
|
||||
dev->buffer[30] = 'V' | ('-' << 8);
|
||||
dev->buffer[31] = 'S' | ('E' << 8);
|
||||
dev->buffer[32] = '1';
|
||||
dev->buffer[47] = 0; /* sectors per interrupt */
|
||||
dev->buffer[48] = 0; /* can use double word read/write? */
|
||||
dev->pos = 0;
|
||||
dev->status = STAT_DRQ|STAT_READY|STAT_DSC;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1007: callback on unknown command %02x\n", esdi->command);
|
||||
hdc_log("WD1007: callback on unknown command %02x\n", dev->command);
|
||||
#endif
|
||||
/*FALLTHROUGH*/
|
||||
|
||||
case 0xe8:
|
||||
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
esdi->error = ERR_ABRT;
|
||||
irq_raise(esdi);
|
||||
dev->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
dev->error = ERR_ABRT;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -782,9 +784,9 @@ esdi_callback(void *priv)
|
||||
|
||||
|
||||
static void
|
||||
loadhd(esdi_t *esdi, int hdd_num, int d, const wchar_t *fn)
|
||||
loadhd(hdc_t *dev, int hdd_num, int d, const wchar_t *fn)
|
||||
{
|
||||
drive_t *drive = &esdi->drives[hdd_num];
|
||||
drive_t *drive = &dev->drives[hdd_num];
|
||||
|
||||
if (! hdd_image_load(d)) {
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
@@ -807,55 +809,55 @@ wd1007vse1_init(const device_t *info)
|
||||
{
|
||||
int c, d;
|
||||
|
||||
esdi_t *esdi = malloc(sizeof(esdi_t));
|
||||
memset(esdi, 0x00, sizeof(esdi_t));
|
||||
hdc_t *dev = malloc(sizeof(hdc_t));
|
||||
memset(dev, 0x00, sizeof(hdc_t));
|
||||
|
||||
c = 0;
|
||||
for (d=0; d<HDD_NUM; d++) {
|
||||
if ((hdd[d].bus==HDD_BUS_ESDI) && (hdd[d].esdi_channel<ESDI_NUM)) {
|
||||
loadhd(esdi, hdd[d].esdi_channel, d, hdd[d].fn);
|
||||
if ((hdd[d].bus==HDD_BUS_ESDI) && (hdd[d].id.esdi_channel<ESDI_NUM)) {
|
||||
loadhd(dev, hdd[d].id.esdi_channel, d, hdd[d].fn);
|
||||
|
||||
if (++c >= ESDI_NUM) break;
|
||||
}
|
||||
}
|
||||
|
||||
esdi->status = STAT_READY|STAT_DSC;
|
||||
esdi->error = 1;
|
||||
dev->status = STAT_READY|STAT_DSC;
|
||||
dev->error = 1;
|
||||
|
||||
rom_init(&esdi->bios_rom,
|
||||
rom_init(&dev->bios_rom,
|
||||
ESDI_BIOS_FILE, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
io_sethandler(0x01f0, 1,
|
||||
esdi_read, esdi_readw, NULL,
|
||||
esdi_write, esdi_writew, NULL, esdi);
|
||||
hdc_read, hdc_readw, NULL,
|
||||
hdc_write, hdc_writew, NULL, dev);
|
||||
io_sethandler(0x01f1, 7,
|
||||
esdi_read, NULL, NULL,
|
||||
esdi_write, NULL, NULL, esdi);
|
||||
hdc_read, NULL, NULL,
|
||||
hdc_write, NULL, NULL, dev);
|
||||
io_sethandler(0x03f6, 1, NULL, NULL, NULL,
|
||||
esdi_write, NULL, NULL, esdi);
|
||||
hdc_write, NULL, NULL, dev);
|
||||
|
||||
timer_add(esdi_callback, &esdi->callback, &esdi->callback, esdi);
|
||||
timer_add(hdc_callback, &dev->callback, &dev->callback, dev);
|
||||
|
||||
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||
|
||||
return(esdi);
|
||||
return(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
wd1007vse1_close(void *priv)
|
||||
{
|
||||
esdi_t *esdi = (esdi_t *)priv;
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
drive_t *drive;
|
||||
int d;
|
||||
|
||||
for (d=0; d<2; d++) {
|
||||
drive = &esdi->drives[d];
|
||||
drive = &dev->drives[d];
|
||||
|
||||
hdd_image_close(drive->hdd_num);
|
||||
}
|
||||
|
||||
free(esdi);
|
||||
free(dev);
|
||||
|
||||
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
* however, are auto-configured by the system software as
|
||||
* shown above.
|
||||
*
|
||||
* Version: @(#)hdc_esdi_mca.c 1.0.5 2018/04/02
|
||||
* Version: @(#)hdc_esdi_mca.c 1.0.7 2018/04/23
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
@@ -102,15 +102,15 @@
|
||||
#define ESDI_IOADDR_SEC 0x3518
|
||||
#define ESDI_IRQCHAN 14
|
||||
|
||||
#define BIOS_FILE_L L"hdd/esdi/90x8969.bin"
|
||||
#define BIOS_FILE_H L"hdd/esdi/90x8970.bin"
|
||||
#define BIOS_FILE_L L"disk/esdi_mca/90x8969.bin"
|
||||
#define BIOS_FILE_H L"disk/esdi_mca/90x8970.bin"
|
||||
|
||||
|
||||
#define ESDI_TIME (200LL*TIMER_USEC)
|
||||
#define CMD_ADAPTER 0
|
||||
|
||||
|
||||
typedef struct esdi_drive {
|
||||
typedef struct {
|
||||
uint8_t spt,
|
||||
hpc;
|
||||
uint16_t tracks;
|
||||
@@ -119,7 +119,7 @@ typedef struct esdi_drive {
|
||||
int8_t hdd_num;
|
||||
} drive_t;
|
||||
|
||||
typedef struct esdi {
|
||||
typedef struct {
|
||||
uint16_t base;
|
||||
int8_t irq;
|
||||
int8_t dma;
|
||||
@@ -164,7 +164,7 @@ typedef struct esdi {
|
||||
drive_t drives[2];
|
||||
|
||||
uint8_t pos_regs[8];
|
||||
} esdi_t;
|
||||
} hdc_t;
|
||||
|
||||
#define STATUS_DMA_ENA (1 << 7)
|
||||
#define STATUS_IRQ_PENDING (1 << 6)
|
||||
@@ -213,7 +213,7 @@ typedef struct esdi {
|
||||
|
||||
|
||||
static __inline void
|
||||
set_irq(esdi_t *dev)
|
||||
set_irq(hdc_t *dev)
|
||||
{
|
||||
if (dev->basic_ctrl & CTRL_IRQ_ENA)
|
||||
picint(1 << dev->irq);
|
||||
@@ -221,14 +221,14 @@ set_irq(esdi_t *dev)
|
||||
|
||||
|
||||
static __inline void
|
||||
clear_irq(esdi_t *dev)
|
||||
clear_irq(hdc_t *dev)
|
||||
{
|
||||
picintc(1 << dev->irq);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cmd_unsupported(esdi_t *dev)
|
||||
cmd_unsupported(hdc_t *dev)
|
||||
{
|
||||
dev->status_len = 9;
|
||||
dev->status_data[0] = dev->command | STATUS_LEN(9) | dev->cmd_dev;
|
||||
@@ -250,7 +250,7 @@ cmd_unsupported(esdi_t *dev)
|
||||
|
||||
|
||||
static void
|
||||
device_not_present(esdi_t *dev)
|
||||
device_not_present(hdc_t *dev)
|
||||
{
|
||||
dev->status_len = 9;
|
||||
dev->status_data[0] = dev->command | STATUS_LEN(9) | dev->cmd_dev;
|
||||
@@ -272,7 +272,7 @@ device_not_present(esdi_t *dev)
|
||||
|
||||
|
||||
static void
|
||||
rba_out_of_range(esdi_t *dev)
|
||||
rba_out_of_range(hdc_t *dev)
|
||||
{
|
||||
dev->status_len = 9;
|
||||
dev->status_data[0] = dev->command | STATUS_LEN(9) | dev->cmd_dev;
|
||||
@@ -316,9 +316,9 @@ rba_out_of_range(esdi_t *dev)
|
||||
|
||||
|
||||
static void
|
||||
esdi_callback(void *priv)
|
||||
hdc_callback(void *priv)
|
||||
{
|
||||
esdi_t *dev = (esdi_t *)priv;
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
drive_t *drive;
|
||||
int val;
|
||||
|
||||
@@ -733,9 +733,9 @@ esdi_callback(void *priv)
|
||||
|
||||
|
||||
static uint8_t
|
||||
esdi_read(uint16_t port, void *priv)
|
||||
hdc_read(uint16_t port, void *priv)
|
||||
{
|
||||
esdi_t *dev = (esdi_t *)priv;
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (port-dev->base) {
|
||||
@@ -757,9 +757,9 @@ esdi_read(uint16_t port, void *priv)
|
||||
|
||||
|
||||
static void
|
||||
esdi_write(uint16_t port, uint8_t val, void *priv)
|
||||
hdc_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
esdi_t *dev = (esdi_t *)priv;
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("ESDI: wr(%04x, %02x)\n", port-dev->base, val);
|
||||
@@ -863,9 +863,9 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
||||
|
||||
|
||||
static uint16_t
|
||||
esdi_readw(uint16_t port, void *priv)
|
||||
hdc_readw(uint16_t port, void *priv)
|
||||
{
|
||||
esdi_t *dev = (esdi_t *)priv;
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
uint16_t ret = 0xffff;
|
||||
|
||||
switch (port-dev->base) {
|
||||
@@ -888,9 +888,9 @@ esdi_readw(uint16_t port, void *priv)
|
||||
|
||||
|
||||
static void
|
||||
esdi_writew(uint16_t port, uint16_t val, void *priv)
|
||||
hdc_writew(uint16_t port, uint16_t val, void *priv)
|
||||
{
|
||||
esdi_t *dev = (esdi_t *)priv;
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("ESDI: wrw(%04x, %04x)\n", port-dev->base, val);
|
||||
@@ -922,9 +922,9 @@ esdi_writew(uint16_t port, uint16_t val, void *priv)
|
||||
|
||||
|
||||
static uint8_t
|
||||
esdi_mca_read(int port, void *priv)
|
||||
hdc_mca_read(int port, void *priv)
|
||||
{
|
||||
esdi_t *dev = (esdi_t *)priv;
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("ESDI: mcard(%04x)\n", port);
|
||||
@@ -934,9 +934,9 @@ esdi_mca_read(int port, void *priv)
|
||||
|
||||
|
||||
static void
|
||||
esdi_mca_write(int port, uint8_t val, void *priv)
|
||||
hdc_mca_write(int port, uint8_t val, void *priv)
|
||||
{
|
||||
esdi_t *dev = (esdi_t *)priv;
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("ESDI: mcawr(%04x, %02x) pos[2]=%02x pos[3]=%02x\n",
|
||||
@@ -956,8 +956,8 @@ esdi_mca_write(int port, uint8_t val, void *priv)
|
||||
* new base.
|
||||
*/
|
||||
io_removehandler(dev->base, 8,
|
||||
esdi_read, esdi_readw, NULL,
|
||||
esdi_write, esdi_writew, NULL, dev);
|
||||
hdc_read, hdc_readw, NULL,
|
||||
hdc_write, hdc_writew, NULL, dev);
|
||||
mem_mapping_disable(&dev->bios_rom.mapping);
|
||||
|
||||
/* Save the new value. */
|
||||
@@ -1046,8 +1046,8 @@ esdi_mca_write(int port, uint8_t val, void *priv)
|
||||
if (dev->pos_regs[2] & 0x01) {
|
||||
/* Card enabled; register (new) I/O handler. */
|
||||
io_sethandler(dev->base, 8,
|
||||
esdi_read, esdi_readw, NULL,
|
||||
esdi_write, esdi_writew, NULL, dev);
|
||||
hdc_read, hdc_readw, NULL,
|
||||
hdc_write, hdc_writew, NULL, dev);
|
||||
|
||||
/* Enable or disable the BIOS ROM. */
|
||||
if (dev->bios != 0x000000) {
|
||||
@@ -1067,12 +1067,12 @@ static void *
|
||||
esdi_init(const device_t *info)
|
||||
{
|
||||
drive_t *drive;
|
||||
esdi_t *dev;
|
||||
hdc_t *dev;
|
||||
int c, i;
|
||||
|
||||
dev = malloc(sizeof(esdi_t));
|
||||
dev = malloc(sizeof(hdc_t));
|
||||
if (dev == NULL) return(NULL);
|
||||
memset(dev, 0x00, sizeof(esdi_t));
|
||||
memset(dev, 0x00, sizeof(hdc_t));
|
||||
|
||||
/* Mark as unconfigured. */
|
||||
dev->irq_status = 0xff;
|
||||
@@ -1088,9 +1088,9 @@ esdi_init(const device_t *info)
|
||||
dev->drives[0].present = dev->drives[1].present = 0;
|
||||
|
||||
for (c=0,i=0; i<HDD_NUM; i++) {
|
||||
if ((hdd[i].bus == HDD_BUS_ESDI) && (hdd[i].esdi_channel < ESDI_NUM)) {
|
||||
if ((hdd[i].bus == HDD_BUS_ESDI) && (hdd[i].id.esdi_channel < ESDI_NUM)) {
|
||||
/* This is an ESDI drive. */
|
||||
drive = &dev->drives[hdd[i].esdi_channel];
|
||||
drive = &dev->drives[hdd[i].id.esdi_channel];
|
||||
|
||||
/* Try to load an image for the drive. */
|
||||
if (! hdd_image_load(i)) {
|
||||
@@ -1118,7 +1118,7 @@ esdi_init(const device_t *info)
|
||||
dev->pos_regs[1] = 0xdd;
|
||||
|
||||
/* Enable the device. */
|
||||
mca_add(esdi_mca_read, esdi_mca_write, dev);
|
||||
mca_add(hdc_mca_read, hdc_mca_write, dev);
|
||||
|
||||
/* Mark for a reset. */
|
||||
dev->in_reset = 1;
|
||||
@@ -1126,7 +1126,7 @@ esdi_init(const device_t *info)
|
||||
dev->status = STATUS_BUSY;
|
||||
|
||||
/* Set the reply timer. */
|
||||
timer_add(esdi_callback, &dev->callback, &dev->callback, dev);
|
||||
timer_add(hdc_callback, &dev->callback, &dev->callback, dev);
|
||||
|
||||
return(dev);
|
||||
}
|
||||
@@ -1135,13 +1135,13 @@ esdi_init(const device_t *info)
|
||||
static void
|
||||
esdi_close(void *priv)
|
||||
{
|
||||
esdi_t *dev = (esdi_t *)priv;
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
drive_t *drive;
|
||||
int d;
|
||||
|
||||
dev->drives[0].present = dev->drives[1].present = 0;
|
||||
|
||||
for (d=0; d<2; d++) {
|
||||
for (d = 0; d < ESDI_NUM; d++) {
|
||||
drive = &dev->drives[d];
|
||||
|
||||
hdd_image_close(drive->hdd_num);
|
||||
@@ -1162,5 +1162,7 @@ const device_t esdi_ps2_device = {
|
||||
"IBM ESDI Fixed Disk Adapter (MCA)",
|
||||
DEVICE_MCA, 0,
|
||||
esdi_init, esdi_close, NULL,
|
||||
esdi_available, NULL, NULL, NULL, NULL
|
||||
esdi_available,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Emulation of hard disk, CD-ROM and ZIP IDE/ATAPI devices.
|
||||
*
|
||||
* Version: @(#)hdc_ide.c 1.0.17 2018/04/10
|
||||
* Version: @(#)hdc_ide.c 1.0.18 2018/04/23
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
@@ -126,7 +126,7 @@ enum
|
||||
};
|
||||
|
||||
|
||||
IDE ide_drives[IDE_NUM + XTIDE_NUM];
|
||||
IDE ide_drives[IDE_NUM];
|
||||
IDE *ext_ide;
|
||||
int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length);
|
||||
int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length);
|
||||
@@ -837,7 +837,7 @@ void ide_destroy_buffers(void)
|
||||
{
|
||||
int d;
|
||||
|
||||
for (d = 0; d < (IDE_NUM+XTIDE_NUM); d++)
|
||||
for (d = 0; d < (IDE_NUM); d++)
|
||||
{
|
||||
if (ide_drives[d].buffer) {
|
||||
free(ide_drives[d].buffer);
|
||||
@@ -860,7 +860,7 @@ void ide_reset(void)
|
||||
build_atapi_zip_map();
|
||||
|
||||
/* Close hard disk image files (if previously open) */
|
||||
for (d = 0; d < (IDE_NUM+XTIDE_NUM); d++)
|
||||
for (d = 0; d < (IDE_NUM); d++)
|
||||
{
|
||||
ide_drives[d].channel = d;
|
||||
ide_drives[d].type = IDE_NONE;
|
||||
@@ -899,25 +899,15 @@ void ide_reset(void)
|
||||
c = 0;
|
||||
for (d = 0; d < HDD_NUM; d++)
|
||||
{
|
||||
if (((hdd[d].bus == HDD_BUS_IDE_PIO_ONLY) || (hdd[d].bus == HDD_BUS_IDE_PIO_AND_DMA)) && (hdd[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].id.ide_channel < IDE_NUM))
|
||||
{
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("Found IDE hard disk on channel %i\n", hdd[d].ide_channel);
|
||||
hdc_log("Found IDE hard disk on channel %i\n", hdd[d].id.ide_channel);
|
||||
#endif
|
||||
loadhd(&ide_drives[hdd[d].ide_channel], d, hdd[d].fn);
|
||||
ide_drives[hdd[d].ide_channel].sector_buffer = (uint8_t *) malloc(256*512);
|
||||
memset(ide_drives[hdd[d].ide_channel].sector_buffer, 0, 256*512);
|
||||
if (++c >= (IDE_NUM+XTIDE_NUM)) break;
|
||||
}
|
||||
if ((hdd[d].bus==HDD_BUS_XTIDE) && (hdd[d].xtide_channel < XTIDE_NUM))
|
||||
{
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("Found XT IDE hard disk on channel %i\n", hdd[d].xtide_channel);
|
||||
#endif
|
||||
loadhd(&ide_drives[hdd[d].xtide_channel | 8], d, hdd[d].fn);
|
||||
ide_drives[hdd[d].xtide_channel | 8].sector_buffer = (uint8_t *) malloc(256*512);
|
||||
memset(ide_drives[hdd[d].ide_channel].sector_buffer, 0, 256*512);
|
||||
if (++c >= (IDE_NUM+XTIDE_NUM)) break;
|
||||
loadhd(&ide_drives[hdd[d].id.ide_channel], d, hdd[d].fn);
|
||||
ide_drives[hdd[d].id.ide_channel].sector_buffer = (uint8_t *) malloc(256*512);
|
||||
memset(ide_drives[hdd[d].id.ide_channel].sector_buffer, 0, 256*512);
|
||||
if (++c >= IDE_NUM) break;
|
||||
}
|
||||
}
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
@@ -942,14 +932,6 @@ void ide_reset(void)
|
||||
ide_drives[d].error = 1;
|
||||
}
|
||||
|
||||
for (d = 0; d < XTIDE_NUM; d++)
|
||||
{
|
||||
ide_set_signature(&ide_drives[d | 8]);
|
||||
|
||||
ide_drives[d | 8].mdma_mode = -1;
|
||||
ide_drives[d | 8].error = 1;
|
||||
}
|
||||
|
||||
for (d = 0; d < 5; d++)
|
||||
{
|
||||
cur_ide[d] = d << 1;
|
||||
@@ -981,7 +963,7 @@ void ide_reset_hard(void)
|
||||
{
|
||||
int d;
|
||||
|
||||
for (d = 0; d < (IDE_NUM+XTIDE_NUM); d++)
|
||||
for (d = 0; d < (IDE_NUM); d++)
|
||||
{
|
||||
ide_drives[d].t_spt = ide_drives[d].spt;
|
||||
ide_drives[d].t_hpc = ide_drives[d].hpc;
|
||||
@@ -2928,7 +2910,7 @@ void ide_init_first(void)
|
||||
int d;
|
||||
|
||||
memset(ide_drives, 0x00, sizeof(ide_drives));
|
||||
for (d = 0; d < (IDE_NUM+XTIDE_NUM); d++)
|
||||
for (d = 0; d < (IDE_NUM); d++)
|
||||
{
|
||||
ide_drives[d].channel = d;
|
||||
ide_drives[d].type = IDE_NONE;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Definitions for the IDE module.
|
||||
*
|
||||
* Version: @(#)hdc_ide.h 1.0.6 2018/04/02
|
||||
* Version: @(#)hdc_ide.h 1.0.8 2018/04/23
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -87,7 +87,7 @@ typedef struct {
|
||||
extern int ideboard;
|
||||
extern int ide_enable[5];
|
||||
extern int ide_irq[5];
|
||||
extern IDE ide_drives[IDE_NUM + XTIDE_NUM];
|
||||
extern IDE ide_drives[IDE_NUM];
|
||||
extern int64_t idecallback[5];
|
||||
|
||||
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
*
|
||||
* This file is part of the VARCem Project.
|
||||
*
|
||||
* Driver for the IBM PC-AT MFM/RLL Fixed Disk controller.
|
||||
* Driver for the PC/AT ST506 MFM/RLL Fixed Disk controller.
|
||||
*
|
||||
* This controller was a 16bit ISA card, and it used a WD1003
|
||||
* based design. Most cards were WD1003-WA2 or -WAH, where the
|
||||
* -WA2 cards had a floppy controller as well (to save space.)
|
||||
*
|
||||
* Version: @(#)hdc_mfm_at.c 1.0.4 2018/04/02
|
||||
* Version: @(#)hdc_st506_at.c 1.0.5 2018/04/23
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
@@ -59,7 +59,7 @@
|
||||
#include "hdd.h"
|
||||
|
||||
|
||||
#define MFM_TIME (TIMER_USEC*10LL)
|
||||
#define ST506_TIME (TIMER_USEC*10LL)
|
||||
|
||||
#define STAT_ERR 0x01
|
||||
#define STAT_INDEX 0x02
|
||||
@@ -124,40 +124,40 @@ typedef struct {
|
||||
|
||||
uint16_t buffer[256]; /* data buffer (16b wide) */
|
||||
|
||||
drive_t drives[MFM_NUM]; /* attached drives */
|
||||
} mfm_t;
|
||||
drive_t drives[ST506_NUM]; /* attached drives */
|
||||
} hdc_t;
|
||||
|
||||
|
||||
static __inline void
|
||||
irq_raise(mfm_t *mfm)
|
||||
irq_raise(hdc_t *dev)
|
||||
{
|
||||
/* If not already pending.. */
|
||||
if (! mfm->irqstat) {
|
||||
if (! dev->irqstat) {
|
||||
/* If enabled in the control register.. */
|
||||
if (! (mfm->fdisk&0x02)) {
|
||||
if (! (dev->fdisk&0x02)) {
|
||||
/* .. raise IRQ14. */
|
||||
picint(1<<14);
|
||||
}
|
||||
|
||||
/* Remember this. */
|
||||
mfm->irqstat = 1;
|
||||
dev->irqstat = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static __inline void
|
||||
irq_lower(mfm_t *mfm)
|
||||
irq_lower(hdc_t *dev)
|
||||
{
|
||||
/* If raised.. */
|
||||
if (mfm->irqstat) {
|
||||
if (dev->irqstat) {
|
||||
/* If enabled in the control register.. */
|
||||
if (! (mfm->fdisk&0x02)) {
|
||||
if (! (dev->fdisk&0x02)) {
|
||||
/* .. drop IRQ14. */
|
||||
picintc(1<<14);
|
||||
}
|
||||
|
||||
/* Remember this. */
|
||||
mfm->irqstat = 0;
|
||||
dev->irqstat = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,52 +175,52 @@ irq_lower(mfm_t *mfm)
|
||||
* geometry information...
|
||||
*/
|
||||
static int
|
||||
get_sector(mfm_t *mfm, off64_t *addr)
|
||||
get_sector(hdc_t *dev, off64_t *addr)
|
||||
{
|
||||
drive_t *drive = &mfm->drives[mfm->drvsel];
|
||||
drive_t *drive = &dev->drives[dev->drvsel];
|
||||
|
||||
if (drive->curcyl != mfm->cylinder) {
|
||||
if (drive->curcyl != dev->cylinder) {
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1003(%d) sector: wrong cylinder\n");
|
||||
#endif
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (mfm->head > drive->cfg_hpc) {
|
||||
if (dev->head > drive->cfg_hpc) {
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1003(%d) get_sector: past end of configured heads\n",
|
||||
mfm->drvsel);
|
||||
dev->drvsel);
|
||||
#endif
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (mfm->sector >= drive->cfg_spt+1) {
|
||||
if (dev->sector >= drive->cfg_spt+1) {
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1003(%d) get_sector: past end of configured sectors\n",
|
||||
mfm->drvsel);
|
||||
dev->drvsel);
|
||||
#endif
|
||||
return(1);
|
||||
}
|
||||
|
||||
#if 1
|
||||
/* We should check this in the SET_DRIVE_PARAMETERS command! --FvK */
|
||||
if (mfm->head > drive->hpc) {
|
||||
if (dev->head > drive->hpc) {
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1003(%d) get_sector: past end of heads\n", mfm->drvsel);
|
||||
hdc_log("WD1003(%d) get_sector: past end of heads\n", dev->drvsel);
|
||||
#endif
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (mfm->sector >= drive->spt+1) {
|
||||
if (dev->sector >= drive->spt+1) {
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1003(%d) get_sector: past end of sectors\n", mfm->drvsel);
|
||||
hdc_log("WD1003(%d) get_sector: past end of sectors\n", dev->drvsel);
|
||||
#endif
|
||||
return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
*addr = ((((off64_t) mfm->cylinder * drive->cfg_hpc) + mfm->head) *
|
||||
drive->cfg_spt) + (mfm->sector - 1);
|
||||
*addr = ((((off64_t) dev->cylinder * drive->cfg_hpc) + dev->head) *
|
||||
drive->cfg_spt) + (dev->sector - 1);
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -228,15 +228,15 @@ get_sector(mfm_t *mfm, off64_t *addr)
|
||||
|
||||
/* Move to the next sector using CHS addressing. */
|
||||
static void
|
||||
next_sector(mfm_t *mfm)
|
||||
next_sector(hdc_t *dev)
|
||||
{
|
||||
drive_t *drive = &mfm->drives[mfm->drvsel];
|
||||
drive_t *drive = &dev->drives[dev->drvsel];
|
||||
|
||||
if (++mfm->sector == (drive->cfg_spt+1)) {
|
||||
mfm->sector = 1;
|
||||
if (++mfm->head == drive->cfg_hpc) {
|
||||
mfm->head = 0;
|
||||
mfm->cylinder++;
|
||||
if (++dev->sector == (drive->cfg_spt+1)) {
|
||||
dev->sector = 1;
|
||||
if (++dev->head == drive->cfg_hpc) {
|
||||
dev->head = 0;
|
||||
dev->cylinder++;
|
||||
if (drive->curcyl < drive->tracks)
|
||||
drive->curcyl++;
|
||||
}
|
||||
@@ -245,47 +245,47 @@ next_sector(mfm_t *mfm)
|
||||
|
||||
|
||||
static void
|
||||
mfm_cmd(mfm_t *mfm, uint8_t val)
|
||||
hdc_cmd(hdc_t *dev, uint8_t val)
|
||||
{
|
||||
drive_t *drive = &mfm->drives[mfm->drvsel];
|
||||
drive_t *drive = &dev->drives[dev->drvsel];
|
||||
|
||||
if (! drive->present) {
|
||||
/* This happens if sofware polls all drives. */
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1003(%d) command %02x on non-present drive\n",
|
||||
mfm->drvsel, val);
|
||||
dev->drvsel, val);
|
||||
#endif
|
||||
mfm->command = 0xff;
|
||||
mfm->status = STAT_BUSY;
|
||||
dev->command = 0xff;
|
||||
dev->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
mfm->callback = 200LL*MFM_TIME;
|
||||
dev->callback = 200LL*ST506_TIME;
|
||||
timer_update_outstanding();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
irq_lower(mfm);
|
||||
mfm->error = 0;
|
||||
irq_lower(dev);
|
||||
dev->error = 0;
|
||||
|
||||
switch (val & 0xf0) {
|
||||
case CMD_RESTORE:
|
||||
drive->steprate = (val & 0x0f);
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1003(%d) restore, step=%d\n",
|
||||
mfm->drvsel, drive->steprate);
|
||||
dev->drvsel, drive->steprate);
|
||||
#endif
|
||||
drive->curcyl = 0;
|
||||
mfm->status = STAT_READY|STAT_DSC;
|
||||
mfm->command = 0x00;
|
||||
irq_raise(mfm);
|
||||
dev->status = STAT_READY|STAT_DSC;
|
||||
dev->command = 0x00;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
|
||||
case CMD_SEEK:
|
||||
drive->steprate = (val & 0x0f);
|
||||
mfm->command = (val & 0xf0);
|
||||
mfm->status = STAT_BUSY;
|
||||
dev->command = (val & 0xf0);
|
||||
dev->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
mfm->callback = 200LL*MFM_TIME;
|
||||
dev->callback = 200LL*ST506_TIME;
|
||||
timer_update_outstanding();
|
||||
break;
|
||||
|
||||
@@ -297,14 +297,14 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
|
||||
case CMD_READ+3:
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1003(%d) read, opt=%d\n",
|
||||
mfm->drvsel, val&0x03);
|
||||
dev->drvsel, val&0x03);
|
||||
#endif
|
||||
mfm->command = (val & 0xf0);
|
||||
dev->command = (val & 0xf0);
|
||||
if (val & 2)
|
||||
fatal("WD1003: READ with ECC\n");
|
||||
mfm->status = STAT_BUSY;
|
||||
dev->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
mfm->callback = 200LL*MFM_TIME;
|
||||
dev->callback = 200LL*ST506_TIME;
|
||||
timer_update_outstanding();
|
||||
break;
|
||||
|
||||
@@ -314,35 +314,35 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
|
||||
case CMD_WRITE+3:
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1003(%d) write, opt=%d\n",
|
||||
mfm->drvsel, val & 0x03);
|
||||
dev->drvsel, val & 0x03);
|
||||
#endif
|
||||
mfm->command = (val & 0xf0);
|
||||
dev->command = (val & 0xf0);
|
||||
if (val & 2)
|
||||
fatal("WD1003: WRITE with ECC\n");
|
||||
mfm->status = STAT_DRQ|STAT_DSC;
|
||||
mfm->pos = 0;
|
||||
dev->status = STAT_DRQ|STAT_DSC;
|
||||
dev->pos = 0;
|
||||
break;
|
||||
|
||||
case CMD_VERIFY:
|
||||
case CMD_VERIFY+1:
|
||||
mfm->command = (val & 0xfe);
|
||||
mfm->status = STAT_BUSY;
|
||||
dev->command = (val & 0xfe);
|
||||
dev->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
mfm->callback = 200LL*MFM_TIME;
|
||||
dev->callback = 200LL*ST506_TIME;
|
||||
timer_update_outstanding();
|
||||
break;
|
||||
|
||||
case CMD_FORMAT:
|
||||
mfm->command = val;
|
||||
mfm->status = STAT_DRQ|STAT_BUSY;
|
||||
mfm->pos = 0;
|
||||
dev->command = val;
|
||||
dev->status = STAT_DRQ|STAT_BUSY;
|
||||
dev->pos = 0;
|
||||
break;
|
||||
|
||||
case CMD_DIAGNOSE:
|
||||
mfm->command = val;
|
||||
mfm->status = STAT_BUSY;
|
||||
dev->command = val;
|
||||
dev->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
mfm->callback = 200LL*MFM_TIME;
|
||||
dev->callback = 200LL*ST506_TIME;
|
||||
timer_update_outstanding();
|
||||
break;
|
||||
|
||||
@@ -365,33 +365,33 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
|
||||
*/
|
||||
if (drive->cfg_spt == 0) {
|
||||
/* Only accept after RESET or DIAG. */
|
||||
drive->cfg_spt = mfm->secount;
|
||||
drive->cfg_hpc = mfm->head+1;
|
||||
drive->cfg_spt = dev->secount;
|
||||
drive->cfg_hpc = dev->head+1;
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1003(%d) parameters: tracks=%d, spt=%i, hpc=%i\n",
|
||||
mfm->drvsel, drive->tracks,
|
||||
dev->drvsel, drive->tracks,
|
||||
drive->cfg_spt, drive->cfg_hpc);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1003(%d) parameters: tracks=%d,spt=%i,hpc=%i (IGNORED)\n",
|
||||
mfm->drvsel, drive->tracks,
|
||||
dev->drvsel, drive->tracks,
|
||||
drive->cfg_spt, drive->cfg_hpc);
|
||||
#endif
|
||||
}
|
||||
mfm->command = 0x00;
|
||||
mfm->status = STAT_READY|STAT_DSC;
|
||||
mfm->error = 1;
|
||||
irq_raise(mfm);
|
||||
dev->command = 0x00;
|
||||
dev->status = STAT_READY|STAT_DSC;
|
||||
dev->error = 1;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1003: bad command %02X\n", val);
|
||||
#endif
|
||||
mfm->status = STAT_BUSY;
|
||||
dev->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
mfm->callback = 200LL*MFM_TIME;
|
||||
dev->callback = 200LL*ST506_TIME;
|
||||
timer_update_outstanding();
|
||||
break;
|
||||
}
|
||||
@@ -400,113 +400,113 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
|
||||
|
||||
|
||||
static void
|
||||
mfm_writew(uint16_t port, uint16_t val, void *priv)
|
||||
hdc_writew(uint16_t port, uint16_t val, void *priv)
|
||||
{
|
||||
mfm_t *mfm = (mfm_t *)priv;
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
|
||||
mfm->buffer[mfm->pos >> 1] = val;
|
||||
mfm->pos += 2;
|
||||
dev->buffer[dev->pos >> 1] = val;
|
||||
dev->pos += 2;
|
||||
|
||||
if (mfm->pos >= 512) {
|
||||
mfm->pos = 0;
|
||||
mfm->status = STAT_BUSY;
|
||||
if (dev->pos >= 512) {
|
||||
dev->pos = 0;
|
||||
dev->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
mfm->callback = 6LL*MFM_TIME;
|
||||
dev->callback = 6LL*ST506_TIME;
|
||||
timer_update_outstanding();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mfm_write(uint16_t port, uint8_t val, void *priv)
|
||||
hdc_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
mfm_t *mfm = (mfm_t *)priv;
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1003 write(%04x, %02x)\n", port, val);
|
||||
#endif
|
||||
switch (port) {
|
||||
case 0x01f0: /* data */
|
||||
mfm_writew(port, val | (val << 8), priv);
|
||||
hdc_writew(port, val | (val << 8), priv);
|
||||
return;
|
||||
|
||||
case 0x01f1: /* write precompenstation */
|
||||
mfm->precomp = val;
|
||||
dev->precomp = val;
|
||||
return;
|
||||
|
||||
case 0x01f2: /* sector count */
|
||||
mfm->secount = val;
|
||||
dev->secount = val;
|
||||
return;
|
||||
|
||||
case 0x01f3: /* sector */
|
||||
mfm->sector = val;
|
||||
dev->sector = val;
|
||||
return;
|
||||
|
||||
case 0x01f4: /* cylinder low */
|
||||
mfm->cylinder = (mfm->cylinder & 0xff00) | val;
|
||||
dev->cylinder = (dev->cylinder & 0xff00) | val;
|
||||
return;
|
||||
|
||||
case 0x01f5: /* cylinder high */
|
||||
mfm->cylinder = (mfm->cylinder & 0xff) | (val << 8);
|
||||
dev->cylinder = (dev->cylinder & 0xff) | (val << 8);
|
||||
return;
|
||||
|
||||
case 0x01f6: /* drive/head */
|
||||
mfm->head = val & 0xF;
|
||||
mfm->drvsel = (val & 0x10) ? 1 : 0;
|
||||
if (mfm->drives[mfm->drvsel].present)
|
||||
mfm->status = STAT_READY|STAT_DSC;
|
||||
dev->head = val & 0xF;
|
||||
dev->drvsel = (val & 0x10) ? 1 : 0;
|
||||
if (dev->drives[dev->drvsel].present)
|
||||
dev->status = STAT_READY|STAT_DSC;
|
||||
else
|
||||
mfm->status = 0;
|
||||
dev->status = 0;
|
||||
return;
|
||||
|
||||
case 0x01f7: /* command register */
|
||||
mfm_cmd(mfm, val);
|
||||
hdc_cmd(dev, val);
|
||||
break;
|
||||
|
||||
case 0x03f6: /* device control */
|
||||
val &= 0x0f;
|
||||
if ((mfm->fdisk & 0x04) && !(val & 0x04)) {
|
||||
mfm->status = STAT_BUSY;
|
||||
mfm->reset = 1;
|
||||
if ((dev->fdisk & 0x04) && !(val & 0x04)) {
|
||||
dev->status = STAT_BUSY;
|
||||
dev->reset = 1;
|
||||
timer_clock();
|
||||
mfm->callback = 500LL*MFM_TIME;
|
||||
dev->callback = 500LL*ST506_TIME;
|
||||
timer_update_outstanding();
|
||||
}
|
||||
|
||||
if (val & 0x04) {
|
||||
/* Drive held in reset. */
|
||||
mfm->status = STAT_BUSY;
|
||||
mfm->callback = 0LL;
|
||||
dev->status = STAT_BUSY;
|
||||
dev->callback = 0LL;
|
||||
timer_clock();
|
||||
timer_update_outstanding();
|
||||
}
|
||||
mfm->fdisk = val;
|
||||
dev->fdisk = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint16_t
|
||||
mfm_readw(uint16_t port, void *priv)
|
||||
hdc_readw(uint16_t port, void *priv)
|
||||
{
|
||||
mfm_t *mfm = (mfm_t *)priv;
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
uint16_t ret;
|
||||
|
||||
ret = mfm->buffer[mfm->pos >> 1];
|
||||
mfm->pos += 2;
|
||||
if (mfm->pos >= 512) {
|
||||
mfm->pos = 0;
|
||||
mfm->status = STAT_READY|STAT_DSC;
|
||||
if (mfm->command == CMD_READ) {
|
||||
mfm->secount = (mfm->secount - 1) & 0xff;
|
||||
if (mfm->secount) {
|
||||
next_sector(mfm);
|
||||
mfm->status = STAT_BUSY;
|
||||
ret = dev->buffer[dev->pos >> 1];
|
||||
dev->pos += 2;
|
||||
if (dev->pos >= 512) {
|
||||
dev->pos = 0;
|
||||
dev->status = STAT_READY|STAT_DSC;
|
||||
if (dev->command == CMD_READ) {
|
||||
dev->secount = (dev->secount - 1) & 0xff;
|
||||
if (dev->secount) {
|
||||
next_sector(dev);
|
||||
dev->status = STAT_BUSY;
|
||||
timer_clock();
|
||||
mfm->callback = 6LL*MFM_TIME;
|
||||
dev->callback = 6LL*ST506_TIME;
|
||||
timer_update_outstanding();
|
||||
} else {
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -516,43 +516,43 @@ mfm_readw(uint16_t port, void *priv)
|
||||
|
||||
|
||||
static uint8_t
|
||||
mfm_read(uint16_t port, void *priv)
|
||||
hdc_read(uint16_t port, void *priv)
|
||||
{
|
||||
mfm_t *mfm = (mfm_t *)priv;
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (port) {
|
||||
case 0x01f0: /* data */
|
||||
ret = mfm_readw(port, mfm) & 0xff;
|
||||
ret = hdc_readw(port, dev) & 0xff;
|
||||
break;
|
||||
|
||||
case 0x01f1: /* error */
|
||||
ret = mfm->error;
|
||||
ret = dev->error;
|
||||
break;
|
||||
|
||||
case 0x01f2: /* sector count */
|
||||
ret = mfm->secount;
|
||||
ret = dev->secount;
|
||||
break;
|
||||
|
||||
case 0x01f3: /* sector */
|
||||
ret = mfm->sector;
|
||||
ret = dev->sector;
|
||||
break;
|
||||
|
||||
case 0x01f4: /* CYlinder low */
|
||||
ret = (uint8_t)(mfm->cylinder&0xff);
|
||||
ret = (uint8_t)(dev->cylinder&0xff);
|
||||
break;
|
||||
|
||||
case 0x01f5: /* Cylinder high */
|
||||
ret = (uint8_t)(mfm->cylinder>>8);
|
||||
ret = (uint8_t)(dev->cylinder>>8);
|
||||
break;
|
||||
|
||||
case 0x01f6: /* drive/head */
|
||||
ret = (uint8_t)(0xa0 | mfm->head | (mfm->drvsel?0x10:0));
|
||||
ret = (uint8_t)(0xa0 | dev->head | (dev->drvsel?0x10:0));
|
||||
break;
|
||||
|
||||
case 0x01f7: /* Status */
|
||||
irq_lower(mfm);
|
||||
ret = mfm->status;
|
||||
irq_lower(dev);
|
||||
ret = dev->status;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -567,16 +567,16 @@ mfm_read(uint16_t port, void *priv)
|
||||
|
||||
|
||||
static void
|
||||
do_seek(mfm_t *mfm)
|
||||
do_seek(hdc_t *dev)
|
||||
{
|
||||
drive_t *drive = &mfm->drives[mfm->drvsel];
|
||||
drive_t *drive = &dev->drives[dev->drvsel];
|
||||
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1003(%d) seek(%d) max=%d\n",
|
||||
mfm->drvsel,mfm->cylinder,drive->tracks);
|
||||
dev->drvsel,dev->cylinder,drive->tracks);
|
||||
#endif
|
||||
if (mfm->cylinder < drive->tracks)
|
||||
drive->curcyl = mfm->cylinder;
|
||||
if (dev->cylinder < drive->tracks)
|
||||
drive->curcyl = dev->cylinder;
|
||||
else
|
||||
drive->curcyl = drive->tracks-1;
|
||||
}
|
||||
@@ -585,152 +585,152 @@ do_seek(mfm_t *mfm)
|
||||
static void
|
||||
do_callback(void *priv)
|
||||
{
|
||||
mfm_t *mfm = (mfm_t *)priv;
|
||||
drive_t *drive = &mfm->drives[mfm->drvsel];
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
drive_t *drive = &dev->drives[dev->drvsel];
|
||||
off64_t addr;
|
||||
|
||||
mfm->callback = 0LL;
|
||||
if (mfm->reset) {
|
||||
dev->callback = 0LL;
|
||||
if (dev->reset) {
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1003(%d) reset\n", mfm->drvsel);
|
||||
hdc_log("WD1003(%d) reset\n", dev->drvsel);
|
||||
#endif
|
||||
mfm->status = STAT_READY|STAT_DSC;
|
||||
mfm->error = 1;
|
||||
mfm->secount = 1;
|
||||
mfm->sector = 1;
|
||||
mfm->head = 0;
|
||||
mfm->cylinder = 0;
|
||||
dev->status = STAT_READY|STAT_DSC;
|
||||
dev->error = 1;
|
||||
dev->secount = 1;
|
||||
dev->sector = 1;
|
||||
dev->head = 0;
|
||||
dev->cylinder = 0;
|
||||
|
||||
drive->steprate = 0x0f; /* default steprate */
|
||||
drive->cfg_spt = 0; /* need new parameters */
|
||||
|
||||
mfm->reset = 0;
|
||||
dev->reset = 0;
|
||||
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
switch (mfm->command) {
|
||||
switch (dev->command) {
|
||||
case CMD_SEEK:
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1003(%d) seek, step=%d\n",
|
||||
mfm->drvsel, drive->steprate);
|
||||
dev->drvsel, drive->steprate);
|
||||
#endif
|
||||
do_seek(mfm);
|
||||
mfm->status = STAT_READY|STAT_DSC;
|
||||
irq_raise(mfm);
|
||||
do_seek(dev);
|
||||
dev->status = STAT_READY|STAT_DSC;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
|
||||
case CMD_READ:
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1003(%d) read(%d,%d,%d)\n",
|
||||
mfm->drvsel, mfm->cylinder, mfm->head, mfm->sector);
|
||||
dev->drvsel, dev->cylinder, dev->head, dev->sector);
|
||||
#endif
|
||||
do_seek(mfm);
|
||||
if (get_sector(mfm, &addr)) {
|
||||
mfm->error = ERR_ID_NOT_FOUND;
|
||||
mfm->status = STAT_READY|STAT_DSC|STAT_ERR;
|
||||
irq_raise(mfm);
|
||||
do_seek(dev);
|
||||
if (get_sector(dev, &addr)) {
|
||||
dev->error = ERR_ID_NOT_FOUND;
|
||||
dev->status = STAT_READY|STAT_DSC|STAT_ERR;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *)mfm->buffer);
|
||||
hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *)dev->buffer);
|
||||
|
||||
mfm->pos = 0;
|
||||
mfm->status = STAT_DRQ|STAT_READY|STAT_DSC;
|
||||
irq_raise(mfm);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1);
|
||||
dev->pos = 0;
|
||||
dev->status = STAT_DRQ|STAT_READY|STAT_DSC;
|
||||
irq_raise(dev);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 1);
|
||||
break;
|
||||
|
||||
case CMD_WRITE:
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1003(%d) write(%d,%d,%d)\n",
|
||||
mfm->drvsel, mfm->cylinder, mfm->head, mfm->sector);
|
||||
dev->drvsel, dev->cylinder, dev->head, dev->sector);
|
||||
#endif
|
||||
do_seek(mfm);
|
||||
if (get_sector(mfm, &addr)) {
|
||||
mfm->error = ERR_ID_NOT_FOUND;
|
||||
mfm->status = STAT_READY|STAT_DSC|STAT_ERR;
|
||||
irq_raise(mfm);
|
||||
do_seek(dev);
|
||||
if (get_sector(dev, &addr)) {
|
||||
dev->error = ERR_ID_NOT_FOUND;
|
||||
dev->status = STAT_READY|STAT_DSC|STAT_ERR;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
hdd_image_write(drive->hdd_num, addr, 1,(uint8_t *)mfm->buffer);
|
||||
hdd_image_write(drive->hdd_num, addr, 1,(uint8_t *)dev->buffer);
|
||||
|
||||
mfm->status = STAT_READY|STAT_DSC;
|
||||
mfm->secount = (mfm->secount - 1) & 0xff;
|
||||
if (mfm->secount) {
|
||||
dev->status = STAT_READY|STAT_DSC;
|
||||
dev->secount = (dev->secount - 1) & 0xff;
|
||||
if (dev->secount) {
|
||||
/* More sectors to do.. */
|
||||
mfm->status |= STAT_DRQ;
|
||||
mfm->pos = 0;
|
||||
next_sector(mfm);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1);
|
||||
dev->status |= STAT_DRQ;
|
||||
dev->pos = 0;
|
||||
next_sector(dev);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 1);
|
||||
} else {
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 0);
|
||||
}
|
||||
irq_raise(mfm);
|
||||
irq_raise(dev);
|
||||
break;
|
||||
|
||||
case CMD_VERIFY:
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1003(%d) verify(%d,%d,%d)\n",
|
||||
mfm->drvsel, mfm->cylinder, mfm->head, mfm->sector);
|
||||
dev->drvsel, dev->cylinder, dev->head, dev->sector);
|
||||
#endif
|
||||
do_seek(mfm);
|
||||
mfm->pos = 0;
|
||||
mfm->status = STAT_READY|STAT_DSC;
|
||||
irq_raise(mfm);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1);
|
||||
do_seek(dev);
|
||||
dev->pos = 0;
|
||||
dev->status = STAT_READY|STAT_DSC;
|
||||
irq_raise(dev);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 1);
|
||||
break;
|
||||
|
||||
case CMD_FORMAT:
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1003(%d) format(%d,%d)\n",
|
||||
mfm->drvsel, mfm->cylinder, mfm->head);
|
||||
dev->drvsel, dev->cylinder, dev->head);
|
||||
#endif
|
||||
do_seek(mfm);
|
||||
if (get_sector(mfm, &addr)) {
|
||||
mfm->error = ERR_ID_NOT_FOUND;
|
||||
mfm->status = STAT_READY|STAT_DSC|STAT_ERR;
|
||||
irq_raise(mfm);
|
||||
do_seek(dev);
|
||||
if (get_sector(dev, &addr)) {
|
||||
dev->error = ERR_ID_NOT_FOUND;
|
||||
dev->status = STAT_READY|STAT_DSC|STAT_ERR;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
hdd_image_zero(drive->hdd_num, addr, mfm->secount);
|
||||
hdd_image_zero(drive->hdd_num, addr, dev->secount);
|
||||
|
||||
mfm->status = STAT_READY|STAT_DSC;
|
||||
irq_raise(mfm);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1);
|
||||
dev->status = STAT_READY|STAT_DSC;
|
||||
irq_raise(dev);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 1);
|
||||
break;
|
||||
|
||||
case CMD_DIAGNOSE:
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1003(%d) diag\n", mfm->drvsel);
|
||||
hdc_log("WD1003(%d) diag\n", dev->drvsel);
|
||||
#endif
|
||||
drive->steprate = 0x0f;
|
||||
mfm->error = 1;
|
||||
mfm->status = STAT_READY|STAT_DSC;
|
||||
irq_raise(mfm);
|
||||
dev->error = 1;
|
||||
dev->status = STAT_READY|STAT_DSC;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1003(%d) callback on unknown command %02x\n",
|
||||
mfm->drvsel, mfm->command);
|
||||
dev->drvsel, dev->command);
|
||||
#endif
|
||||
mfm->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
mfm->error = ERR_ABRT;
|
||||
irq_raise(mfm);
|
||||
dev->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||
dev->error = ERR_ABRT;
|
||||
irq_raise(dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
loadhd(mfm_t *mfm, int c, int d, const wchar_t *fn)
|
||||
loadhd(hdc_t *dev, int c, int d, const wchar_t *fn)
|
||||
{
|
||||
drive_t *drive = &mfm->drives[c];
|
||||
drive_t *drive = &dev->drives[c];
|
||||
|
||||
if (! hdd_image_load(d)) {
|
||||
drive->present = 0;
|
||||
@@ -747,71 +747,72 @@ loadhd(mfm_t *mfm, int c, int d, const wchar_t *fn)
|
||||
|
||||
|
||||
static void *
|
||||
mfm_init(const device_t *info)
|
||||
st506_init(const device_t *info)
|
||||
{
|
||||
mfm_t *mfm;
|
||||
hdc_t *dev;
|
||||
int c, d;
|
||||
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1003: ISA MFM/RLL Fixed Disk Adapter initializing ...\n");
|
||||
hdc_log("WD1003: ISA ST506/RLL Fixed Disk Adapter initializing ...\n");
|
||||
#endif
|
||||
mfm = malloc(sizeof(mfm_t));
|
||||
memset(mfm, 0x00, sizeof(mfm_t));
|
||||
dev = malloc(sizeof(hdc_t));
|
||||
memset(dev, 0x00, sizeof(hdc_t));
|
||||
|
||||
c = 0;
|
||||
for (d=0; d<HDD_NUM; d++) {
|
||||
if ((hdd[d].bus == HDD_BUS_MFM) && (hdd[d].mfm_channel < MFM_NUM)) {
|
||||
loadhd(mfm, hdd[d].mfm_channel, d, hdd[d].fn);
|
||||
if ((hdd[d].bus == HDD_BUS_ST506) && (hdd[d].id.st506_channel < ST506_NUM)) {
|
||||
loadhd(dev, hdd[d].id.st506_channel, d, hdd[d].fn);
|
||||
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("WD1003(%d): (%ls) geometry %d/%d/%d\n", c, hdd[d].fn,
|
||||
(int)hdd[d].tracks, (int)hdd[d].hpc, (int)hdd[d].spt);
|
||||
#endif
|
||||
|
||||
if (++c >= MFM_NUM) break;
|
||||
if (++c >= ST506_NUM) break;
|
||||
}
|
||||
}
|
||||
|
||||
mfm->status = STAT_READY|STAT_DSC; /* drive is ready */
|
||||
mfm->error = 1; /* no errors */
|
||||
dev->status = STAT_READY|STAT_DSC; /* drive is ready */
|
||||
dev->error = 1; /* no errors */
|
||||
|
||||
io_sethandler(0x01f0, 1,
|
||||
mfm_read, mfm_readw, NULL, mfm_write, mfm_writew, NULL, mfm);
|
||||
hdc_read, hdc_readw, NULL, hdc_write, hdc_writew, NULL, dev);
|
||||
io_sethandler(0x01f1, 7,
|
||||
mfm_read, NULL, NULL, mfm_write, NULL, NULL, mfm);
|
||||
hdc_read, NULL, NULL, hdc_write, NULL, NULL, dev);
|
||||
io_sethandler(0x03f6, 1,
|
||||
NULL, NULL, NULL, mfm_write, NULL, NULL, mfm);
|
||||
NULL, NULL, NULL, hdc_write, NULL, NULL, dev);
|
||||
|
||||
timer_add(do_callback, &mfm->callback, &mfm->callback, mfm);
|
||||
timer_add(do_callback, &dev->callback, &dev->callback, dev);
|
||||
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 0);
|
||||
|
||||
return(mfm);
|
||||
return(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mfm_close(void *priv)
|
||||
st506_close(void *priv)
|
||||
{
|
||||
mfm_t *mfm = (mfm_t *)priv;
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
int d;
|
||||
|
||||
for (d=0; d<2; d++) {
|
||||
drive_t *drive = &mfm->drives[d];
|
||||
drive_t *drive = &dev->drives[d];
|
||||
|
||||
hdd_image_close(drive->hdd_num);
|
||||
}
|
||||
|
||||
free(mfm);
|
||||
free(dev);
|
||||
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 0);
|
||||
}
|
||||
|
||||
|
||||
const device_t mfm_at_wd1003_device = {
|
||||
const device_t st506_at_wd1003_device = {
|
||||
"WD1003 AT MFM/RLL Controller",
|
||||
DEVICE_ISA | DEVICE_AT,
|
||||
0,
|
||||
mfm_init, mfm_close, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL
|
||||
st506_init, st506_close, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -41,7 +41,7 @@
|
||||
* Since all controllers (including the ones made by DTC) use
|
||||
* (mostly) the same API, we keep them all in this module.
|
||||
*
|
||||
* Version: @(#)hdc_mfm_xt.c 1.0.6 2018/04/18
|
||||
* Version: @(#)hdc_st506_xt.c 1.0.7 2018/04/23
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
@@ -89,9 +89,10 @@
|
||||
#include "hdd.h"
|
||||
|
||||
|
||||
#define MFM_TIME (2000LL*TIMER_USEC)
|
||||
#define XEBEC_BIOS_FILE L"hdd/mfm_xebec/ibm_xebec_62x0822_1985.bin"
|
||||
#define DTC_BIOS_FILE L"hdd/mfm_xebec/dtc_cxd21a.bin"
|
||||
#define ST506_TIME (2000LL*TIMER_USEC)
|
||||
|
||||
#define XEBEC_BIOS_FILE L"disk/st506/ibm_xebec_62x0822_1985.bin"
|
||||
#define DTC_BIOS_FILE L"disk/st506/dtc_cxd21a.bin"
|
||||
|
||||
|
||||
enum {
|
||||
@@ -140,7 +141,7 @@ typedef struct {
|
||||
cylinder;
|
||||
int sector_count;
|
||||
uint8_t switches;
|
||||
} mfm_t;
|
||||
} hdc_t;
|
||||
|
||||
#define STAT_IRQ 0x20
|
||||
#define STAT_DRQ 0x10
|
||||
@@ -164,6 +165,7 @@ typedef struct {
|
||||
#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
|
||||
@@ -175,9 +177,9 @@ typedef struct {
|
||||
|
||||
|
||||
static uint8_t
|
||||
mfm_read(uint16_t port, void *priv)
|
||||
st506_read(uint16_t port, void *priv)
|
||||
{
|
||||
mfm_t *dev = (mfm_t *)priv;
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
uint8_t temp = 0xff;
|
||||
|
||||
switch (port) {
|
||||
@@ -202,7 +204,7 @@ mfm_read(uint16_t port, void *priv)
|
||||
if (dev->data_pos == dev->data_len) {
|
||||
dev->status = STAT_BSY;
|
||||
dev->state = STATE_SENT_DATA;
|
||||
dev->callback = MFM_TIME;
|
||||
dev->callback = ST506_TIME;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -225,9 +227,9 @@ mfm_read(uint16_t port, void *priv)
|
||||
|
||||
|
||||
static void
|
||||
mfm_write(uint16_t port, uint8_t val, void *priv)
|
||||
st506_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
mfm_t *dev = (mfm_t *)priv;
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
|
||||
switch (port) {
|
||||
case 0x320: /*Write data*/
|
||||
@@ -242,7 +244,7 @@ mfm_write(uint16_t port, uint8_t val, void *priv)
|
||||
if (dev->command_pos == 6) {
|
||||
dev->status = STAT_BSY;
|
||||
dev->state = STATE_START_COMMAND;
|
||||
dev->callback = MFM_TIME;
|
||||
dev->callback = ST506_TIME;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -256,7 +258,7 @@ mfm_write(uint16_t port, uint8_t val, void *priv)
|
||||
if (dev->data_pos == dev->data_len) {
|
||||
dev->status = STAT_BSY;
|
||||
dev->state = STATE_RECEIVED_DATA;
|
||||
dev->callback = MFM_TIME;
|
||||
dev->callback = ST506_TIME;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -283,7 +285,7 @@ mfm_write(uint16_t port, uint8_t val, void *priv)
|
||||
|
||||
|
||||
static void
|
||||
mfm_complete(mfm_t *dev)
|
||||
st506_complete(hdc_t *dev)
|
||||
{
|
||||
dev->status = STAT_REQ | STAT_CD | STAT_IO | STAT_BSY;
|
||||
dev->state = STATE_COMPLETION_BYTE;
|
||||
@@ -296,47 +298,47 @@ mfm_complete(mfm_t *dev)
|
||||
|
||||
|
||||
static void
|
||||
mfm_error(mfm_t *dev, uint8_t error)
|
||||
st506_error(hdc_t *dev, uint8_t error)
|
||||
{
|
||||
dev->completion_byte |= 0x02;
|
||||
dev->error = error;
|
||||
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("mfm_error - %02x\n", dev->error);
|
||||
hdc_log("st506_error - %02x\n", dev->error);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
get_sector(mfm_t *dev, off64_t *addr)
|
||||
get_sector(hdc_t *dev, off64_t *addr)
|
||||
{
|
||||
drive_t *drive = &dev->drives[dev->drive_sel];
|
||||
int heads = drive->cfg_hpc;
|
||||
|
||||
if (drive->current_cylinder != dev->cylinder) {
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("mfm_get_sector: wrong cylinder\n");
|
||||
hdc_log("st506_get_sector: wrong cylinder\n");
|
||||
#endif
|
||||
dev->error = ERR_ILLEGAL_SECTOR_ADDRESS;
|
||||
return(1);
|
||||
}
|
||||
if (dev->head > heads) {
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("mfm_get_sector: past end of configured heads\n");
|
||||
hdc_log("st506_get_sector: past end of configured heads\n");
|
||||
#endif
|
||||
dev->error = ERR_ILLEGAL_SECTOR_ADDRESS;
|
||||
return(1);
|
||||
}
|
||||
if (dev->head > drive->hpc) {
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("mfm_get_sector: past end of heads\n");
|
||||
hdc_log("st506_get_sector: past end of heads\n");
|
||||
#endif
|
||||
dev->error = ERR_ILLEGAL_SECTOR_ADDRESS;
|
||||
return(1);
|
||||
}
|
||||
if (dev->sector >= 17) {
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("mfm_get_sector: past end of sectors\n");
|
||||
hdc_log("st506_get_sector: past end of sectors\n");
|
||||
#endif
|
||||
dev->error = ERR_ILLEGAL_SECTOR_ADDRESS;
|
||||
return(1);
|
||||
@@ -350,7 +352,7 @@ get_sector(mfm_t *dev, off64_t *addr)
|
||||
|
||||
|
||||
static void
|
||||
next_sector(mfm_t *dev)
|
||||
next_sector(hdc_t *dev)
|
||||
{
|
||||
drive_t *drive = &dev->drives[dev->drive_sel];
|
||||
|
||||
@@ -370,9 +372,9 @@ next_sector(mfm_t *dev)
|
||||
|
||||
|
||||
static void
|
||||
mfm_callback(void *priv)
|
||||
st506_callback(void *priv)
|
||||
{
|
||||
mfm_t *dev = (mfm_t *)priv;
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
drive_t *drive;
|
||||
off64_t addr;
|
||||
|
||||
@@ -385,18 +387,18 @@ mfm_callback(void *priv)
|
||||
switch (dev->command[0]) {
|
||||
case CMD_TEST_DRIVE_READY:
|
||||
if (!drive->present)
|
||||
mfm_error(dev, ERR_NOT_READY);
|
||||
mfm_complete(dev);
|
||||
st506_error(dev, ERR_NOT_READY);
|
||||
st506_complete(dev);
|
||||
break;
|
||||
|
||||
case CMD_RECALIBRATE:
|
||||
if (!drive->present)
|
||||
mfm_error(dev, ERR_NOT_READY);
|
||||
st506_error(dev, ERR_NOT_READY);
|
||||
else {
|
||||
dev->cylinder = 0;
|
||||
drive->current_cylinder = 0;
|
||||
}
|
||||
mfm_complete(dev);
|
||||
st506_complete(dev);
|
||||
break;
|
||||
|
||||
case CMD_READ_STATUS:
|
||||
@@ -413,7 +415,7 @@ mfm_callback(void *priv)
|
||||
break;
|
||||
|
||||
case STATE_SENT_DATA:
|
||||
mfm_complete(dev);
|
||||
st506_complete(dev);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -431,8 +433,8 @@ mfm_callback(void *priv)
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("get_sector failed\n");
|
||||
#endif
|
||||
mfm_error(dev, dev->error);
|
||||
mfm_complete(dev);
|
||||
st506_error(dev, dev->error);
|
||||
st506_complete(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -441,9 +443,9 @@ mfm_callback(void *priv)
|
||||
dev->sector_count = (dev->sector_count-1) & 0xff;
|
||||
} while (dev->sector_count);
|
||||
|
||||
mfm_complete(dev);
|
||||
st506_complete(dev);
|
||||
|
||||
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1);
|
||||
ui_sb_update_icon(SB_HDD | HDD_BUS_ST506, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -460,14 +462,14 @@ mfm_callback(void *priv)
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("get_sector failed\n");
|
||||
#endif
|
||||
mfm_error(dev, dev->error);
|
||||
mfm_complete(dev);
|
||||
st506_error(dev, dev->error);
|
||||
st506_complete(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
hdd_image_zero(drive->hdd_num, addr, 17);
|
||||
|
||||
mfm_complete(dev);
|
||||
st506_complete(dev);
|
||||
break;
|
||||
|
||||
case CMD_READ_SECTORS:
|
||||
@@ -483,17 +485,17 @@ mfm_callback(void *priv)
|
||||
dev->data_len = 512;
|
||||
|
||||
if (get_sector(dev, &addr)) {
|
||||
mfm_error(dev, dev->error);
|
||||
mfm_complete(dev);
|
||||
st506_error(dev, dev->error);
|
||||
st506_complete(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
hdd_image_read(drive->hdd_num, addr, 1,
|
||||
(uint8_t *) dev->sector_buf);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 1);
|
||||
|
||||
if (dev->irq_dma_mask & DMA_ENA)
|
||||
dev->callback = MFM_TIME;
|
||||
dev->callback = ST506_TIME;
|
||||
else {
|
||||
dev->status = STAT_BSY | STAT_IO | STAT_REQ;
|
||||
memcpy(dev->data, dev->sector_buf, 512);
|
||||
@@ -511,12 +513,12 @@ mfm_callback(void *priv)
|
||||
hdc_log("CMD_READ_SECTORS out of data!\n");
|
||||
#endif
|
||||
dev->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ;
|
||||
dev->callback = MFM_TIME;
|
||||
dev->callback = ST506_TIME;
|
||||
return;
|
||||
}
|
||||
}
|
||||
dev->state = STATE_SENT_DATA;
|
||||
dev->callback = MFM_TIME;
|
||||
dev->callback = ST506_TIME;
|
||||
} else
|
||||
fatal("Read sectors no DMA! - shouldn't get here\n");
|
||||
break;
|
||||
@@ -530,26 +532,26 @@ mfm_callback(void *priv)
|
||||
|
||||
if (dev->sector_count) {
|
||||
if (get_sector(dev, &addr)) {
|
||||
mfm_error(dev, dev->error);
|
||||
mfm_complete(dev);
|
||||
st506_error(dev, dev->error);
|
||||
st506_complete(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
hdd_image_read(drive->hdd_num, addr, 1,
|
||||
(uint8_t *) dev->sector_buf);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 1);
|
||||
|
||||
dev->state = STATE_SEND_DATA;
|
||||
|
||||
if (dev->irq_dma_mask & DMA_ENA)
|
||||
dev->callback = MFM_TIME;
|
||||
dev->callback = ST506_TIME;
|
||||
else {
|
||||
dev->status = STAT_BSY | STAT_IO | STAT_REQ;
|
||||
memcpy(dev->data, dev->sector_buf, 512);
|
||||
}
|
||||
} else {
|
||||
mfm_complete(dev);
|
||||
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
|
||||
st506_complete(dev);
|
||||
ui_sb_update_icon(SB_HDD | HDD_BUS_ST506, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -570,7 +572,7 @@ mfm_callback(void *priv)
|
||||
dev->data_pos = 0;
|
||||
dev->data_len = 512;
|
||||
if (dev->irq_dma_mask & DMA_ENA)
|
||||
dev->callback = MFM_TIME;
|
||||
dev->callback = ST506_TIME;
|
||||
else
|
||||
dev->status = STAT_BSY | STAT_REQ;
|
||||
break;
|
||||
@@ -586,7 +588,7 @@ mfm_callback(void *priv)
|
||||
hdc_log("CMD_WRITE_SECTORS out of data!\n");
|
||||
#endif
|
||||
dev->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ;
|
||||
dev->callback = MFM_TIME;
|
||||
dev->callback = ST506_TIME;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -594,7 +596,7 @@ mfm_callback(void *priv)
|
||||
}
|
||||
|
||||
dev->state = STATE_RECEIVED_DATA;
|
||||
dev->callback = MFM_TIME;
|
||||
dev->callback = ST506_TIME;
|
||||
} else
|
||||
fatal("Write sectors no DMA! - should never get here\n");
|
||||
break;
|
||||
@@ -604,14 +606,14 @@ mfm_callback(void *priv)
|
||||
memcpy(dev->sector_buf, dev->data, 512);
|
||||
|
||||
if (get_sector(dev, &addr)) {
|
||||
mfm_error(dev, dev->error);
|
||||
mfm_complete(dev);
|
||||
st506_error(dev, dev->error);
|
||||
st506_complete(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
hdd_image_write(drive->hdd_num, addr, 1,
|
||||
(uint8_t *) dev->sector_buf);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 1);
|
||||
|
||||
next_sector(dev);
|
||||
dev->data_pos = 0;
|
||||
@@ -620,11 +622,11 @@ mfm_callback(void *priv)
|
||||
if (dev->sector_count) {
|
||||
dev->state = STATE_RECEIVE_DATA;
|
||||
if (dev->irq_dma_mask & DMA_ENA)
|
||||
dev->callback = MFM_TIME;
|
||||
dev->callback = ST506_TIME;
|
||||
else
|
||||
dev->status = STAT_BSY | STAT_REQ;
|
||||
} else
|
||||
mfm_complete(dev);
|
||||
st506_complete(dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -634,16 +636,16 @@ mfm_callback(void *priv)
|
||||
|
||||
case CMD_SEEK:
|
||||
if (! drive->present)
|
||||
mfm_error(dev, ERR_NOT_READY);
|
||||
st506_error(dev, ERR_NOT_READY);
|
||||
else {
|
||||
int cylinder = dev->command[3] | ((dev->command[2] & 0xc0) << 2);
|
||||
|
||||
drive->current_cylinder = (cylinder >= drive->cfg_cyl) ? drive->cfg_cyl-1 : cylinder;
|
||||
|
||||
if (cylinder != drive->current_cylinder)
|
||||
mfm_error(dev, ERR_SEEK_ERROR);
|
||||
st506_error(dev, ERR_SEEK_ERROR);
|
||||
}
|
||||
mfm_complete(dev);
|
||||
st506_complete(dev);
|
||||
break;
|
||||
|
||||
case CMD_INIT_DRIVE_PARAMS:
|
||||
@@ -661,7 +663,7 @@ mfm_callback(void *priv)
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("Drive %i: cylinders=%i, heads=%i\n", dev->drive_sel, drive->cfg_cyl, drive->cfg_hpc);
|
||||
#endif
|
||||
mfm_complete(dev);
|
||||
st506_complete(dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -676,7 +678,7 @@ mfm_callback(void *priv)
|
||||
dev->data_pos = 0;
|
||||
dev->data_len = 512;
|
||||
if (dev->irq_dma_mask & DMA_ENA)
|
||||
dev->callback = MFM_TIME;
|
||||
dev->callback = ST506_TIME;
|
||||
else
|
||||
dev->status = STAT_BSY | STAT_REQ;
|
||||
break;
|
||||
@@ -691,7 +693,7 @@ mfm_callback(void *priv)
|
||||
if (val == DMA_NODATA) {
|
||||
hdc_log("CMD_WRITE_SECTOR_BUFFER out of data!\n");
|
||||
dev->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ;
|
||||
dev->callback = MFM_TIME;
|
||||
dev->callback = ST506_TIME;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -699,14 +701,14 @@ mfm_callback(void *priv)
|
||||
}
|
||||
|
||||
dev->state = STATE_RECEIVED_DATA;
|
||||
dev->callback = MFM_TIME;
|
||||
dev->callback = ST506_TIME;
|
||||
} else
|
||||
fatal("CMD_WRITE_SECTOR_BUFFER - should never get here!\n");
|
||||
break;
|
||||
|
||||
case STATE_RECEIVED_DATA:
|
||||
memcpy(dev->sector_buf, dev->data, 512);
|
||||
mfm_complete(dev);
|
||||
st506_complete(dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -716,15 +718,15 @@ mfm_callback(void *priv)
|
||||
|
||||
case CMD_BUFFER_DIAGNOSTIC:
|
||||
case CMD_CONTROLLER_DIAGNOSTIC:
|
||||
mfm_complete(dev);
|
||||
st506_complete(dev);
|
||||
break;
|
||||
|
||||
case 0xfa:
|
||||
mfm_complete(dev);
|
||||
st506_complete(dev);
|
||||
break;
|
||||
|
||||
case CMD_DTC_SET_STEP_RATE:
|
||||
mfm_complete(dev);
|
||||
st506_complete(dev);
|
||||
break;
|
||||
|
||||
case CMD_DTC_GET_DRIVE_PARAMS:
|
||||
@@ -744,7 +746,7 @@ mfm_callback(void *priv)
|
||||
break;
|
||||
|
||||
case STATE_SENT_DATA:
|
||||
mfm_complete(dev);
|
||||
st506_complete(dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -766,7 +768,7 @@ mfm_callback(void *priv)
|
||||
break;
|
||||
|
||||
case STATE_SENT_DATA:
|
||||
mfm_complete(dev);
|
||||
st506_complete(dev);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -782,7 +784,7 @@ mfm_callback(void *priv)
|
||||
|
||||
case STATE_RECEIVED_DATA:
|
||||
/*Bit of a cheat here - we always report the actual geometry of the drive in use*/
|
||||
mfm_complete(dev);
|
||||
st506_complete(dev);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -797,7 +799,7 @@ mfm_callback(void *priv)
|
||||
|
||||
|
||||
static void
|
||||
loadhd(mfm_t *dev, int c, int d, const wchar_t *fn)
|
||||
loadhd(hdc_t *dev, int c, int d, const wchar_t *fn)
|
||||
{
|
||||
drive_t *drive = &dev->drives[d];
|
||||
|
||||
@@ -826,7 +828,7 @@ static const struct {
|
||||
|
||||
|
||||
static void
|
||||
mfm_set_switches(mfm_t *dev)
|
||||
st506_set_switches(hdc_t *dev)
|
||||
{
|
||||
int c, d;
|
||||
|
||||
@@ -856,37 +858,37 @@ mfm_set_switches(mfm_t *dev)
|
||||
|
||||
|
||||
static void *
|
||||
mfm_init(const device_t *info)
|
||||
st506_init(const device_t *info)
|
||||
{
|
||||
wchar_t *fn = NULL;
|
||||
mfm_t *dev;
|
||||
hdc_t *dev;
|
||||
int i, c;
|
||||
|
||||
dev = malloc(sizeof(mfm_t));
|
||||
memset(dev, 0x00, sizeof(mfm_t));
|
||||
dev = malloc(sizeof(hdc_t));
|
||||
memset(dev, 0x00, sizeof(hdc_t));
|
||||
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("MFM: looking for disks..\n");
|
||||
hdc_log("ST506: looking for disks..\n");
|
||||
#endif
|
||||
c = 0;
|
||||
for (i=0; i<HDD_NUM; i++) {
|
||||
if ((hdd[i].bus == HDD_BUS_MFM) && (hdd[i].mfm_channel < MFM_NUM)) {
|
||||
if ((hdd[i].bus == HDD_BUS_ST506) && (hdd[i].id.st506_channel < ST506_NUM)) {
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("Found MFM hard disk on channel %i\n", hdd[i].mfm_channel);
|
||||
hdc_log("Found ST506 hard disk on channel %i\n", hdd[i].id.st506_channel);
|
||||
#endif
|
||||
loadhd(dev, hdd[i].mfm_channel, i, hdd[i].fn);
|
||||
loadhd(dev, hdd[i].id.st506_channel, i, hdd[i].fn);
|
||||
|
||||
if (++c > MFM_NUM) break;
|
||||
if (++c > ST506_NUM) break;
|
||||
}
|
||||
}
|
||||
#ifdef ENABLE_HDC_LOG
|
||||
hdc_log("MFM: %d disks loaded.\n", c);
|
||||
hdc_log("ST506: %d disks loaded.\n", c);
|
||||
#endif
|
||||
|
||||
switch(info->local) {
|
||||
case 0: /* Xebec */
|
||||
fn = XEBEC_BIOS_FILE;
|
||||
mfm_set_switches(dev);
|
||||
st506_set_switches(dev);
|
||||
break;
|
||||
|
||||
case 1: /* DTC5150 */
|
||||
@@ -903,18 +905,18 @@ mfm_init(const device_t *info)
|
||||
0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
io_sethandler(0x0320, 4,
|
||||
mfm_read,NULL,NULL, mfm_write,NULL,NULL, dev);
|
||||
st506_read,NULL,NULL, st506_write,NULL,NULL, dev);
|
||||
|
||||
timer_add(mfm_callback, &dev->callback, &dev->callback, dev);
|
||||
timer_add(st506_callback, &dev->callback, &dev->callback, dev);
|
||||
|
||||
return(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mfm_close(void *priv)
|
||||
st506_close(void *priv)
|
||||
{
|
||||
mfm_t *dev = (mfm_t *)priv;
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
int d;
|
||||
|
||||
for (d=0; d<2; d++) {
|
||||
@@ -941,20 +943,20 @@ dtc5150x_available(void)
|
||||
}
|
||||
|
||||
|
||||
const device_t mfm_xt_xebec_device = {
|
||||
const device_t st506_xt_xebec_device = {
|
||||
"IBM PC Fixed Disk Adapter",
|
||||
DEVICE_ISA,
|
||||
0,
|
||||
mfm_init, mfm_close, NULL,
|
||||
st506_init, st506_close, NULL,
|
||||
xebec_available, NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
const device_t mfm_xt_dtc5150x_device = {
|
||||
const device_t st506_xt_dtc5150x_device = {
|
||||
"DTC 5150X",
|
||||
DEVICE_ISA,
|
||||
1,
|
||||
mfm_init, mfm_close, NULL,
|
||||
st506_init, st506_close, NULL,
|
||||
dtc5150x_available, NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -21,7 +21,7 @@
|
||||
* 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: @(#)hdc_xtide.c 1.0.5 2018/04/02
|
||||
* Version: @(#)hdc_xtide.c 1.0.6 2018/04/23
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -61,26 +61,26 @@
|
||||
#include "hdc_ide.h"
|
||||
|
||||
|
||||
#define ROM_PATH_XT L"hdd/xtide/ide_xt.bin"
|
||||
#define ROM_PATH_AT L"hdd/xtide/ide_at.bin"
|
||||
#define ROM_PATH_PS2 L"hdd/xtide/side1v12.bin"
|
||||
#define ROM_PATH_PS2AT L"hdd/xtide/ide_at_1_1_5.bin"
|
||||
#define ROM_PATH_XT L"disk/xtide/ide_xt.bin"
|
||||
#define ROM_PATH_AT L"disk/xtide/ide_at.bin"
|
||||
#define ROM_PATH_PS2 L"disk/xtide/side1v12.bin"
|
||||
#define ROM_PATH_PS2AT L"disk/xtide/ide_at_1_1_5.bin"
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t data_high;
|
||||
rom_t bios_rom;
|
||||
} xtide_t;
|
||||
} hdc_t;
|
||||
|
||||
|
||||
static void
|
||||
xtide_write(uint16_t port, uint8_t val, void *priv)
|
||||
hdc_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
xtide_t *xtide = (xtide_t *)priv;
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
|
||||
switch (port & 0xf) {
|
||||
case 0x0:
|
||||
writeidew(4, val | (xtide->data_high << 8));
|
||||
writeidew(4, val | (dev->data_high << 8));
|
||||
return;
|
||||
|
||||
case 0x1:
|
||||
@@ -94,7 +94,7 @@ xtide_write(uint16_t port, uint8_t val, void *priv)
|
||||
return;
|
||||
|
||||
case 0x8:
|
||||
xtide->data_high = val;
|
||||
dev->data_high = val;
|
||||
return;
|
||||
|
||||
case 0xe:
|
||||
@@ -105,15 +105,15 @@ xtide_write(uint16_t port, uint8_t val, void *priv)
|
||||
|
||||
|
||||
static uint8_t
|
||||
xtide_read(uint16_t port, void *priv)
|
||||
hdc_read(uint16_t port, void *priv)
|
||||
{
|
||||
xtide_t *xtide = (xtide_t *)priv;
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
uint16_t tempw = 0xffff;
|
||||
|
||||
switch (port & 0xf) {
|
||||
case 0x0:
|
||||
tempw = readidew(4);
|
||||
xtide->data_high = tempw >> 8;
|
||||
dev->data_high = tempw >> 8;
|
||||
break;
|
||||
|
||||
case 0x1:
|
||||
@@ -127,7 +127,7 @@ xtide_read(uint16_t port, void *priv)
|
||||
break;
|
||||
|
||||
case 0x8:
|
||||
tempw = xtide->data_high;
|
||||
tempw = dev->data_high;
|
||||
break;
|
||||
|
||||
case 0xe:
|
||||
@@ -145,20 +145,65 @@ xtide_read(uint16_t port, void *priv)
|
||||
static void *
|
||||
xtide_init(const device_t *info)
|
||||
{
|
||||
xtide_t *xtide = malloc(sizeof(xtide_t));
|
||||
wchar_t *fn = NULL;
|
||||
int rom_sz = 0;
|
||||
int io = 0;
|
||||
hdc_t *dev;
|
||||
|
||||
memset(xtide, 0x00, sizeof(xtide_t));
|
||||
dev = malloc(sizeof(hdc_t));
|
||||
memset(dev, 0x00, sizeof(hdc_t));
|
||||
|
||||
rom_init(&xtide->bios_rom, ROM_PATH_XT,
|
||||
0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
switch(info->local) {
|
||||
case 0:
|
||||
fn = ROM_PATH_XT;
|
||||
rom_sz = 0x4000;
|
||||
io = 0x300;
|
||||
|
||||
ide_xtide_init();
|
||||
ide_xtide_init();
|
||||
break;
|
||||
|
||||
io_sethandler(0x0300, 16,
|
||||
xtide_read, NULL, NULL,
|
||||
xtide_write, NULL, NULL, xtide);
|
||||
case 1:
|
||||
fn = ROM_PATH_AT;
|
||||
rom_sz = 0x4000;
|
||||
io = 0x300;
|
||||
|
||||
return(xtide);
|
||||
device_add(&ide_isa_2ch_device);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
fn = ROM_PATH_PS2;
|
||||
rom_sz = 0x8000;
|
||||
io = 0x360;
|
||||
|
||||
ide_xtide_init();
|
||||
break;
|
||||
|
||||
case 3:
|
||||
fn = ROM_PATH_PS2AT;
|
||||
rom_sz = 0x4000;
|
||||
|
||||
device_add(&ide_isa_2ch_device);
|
||||
break;
|
||||
}
|
||||
|
||||
if (fn != NULL)
|
||||
rom_init(&dev->bios_rom, fn,
|
||||
0xc8000, rom_sz, rom_sz-1, 0, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
if (io != 0)
|
||||
io_sethandler(io, 16,
|
||||
hdc_read,NULL,NULL, hdc_write,NULL,NULL, dev);
|
||||
|
||||
return(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
xtide_close(void *priv)
|
||||
{
|
||||
hdc_t *dev = (hdc_t *)priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -168,73 +213,18 @@ xtide_available(void)
|
||||
return(rom_present(ROM_PATH_XT));
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
xtide_at_init(const device_t *info)
|
||||
{
|
||||
xtide_t *xtide = malloc(sizeof(xtide_t));
|
||||
|
||||
memset(xtide, 0x00, sizeof(xtide_t));
|
||||
|
||||
rom_init(&xtide->bios_rom, ROM_PATH_AT,
|
||||
0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
device_add(&ide_isa_2ch_device);
|
||||
|
||||
return(xtide);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
xtide_at_available(void)
|
||||
{
|
||||
return(rom_present(ROM_PATH_AT));
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
xtide_acculogic_init(const device_t *info)
|
||||
{
|
||||
xtide_t *xtide = malloc(sizeof(xtide_t));
|
||||
|
||||
memset(xtide, 0x00, sizeof(xtide_t));
|
||||
|
||||
rom_init(&xtide->bios_rom, ROM_PATH_PS2,
|
||||
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_acculogic_available(void)
|
||||
{
|
||||
return(rom_present(ROM_PATH_PS2));
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
xtide_at_ps2_init(const device_t *info)
|
||||
{
|
||||
xtide_t *xtide = malloc(sizeof(xtide_t));
|
||||
|
||||
memset(xtide, 0x00, sizeof(xtide_t));
|
||||
|
||||
rom_init(&xtide->bios_rom, ROM_PATH_PS2AT,
|
||||
0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
device_add(&ide_isa_2ch_device);
|
||||
|
||||
return(xtide);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
xtide_at_ps2_available(void)
|
||||
{
|
||||
@@ -242,15 +232,6 @@ xtide_at_ps2_available(void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
xtide_close(void *priv)
|
||||
{
|
||||
xtide_t *xtide = (xtide_t *)priv;
|
||||
|
||||
free(xtide);
|
||||
}
|
||||
|
||||
|
||||
const device_t xtide_device = {
|
||||
"XTIDE",
|
||||
DEVICE_ISA,
|
||||
@@ -263,8 +244,8 @@ const device_t xtide_device = {
|
||||
const device_t xtide_at_device = {
|
||||
"XTIDE (AT)",
|
||||
DEVICE_ISA | DEVICE_AT,
|
||||
0,
|
||||
xtide_at_init, xtide_close, NULL,
|
||||
1,
|
||||
xtide_init, xtide_close, NULL,
|
||||
xtide_at_available, NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -272,8 +253,8 @@ const device_t xtide_at_device = {
|
||||
const device_t xtide_acculogic_device = {
|
||||
"XTIDE (Acculogic)",
|
||||
DEVICE_ISA,
|
||||
0,
|
||||
xtide_acculogic_init, xtide_close, NULL,
|
||||
2,
|
||||
xtide_init, xtide_close, NULL,
|
||||
xtide_acculogic_available, NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -281,8 +262,8 @@ const device_t xtide_acculogic_device = {
|
||||
const device_t xtide_at_ps2_device = {
|
||||
"XTIDE (AT) (1.1.5)",
|
||||
DEVICE_ISA | DEVICE_PS2,
|
||||
0,
|
||||
xtide_at_ps2_init, xtide_close, NULL,
|
||||
3,
|
||||
xtide_init, xtide_close, NULL,
|
||||
xtide_at_ps2_available, NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Common code to handle all sorts of hard disk images.
|
||||
*
|
||||
* Version: @(#)hdd.c 1.0.2 2018/04/02
|
||||
* Version: @(#)hdd.c 1.0.3 2018/04/23
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -83,14 +83,14 @@ hdd_string_to_bus(char *str, int cdrom)
|
||||
if (! strcmp(str, "none"))
|
||||
return(HDD_BUS_DISABLED);
|
||||
|
||||
if (! strcmp(str, "mfm")) {
|
||||
if (!strcmp(str, "st506") || !strcmp(str, "mfm")) {
|
||||
if (cdrom) {
|
||||
no_cdrom:
|
||||
ui_msgbox(MBX_ERROR, (wchar_t *)IDS_4114);
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(HDD_BUS_MFM);
|
||||
return(HDD_BUS_ST506);
|
||||
}
|
||||
|
||||
if (! strcmp(str, "esdi")) {
|
||||
@@ -99,30 +99,21 @@ no_cdrom:
|
||||
return(HDD_BUS_ESDI);
|
||||
}
|
||||
|
||||
if (! strcmp(str, "ide_pio_only"))
|
||||
return(HDD_BUS_IDE_PIO_ONLY);
|
||||
|
||||
if (! strcmp(str, "ide"))
|
||||
return(HDD_BUS_IDE_PIO_ONLY);
|
||||
|
||||
if (! strcmp(str, "atapi_pio_only"))
|
||||
return(HDD_BUS_IDE_PIO_ONLY);
|
||||
|
||||
if (! strcmp(str, "atapi"))
|
||||
return(HDD_BUS_IDE_PIO_ONLY);
|
||||
|
||||
if (! strcmp(str, "eide"))
|
||||
return(HDD_BUS_IDE_PIO_ONLY);
|
||||
|
||||
if (! strcmp(str, "xtide"))
|
||||
return(HDD_BUS_XTIDE);
|
||||
|
||||
if (! strcmp(str, "atide"))
|
||||
if (! strcmp(str, "ide_pio_only"))
|
||||
return(HDD_BUS_IDE_PIO_ONLY);
|
||||
|
||||
if (! strcmp(str, "ide_pio_and_dma"))
|
||||
return(HDD_BUS_IDE_PIO_AND_DMA);
|
||||
|
||||
if (! strcmp(str, "atapi"))
|
||||
return(HDD_BUS_IDE_PIO_ONLY);
|
||||
|
||||
if (! strcmp(str, "atapi_pio_only"))
|
||||
return(HDD_BUS_IDE_PIO_ONLY);
|
||||
|
||||
if (! strcmp(str, "atapi_pio_and_dma"))
|
||||
return(HDD_BUS_IDE_PIO_AND_DMA);
|
||||
|
||||
@@ -164,12 +155,8 @@ hdd_bus_to_string(int bus, int cdrom)
|
||||
default:
|
||||
break;
|
||||
|
||||
case HDD_BUS_MFM:
|
||||
s = "mfm";
|
||||
break;
|
||||
|
||||
case HDD_BUS_XTIDE:
|
||||
s = "xtide";
|
||||
case HDD_BUS_ST506:
|
||||
s = "st506";
|
||||
break;
|
||||
|
||||
case HDD_BUS_ESDI:
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Definitions for the hard disk image handler.
|
||||
*
|
||||
* Version: @(#)hdd.h 1.0.5 2018/04/12
|
||||
* Version: @(#)hdd.h 1.0.6 2018/04/23
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -44,8 +44,7 @@
|
||||
/* Hard Disk bus types. */
|
||||
enum {
|
||||
HDD_BUS_DISABLED = 0,
|
||||
HDD_BUS_MFM,
|
||||
HDD_BUS_XTIDE,
|
||||
HDD_BUS_ST506,
|
||||
HDD_BUS_ESDI,
|
||||
HDD_BUS_IDE_PIO_ONLY,
|
||||
HDD_BUS_IDE_PIO_AND_DMA,
|
||||
@@ -71,12 +70,17 @@ typedef struct {
|
||||
|
||||
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;
|
||||
union {
|
||||
uint8_t st506_channel; /* bus channel ID's */
|
||||
uint8_t esdi_channel;
|
||||
uint8_t xtide_channel;
|
||||
uint8_t ide_channel;
|
||||
uint8_t scsi_id;
|
||||
union {
|
||||
uint8_t id;
|
||||
uint8_t lun;
|
||||
} scsi;
|
||||
} id;
|
||||
|
||||
uint32_t base;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* NOTE: FIXME: Strings 2176 and 2193 are same.
|
||||
*
|
||||
* Version: @(#)language.h 1.0.7 2018/04/09
|
||||
* Version: @(#)language.h 1.0.8 2018/04/23
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
@@ -196,24 +196,22 @@
|
||||
#define IDS_4111 4111 // "This image exists and will be.."
|
||||
#define IDS_4112 4112 // "Please enter a valid file name"
|
||||
#define IDS_4113 4113 // "Remember to partition and fo.."
|
||||
#define IDS_4114 4114 // "MFM/RLL or ESDI CD-ROM driv.."
|
||||
#define IDS_4114 4114 // "ST506 or ESDI CD-ROM driv.."
|
||||
#define IDS_4115 4115 // "Removable disk %i (SCSI): %ls"
|
||||
|
||||
#define IDS_4352 4352 // "MFM/RLL"
|
||||
#define IDS_4353 4353 // "XT IDE"
|
||||
#define IDS_4354 4354 // "ESDI"
|
||||
#define IDS_4355 4355 // "IDE (PIO-only)"
|
||||
#define IDS_4356 4356 // "IDE (PIO+DMA)"
|
||||
#define IDS_4357 4357 // "SCSI"
|
||||
#define IDS_4358 4358 // "SCSI (removable)"
|
||||
#define IDS_4352 4352 // "ST506"
|
||||
#define IDS_4353 4353 // "ESDI"
|
||||
#define IDS_4354 4354 // "IDE (PIO-only)"
|
||||
#define IDS_4355 4355 // "IDE (PIO+DMA)"
|
||||
#define IDS_4356 4356 // "SCSI"
|
||||
#define IDS_4357 4357 // "SCSI (removable)"
|
||||
|
||||
#define IDS_4608 4608 // "MFM/RLL (%01i:%01i)"
|
||||
#define IDS_4609 4609 // "XT IDE (%01i:%01i)"
|
||||
#define IDS_4610 4610 // "ESDI (%01i:%01i)"
|
||||
#define IDS_4611 4611 // "IDE (PIO-only) (%01i:%01i)"
|
||||
#define IDS_4612 4612 // "IDE (PIO+DMA) (%01i:%01i)"
|
||||
#define IDS_4613 4613 // "SCSI (%02i:%02i)"
|
||||
#define IDS_4614 4614 // "SCSI (removable) (%02i:%02i)"
|
||||
#define IDS_4608 4608 // "ST506 (%01i:%01i)"
|
||||
#define IDS_4609 4609 // "ESDI (%01i:%01i)"
|
||||
#define IDS_4610 4610 // "IDE (PIO-only) (%01i:%01i)"
|
||||
#define IDS_4611 4611 // "IDE (PIO+DMA) (%01i:%01i)"
|
||||
#define IDS_4612 4612 // "SCSI (%02i:%02i)"
|
||||
#define IDS_4613 4613 // "SCSI (removable) (%02i:%02i)"
|
||||
|
||||
#define IDS_5120 5120 // "CD-ROM %i (%s): %s"
|
||||
|
||||
@@ -260,8 +258,8 @@
|
||||
#define STR_NUM_2048 132
|
||||
#define STR_NUM_3072 11
|
||||
#define STR_NUM_4096 20
|
||||
#define STR_NUM_4352 7
|
||||
#define STR_NUM_4608 7
|
||||
#define STR_NUM_4352 6
|
||||
#define STR_NUM_4608 6
|
||||
#define STR_NUM_5120 1
|
||||
#define STR_NUM_5376 7
|
||||
#define STR_NUM_5632 7
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
*
|
||||
* Based on the original "xebec.c" from Sarah Walker.
|
||||
*
|
||||
* Version: @(#)m_europc_hdc.c 1.0.4 2018/03/27
|
||||
* Version: @(#)m_europc_hdc.c 1.0.5 2018/04/23
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
@@ -255,7 +255,7 @@ typedef struct {
|
||||
|
||||
struct dcb dcb; /* device control block */
|
||||
|
||||
drive_t drives[MFM_NUM];
|
||||
drive_t drives[ST506_NUM];
|
||||
|
||||
uint8_t data[512]; /* data buffer */
|
||||
uint8_t sector_buf[512];
|
||||
@@ -421,7 +421,7 @@ hd20_callback(void *priv)
|
||||
|
||||
hd20_intr(dev);
|
||||
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -443,7 +443,7 @@ hd20_callback(void *priv)
|
||||
|
||||
hdd_image_zero(drive->hdd_num,addr,drive->spt);
|
||||
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 1);
|
||||
}
|
||||
}
|
||||
hd20_intr(dev);
|
||||
@@ -472,7 +472,7 @@ hd20_callback(void *priv)
|
||||
|
||||
hdd_image_zero(drive->hdd_num, addr, drive->spt);
|
||||
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 1);
|
||||
|
||||
hd20_intr(dev);
|
||||
break;
|
||||
@@ -506,7 +506,7 @@ hd20_callback(void *priv)
|
||||
|
||||
hdd_image_read(drive->hdd_num, addr, 1,
|
||||
(uint8_t *)dev->sector_buf);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 1);
|
||||
|
||||
/* Ready to transfer the data out. */
|
||||
dev->buf_idx = 0;
|
||||
@@ -545,7 +545,7 @@ hd20_callback(void *priv)
|
||||
|
||||
dev->buf_idx = 0;
|
||||
if (--dev->count == 0) {
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 0);
|
||||
hd20_intr(dev);
|
||||
return;
|
||||
}
|
||||
@@ -558,7 +558,7 @@ hd20_callback(void *priv)
|
||||
|
||||
hdd_image_read(drive->hdd_num, addr, 1,
|
||||
(uint8_t *)dev->sector_buf);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 1);
|
||||
|
||||
dev->state = STATE_TXDTA;
|
||||
|
||||
@@ -640,13 +640,13 @@ hd20_callback(void *priv)
|
||||
|
||||
hdd_image_write(drive->hdd_num, addr, 1,
|
||||
(uint8_t *)dev->sector_buf);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 1);
|
||||
|
||||
next_sector(dev, drive);
|
||||
|
||||
dev->buf_idx = 0;
|
||||
if (--dev->count == 0) {
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0);
|
||||
ui_sb_update_icon(SB_HDD|HDD_BUS_ST506, 0);
|
||||
hd20_intr(dev);
|
||||
break;
|
||||
}
|
||||
@@ -917,8 +917,8 @@ hd20_init(const device_t *info)
|
||||
dev->dma = HDD_DMACHAN;
|
||||
|
||||
for (c=0,i=0; i<HDD_NUM; i++) {
|
||||
if ((hdd[i].bus == HDD_BUS_MFM) && (hdd[i].mfm_channel < MFM_NUM)) {
|
||||
drive = &dev->drives[hdd[i].mfm_channel];
|
||||
if ((hdd[i].bus == HDD_BUS_ST506) && (hdd[i].id.st506_channel < ST506_NUM)) {
|
||||
drive = &dev->drives[hdd[i].id.st506_channel];
|
||||
|
||||
if (! hdd_image_load(i)) {
|
||||
drive->present = 0;
|
||||
@@ -928,7 +928,7 @@ hd20_init(const device_t *info)
|
||||
/* These are the "hardware" parameters (from the image.) */
|
||||
drive->spt = (uint8_t)(hdd[i].spt & 0xff);
|
||||
drive->hpc = (uint8_t)(hdd[i].hpc & 0xff);
|
||||
drive->tracks = (uint8_t)(hdd[i].tracks & 0xff);
|
||||
drive->tracks = (uint16_t)hdd[i].tracks;
|
||||
|
||||
/* Use them as "configured" parameters until overwritten. */
|
||||
drive->cfg_spt = drive->spt;
|
||||
@@ -939,9 +939,9 @@ hd20_init(const device_t *info)
|
||||
drive->present = 1;
|
||||
|
||||
pclog("HD20: drive%d (cyl=%d,hd=%d,spt=%d), disk %d\n",
|
||||
hdd[i].mfm_channel,drive->tracks,drive->hpc,drive->spt,i);
|
||||
hdd[i].id.st506_channel,drive->tracks,drive->hpc,drive->spt,i);
|
||||
|
||||
if (++c > MFM_NUM) break;
|
||||
if (++c > ST506_NUM) break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
* Type table with the main code, so the user can only select
|
||||
* items from that list...
|
||||
*
|
||||
* Version: @(#)m_ps1_hdc.c 1.0.3 2018/04/23
|
||||
* Version: @(#)m_ps1_hdc.c 1.0.4 2018/04/23
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
@@ -1398,8 +1398,8 @@ ps1_hdc_init(const device_t *info)
|
||||
/* Load any disks for this device class. */
|
||||
c = 0;
|
||||
for (i = 0; i < HDD_NUM; i++) {
|
||||
if ((hdd[i].bus == HDD_BUS_IDE) && (hdd[i].mfm_channel < XTA_NUM)) {
|
||||
drive = &dev->drives[hdd[i].ide_channel];
|
||||
if ((hdd[i].bus == HDD_BUS_IDE) && (hdd[i].id.ide_channel < XTA_NUM)) {
|
||||
drive = &dev->drives[hdd[i].id.ide_channel];
|
||||
|
||||
if (! hdd_image_load(i)) {
|
||||
drive->present = 0;
|
||||
@@ -1422,7 +1422,7 @@ ps1_hdc_init(const device_t *info)
|
||||
drive->present = 1;
|
||||
|
||||
pclog("HDC: drive%d (type %d: cyl=%d,hd=%d,spt=%d), disk %d\n",
|
||||
hdd[i].ide_channel, drive->type,
|
||||
hdd[i].id.ide_channel, drive->type,
|
||||
drive->tracks, drive->hpc, drive->spt, i);
|
||||
|
||||
if (++c > XTA_NUM) break;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Emulation of SCSI fixed and removable disks.
|
||||
*
|
||||
* Version: @(#)scsi_disk.c 1.0.6 2018/03/28
|
||||
* Version: @(#)scsi_disk.c 1.0.7 2018/04/23
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -234,7 +234,7 @@ find_hdd_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun)
|
||||
if (((hdd[i].spt == 0) || (hdd[i].hpc == 0) || (hdd[i].tracks == 0)) && (hdd[i].bus != HDD_BUS_SCSI_REMOVABLE)) {
|
||||
continue;
|
||||
}
|
||||
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)) {
|
||||
if (((hdd[i].bus == HDD_BUS_SCSI) || (hdd[i].bus == HDD_BUS_SCSI_REMOVABLE)) && (hdd[i].id.scsi.id == scsi_id) && (hdd[i].id.scsi.lun == scsi_lun)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -550,8 +550,8 @@ scsi_hd_sense_clear(int id, int command)
|
||||
static void
|
||||
scsi_hd_set_phase(uint8_t id, uint8_t phase)
|
||||
{
|
||||
uint8_t scsi_id = hdd[id].scsi_id;
|
||||
uint8_t scsi_lun = hdd[id].scsi_lun;
|
||||
uint8_t scsi_id = hdd[id].id.scsi.id;
|
||||
uint8_t scsi_lun = hdd[id].id.scsi.lun;
|
||||
|
||||
if ((hdd[id].bus != HDD_BUS_SCSI) &&
|
||||
(hdd[id].bus != HDD_BUS_SCSI_REMOVABLE)) return;
|
||||
@@ -692,7 +692,7 @@ scsi_hd_pre_execution_check(uint8_t id, uint8_t *cdb)
|
||||
{
|
||||
int ready = 1;
|
||||
|
||||
if (((shdc[id].request_length >> 5) & 7) != hdd[id].scsi_lun) {
|
||||
if (((shdc[id].request_length >> 5) & 7) != hdd[id].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);
|
||||
return 0;
|
||||
@@ -859,7 +859,7 @@ void
|
||||
scsi_hd_command(uint8_t id, uint8_t *cdb)
|
||||
{
|
||||
/* uint8_t *hdbufferb = (uint8_t *) shdc[id].buffer; */
|
||||
uint8_t *hdbufferb = SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].CmdBuffer;
|
||||
uint8_t *hdbufferb = SCSIDevices[hdd[id].id.scsi.id][hdd[id].id.scsi.lun].CmdBuffer;
|
||||
int32_t len;
|
||||
int pos=0;
|
||||
int max_len;
|
||||
@@ -873,7 +873,7 @@ scsi_hd_command(uint8_t id, uint8_t *cdb)
|
||||
'E','M','U','_','H','D','0','0',' ','v','1','.','0','0',0 };
|
||||
uint32_t last_sector = 0;
|
||||
int block_desc = 0;
|
||||
int32_t *BufLen = &SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].BufferLength;
|
||||
int32_t *BufLen = &SCSIDevices[hdd[id].id.scsi.id][hdd[id].id.scsi.lun].BufferLength;
|
||||
#if 0
|
||||
int CdbLength;
|
||||
#endif
|
||||
@@ -1393,8 +1393,8 @@ atapi_out:
|
||||
void
|
||||
scsi_hd_phase_data_in(uint8_t id)
|
||||
{
|
||||
uint8_t *hdbufferb = SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].CmdBuffer;
|
||||
int32_t *BufLen = &SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].BufferLength;
|
||||
uint8_t *hdbufferb = SCSIDevices[hdd[id].id.scsi.id][hdd[id].id.scsi.lun].CmdBuffer;
|
||||
int32_t *BufLen = &SCSIDevices[hdd[id].id.scsi.id][hdd[id].id.scsi.lun].BufferLength;
|
||||
|
||||
if (!*BufLen) {
|
||||
scsi_hd_log("scsi_hd_phase_data_in(): Buffer length is 0\n");
|
||||
@@ -1449,9 +1449,9 @@ scsi_hd_phase_data_in(uint8_t id)
|
||||
void
|
||||
scsi_hd_phase_data_out(uint8_t id)
|
||||
{
|
||||
uint8_t *hdbufferb = SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].CmdBuffer;
|
||||
uint8_t *hdbufferb = SCSIDevices[hdd[id].id.scsi.id][hdd[id].id.scsi.lun].CmdBuffer;
|
||||
uint32_t i;
|
||||
int32_t *BufLen = &SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].BufferLength;
|
||||
int32_t *BufLen = &SCSIDevices[hdd[id].id.scsi.id][hdd[id].id.scsi.lun].BufferLength;
|
||||
uint32_t last_sector = hdd_image_get_last_sector(id);
|
||||
uint32_t last_to_write = 0;
|
||||
uint32_t c, h, s;
|
||||
|
||||
@@ -8,9 +8,7 @@
|
||||
*
|
||||
* Application resource script for Windows.
|
||||
*
|
||||
* NOTE: maybe have to add CBS_HASSTRINGS to all dropdowns for VC.
|
||||
*
|
||||
* Version: @(#)VARCem.rc 1.0.19 2018/04/10
|
||||
* Version: @(#)VARCem.rc 1.0.20 2018/04/23
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -1046,24 +1044,22 @@ END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_4352 "MFM/RLL"
|
||||
IDS_4353 "XT IDE"
|
||||
IDS_4354 "ESDI"
|
||||
IDS_4355 "IDE (PIO-only)"
|
||||
IDS_4356 "IDE (PIO+DMA)"
|
||||
IDS_4357 "SCSI"
|
||||
IDS_4358 "SCSI (removable)"
|
||||
IDS_4352 "ST506"
|
||||
IDS_4353 "ESDI"
|
||||
IDS_4354 "IDE (PIO-only)"
|
||||
IDS_4355 "IDE (PIO+DMA)"
|
||||
IDS_4356 "SCSI"
|
||||
IDS_4357 "SCSI (removable)"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_4608 "MFM/RLL (%01i:%01i)"
|
||||
IDS_4609 "XT IDE (%01i:%01i)"
|
||||
IDS_4610 "ESDI (%01i:%01i)"
|
||||
IDS_4611 "IDE (PIO-only) (%01i:%01i)"
|
||||
IDS_4612 "IDE (PIO+DMA) (%01i:%01i)"
|
||||
IDS_4613 "SCSI (%02i:%02i)"
|
||||
IDS_4614 "SCSI (removable) (%02i:%02i)"
|
||||
IDS_4608 "ST506 (%01i:%01i)"
|
||||
IDS_4609 "ESDI (%01i:%01i)"
|
||||
IDS_4610 "IDE (PIO-only) (%01i:%01i)"
|
||||
IDS_4611 "IDE (PIO+DMA) (%01i:%01i)"
|
||||
IDS_4612 "SCSI (%02i:%02i)"
|
||||
IDS_4613 "SCSI (removable) (%02i:%02i)"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
# Makefile for Windows systems using the MinGW32 environment.
|
||||
#
|
||||
# Version: @(#)Makefile.mingw 1.0.27 2018/04/20
|
||||
# Version: @(#)Makefile.mingw 1.0.28 2018/04/23
|
||||
#
|
||||
# Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
#
|
||||
@@ -545,10 +545,9 @@ FDDOBJ := fdc.o \
|
||||
HDDOBJ := hdd.o \
|
||||
hdd_image.o hdd_table.o \
|
||||
hdc.o \
|
||||
hdc_mfm_xt.o hdc_xtide.o \
|
||||
hdc_mfm_at.o \
|
||||
hdc_st506_xt.o hdc_st506_at.o \
|
||||
hdc_esdi_at.o hdc_esdi_mca.o \
|
||||
hdc_ide.o
|
||||
hdc_ide.o hdc_xtide.o
|
||||
ifeq ($(XTA), y)
|
||||
HDDOBJ += hdc_ide_xta.o
|
||||
endif
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
# Makefile for Windows using Visual Studio 2015.
|
||||
#
|
||||
# Version: @(#)Makefile.VC 1.0.13 2018/04/20
|
||||
# Version: @(#)Makefile.VC 1.0.14 2018/04/23
|
||||
#
|
||||
# Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
#
|
||||
@@ -510,10 +510,9 @@ FDDOBJ := fdc.obj \
|
||||
HDDOBJ := hdd.obj \
|
||||
hdd_image.obj hdd_table.obj \
|
||||
hdc.obj \
|
||||
hdc_mfm_xt.obj hdc_xtide.obj \
|
||||
hdc_mfm_at.obj \
|
||||
hdc_st506_xt.obj hdc_st506_at.obj \
|
||||
hdc_esdi_at.obj hdc_esdi_mca.obj \
|
||||
hdc_ide.obj
|
||||
hdc_ide.obj hdc_xtide.obj
|
||||
ifeq ($(XTA), y)
|
||||
HDDOBJ += hdc_ide_xta.o
|
||||
#endif
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Handle the platform-side of CDROM drives.
|
||||
*
|
||||
* Version: @(#)win_cdrom.c 1.0.5 2018/03/18
|
||||
* Version: @(#)win_cdrom.c 1.0.6 2018/04/23
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -219,7 +219,7 @@ removable_disk_unload(uint8_t id)
|
||||
return;
|
||||
}
|
||||
|
||||
scsi_unloadhd(hdd[id].scsi_id, hdd[id].scsi_lun, id);
|
||||
scsi_unloadhd(hdd[id].id.scsi.id, hdd[id].id.scsi.lun, id);
|
||||
scsi_disk_insert(id);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Implementation of the Settings dialog.
|
||||
*
|
||||
* Version: @(#)win_settings_disk.h 1.0.2 2018/04/07
|
||||
* Version: @(#)win_settings_disk.h 1.0.3 2018/04/23
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -43,7 +43,7 @@
|
||||
************************************************************************/
|
||||
|
||||
/* Global variables needed for the Hard Disk dialogs. */
|
||||
static uint64_t mfm_tracking, esdi_tracking, xtide_tracking,
|
||||
static uint64_t st506_tracking, esdi_tracking,
|
||||
ide_tracking, scsi_tracking[16];
|
||||
static hard_disk_t *hdd_ptr;
|
||||
static hard_disk_t new_hdd;
|
||||
@@ -69,25 +69,23 @@ disk_track_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
mfm_tracking = xtide_tracking = esdi_tracking = ide_tracking = 0;
|
||||
st506_tracking = esdi_tracking = ide_tracking = 0;
|
||||
for (i = 0; i < 16; i++)
|
||||
scsi_tracking[i] = 0;
|
||||
|
||||
for (i=0; i<HDD_NUM; i++) {
|
||||
if (hdd[i].bus == HDD_BUS_MFM)
|
||||
mfm_tracking |= (1ULL << (hdd[i].mfm_channel << 3));
|
||||
else if (hdd[i].bus == HDD_BUS_XTIDE)
|
||||
xtide_tracking |= (1ULL << (hdd[i].xtide_channel << 3));
|
||||
if (hdd[i].bus == HDD_BUS_ST506)
|
||||
st506_tracking |= (1ULL << (hdd[i].id.st506_channel << 3));
|
||||
else if (hdd[i].bus == HDD_BUS_ESDI)
|
||||
esdi_tracking |= (1ULL << (hdd[i].esdi_channel << 3));
|
||||
esdi_tracking |= (1ULL << (hdd[i].id.esdi_channel << 3));
|
||||
else if (hdd[i].bus == HDD_BUS_IDE_PIO_ONLY)
|
||||
ide_tracking |= (1ULL << (hdd[i].ide_channel << 3));
|
||||
ide_tracking |= (1ULL << (hdd[i].id.ide_channel << 3));
|
||||
else if (hdd[i].bus == HDD_BUS_IDE_PIO_AND_DMA)
|
||||
ide_tracking |= (1ULL << (hdd[i].ide_channel << 3));
|
||||
ide_tracking |= (1ULL << (hdd[i].id.ide_channel << 3));
|
||||
else if (hdd[i].bus == HDD_BUS_SCSI)
|
||||
scsi_tracking[hdd[i].scsi_id] |= (1ULL << (hdd[i].scsi_lun << 3));
|
||||
scsi_tracking[hdd[i].id.scsi.id] |= (1ULL << (hdd[i].id.scsi.lun << 3));
|
||||
else if (hdd[i].bus == HDD_BUS_SCSI_REMOVABLE)
|
||||
scsi_tracking[hdd[i].scsi_id] |= (1ULL << (hdd[i].scsi_lun << 3));
|
||||
scsi_tracking[hdd[i].id.scsi.id] |= (1ULL << (hdd[i].id.scsi.lun << 3));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,7 +301,7 @@ disk_recalc_location_controls(HWND hdlg, int is_add_dlg, int assign_id)
|
||||
bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1;
|
||||
|
||||
switch(bus) {
|
||||
case HDD_BUS_MFM: /* MFM */
|
||||
case HDD_BUS_ST506: /* ST506 MFM/RLL */
|
||||
h = GetDlgItem(hdlg, IDT_1722);
|
||||
ShowWindow(h, SW_SHOW);
|
||||
EnableWindow(h, TRUE);
|
||||
@@ -312,21 +310,8 @@ disk_recalc_location_controls(HWND hdlg, int is_add_dlg, int assign_id)
|
||||
ShowWindow(h, SW_SHOW);
|
||||
EnableWindow(h, TRUE);
|
||||
if (assign_id)
|
||||
temp_hdd[hdlv_current_sel].mfm_channel = next_free_binary_channel(&mfm_tracking);
|
||||
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);
|
||||
ShowWindow(h, SW_SHOW);
|
||||
EnableWindow(h, TRUE);
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL);
|
||||
ShowWindow(h, SW_SHOW);
|
||||
EnableWindow(h, TRUE);
|
||||
if (assign_id)
|
||||
temp_hdd[hdlv_current_sel].xtide_channel = next_free_binary_channel(&xtide_tracking);
|
||||
SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.xtide_channel : temp_hdd[hdlv_current_sel].xtide_channel, 0);
|
||||
temp_hdd[hdlv_current_sel].id.st506_channel = next_free_binary_channel(&st506_tracking);
|
||||
SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.id.st506_channel : temp_hdd[hdlv_current_sel].id.st506_channel, 0);
|
||||
break;
|
||||
|
||||
case HDD_BUS_ESDI: /* ESDI */
|
||||
@@ -338,8 +323,8 @@ disk_recalc_location_controls(HWND hdlg, int is_add_dlg, int assign_id)
|
||||
ShowWindow(h, SW_SHOW);
|
||||
EnableWindow(h, TRUE);
|
||||
if (assign_id)
|
||||
temp_hdd[hdlv_current_sel].esdi_channel = next_free_binary_channel(&esdi_tracking);
|
||||
SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.esdi_channel : temp_hdd[hdlv_current_sel].esdi_channel, 0);
|
||||
temp_hdd[hdlv_current_sel].id.esdi_channel = next_free_binary_channel(&esdi_tracking);
|
||||
SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.id.esdi_channel : temp_hdd[hdlv_current_sel].id.esdi_channel, 0);
|
||||
break;
|
||||
|
||||
case HDD_BUS_IDE_PIO_ONLY: /* IDE (PIO-only) */
|
||||
@@ -352,8 +337,8 @@ disk_recalc_location_controls(HWND hdlg, int is_add_dlg, int assign_id)
|
||||
ShowWindow(h, SW_SHOW);
|
||||
EnableWindow(h, TRUE);
|
||||
if (assign_id)
|
||||
temp_hdd[hdlv_current_sel].ide_channel = next_free_ide_channel();
|
||||
SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.ide_channel : temp_hdd[hdlv_current_sel].ide_channel, 0);
|
||||
temp_hdd[hdlv_current_sel].id.ide_channel = next_free_ide_channel();
|
||||
SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.id.ide_channel : temp_hdd[hdlv_current_sel].id.ide_channel, 0);
|
||||
break;
|
||||
|
||||
case HDD_BUS_SCSI: /* SCSI */
|
||||
@@ -366,17 +351,17 @@ disk_recalc_location_controls(HWND hdlg, int is_add_dlg, int assign_id)
|
||||
EnableWindow(h, TRUE);
|
||||
|
||||
if (assign_id)
|
||||
next_free_scsi_id_and_lun((uint8_t *) &temp_hdd[hdlv_current_sel].scsi_id, (uint8_t *) &temp_hdd[hdlv_current_sel].scsi_lun);
|
||||
next_free_scsi_id_and_lun((uint8_t *) &temp_hdd[hdlv_current_sel].id.scsi.id, (uint8_t *) &temp_hdd[hdlv_current_sel].id.scsi.lun);
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_HD_ID);
|
||||
ShowWindow(h, SW_SHOW);
|
||||
EnableWindow(h, TRUE);
|
||||
SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.scsi_id : temp_hdd[hdlv_current_sel].scsi_id, 0);
|
||||
SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.id.scsi.id : temp_hdd[hdlv_current_sel].id.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_hdd.scsi_lun : temp_hdd[hdlv_current_sel].scsi_lun, 0);
|
||||
SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.id.scsi.lun : temp_hdd[hdlv_current_sel].id.scsi.lun, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -405,9 +390,8 @@ static void
|
||||
recalc_next_free_id(HWND hdlg)
|
||||
{
|
||||
HWND h;
|
||||
int c_mfm = 0;
|
||||
int c_st506 = 0;
|
||||
int c_esdi = 0;
|
||||
int c_xtide = 0;
|
||||
int c_ide_pio = 0;
|
||||
int c_ide_dma = 0;
|
||||
int c_scsi = 0;
|
||||
@@ -417,12 +401,10 @@ recalc_next_free_id(HWND hdlg)
|
||||
next_free_id = -1;
|
||||
|
||||
for (i = 0; i < HDD_NUM; i++) {
|
||||
if (temp_hdd[i].bus == HDD_BUS_MFM)
|
||||
c_mfm++;
|
||||
if (temp_hdd[i].bus == HDD_BUS_ST506)
|
||||
c_st506++;
|
||||
else if (temp_hdd[i].bus == HDD_BUS_ESDI)
|
||||
c_esdi++;
|
||||
else if (temp_hdd[i].bus == HDD_BUS_XTIDE)
|
||||
c_xtide++;
|
||||
else if (temp_hdd[i].bus == HDD_BUS_IDE_PIO_ONLY)
|
||||
c_ide_pio++;
|
||||
else if (temp_hdd[i].bus == HDD_BUS_IDE_PIO_AND_DMA)
|
||||
@@ -441,10 +423,9 @@ recalc_next_free_id(HWND hdlg)
|
||||
}
|
||||
|
||||
enable_add = enable_add || (next_free_id >= 0);
|
||||
enable_add = enable_add && ((c_mfm < MFM_NUM) || (c_esdi < ESDI_NUM) || (c_xtide < XTIDE_NUM) || (c_ide_pio < IDE_NUM) || (c_ide_dma < IDE_NUM) || (c_scsi < SCSI_NUM));
|
||||
enable_add = enable_add && !bus_full(&mfm_tracking, 2);
|
||||
enable_add = enable_add && ((c_st506 < ST506_NUM) || (c_esdi < ESDI_NUM) || (c_ide_pio < IDE_NUM) || (c_ide_dma < IDE_NUM) || (c_scsi < SCSI_NUM));
|
||||
enable_add = enable_add && !bus_full(&st506_tracking, 2);
|
||||
enable_add = enable_add && !bus_full(&esdi_tracking, 2);
|
||||
enable_add = enable_add && !bus_full(&xtide_tracking, 2);
|
||||
enable_add = enable_add && !bus_full(&ide_tracking, 8);
|
||||
for (i = 0; i < 16; i++)
|
||||
enable_add = enable_add && !bus_full(&(scsi_tracking[i]), 8);
|
||||
@@ -462,7 +443,7 @@ recalc_next_free_id(HWND hdlg)
|
||||
EnableWindow(h, FALSE);
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_BUTTON_HDD_REMOVE);
|
||||
if ((c_mfm == 0) && (c_esdi == 0) && (c_xtide == 0) && (c_ide_pio == 0) && (c_ide_dma == 0) && (c_scsi == 0))
|
||||
if ((c_st506 == 0) && (c_esdi == 0) && (c_ide_pio == 0) && (c_ide_dma == 0) && (c_scsi == 0))
|
||||
EnableWindow(h, FALSE);
|
||||
else
|
||||
EnableWindow(h, TRUE);
|
||||
@@ -482,32 +463,28 @@ disk_update_item(HWND hwndList, int i, int column)
|
||||
|
||||
if (column == 0) {
|
||||
switch(temp_hdd[i].bus) {
|
||||
case HDD_BUS_MFM:
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4608), temp_hdd[i].mfm_channel >> 1, temp_hdd[i].mfm_channel & 1);
|
||||
break;
|
||||
|
||||
case HDD_BUS_XTIDE:
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4609), temp_hdd[i].xtide_channel >> 1, temp_hdd[i].xtide_channel & 1);
|
||||
case HDD_BUS_ST506:
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4608), temp_hdd[i].id.st506_channel >> 1, temp_hdd[i].id.st506_channel & 1);
|
||||
break;
|
||||
|
||||
case HDD_BUS_ESDI:
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4610), temp_hdd[i].esdi_channel >> 1, temp_hdd[i].esdi_channel & 1);
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4609), temp_hdd[i].id.esdi_channel >> 1, temp_hdd[i].id.esdi_channel & 1);
|
||||
break;
|
||||
|
||||
case HDD_BUS_IDE_PIO_ONLY:
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4611), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1);
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4610), temp_hdd[i].id.ide_channel >> 1, temp_hdd[i].id.ide_channel & 1);
|
||||
break;
|
||||
|
||||
case HDD_BUS_IDE_PIO_AND_DMA:
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4612), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1);
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4611), temp_hdd[i].id.ide_channel >> 1, temp_hdd[i].id.ide_channel & 1);
|
||||
break;
|
||||
|
||||
case HDD_BUS_SCSI:
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4613), temp_hdd[i].scsi_id, temp_hdd[i].scsi_lun);
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4612), temp_hdd[i].id.scsi.id, temp_hdd[i].id.scsi.lun);
|
||||
break;
|
||||
|
||||
case HDD_BUS_SCSI_REMOVABLE:
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4614), temp_hdd[i].scsi_id, temp_hdd[i].scsi_lun);
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4613), temp_hdd[i].id.scsi.id, temp_hdd[i].id.scsi.lun);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -569,32 +546,28 @@ disk_recalc_list(HWND hwndList)
|
||||
hdc_id_to_listview_index[i] = j;
|
||||
|
||||
switch(temp_hdd[i].bus) {
|
||||
case HDD_BUS_MFM:
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4608), temp_hdd[i].mfm_channel >> 1, temp_hdd[i].mfm_channel & 1);
|
||||
break;
|
||||
|
||||
case HDD_BUS_XTIDE:
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4609), temp_hdd[i].xtide_channel >> 1, temp_hdd[i].xtide_channel & 1);
|
||||
case HDD_BUS_ST506:
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4608), temp_hdd[i].id.st506_channel >> 1, temp_hdd[i].id.st506_channel & 1);
|
||||
break;
|
||||
|
||||
case HDD_BUS_ESDI:
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4610), temp_hdd[i].esdi_channel >> 1, temp_hdd[i].esdi_channel & 1);
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4609), temp_hdd[i].id.esdi_channel >> 1, temp_hdd[i].id.esdi_channel & 1);
|
||||
break;
|
||||
|
||||
case HDD_BUS_IDE_PIO_ONLY:
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4611), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1);
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4610), temp_hdd[i].id.ide_channel >> 1, temp_hdd[i].id.ide_channel & 1);
|
||||
break;
|
||||
|
||||
case HDD_BUS_IDE_PIO_AND_DMA:
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4612), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1);
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4611), temp_hdd[i].id.ide_channel >> 1, temp_hdd[i].id.ide_channel & 1);
|
||||
break;
|
||||
|
||||
case HDD_BUS_SCSI:
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4613), temp_hdd[i].scsi_id, temp_hdd[i].scsi_lun);
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4612), temp_hdd[i].id.scsi.id, temp_hdd[i].id.scsi.lun);
|
||||
break;
|
||||
|
||||
case HDD_BUS_SCSI_REMOVABLE:
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4614), temp_hdd[i].scsi_id, temp_hdd[i].scsi_lun);
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_4613), temp_hdd[i].id.scsi.id, temp_hdd[i].id.scsi.lun);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -896,12 +869,11 @@ disk_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE);
|
||||
SendMessage(h, CB_SETCURSEL, channel, 0);
|
||||
|
||||
new_hdd.mfm_channel = next_free_binary_channel(&mfm_tracking);
|
||||
new_hdd.esdi_channel = next_free_binary_channel(&esdi_tracking);
|
||||
new_hdd.xtide_channel = next_free_binary_channel(&xtide_tracking);
|
||||
new_hdd.ide_channel = channel;
|
||||
new_hdd.scsi_id = id;
|
||||
new_hdd.scsi_lun = lun;
|
||||
new_hdd.id.st506_channel = next_free_binary_channel(&st506_tracking);
|
||||
new_hdd.id.esdi_channel = next_free_binary_channel(&esdi_tracking);
|
||||
new_hdd.id.ide_channel = channel;
|
||||
new_hdd.id.scsi.id = id;
|
||||
new_hdd.id.scsi.lun = lun;
|
||||
}
|
||||
h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME);
|
||||
EnableWindow(h, FALSE);
|
||||
@@ -956,33 +928,28 @@ disk_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
}
|
||||
} else {
|
||||
switch(hdd_ptr->bus) {
|
||||
case HDD_BUS_MFM:
|
||||
case HDD_BUS_ST506:
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL);
|
||||
hdd_ptr->mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0) & 0xff;
|
||||
hdd_ptr->id.st506_channel = SendMessage(h, CB_GETCURSEL, 0, 0) & 0xff;
|
||||
break;
|
||||
|
||||
case HDD_BUS_ESDI:
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL);
|
||||
hdd_ptr->esdi_channel = SendMessage(h, CB_GETCURSEL, 0, 0) & 0xff;
|
||||
break;
|
||||
|
||||
case HDD_BUS_XTIDE:
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL);
|
||||
hdd_ptr->xtide_channel = SendMessage(h, CB_GETCURSEL, 0, 0) & 0xff;
|
||||
hdd_ptr->id.esdi_channel = SendMessage(h, CB_GETCURSEL, 0, 0) & 0xff;
|
||||
break;
|
||||
|
||||
case HDD_BUS_IDE_PIO_ONLY:
|
||||
case HDD_BUS_IDE_PIO_AND_DMA:
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE);
|
||||
hdd_ptr->ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0) & 0xff;
|
||||
hdd_ptr->id.ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0) & 0xff;
|
||||
break;
|
||||
|
||||
case HDD_BUS_SCSI:
|
||||
case HDD_BUS_SCSI_REMOVABLE:
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_HD_ID);
|
||||
hdd_ptr->scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0) & 0xff;
|
||||
hdd_ptr->id.scsi.id = SendMessage(h, CB_GETCURSEL, 0, 0) & 0xff;
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN);
|
||||
hdd_ptr->scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0) & 0xff;
|
||||
hdd_ptr->id.scsi.lun = SendMessage(h, CB_GETCURSEL, 0, 0) & 0xff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1369,14 +1336,13 @@ hdd_add_file_open_error:
|
||||
max_spt = max_hpc = max_tracks = 0;
|
||||
break;
|
||||
|
||||
case HDD_BUS_MFM:
|
||||
max_spt = 17;
|
||||
case HDD_BUS_ST506:
|
||||
max_spt = 26;
|
||||
max_hpc = 15;
|
||||
max_tracks = 1023;
|
||||
break;
|
||||
|
||||
case HDD_BUS_ESDI:
|
||||
case HDD_BUS_XTIDE:
|
||||
max_spt = 63;
|
||||
max_hpc = 16;
|
||||
max_tracks = 1023;
|
||||
@@ -1492,26 +1458,22 @@ static void
|
||||
disk_track(uint8_t id)
|
||||
{
|
||||
switch(temp_hdd[id].bus) {
|
||||
case HDD_BUS_MFM:
|
||||
mfm_tracking |= (1ULL << (temp_hdd[id].mfm_channel << 3));
|
||||
case HDD_BUS_ST506:
|
||||
st506_tracking |= (1ULL << (temp_hdd[id].id.st506_channel << 3));
|
||||
break;
|
||||
|
||||
case HDD_BUS_ESDI:
|
||||
esdi_tracking |= (1ULL << (temp_hdd[id].esdi_channel << 3));
|
||||
break;
|
||||
|
||||
case HDD_BUS_XTIDE:
|
||||
xtide_tracking |= (1ULL << (temp_hdd[id].xtide_channel << 3));
|
||||
esdi_tracking |= (1ULL << (temp_hdd[id].id.esdi_channel << 3));
|
||||
break;
|
||||
|
||||
case HDD_BUS_IDE_PIO_ONLY:
|
||||
case HDD_BUS_IDE_PIO_AND_DMA:
|
||||
ide_tracking |= (1ULL << (temp_hdd[id].ide_channel << 3));
|
||||
ide_tracking |= (1ULL << (temp_hdd[id].id.ide_channel << 3));
|
||||
break;
|
||||
|
||||
case HDD_BUS_SCSI:
|
||||
case HDD_BUS_SCSI_REMOVABLE:
|
||||
scsi_tracking[temp_hdd[id].scsi_id] |= (1ULL << (temp_hdd[id].scsi_lun << 3));
|
||||
scsi_tracking[temp_hdd[id].id.scsi.id] |= (1ULL << (temp_hdd[id].id.scsi.lun << 3));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1521,26 +1483,22 @@ static void
|
||||
disk_untrack(uint8_t id)
|
||||
{
|
||||
switch(temp_hdd[id].bus) {
|
||||
case HDD_BUS_MFM:
|
||||
mfm_tracking &= ~(1 << (temp_hdd[id].mfm_channel << 3));
|
||||
case HDD_BUS_ST506:
|
||||
st506_tracking &= ~(1 << (temp_hdd[id].id.st506_channel << 3));
|
||||
break;
|
||||
|
||||
case HDD_BUS_ESDI:
|
||||
esdi_tracking &= ~(1 << (temp_hdd[id].esdi_channel << 3));
|
||||
break;
|
||||
|
||||
case HDD_BUS_XTIDE:
|
||||
xtide_tracking &= ~(1 << (temp_hdd[id].xtide_channel << 3));
|
||||
esdi_tracking &= ~(1 << (temp_hdd[id].id.esdi_channel << 3));
|
||||
break;
|
||||
|
||||
case HDD_BUS_IDE_PIO_ONLY:
|
||||
case HDD_BUS_IDE_PIO_AND_DMA:
|
||||
ide_tracking &= ~(1 << (temp_hdd[id].ide_channel << 3));
|
||||
ide_tracking &= ~(1 << (temp_hdd[id].id.ide_channel << 3));
|
||||
break;
|
||||
|
||||
case HDD_BUS_SCSI:
|
||||
case HDD_BUS_SCSI_REMOVABLE:
|
||||
scsi_tracking[temp_hdd[id].scsi_id] &= ~(1 << (temp_hdd[id].scsi_lun << 3));
|
||||
scsi_tracking[temp_hdd[id].id.scsi.id] &= ~(1 << (temp_hdd[id].id.scsi.lun << 3));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1660,12 +1618,10 @@ hd_bus_skip:
|
||||
ignore_change = 1;
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL);
|
||||
disk_untrack(hdlv_current_sel);
|
||||
if (temp_hdd[hdlv_current_sel].bus == HDD_BUS_MFM)
|
||||
temp_hdd[hdlv_current_sel].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0) & 0xff;
|
||||
if (temp_hdd[hdlv_current_sel].bus == HDD_BUS_ST506)
|
||||
temp_hdd[hdlv_current_sel].id.st506_channel = SendMessage(h, CB_GETCURSEL, 0, 0) & 0xff;
|
||||
else if (temp_hdd[hdlv_current_sel].bus == HDD_BUS_ESDI)
|
||||
temp_hdd[hdlv_current_sel].esdi_channel = SendMessage(h, CB_GETCURSEL, 0, 0) & 0xff;
|
||||
else if (temp_hdd[hdlv_current_sel].bus == HDD_BUS_XTIDE)
|
||||
temp_hdd[hdlv_current_sel].xtide_channel = SendMessage(h, CB_GETCURSEL, 0, 0) & 0xff;
|
||||
temp_hdd[hdlv_current_sel].id.esdi_channel = SendMessage(h, CB_GETCURSEL, 0, 0) & 0xff;
|
||||
disk_track(hdlv_current_sel);
|
||||
h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS);
|
||||
disk_update_item(h, hdlv_current_sel, 0);
|
||||
@@ -1679,7 +1635,7 @@ hd_bus_skip:
|
||||
ignore_change = 1;
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE);
|
||||
disk_untrack(hdlv_current_sel);
|
||||
temp_hdd[hdlv_current_sel].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0) & 0xff;
|
||||
temp_hdd[hdlv_current_sel].id.ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0) & 0xff;
|
||||
disk_track(hdlv_current_sel);
|
||||
h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS);
|
||||
disk_update_item(h, hdlv_current_sel, 0);
|
||||
@@ -1693,7 +1649,7 @@ hd_bus_skip:
|
||||
ignore_change = 1;
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_HD_ID);
|
||||
disk_untrack(hdlv_current_sel);
|
||||
temp_hdd[hdlv_current_sel].scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0) & 0xff;
|
||||
temp_hdd[hdlv_current_sel].id.scsi.id = SendMessage(h, CB_GETCURSEL, 0, 0) & 0xff;
|
||||
disk_track(hdlv_current_sel);
|
||||
h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS);
|
||||
disk_update_item(h, hdlv_current_sel, 0);
|
||||
@@ -1707,7 +1663,7 @@ hd_bus_skip:
|
||||
ignore_change = 1;
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN);
|
||||
disk_untrack(hdlv_current_sel);
|
||||
temp_hdd[hdlv_current_sel].scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0) & 0xff;
|
||||
temp_hdd[hdlv_current_sel].id.scsi.lun = SendMessage(h, CB_GETCURSEL, 0, 0) & 0xff;
|
||||
disk_track(hdlv_current_sel);
|
||||
h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS);
|
||||
disk_update_item(h, hdlv_current_sel, 0);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Implementation of the Status Bar module.
|
||||
*
|
||||
* Version: @(#)win_stbar.c 1.0.9 2018/04/14
|
||||
* Version: @(#)win_stbar.c 1.0.10 2018/04/23
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -614,17 +614,16 @@ ui_sb_update_panes(void)
|
||||
{
|
||||
int i, id, hdint;
|
||||
int edge = 0;
|
||||
int c_mfm, c_esdi, c_scsi;
|
||||
int c_xtide, c_ide_pio, c_ide_dma;
|
||||
int c_st506, c_esdi, c_scsi;
|
||||
int c_ide_pio, c_ide_dma;
|
||||
int do_net;
|
||||
const char *hdc;
|
||||
|
||||
sb_ready = 0;
|
||||
|
||||
hdint = (machines[machine].flags & MACHINE_HDC) ? 1 : 0;
|
||||
c_mfm = hdd_count(HDD_BUS_MFM);
|
||||
c_st506 = hdd_count(HDD_BUS_ST506);
|
||||
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);
|
||||
@@ -703,17 +702,14 @@ ui_sb_update_panes(void)
|
||||
sb_parts++;
|
||||
}
|
||||
}
|
||||
if (c_mfm && (hdint || !strncmp(hdc, "mfm", 3))) {
|
||||
/* MFM drives, and MFM or Internal controller. */
|
||||
if (c_st506 && (hdint || !strncmp(hdc, "st506", 5))) {
|
||||
/* ST506 MFM/RLL drives, and MFM or Internal controller. */
|
||||
sb_parts++;
|
||||
}
|
||||
if (c_esdi && (hdint || !strncmp(hdc, "esdi", 4))) {
|
||||
/* ESDI drives, and ESDI or Internal controller. */
|
||||
sb_parts++;
|
||||
}
|
||||
if (c_xtide && !strncmp(hdc, "ide", 3)) {
|
||||
sb_parts++;
|
||||
}
|
||||
if (c_ide_pio && (hdint || !strncmp(hdc, "ide", 3))) {
|
||||
/* IDE_PIO drives, and IDE or Internal controller. */
|
||||
sb_parts++;
|
||||
@@ -805,10 +801,10 @@ ui_sb_update_panes(void)
|
||||
sb_parts++;
|
||||
}
|
||||
}
|
||||
if (c_mfm && (hdint || !strncmp(hdc, "mfm", 3))) {
|
||||
if (c_st506 && (hdint || !strncmp(hdc, "st506", 5))) {
|
||||
edge += SB_ICON_WIDTH;
|
||||
iStatusWidths[sb_parts] = edge;
|
||||
sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_MFM;
|
||||
sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_ST506;
|
||||
sb_parts++;
|
||||
}
|
||||
if (c_esdi && (hdint || !strncmp(hdc, "esdi", 4))) {
|
||||
@@ -817,12 +813,6 @@ ui_sb_update_panes(void)
|
||||
sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_ESDI;
|
||||
sb_parts++;
|
||||
}
|
||||
if (c_xtide && !strncmp(hdc, "xtide", 5)) {
|
||||
edge += SB_ICON_WIDTH;
|
||||
iStatusWidths[sb_parts] = edge;
|
||||
sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_XTIDE;
|
||||
sb_parts++;
|
||||
}
|
||||
if (c_ide_pio && (hdint || !strncmp(hdc, "ide", 3))) {
|
||||
edge += SB_ICON_WIDTH;
|
||||
iStatusWidths[sb_parts] = edge;
|
||||
@@ -1203,7 +1193,7 @@ StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
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_loadhd(hdd[id].id.scsi.id, hdd[id].id.scsi.lun, id);
|
||||
scsi_disk_insert(id);
|
||||
if (wcslen(hdd[id].fn) > 0) {
|
||||
ui_sb_update_icon_state(SB_RDISK | id, 0);
|
||||
|
||||
Reference in New Issue
Block a user