Fix for AT ESDI driver from TheCollector1995.
Renamed "mfm_xebec" to "mfm_xt" and "esdi_wd1007vse1" to "esdi_at".
This commit is contained in:
@@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
* Common code to handle all sorts of disk controllers.
|
* Common code to handle all sorts of disk controllers.
|
||||||
*
|
*
|
||||||
* Version: @(#)hdc.c 1.0.6 2017/11/04
|
* Version: @(#)hdc.c 1.0.7 2017/11/08
|
||||||
*
|
*
|
||||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||||
@@ -76,48 +76,48 @@ static struct {
|
|||||||
device_t *device;
|
device_t *device;
|
||||||
int is_mfm;
|
int is_mfm;
|
||||||
} controllers[] = {
|
} controllers[] = {
|
||||||
{ "None", "none",
|
{ "None", "none",
|
||||||
&null_device, 0 },
|
&null_device, 0 },
|
||||||
|
|
||||||
{ "Internal Controller", "internal",
|
{ "Internal Controller", "internal",
|
||||||
&inthdc_device, 0 },
|
&inthdc_device, 0 },
|
||||||
|
|
||||||
{ "[ISA] [MFM] IBM PC Fixed Disk Adapter", "mfm_xebec",
|
{ "[ISA] [MFM] IBM PC Fixed Disk Adapter", "mfm_xt",
|
||||||
&mfm_xt_xebec_device, 1 },
|
&mfm_xt_xebec_device, 1 },
|
||||||
|
|
||||||
{ "[ISA] [MFM] DTC-5150X Fixed Disk Adapter", "mfm_dtc5150x",
|
{ "[ISA] [MFM] DTC-5150X Fixed Disk Adapter", "mfm_dtc5150x",
|
||||||
&mfm_xt_dtc5150x_device, 1 },
|
&mfm_xt_dtc5150x_device, 1 },
|
||||||
|
|
||||||
{ "[ISA] [MFM] IBM PC/AT Fixed Disk Adapter", "mfm_at",
|
{ "[ISA] [MFM] IBM PC/AT Fixed Disk Adapter", "mfm_at",
|
||||||
&mfm_at_wd1003_device, 1 },
|
&mfm_at_wd1003_device, 1 },
|
||||||
|
|
||||||
{ "[ISA] [ESDI] PC/AT ESDI Fixed Disk Adapter", "esdi_wd1007vse1",
|
{ "[ISA] [ESDI] PC/AT ESDI Fixed Disk Adapter", "esdi_at",
|
||||||
&esdi_at_wd1007vse1_device, 0 },
|
&esdi_at_wd1007vse1_device, 0 },
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
{ "[ISA] [IDE] PC/AT IDE Adapter", "ide_isa",
|
{ "[ISA] [IDE] PC/AT IDE Adapter", "ide_isa",
|
||||||
&ide_isa_device, 0 },
|
&ide_isa_device, 0 },
|
||||||
|
|
||||||
{ "[PCI] [IDE] PCI IDE Adapter", "ide_pci",
|
{ "[PCI] [IDE] PCI IDE Adapter", "ide_pci",
|
||||||
&ide_pci_device, 0 },
|
&ide_pci_device, 0 },
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{ "[ISA] [IDE] PC/XT XTIDE", "xtide",
|
{ "[ISA] [IDE] PC/XT XTIDE", "xtide",
|
||||||
&xtide_device , 0 },
|
&xtide_device , 0 },
|
||||||
|
|
||||||
{ "[ISA] [IDE] PC/AT XTIDE", "xtide_at",
|
{ "[ISA] [IDE] PC/AT XTIDE", "xtide_at",
|
||||||
&xtide_at_device, 0 },
|
&xtide_at_device, 0 },
|
||||||
|
|
||||||
{ "[ISA] [IDE] PS/2 XTIDE (Acculogic)", "xtide_ps2",
|
{ "[ISA] [IDE] PS/2 XTIDE (Acculogic)", "xtide_ps2",
|
||||||
&xtide_ps2_device, 0 },
|
&xtide_ps2_device, 0 },
|
||||||
|
|
||||||
{ "[ISA] [IDE] PS/2 AT XTIDE (1.1.5)", "xtide_at_ps2",
|
{ "[ISA] [IDE] PS/2 AT XTIDE (1.1.5)", "xtide_at_ps2",
|
||||||
&xtide_at_ps2_device, 0 },
|
&xtide_at_ps2_device, 0 },
|
||||||
|
|
||||||
{ "[MCA] [ESDI] IBM PS/2 ESDI Fixed Disk Adapter","esdi_mca",
|
{ "[MCA] [ESDI] IBM PS/2 ESDI Fixed Disk Adapter","esdi_mca",
|
||||||
&esdi_ps2_device, 1 },
|
&esdi_ps2_device, 1 },
|
||||||
|
|
||||||
{ "", "", NULL, 0 }
|
{ "", "", NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
* Driver for the ESDI controller (WD1007-vse1) for PC/AT.
|
* Driver for the ESDI controller (WD1007-vse1) for PC/AT.
|
||||||
*
|
*
|
||||||
* Version: @(#)hdc_esdi_at.c 1.0.7 2017/11/04
|
* Version: @(#)hdc_esdi_at.c 1.0.8 2017/11/08
|
||||||
*
|
*
|
||||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||||
* Miran Grca, <mgrca8@gmail.com>
|
* Miran Grca, <mgrca8@gmail.com>
|
||||||
@@ -45,18 +45,18 @@
|
|||||||
#define STAT_ERR 0x01
|
#define STAT_ERR 0x01
|
||||||
#define STAT_INDEX 0x02
|
#define STAT_INDEX 0x02
|
||||||
#define STAT_CORRECTED_DATA 0x04
|
#define STAT_CORRECTED_DATA 0x04
|
||||||
#define STAT_DRQ 0x08 /* Data request */
|
#define STAT_DRQ 0x08 /* Data request */
|
||||||
#define STAT_DSC 0x10
|
#define STAT_DSC 0x10
|
||||||
#define STAT_SEEK_COMPLETE 0x20
|
#define STAT_SEEK_COMPLETE 0x20
|
||||||
#define STAT_READY 0x40
|
#define STAT_READY 0x40
|
||||||
#define STAT_BUSY 0x80
|
#define STAT_BUSY 0x80
|
||||||
|
|
||||||
#define ERR_DAM_NOT_FOUND 0x01 /*Data Address Mark not found*/
|
#define ERR_DAM_NOT_FOUND 0x01 /* Data Address Mark not found */
|
||||||
#define ERR_TR000 0x02 /*Track 0 not found*/
|
#define ERR_TR000 0x02 /* track 0 not found */
|
||||||
#define ERR_ABRT 0x04 /*Command aborted*/
|
#define ERR_ABRT 0x04 /* command aborted */
|
||||||
#define ERR_ID_NOT_FOUND 0x10 /*ID not found*/
|
#define ERR_ID_NOT_FOUND 0x10 /* ID not found */
|
||||||
#define ERR_DATA_CRC 0x40 /*Data CRC error*/
|
#define ERR_DATA_CRC 0x40 /* data CRC error */
|
||||||
#define ERR_BAD_BLOCK 0x80 /*Bad Block detected*/
|
#define ERR_BAD_BLOCK 0x80 /* bad block detected */
|
||||||
|
|
||||||
#define CMD_NOP 0x00
|
#define CMD_NOP 0x00
|
||||||
#define CMD_RESTORE 0x10
|
#define CMD_RESTORE 0x10
|
||||||
@@ -70,63 +70,67 @@
|
|||||||
#define CMD_READ_PARAMETERS 0xec
|
#define CMD_READ_PARAMETERS 0xec
|
||||||
|
|
||||||
|
|
||||||
extern char ide_fn[4][512];
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int cfg_spt;
|
int cfg_spt;
|
||||||
int cfg_hpc;
|
int cfg_hpc;
|
||||||
int current_cylinder;
|
int current_cylinder;
|
||||||
int real_spt;
|
int real_spt;
|
||||||
int real_hpc;
|
int real_hpc;
|
||||||
int real_tracks;
|
int real_tracks;
|
||||||
int present;
|
int present;
|
||||||
int hdd_num;
|
int hdd_num;
|
||||||
} drive_t;
|
} drive_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
uint8_t error;
|
uint8_t error;
|
||||||
int secount,sector,cylinder,head,cylprecomp;
|
int secount,sector,cylinder,head,cylprecomp;
|
||||||
uint8_t command;
|
uint8_t command;
|
||||||
uint8_t fdisk;
|
uint8_t fdisk;
|
||||||
int pos;
|
int pos;
|
||||||
|
|
||||||
int drive_sel;
|
|
||||||
int reset;
|
|
||||||
uint16_t buffer[256];
|
|
||||||
int irqstat;
|
|
||||||
|
|
||||||
int64_t callback;
|
int drive_sel;
|
||||||
|
int reset;
|
||||||
|
uint16_t buffer[256];
|
||||||
|
int irqstat;
|
||||||
|
|
||||||
drive_t drives[2];
|
int64_t callback;
|
||||||
|
|
||||||
rom_t bios_rom;
|
drive_t drives[2];
|
||||||
|
|
||||||
|
rom_t bios_rom;
|
||||||
} esdi_t;
|
} esdi_t;
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
static __inline void irq_raise(esdi_t *esdi)
|
||||||
irq_raise(esdi_t *esdi)
|
|
||||||
{
|
{
|
||||||
if (! (esdi->fdisk&2))
|
/* If not already pending.. */
|
||||||
picint(1<<14);
|
if (! esdi->irqstat) {
|
||||||
|
/* If enabled in the control register.. */
|
||||||
|
if (! (esdi->fdisk & 0x02)) {
|
||||||
|
/* .. raise IRQ14. */
|
||||||
|
picint(1<<14);
|
||||||
|
}
|
||||||
|
|
||||||
esdi->irqstat=1;
|
/* Remember this. */
|
||||||
|
esdi->irqstat = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
static __inline void irq_lower(esdi_t *esdi)
|
||||||
irq_lower(esdi_t *esdi)
|
|
||||||
{
|
{
|
||||||
picintc(1<<14);
|
/* If raised.. */
|
||||||
}
|
if (esdi->irqstat) {
|
||||||
|
/* If enabled in the control register.. */
|
||||||
|
if (! (esdi->fdisk & 0x02)) {
|
||||||
|
/* .. drop IRQ14. */
|
||||||
|
picintc(1<<14);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remember this. */
|
||||||
static void
|
esdi->irqstat = 0;
|
||||||
irq_update(esdi_t *esdi)
|
}
|
||||||
{
|
|
||||||
if (esdi->irqstat && !((pic2.pend|pic2.ins)&0x40) && !(esdi->fdisk & 2))
|
|
||||||
picint(1<<14);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -137,15 +141,16 @@ get_sector(esdi_t *esdi, off64_t *addr)
|
|||||||
drive_t *drive = &esdi->drives[esdi->drive_sel];
|
drive_t *drive = &esdi->drives[esdi->drive_sel];
|
||||||
int heads = drive->cfg_hpc;
|
int heads = drive->cfg_hpc;
|
||||||
int sectors = drive->cfg_spt;
|
int sectors = drive->cfg_spt;
|
||||||
|
int c, h, s;
|
||||||
|
|
||||||
if (esdi->head > heads) {
|
if (esdi->head > heads) {
|
||||||
pclog("esdi_get_sector: past end of configured heads\n");
|
pclog("esdi_get_sector: past end of configured heads\n");
|
||||||
return 1;
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (esdi->sector >= sectors+1) {
|
if (esdi->sector >= sectors+1) {
|
||||||
pclog("esdi_get_sector: past end of configured sectors\n");
|
pclog("esdi_get_sector: past end of configured sectors\n");
|
||||||
return 1;
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drive->cfg_spt==drive->real_spt && drive->cfg_hpc==drive->real_hpc) {
|
if (drive->cfg_spt==drive->real_spt && drive->cfg_hpc==drive->real_hpc) {
|
||||||
@@ -156,7 +161,6 @@ get_sector(esdi_t *esdi, off64_t *addr)
|
|||||||
* When performing translation, the firmware seems to leave 1
|
* When performing translation, the firmware seems to leave 1
|
||||||
* sector per track inaccessible (spare sector)
|
* sector per track inaccessible (spare sector)
|
||||||
*/
|
*/
|
||||||
int c, h, s;
|
|
||||||
|
|
||||||
*addr = ((((off64_t) esdi->cylinder * heads) + esdi->head) *
|
*addr = ((((off64_t) esdi->cylinder * heads) + esdi->head) *
|
||||||
sectors) + (esdi->sector - 1);
|
sectors) + (esdi->sector - 1);
|
||||||
@@ -177,7 +181,7 @@ static void
|
|||||||
next_sector(esdi_t *esdi)
|
next_sector(esdi_t *esdi)
|
||||||
{
|
{
|
||||||
drive_t *drive = &esdi->drives[esdi->drive_sel];
|
drive_t *drive = &esdi->drives[esdi->drive_sel];
|
||||||
|
|
||||||
esdi->sector++;
|
esdi->sector++;
|
||||||
if (esdi->sector == (drive->cfg_spt + 1)) {
|
if (esdi->sector == (drive->cfg_spt + 1)) {
|
||||||
esdi->sector = 1;
|
esdi->sector = 1;
|
||||||
@@ -195,7 +199,7 @@ static void
|
|||||||
esdi_writew(uint16_t port, uint16_t val, void *priv)
|
esdi_writew(uint16_t port, uint16_t val, void *priv)
|
||||||
{
|
{
|
||||||
esdi_t *esdi = (esdi_t *)priv;
|
esdi_t *esdi = (esdi_t *)priv;
|
||||||
|
|
||||||
esdi->buffer[esdi->pos >> 1] = val;
|
esdi->buffer[esdi->pos >> 1] = val;
|
||||||
esdi->pos += 2;
|
esdi->pos += 2;
|
||||||
|
|
||||||
@@ -214,48 +218,56 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
{
|
{
|
||||||
esdi_t *esdi = (esdi_t *)priv;
|
esdi_t *esdi = (esdi_t *)priv;
|
||||||
|
|
||||||
|
#ifdef ENABLE_HDD_LOG
|
||||||
|
pclog("WD1007 write(%04x, %02x)\n", port, val);
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (port) {
|
switch (port) {
|
||||||
case 0x1F0: /* Data */
|
case 0x1f0: /* data */
|
||||||
esdi_writew(port, val | (val << 8), priv);
|
esdi_writew(port, val | (val << 8), priv);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x1F1: /* Write precompenstation */
|
case 0x1f1: /* write precompensation */
|
||||||
esdi->cylprecomp = val;
|
esdi->cylprecomp = val;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x1F2: /* Sector count */
|
case 0x1f2: /* sector count */
|
||||||
esdi->secount = val;
|
esdi->secount = val;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x1F3: /* Sector */
|
case 0x1f3: /* sector */
|
||||||
esdi->sector = val;
|
esdi->sector = val;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x1F4: /* Cylinder low */
|
case 0x1f4: /* cylinder low */
|
||||||
esdi->cylinder = (esdi->cylinder & 0xFF00) | val;
|
esdi->cylinder = (esdi->cylinder & 0xFF00) | val;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x1F5: /* Cylinder high */
|
case 0x1f5: /* cylinder high */
|
||||||
esdi->cylinder = (esdi->cylinder & 0xFF) | (val << 8);
|
esdi->cylinder = (esdi->cylinder & 0xFF) | (val << 8);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x1F6: /* Drive/Head */
|
case 0x1f6: /* drive/Head */
|
||||||
esdi->head = val & 0xF;
|
esdi->head = val & 0xF;
|
||||||
esdi->drive_sel = (val & 0x10) ? 1 : 0;
|
esdi->drive_sel = (val & 0x10) ? 1 : 0;
|
||||||
if (esdi->drives[esdi->drive_sel].present)
|
if (esdi->drives[esdi->drive_sel].present) {
|
||||||
|
esdi->status = STAT_READY|STAT_DSC;
|
||||||
|
} else {
|
||||||
esdi->status = 0;
|
esdi->status = 0;
|
||||||
else
|
}
|
||||||
esdi->status = STAT_READY | STAT_DSC;
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x1F7: /* Command register */
|
case 0x1f7: /* command register */
|
||||||
irq_lower(esdi);
|
irq_lower(esdi);
|
||||||
esdi->command = val;
|
esdi->command = val;
|
||||||
esdi->error = 0;
|
esdi->error = 0;
|
||||||
|
|
||||||
|
#ifdef ENABLE_HDD_LOG
|
||||||
|
pclog("WD1007: command %02x\n", val & 0xf0);
|
||||||
|
#endif
|
||||||
switch (val & 0xf0) {
|
switch (val & 0xf0) {
|
||||||
case CMD_RESTORE:
|
case CMD_RESTORE:
|
||||||
esdi->command &= ~0x0f; /*Mask off step rate*/
|
esdi->command &= ~0x0f; /*mask off step rate*/
|
||||||
esdi->status = STAT_BUSY;
|
esdi->status = STAT_BUSY;
|
||||||
timer_process();
|
timer_process();
|
||||||
esdi->callback = 200LL*HDC_TIME;
|
esdi->callback = 200LL*HDC_TIME;
|
||||||
@@ -263,7 +275,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_SEEK:
|
case CMD_SEEK:
|
||||||
esdi->command &= ~0x0f; /*Mask off step rate*/
|
esdi->command &= ~0x0f; /*mask off step rate*/
|
||||||
esdi->status = STAT_BUSY;
|
esdi->status = STAT_BUSY;
|
||||||
timer_process();
|
timer_process();
|
||||||
esdi->callback = 200LL*HDC_TIME;
|
esdi->callback = 200LL*HDC_TIME;
|
||||||
@@ -278,13 +290,13 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
esdi->callback = 200LL*HDC_TIME;
|
esdi->callback = 200LL*HDC_TIME;
|
||||||
timer_update_outstanding();
|
timer_update_outstanding();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_READ:
|
case CMD_READ:
|
||||||
case CMD_READ+1:
|
case CMD_READ+1:
|
||||||
case CMD_READ+2:
|
case CMD_READ+2:
|
||||||
case CMD_READ+3:
|
case CMD_READ+3:
|
||||||
esdi->command &= ~3;
|
esdi->command &= ~0x03;
|
||||||
if (val & 2)
|
if (val & 0x02)
|
||||||
fatal("Read with ECC\n");
|
fatal("Read with ECC\n");
|
||||||
|
|
||||||
case 0xa0:
|
case 0xa0:
|
||||||
@@ -298,16 +310,16 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
case CMD_WRITE+1:
|
case CMD_WRITE+1:
|
||||||
case CMD_WRITE+2:
|
case CMD_WRITE+2:
|
||||||
case CMD_WRITE+3:
|
case CMD_WRITE+3:
|
||||||
esdi->command &= ~3;
|
esdi->command &= ~0x03;
|
||||||
if (val & 2)
|
if (val & 0x02)
|
||||||
fatal("Write with ECC\n");
|
fatal("Write with ECC\n");
|
||||||
esdi->status = STAT_DRQ | STAT_DSC;
|
esdi->status = STAT_DRQ | STAT_DSC;
|
||||||
esdi->pos=0;
|
esdi->pos = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_VERIFY:
|
case CMD_VERIFY:
|
||||||
case CMD_VERIFY+1:
|
case CMD_VERIFY+1:
|
||||||
esdi->command &= ~1;
|
esdi->command &= ~0x01;
|
||||||
esdi->status = STAT_BUSY;
|
esdi->status = STAT_BUSY;
|
||||||
timer_process();
|
timer_process();
|
||||||
esdi->callback = 200LL*HDC_TIME;
|
esdi->callback = 200LL*HDC_TIME;
|
||||||
@@ -316,7 +328,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
|
|
||||||
case CMD_FORMAT:
|
case CMD_FORMAT:
|
||||||
esdi->status = STAT_DRQ;
|
esdi->status = STAT_DRQ;
|
||||||
esdi->pos=0;
|
esdi->pos = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */
|
case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */
|
||||||
@@ -342,7 +354,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
pclog("Bad esdi command %02X\n", val);
|
pclog("WD1007: bad command %02X\n", val);
|
||||||
case 0xe8: /*???*/
|
case 0xe8: /*???*/
|
||||||
esdi->status = STAT_BUSY;
|
esdi->status = STAT_BUSY;
|
||||||
timer_process();
|
timer_process();
|
||||||
@@ -350,11 +362,11 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
timer_update_outstanding();
|
timer_update_outstanding();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x3F6: /* Device control */
|
case 0x3f6: /* Device control */
|
||||||
if ((esdi->fdisk & 4) && !(val & 4)) {
|
if ((esdi->fdisk & 0x04) && !(val & 0x04)) {
|
||||||
timer_process();
|
timer_process();
|
||||||
esdi->callback = 500LL*HDC_TIME;
|
esdi->callback = 500LL*HDC_TIME;
|
||||||
timer_update_outstanding();
|
timer_update_outstanding();
|
||||||
@@ -362,7 +374,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
esdi->status = STAT_BUSY;
|
esdi->status = STAT_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val & 4) {
|
if (val & 0x04) {
|
||||||
/*Drive held in reset*/
|
/*Drive held in reset*/
|
||||||
timer_process();
|
timer_process();
|
||||||
esdi->callback = 0LL;
|
esdi->callback = 0LL;
|
||||||
@@ -370,7 +382,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
esdi->status = STAT_BUSY;
|
esdi->status = STAT_BUSY;
|
||||||
}
|
}
|
||||||
esdi->fdisk = val;
|
esdi->fdisk = val;
|
||||||
irq_update(esdi);
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,6 +407,8 @@ esdi_readw(uint16_t port, void *priv)
|
|||||||
timer_process();
|
timer_process();
|
||||||
esdi->callback = 6LL*HDC_TIME;
|
esdi->callback = 6LL*HDC_TIME;
|
||||||
timer_update_outstanding();
|
timer_update_outstanding();
|
||||||
|
} else {
|
||||||
|
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -410,40 +424,44 @@ esdi_read(uint16_t port, void *priv)
|
|||||||
uint8_t temp = 0xff;
|
uint8_t temp = 0xff;
|
||||||
|
|
||||||
switch (port) {
|
switch (port) {
|
||||||
case 0x1F0: /* Data */
|
case 0x1f0: /* data */
|
||||||
temp = esdi_readw(port, esdi) & 0xff;
|
temp = esdi_readw(port, esdi) & 0xff;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1F1: /* Error */
|
case 0x1f1: /* error */
|
||||||
temp = esdi->error;
|
temp = esdi->error;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1F2: /* Sector count */
|
case 0x1f2: /* sector count */
|
||||||
temp = (uint8_t)esdi->secount;
|
temp = esdi->secount;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1F3: /* Sector */
|
case 0x1f3: /* sector */
|
||||||
temp = (uint8_t)esdi->sector;
|
temp = esdi->sector;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1F4: /* Cylinder low */
|
case 0x1f4: /* cylinder low */
|
||||||
temp = (uint8_t)(esdi->cylinder&0xFF);
|
temp = (uint8_t)(esdi->cylinder&0xff);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1F5: /* Cylinder high */
|
case 0x1f5: /* cylinder high */
|
||||||
temp = (uint8_t)(esdi->cylinder>>8);
|
temp = (uint8_t)(esdi->cylinder>>8);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1F6: /* Drive/Head */
|
case 0x1f6: /* drive/Head */
|
||||||
temp = (uint8_t)(esdi->head | (esdi->drive_sel?0x10:0) | 0xa0);
|
temp = (uint8_t)(0xa0|esdi->head|(esdi->drive_sel?0x10:0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1F7: /* Status */
|
case 0x1f7: /* status */
|
||||||
irq_lower(esdi);
|
irq_lower(esdi);
|
||||||
temp = esdi->status;
|
temp = esdi->status;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_HDD_LOG
|
||||||
|
pclog("WD1007 read(%04x) = %02x\n", port, temp);
|
||||||
|
#endif
|
||||||
|
|
||||||
return(temp);
|
return(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -454,10 +472,10 @@ esdi_callback(void *priv)
|
|||||||
esdi_t *esdi = (esdi_t *)priv;
|
esdi_t *esdi = (esdi_t *)priv;
|
||||||
drive_t *drive = &esdi->drives[esdi->drive_sel];
|
drive_t *drive = &esdi->drives[esdi->drive_sel];
|
||||||
off64_t addr;
|
off64_t addr;
|
||||||
|
|
||||||
esdi->callback = 0;
|
esdi->callback = 0LL;
|
||||||
if (esdi->reset) {
|
if (esdi->reset) {
|
||||||
esdi->status = STAT_READY | STAT_DSC;
|
esdi->status = STAT_READY|STAT_DSC;
|
||||||
esdi->error = 1;
|
esdi->error = 1;
|
||||||
esdi->secount = 1;
|
esdi->secount = 1;
|
||||||
esdi->sector = 1;
|
esdi->sector = 1;
|
||||||
@@ -465,34 +483,40 @@ esdi_callback(void *priv)
|
|||||||
esdi->cylinder = 0;
|
esdi->cylinder = 0;
|
||||||
esdi->reset = 0;
|
esdi->reset = 0;
|
||||||
|
|
||||||
|
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_HDD_LOG
|
||||||
|
pclog("WD1007: command %02x\n", esdi->command);
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (esdi->command) {
|
switch (esdi->command) {
|
||||||
case CMD_RESTORE:
|
case CMD_RESTORE:
|
||||||
if (! drive->present) {
|
if (! drive->present) {
|
||||||
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
esdi->error = ERR_ABRT;
|
||||||
} else {
|
} else {
|
||||||
drive->current_cylinder = 0;
|
drive->current_cylinder = 0;
|
||||||
esdi->status = STAT_READY | STAT_DSC;
|
esdi->status = STAT_READY|STAT_DSC;
|
||||||
}
|
}
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_SEEK:
|
case CMD_SEEK:
|
||||||
if (! drive->present) {
|
if (! drive->present) {
|
||||||
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
esdi->error = ERR_ABRT;
|
||||||
} else {
|
} else {
|
||||||
esdi->status = STAT_READY | STAT_DSC;
|
esdi->status = STAT_READY|STAT_DSC;
|
||||||
}
|
}
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_READ:
|
case CMD_READ:
|
||||||
if (! drive->present) {
|
if (! drive->present) {
|
||||||
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
esdi->error = ERR_ABRT;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
break;
|
break;
|
||||||
@@ -500,28 +524,23 @@ esdi_callback(void *priv)
|
|||||||
|
|
||||||
if (get_sector(esdi, &addr)) {
|
if (get_sector(esdi, &addr)) {
|
||||||
esdi->error = ERR_ID_NOT_FOUND;
|
esdi->error = ERR_ID_NOT_FOUND;
|
||||||
esdi->status = STAT_READY | STAT_DSC | STAT_ERR;
|
esdi->status = STAT_READY|STAT_DSC|STAT_ERR;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hdd_image_read_ex(drive->hdd_num, addr, 1,
|
hdd_image_read(drive->hdd_num, addr, 1,
|
||||||
(uint8_t *)esdi->buffer)) {
|
(uint8_t *)esdi->buffer);
|
||||||
esdi->error = ERR_ID_NOT_FOUND;
|
|
||||||
esdi->status = STAT_READY | STAT_DSC | STAT_ERR;
|
|
||||||
irq_raise(esdi);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
esdi->pos = 0;
|
esdi->pos = 0;
|
||||||
esdi->status = STAT_DRQ | STAT_READY | STAT_DSC;
|
esdi->status = STAT_DRQ|STAT_READY|STAT_DSC;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1);
|
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_WRITE:
|
case CMD_WRITE:
|
||||||
if (! drive->present) {
|
if (! drive->present) {
|
||||||
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
esdi->error = ERR_ABRT;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
break;
|
break;
|
||||||
@@ -529,34 +548,29 @@ esdi_callback(void *priv)
|
|||||||
|
|
||||||
if (get_sector(esdi, &addr)) {
|
if (get_sector(esdi, &addr)) {
|
||||||
esdi->error = ERR_ID_NOT_FOUND;
|
esdi->error = ERR_ID_NOT_FOUND;
|
||||||
esdi->status = STAT_READY | STAT_DSC | STAT_ERR;
|
esdi->status = STAT_READY|STAT_DSC|STAT_ERR;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hdd_image_write_ex(drive->hdd_num, addr, 1,
|
hdd_image_write(drive->hdd_num, addr, 1,
|
||||||
(uint8_t *)esdi->buffer)) {
|
(uint8_t *)esdi->buffer);
|
||||||
esdi->error = ERR_ID_NOT_FOUND;
|
|
||||||
esdi->status = STAT_READY | STAT_DSC | STAT_ERR;
|
|
||||||
irq_raise(esdi);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
esdi->secount = (esdi->secount - 1) & 0xff;
|
esdi->secount = (esdi->secount - 1) & 0xff;
|
||||||
if (esdi->secount) {
|
if (esdi->secount) {
|
||||||
esdi->status = STAT_DRQ | STAT_READY | STAT_DSC;
|
esdi->status = STAT_DRQ|STAT_READY|STAT_DSC;
|
||||||
esdi->pos = 0;
|
esdi->pos = 0;
|
||||||
next_sector(esdi);
|
next_sector(esdi);
|
||||||
} else {
|
} else {
|
||||||
esdi->status = STAT_READY | STAT_DSC;
|
esdi->status = STAT_READY|STAT_DSC;
|
||||||
}
|
}
|
||||||
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1);
|
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_VERIFY:
|
case CMD_VERIFY:
|
||||||
if (! drive->present) {
|
if (! drive->present) {
|
||||||
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
esdi->error = ERR_ABRT;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
break;
|
break;
|
||||||
@@ -564,34 +578,29 @@ esdi_callback(void *priv)
|
|||||||
|
|
||||||
if (get_sector(esdi, &addr)) {
|
if (get_sector(esdi, &addr)) {
|
||||||
esdi->error = ERR_ID_NOT_FOUND;
|
esdi->error = ERR_ID_NOT_FOUND;
|
||||||
esdi->status = STAT_READY | STAT_DSC | STAT_ERR;
|
esdi->status = STAT_READY|STAT_DSC|STAT_ERR;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hdd_image_read_ex(drive->hdd_num, addr, 1,
|
hdd_image_read(drive->hdd_num, addr, 1,
|
||||||
(uint8_t *)esdi->buffer)) {
|
(uint8_t *)esdi->buffer);
|
||||||
esdi->error = ERR_ID_NOT_FOUND;
|
|
||||||
esdi->status = STAT_READY | STAT_DSC | STAT_ERR;
|
|
||||||
irq_raise(esdi);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1);
|
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1);
|
||||||
next_sector(esdi);
|
next_sector(esdi);
|
||||||
esdi->secount = (esdi->secount - 1) & 0xff;
|
esdi->secount = (esdi->secount - 1) & 0xff;
|
||||||
if (esdi->secount)
|
if (esdi->secount)
|
||||||
esdi->callback = 6LL*HDC_TIME;
|
esdi->callback = 6LL*HDC_TIME;
|
||||||
else {
|
else {
|
||||||
esdi->pos = 0;
|
esdi->pos = 0;
|
||||||
esdi->status = STAT_READY | STAT_DSC;
|
esdi->status = STAT_READY|STAT_DSC;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_FORMAT:
|
case CMD_FORMAT:
|
||||||
if (! drive->present) {
|
if (! drive->present) {
|
||||||
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
esdi->error = ERR_ABRT;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
break;
|
break;
|
||||||
@@ -599,35 +608,27 @@ esdi_callback(void *priv)
|
|||||||
|
|
||||||
if (get_sector(esdi, &addr)) {
|
if (get_sector(esdi, &addr)) {
|
||||||
esdi->error = ERR_ID_NOT_FOUND;
|
esdi->error = ERR_ID_NOT_FOUND;
|
||||||
esdi->status = STAT_READY | STAT_DSC | STAT_ERR;
|
esdi->status = STAT_READY|STAT_DSC|STAT_ERR;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (hdd_image_zero_ex(drive->hdd_num, addr, esdi->secount)) {
|
|
||||||
esdi->error = ERR_ID_NOT_FOUND;
|
hdd_image_zero(drive->hdd_num, addr, esdi->secount);
|
||||||
esdi->status = STAT_READY | STAT_DSC | STAT_ERR;
|
|
||||||
irq_raise(esdi);
|
esdi->status = STAT_READY|STAT_DSC;
|
||||||
break;
|
|
||||||
}
|
|
||||||
esdi->status = STAT_READY | STAT_DSC;
|
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1);
|
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_DIAGNOSE:
|
case CMD_DIAGNOSE:
|
||||||
if (! drive->present) {
|
esdi->error = 1; /*no error detected*/
|
||||||
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
esdi->status = STAT_READY|STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
|
||||||
} else {
|
|
||||||
esdi->error = 1; /*No error detected*/
|
|
||||||
esdi->status = STAT_READY | STAT_DSC;
|
|
||||||
}
|
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */
|
case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */
|
||||||
if (! drive->present) {
|
if (drive->present == 0) {
|
||||||
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
esdi->error = ERR_ABRT;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
break;
|
break;
|
||||||
@@ -635,22 +636,24 @@ esdi_callback(void *priv)
|
|||||||
|
|
||||||
drive->cfg_spt = esdi->secount;
|
drive->cfg_spt = esdi->secount;
|
||||||
drive->cfg_hpc = esdi->head+1;
|
drive->cfg_hpc = esdi->head+1;
|
||||||
pclog("Parameters: spt=%i hpc=%i\n", drive->cfg_spt,drive->cfg_hpc);
|
#ifdef ENABLE_HDD_LOG
|
||||||
|
pclog("WD1007: parameters: spt=%i hpc=%i\n", drive->cfg_spt,drive->cfg_hpc);
|
||||||
|
#endif
|
||||||
if (! esdi->secount)
|
if (! esdi->secount)
|
||||||
fatal("secount=0\n");
|
fatal("WD1007: secount=0\n");
|
||||||
esdi->status = STAT_READY | STAT_DSC;
|
esdi->status = STAT_READY|STAT_DSC;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_NOP:
|
case CMD_NOP:
|
||||||
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
esdi->error = ERR_ABRT;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xe0:
|
case 0xe0:
|
||||||
if (! drive->present) {
|
if (! drive->present) {
|
||||||
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
esdi->error = ERR_ABRT;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
break;
|
break;
|
||||||
@@ -674,100 +677,92 @@ esdi_callback(void *priv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
pclog("EDSI Bad read config %02x\n",
|
pclog("WD1007: bad read config %02x\n",
|
||||||
esdi->cylinder >> 8);
|
esdi->cylinder >> 8);
|
||||||
}
|
}
|
||||||
esdi->status = STAT_READY | STAT_DSC;
|
esdi->status = STAT_READY|STAT_DSC;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xa0:
|
case 0xa0:
|
||||||
if (! drive->present) {
|
if (! drive->present) {
|
||||||
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
esdi->error = ERR_ABRT;
|
||||||
} else {
|
} else {
|
||||||
memset(esdi->buffer, 0, 512);
|
memset(esdi->buffer, 0x00, 512);
|
||||||
memset(&esdi->buffer[3], 0xff, 512-6);
|
memset(&esdi->buffer[3], 0xff, 512-6);
|
||||||
esdi->pos = 0;
|
esdi->pos = 0;
|
||||||
esdi->status = STAT_DRQ | STAT_READY | STAT_DSC;
|
esdi->status = STAT_DRQ|STAT_READY|STAT_DSC;
|
||||||
}
|
}
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_READ_PARAMETERS:
|
case CMD_READ_PARAMETERS:
|
||||||
if (! drive->present) {
|
if (! drive->present) {
|
||||||
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
esdi->error = ERR_ABRT;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(esdi->buffer, 0, 512);
|
memset(esdi->buffer, 0x00, 512);
|
||||||
esdi->buffer[0] = 0x44; /* general configuration */
|
esdi->buffer[0] = 0x44; /* general configuration */
|
||||||
esdi->buffer[1] = drive->real_tracks; /* number of non-removable cylinders */
|
esdi->buffer[1] = drive->real_tracks; /* number of non-removable cylinders */
|
||||||
esdi->buffer[2] = 0; /* number of removable cylinders */
|
esdi->buffer[2] = 0; /* number of removable cylinders */
|
||||||
esdi->buffer[3] = drive->real_hpc; /* number of heads */
|
esdi->buffer[3] = drive->real_hpc; /* number of heads */
|
||||||
esdi->buffer[4] = 600; /* number of unformatted bytes/track */
|
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[5] = esdi->buffer[4] * drive->real_spt; /* number of unformatted bytes/sector */
|
||||||
esdi->buffer[6] = drive->real_spt; /* number of sectors */
|
esdi->buffer[6] = drive->real_spt; /* number of sectors */
|
||||||
esdi->buffer[7] = 0; /*minimum bytes in inter-sector gap*/
|
esdi->buffer[7] = 0; /*minimum bytes in inter-sector gap*/
|
||||||
esdi->buffer[8] = 0; /* minimum bytes in postamble */
|
esdi->buffer[8] = 0; /* minimum bytes in postamble */
|
||||||
esdi->buffer[9] = 0; /* number of words of vendor status */
|
esdi->buffer[9] = 0; /* number of words of vendor status */
|
||||||
/* controller info */
|
/* controller info */
|
||||||
esdi->buffer[20] = 2; /* controller type */
|
esdi->buffer[20] = 2; /* controller type */
|
||||||
esdi->buffer[21] = 1; /* sector buffer size, in sectors */
|
esdi->buffer[21] = 1; /* sector buffer size, in sectors */
|
||||||
esdi->buffer[22] = 0; /* ecc bytes appended */
|
esdi->buffer[22] = 0; /* ecc bytes appended */
|
||||||
esdi->buffer[27] = 'W' | ('D' << 8);
|
esdi->buffer[27] = 'W' | ('D' << 8);
|
||||||
esdi->buffer[28] = '1' | ('0' << 8);
|
esdi->buffer[28] = '1' | ('0' << 8);
|
||||||
esdi->buffer[29] = '0' | ('7' << 8);
|
esdi->buffer[29] = '0' | ('7' << 8);
|
||||||
esdi->buffer[30] = 'V' | ('-' << 8);
|
esdi->buffer[30] = 'V' | ('-' << 8);
|
||||||
esdi->buffer[31] = 'S' | ('E' << 8);
|
esdi->buffer[31] = 'S' | ('E' << 8);
|
||||||
esdi->buffer[32] = '1';
|
esdi->buffer[32] = '1';
|
||||||
esdi->buffer[47] = 0; /* sectors per interrupt */
|
esdi->buffer[47] = 0; /* sectors per interrupt */
|
||||||
esdi->buffer[48] = 0;/* can use double word read/write? */
|
esdi->buffer[48] = 0; /* can use double word read/write? */
|
||||||
esdi->pos = 0;
|
esdi->pos = 0;
|
||||||
esdi->status = STAT_DRQ | STAT_READY | STAT_DSC;
|
esdi->status = STAT_DRQ|STAT_READY|STAT_DSC;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
pclog("ESDI Callback on unknown command %02x\n", esdi->command);
|
pclog("WD1007: callback on unknown command %02x\n", esdi->command);
|
||||||
|
/*FALLTHROUGH*/
|
||||||
|
|
||||||
case 0xe8:
|
case 0xe8:
|
||||||
esdi->status = STAT_READY | STAT_ERR | STAT_DSC;
|
esdi->status = STAT_READY|STAT_ERR|STAT_DSC;
|
||||||
esdi->error = ERR_ABRT;
|
esdi->error = ERR_ABRT;
|
||||||
irq_raise(esdi);
|
irq_raise(esdi);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
esdi_rom_write(uint32_t addr, uint8_t val, void *priv)
|
|
||||||
{
|
|
||||||
rom_t *rom = (rom_t *)priv;
|
|
||||||
|
|
||||||
addr &= rom->mask;
|
|
||||||
if (addr >= 0x1f00 && addr < 0x2000)
|
|
||||||
rom->rom[addr] = val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
loadhd(esdi_t *esdi, int hdd_num, int d, const wchar_t *fn)
|
loadhd(esdi_t *esdi, int hdd_num, int d, const wchar_t *fn)
|
||||||
{
|
{
|
||||||
drive_t *drive = &esdi->drives[d];
|
drive_t *drive = &esdi->drives[hdd_num];
|
||||||
|
|
||||||
if (! hdd_image_load(hdd_num)) {
|
if (! hdd_image_load(d)) {
|
||||||
|
pclog("WD1007: drive %d not present!\n", d);
|
||||||
drive->present = 0;
|
drive->present = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
drive->cfg_spt = drive->real_spt = hdd[hdd_num].spt;
|
drive->cfg_spt = drive->real_spt = hdd[d].spt;
|
||||||
drive->cfg_hpc = drive->real_hpc = hdd[hdd_num].hpc;
|
drive->cfg_hpc = drive->real_hpc = hdd[d].hpc;
|
||||||
drive->real_tracks = hdd[hdd_num].tracks;
|
drive->real_tracks = hdd[d].tracks;
|
||||||
drive->hdd_num = hdd_num;
|
drive->hdd_num = d;
|
||||||
drive->present = 1;
|
drive->present = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -775,32 +770,26 @@ loadhd(esdi_t *esdi, int hdd_num, int d, const wchar_t *fn)
|
|||||||
static void *
|
static void *
|
||||||
wd1007vse1_init(device_t *info)
|
wd1007vse1_init(device_t *info)
|
||||||
{
|
{
|
||||||
int i, c = 0;
|
int c, d;
|
||||||
|
|
||||||
esdi_t *esdi = malloc(sizeof(esdi_t));
|
esdi_t *esdi = malloc(sizeof(esdi_t));
|
||||||
memset(esdi, 0x00, sizeof(esdi_t));
|
memset(esdi, 0x00, sizeof(esdi_t));
|
||||||
|
|
||||||
esdi->drives[0].present = esdi->drives[1].present = 0;
|
c = 0;
|
||||||
|
for (d=0; d<HDD_NUM; d++) {
|
||||||
for (i=0; i<HDD_NUM; i++) {
|
if ((hdd[d].bus==HDD_BUS_ESDI) && (hdd[d].esdi_channel<ESDI_NUM)) {
|
||||||
if ((hdd[i].bus==HDD_BUS_ESDI) && (hdd[i].esdi_channel<ESDI_NUM)) {
|
loadhd(esdi, hdd[d].esdi_channel, d, hdd[d].fn);
|
||||||
loadhd(esdi, i, hdd[i].esdi_channel, hdd[i].fn);
|
|
||||||
|
|
||||||
if (++c >= ESDI_NUM) break;
|
if (++c >= ESDI_NUM) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
esdi->status = STAT_READY | STAT_DSC;
|
esdi->status = STAT_READY|STAT_DSC;
|
||||||
esdi->error = 1;
|
esdi->error = 1;
|
||||||
|
|
||||||
rom_init(&esdi->bios_rom,
|
rom_init(&esdi->bios_rom,
|
||||||
BIOS_FILE, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
|
BIOS_FILE, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
|
||||||
|
|
||||||
mem_mapping_set_handler(
|
|
||||||
&esdi->bios_rom.mapping,
|
|
||||||
rom_read, rom_readw, rom_readl,
|
|
||||||
esdi_rom_write, NULL, NULL);
|
|
||||||
|
|
||||||
io_sethandler(0x01f0, 1,
|
io_sethandler(0x01f0, 1,
|
||||||
esdi_read, esdi_readw, NULL,
|
esdi_read, esdi_readw, NULL,
|
||||||
esdi_write, esdi_writew, NULL, esdi);
|
esdi_write, esdi_writew, NULL, esdi);
|
||||||
@@ -810,8 +799,10 @@ wd1007vse1_init(device_t *info)
|
|||||||
io_sethandler(0x03f6, 1, NULL, NULL, NULL,
|
io_sethandler(0x03f6, 1, NULL, NULL, NULL,
|
||||||
esdi_write, NULL, NULL, esdi);
|
esdi_write, NULL, NULL, esdi);
|
||||||
|
|
||||||
timer_add(esdi_callback, &esdi->callback, &esdi->callback, esdi);
|
timer_add(esdi_callback, &esdi->callback, &esdi->callback, esdi);
|
||||||
|
|
||||||
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||||
|
|
||||||
return(esdi);
|
return(esdi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -823,8 +814,6 @@ wd1007vse1_close(void *priv)
|
|||||||
drive_t *drive;
|
drive_t *drive;
|
||||||
int d;
|
int d;
|
||||||
|
|
||||||
esdi->drives[0].present = esdi->drives[1].present = 0;
|
|
||||||
|
|
||||||
for (d=0; d<2; d++) {
|
for (d=0; d<2; d++) {
|
||||||
drive = &esdi->drives[d];
|
drive = &esdi->drives[d];
|
||||||
|
|
||||||
@@ -832,6 +821,8 @@ wd1007vse1_close(void *priv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
free(esdi);
|
free(esdi);
|
||||||
|
|
||||||
|
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -846,9 +837,8 @@ device_t esdi_at_wd1007vse1_device = {
|
|||||||
"Western Digital WD1007V-SE1 (ESDI)",
|
"Western Digital WD1007V-SE1 (ESDI)",
|
||||||
DEVICE_ISA | DEVICE_AT,
|
DEVICE_ISA | DEVICE_AT,
|
||||||
0,
|
0,
|
||||||
wd1007vse1_init,
|
wd1007vse1_init, wd1007vse1_close, NULL,
|
||||||
wd1007vse1_close,
|
|
||||||
NULL,
|
|
||||||
wd1007vse1_available,
|
wd1007vse1_available,
|
||||||
NULL, NULL, NULL, NULL
|
NULL, NULL, NULL,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
@@ -41,7 +41,7 @@
|
|||||||
* Since all controllers (including the ones made by DTC) use
|
* Since all controllers (including the ones made by DTC) use
|
||||||
* (mostly) the same API, we keep them all in this module.
|
* (mostly) the same API, we keep them all in this module.
|
||||||
*
|
*
|
||||||
* Version: @(#)hdc_mfm_xt.c 1.0.12 2017/11/04
|
* Version: @(#)hdc_mfm_xt.c 1.0.13 2017/11/06
|
||||||
*
|
*
|
||||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||||
@@ -815,13 +815,16 @@ xebec_init(device_t *info)
|
|||||||
mfm_t *xebec = malloc(sizeof(mfm_t));
|
mfm_t *xebec = malloc(sizeof(mfm_t));
|
||||||
memset(xebec, 0x00, sizeof(mfm_t));
|
memset(xebec, 0x00, sizeof(mfm_t));
|
||||||
|
|
||||||
|
pclog("MFM: looking for disks..\n");
|
||||||
for (i=0; i<HDD_NUM; i++) {
|
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_MFM) && (hdd[i].mfm_channel < MFM_NUM)) {
|
||||||
|
pclog("Found MFM hard disk on channel %i\n", hdd[i].mfm_channel);
|
||||||
loadhd(xebec, i, hdd[i].mfm_channel, hdd[i].fn);
|
loadhd(xebec, i, hdd[i].mfm_channel, hdd[i].fn);
|
||||||
|
|
||||||
if (++c > MFM_NUM) break;
|
if (++c > MFM_NUM) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pclog("MFM: %d disks loaded.\n", c);
|
||||||
|
|
||||||
mfm_set_switches(xebec);
|
mfm_set_switches(xebec);
|
||||||
|
|
||||||
@@ -878,13 +881,16 @@ dtc5150x_init(device_t *info)
|
|||||||
mfm_t *dtc = malloc(sizeof(mfm_t));
|
mfm_t *dtc = malloc(sizeof(mfm_t));
|
||||||
memset(dtc, 0x00, sizeof(mfm_t));
|
memset(dtc, 0x00, sizeof(mfm_t));
|
||||||
|
|
||||||
|
pclog("MFM: looking for disks..\n");
|
||||||
for (i=0; i<HDD_NUM; i++) {
|
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_MFM) && (hdd[i].mfm_channel < MFM_NUM)) {
|
||||||
|
pclog("Found MFM hard disk on channel %i\n", hdd[i].mfm_channel);
|
||||||
loadhd(dtc, i, hdd[i].mfm_channel, hdd[i].fn);
|
loadhd(dtc, i, hdd[i].mfm_channel, hdd[i].fn);
|
||||||
|
|
||||||
if (++c > MFM_NUM) break;
|
if (++c > MFM_NUM) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pclog("MFM: %d disks loaded.\n", c);
|
||||||
|
|
||||||
dtc->switches = 0xff;
|
dtc->switches = 0xff;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user