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