Fixed ATAPI PIO multi-phased transfers - fixes the catalog read error in Windows 2000;
Fixed the last remaining ATAPI DMA bugs; Fixed IDE hard disk DMA; Fixed PIIX bus master DMA read and write; The Settings dialog now accepts more than 16 heads for IDE hard disks; Added the IDE READ DMA ALT and WRITE DMA ALT commands; Reenabled current CHS translation reporting, with bugfixes, hopefully the bugfixes will prevent certain larger hard disks from being detected as 250 MB.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -73,7 +73,9 @@
|
|||||||
#define WIN_WRITE_MULTIPLE 0xC5
|
#define WIN_WRITE_MULTIPLE 0xC5
|
||||||
#define WIN_SET_MULTIPLE_MODE 0xC6
|
#define WIN_SET_MULTIPLE_MODE 0xC6
|
||||||
#define WIN_READ_DMA 0xC8
|
#define WIN_READ_DMA 0xC8
|
||||||
|
#define WIN_READ_DMA_ALT 0xC9
|
||||||
#define WIN_WRITE_DMA 0xCA
|
#define WIN_WRITE_DMA 0xCA
|
||||||
|
#define WIN_WRITE_DMA_ALT 0xCB
|
||||||
#define WIN_STANDBYNOW1 0xE0
|
#define WIN_STANDBYNOW1 0xE0
|
||||||
#define WIN_IDLENOW1 0xE1
|
#define WIN_IDLENOW1 0xE1
|
||||||
#define WIN_SETIDLE1 0xE3
|
#define WIN_SETIDLE1 0xE3
|
||||||
@@ -327,20 +329,39 @@ void ide_padstr8(uint8_t *buf, int buf_size, const char *src)
|
|||||||
*/
|
*/
|
||||||
static void ide_identify(IDE *ide)
|
static void ide_identify(IDE *ide)
|
||||||
{
|
{
|
||||||
uint32_t c, h, s;
|
uint32_t d;
|
||||||
char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 };
|
char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 };
|
||||||
#if 0
|
|
||||||
|
uint64_t d_hpc, d_spt, d_tracks;
|
||||||
uint64_t full_size = (hdd[ide->hdd_num].tracks * hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt);
|
uint64_t full_size = (hdd[ide->hdd_num].tracks * hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt);
|
||||||
#endif
|
|
||||||
|
|
||||||
device_identify[6] = (ide->hdd_num / 10) + 0x30;
|
device_identify[6] = (ide->hdd_num / 10) + 0x30;
|
||||||
device_identify[7] = (ide->hdd_num % 10) + 0x30;
|
device_identify[7] = (ide->hdd_num % 10) + 0x30;
|
||||||
ide_log("IDE Identify: %s\n", device_identify);
|
ide_log("IDE Identify: %s\n", device_identify);
|
||||||
|
|
||||||
memset(ide->buffer, 0, 512);
|
memset(ide->buffer, 0, 512);
|
||||||
|
d_spt = ide->spt;
|
||||||
c = hdd[ide->hdd_num].tracks; /* Cylinders */
|
if (ide->hpc <= 16) {
|
||||||
h = hdd[ide->hdd_num].hpc; /* Heads */
|
/* HPC <= 16, report as needed. */
|
||||||
|
d_tracks = ide->tracks;
|
||||||
|
d_hpc = ide->hpc;
|
||||||
|
} else {
|
||||||
|
/* HPC > 16, convert to 16 HPC. */
|
||||||
|
d_hpc = 16;
|
||||||
|
d_tracks = (ide->tracks * ide->hpc) / 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Specify default CHS translation */
|
||||||
|
if (full_size <= 16514064) {
|
||||||
|
ide->buffer[1] = d_tracks; /* Tracks in default CHS translation. */
|
||||||
|
ide->buffer[3] = d_hpc; /* Heads in default CHS translation. */
|
||||||
|
ide->buffer[6] = d_spt; /* Heads in default CHS translation. */
|
||||||
|
}
|
||||||
|
ide_log("Default CHS translation: %i, %i, %i\n", ide->buffer[1], ide->buffer[3], ide->buffer[6]);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
c = d_tracks; /* Cylinders */
|
||||||
|
h = d_hpc; /* Heads */
|
||||||
s = hdd[ide->hdd_num].spt; /* Sectors */
|
s = hdd[ide->hdd_num].spt; /* Sectors */
|
||||||
|
|
||||||
if (hdd[ide->hdd_num].tracks <= 16383)
|
if (hdd[ide->hdd_num].tracks <= 16383)
|
||||||
@@ -353,60 +374,80 @@ static void ide_identify(IDE *ide)
|
|||||||
}
|
}
|
||||||
ide->buffer[3] = hdd[ide->hdd_num].hpc; /* Heads */
|
ide->buffer[3] = hdd[ide->hdd_num].hpc; /* Heads */
|
||||||
ide->buffer[6] = hdd[ide->hdd_num].spt; /* Sectors */
|
ide->buffer[6] = hdd[ide->hdd_num].spt; /* Sectors */
|
||||||
|
#endif
|
||||||
|
|
||||||
ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */
|
ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */
|
||||||
ide_padstr((char *) (ide->buffer + 23), EMU_VERSION, 8); /* Firmware */
|
ide_padstr((char *) (ide->buffer + 23), EMU_VERSION, 8); /* Firmware */
|
||||||
ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */
|
ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */
|
||||||
ide->buffer[20] = 3; /*Buffer type*/
|
ide->buffer[20] = 3; /*Buffer type*/
|
||||||
ide->buffer[21] = 512; /*Buffer size*/
|
ide->buffer[21] = 512; /*Buffer size*/
|
||||||
ide->buffer[47] = 16; /*Max sectors on multiple transfer command*/
|
|
||||||
ide->buffer[48] = 1; /*Dword transfers supported*/
|
ide->buffer[48] = 1; /*Dword transfers supported*/
|
||||||
if (PCI && (ide->board < 2) && (hdd[ide->hdd_num].bus == HDD_BUS_IDE_PIO_AND_DMA))
|
if (PCI && (ide->board < 2) && (hdd[ide->hdd_num].bus == HDD_BUS_IDE_PIO_AND_DMA)) {
|
||||||
{
|
ide->buffer[47] = 32 | 0x8000; /*Max sectors on multiple transfer command*/
|
||||||
ide->buffer[49] = (1 << 8); /* LBA and DMA supported */
|
ide->buffer[49] = (1 << 8); /* LBA and DMA supported */
|
||||||
}
|
} else {
|
||||||
else
|
ide->buffer[47] = 16 | 0x8000; /*Max sectors on multiple transfer command*/
|
||||||
{
|
|
||||||
ide->buffer[49] = 0;
|
ide->buffer[49] = 0;
|
||||||
}
|
}
|
||||||
if ((c > 1024) || (h > 16) || (s > 63))
|
if ((ide->tracks >= 1024) || (ide->hpc > 16) || (ide->spt > 63))
|
||||||
{
|
{
|
||||||
ide->buffer[49] |= (1 << 9);
|
ide->buffer[49] |= (1 << 9);
|
||||||
}
|
}
|
||||||
ide->buffer[50] = 0x4000; /* Capabilities */
|
ide->buffer[50] = 0x4000; /* Capabilities */
|
||||||
ide->buffer[51] = 2 << 8; /*PIO timing mode*/
|
ide->buffer[51] = 2 << 8; /*PIO timing mode*/
|
||||||
#if 0
|
|
||||||
ide->buffer[53] = 1;
|
|
||||||
ide->buffer[55] = ide->hpc;
|
|
||||||
ide->buffer[56] = ide->spt;
|
|
||||||
if (((full_size / ide->hpc) / ide->spt) <= 16383)
|
|
||||||
{
|
|
||||||
ide->buffer[54] = (full_size / ide->hpc) / ide->spt;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ide->buffer[54] = 16383;
|
|
||||||
}
|
|
||||||
full_size = ((uint64_t) ide->hpc) * ((uint64_t) ide->spt) * ((uint64_t) ide->buffer[54]);
|
|
||||||
ide->buffer[57] = full_size & 0xFFFF; /* Total addressable sectors (LBA) */
|
|
||||||
ide->buffer[58] = (full_size >> 16) & 0x0FFF;
|
|
||||||
#endif
|
|
||||||
ide->buffer[59] = ide->blocksize ? (ide->blocksize | 0x100) : 0;
|
|
||||||
if (ide->buffer[49] & (1 << 9))
|
if (ide->buffer[49] & (1 << 9))
|
||||||
{
|
{
|
||||||
ide->buffer[60] = (hdd[ide->hdd_num].tracks * hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt) & 0xFFFF; /* Total addressable sectors (LBA) */
|
ide->buffer[60] = full_size & 0xFFFF; /* Total addressable sectors (LBA) */
|
||||||
ide->buffer[61] = ((hdd[ide->hdd_num].tracks * hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt) >> 16) & 0x0FFF;
|
ide->buffer[61] = (full_size >> 16) & 0x0FFF;
|
||||||
|
|
||||||
|
ide->buffer[53] |= 1;
|
||||||
|
|
||||||
|
if (full_size <= 16514064) {
|
||||||
|
if (ide->specify_success) {
|
||||||
|
ide->buffer[54] = (full_size / ide->t_hpc) / ide->t_spt;
|
||||||
|
ide->buffer[55] = ide->t_hpc;
|
||||||
|
ide->buffer[56] = ide->t_spt;
|
||||||
|
full_size = ((uint64_t) ide->t_hpc) * ((uint64_t) ide->t_spt) * ((uint64_t) ide->buffer[54]);
|
||||||
|
} else {
|
||||||
|
ide->buffer[54] = d_tracks;
|
||||||
|
ide->buffer[55] = d_hpc;
|
||||||
|
ide->buffer[56] = d_spt;
|
||||||
|
}
|
||||||
|
|
||||||
|
ide->buffer[57] = full_size & 0xFFFF; /* Total addressable sectors (LBA) */
|
||||||
|
ide->buffer[58] = (full_size >> 16) & 0x0FFF;
|
||||||
|
|
||||||
|
ide_log("Current CHS translation: %i, %i, %i\n", ide->buffer[54], ide->buffer[55], ide->buffer[56]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ide->buffer[59] = ide->blocksize ? (ide->blocksize | 0x100) : 0;
|
||||||
|
|
||||||
if (PCI && (ide->board < 2) && (hdd[ide->hdd_num].bus == HDD_BUS_IDE_PIO_AND_DMA))
|
if (PCI && (ide->board < 2) && (hdd[ide->hdd_num].bus == HDD_BUS_IDE_PIO_AND_DMA))
|
||||||
{
|
{
|
||||||
ide->buffer[52] = 2 << 8; /*DMA timing mode*/
|
ide->buffer[52] = 2 << 8; /*DMA timing mode*/
|
||||||
|
ide->buffer[53] |= 2;
|
||||||
|
|
||||||
|
ide->buffer[62] = 7;
|
||||||
ide->buffer[63] = 7;
|
ide->buffer[63] = 7;
|
||||||
if (ide->mdma_mode != -1)
|
if (ide->mdma_mode != -1)
|
||||||
{
|
{
|
||||||
ide->buffer[63] = (ide->mdma_mode << 8);
|
d = (ide->mdma_mode & 0xff);
|
||||||
|
d <<= 8;
|
||||||
|
if (ide->mdma_mode & 0x100)
|
||||||
|
ide->buffer[63] |= d;
|
||||||
|
else
|
||||||
|
ide->buffer[62] |= d;
|
||||||
|
pclog(" IDENTIFY DMA Mode: %04X, %04X\n", ide->buffer[62], ide->buffer[63]);
|
||||||
}
|
}
|
||||||
|
ide->buffer[65] = 120;
|
||||||
|
ide->buffer[66] = 120;
|
||||||
|
ide->buffer[80] = 0x1e; /*ATA-1 to ATA-4 supported*/
|
||||||
|
ide->buffer[81] = 0x18; /*ATA-4 revision 18 supported*/
|
||||||
|
} else {
|
||||||
|
ide->buffer[80] = 0x0e; /*ATA-1 to ATA-3 supported*/
|
||||||
}
|
}
|
||||||
ide->buffer[80] = 0xe; /*ATA-1 to ATA-3 supported*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -415,7 +456,9 @@ static void ide_identify(IDE *ide)
|
|||||||
static void ide_atapi_identify(IDE *ide)
|
static void ide_atapi_identify(IDE *ide)
|
||||||
{
|
{
|
||||||
char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 };
|
char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 };
|
||||||
|
|
||||||
uint8_t cdrom_id;
|
uint8_t cdrom_id;
|
||||||
|
int32_t d;
|
||||||
|
|
||||||
memset(ide->buffer, 0, 512);
|
memset(ide->buffer, 0, 512);
|
||||||
cdrom_id = atapi_cdrom_drives[ide->channel];
|
cdrom_id = atapi_cdrom_drives[ide->channel];
|
||||||
@@ -427,16 +470,33 @@ static void ide_atapi_identify(IDE *ide)
|
|||||||
ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */
|
ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */
|
||||||
ide_padstr((char *) (ide->buffer + 23), EMU_VERSION, 8); /* Firmware */
|
ide_padstr((char *) (ide->buffer + 23), EMU_VERSION, 8); /* Firmware */
|
||||||
ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */
|
ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */
|
||||||
|
ide->buffer[48] = 1; /*Dword transfers supported*/
|
||||||
ide->buffer[49] = 0x200; /* LBA supported */
|
ide->buffer[49] = 0x200; /* LBA supported */
|
||||||
|
ide->buffer[51] = 2 << 8; /*PIO timing mode*/
|
||||||
|
|
||||||
if (PCI && (ide->board < 2) && (cdrom_drives[cdrom_id].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA))
|
if (PCI && (ide->board < 2) && (cdrom_drives[cdrom_id].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA))
|
||||||
{
|
{
|
||||||
ide->buffer[48] = 1; /*Dword transfers supported*/
|
|
||||||
ide->buffer[49] |= 0x100; /* DMA supported */
|
ide->buffer[49] |= 0x100; /* DMA supported */
|
||||||
|
ide->buffer[52] = 2 << 8; /*DMA timing mode*/
|
||||||
|
ide->buffer[53] = 3;
|
||||||
|
ide->buffer[62] = 7;
|
||||||
ide->buffer[63] = 7;
|
ide->buffer[63] = 7;
|
||||||
ide->buffer[73] = 6;
|
if (ide->mdma_mode != -1)
|
||||||
ide->buffer[74] = 9;
|
{
|
||||||
ide->buffer[80] = 0x10; /*ATA/ATAPI-4 supported*/
|
d = (ide->mdma_mode & 0xff);
|
||||||
|
d <<= 8;
|
||||||
|
if (ide->mdma_mode & 0x100)
|
||||||
|
ide->buffer[63] |= d;
|
||||||
|
else
|
||||||
|
ide->buffer[62] |= d;
|
||||||
|
pclog("PIDENTIFY DMA Mode: %04X, %04X\n", ide->buffer[62], ide->buffer[63]);
|
||||||
|
}
|
||||||
|
ide->buffer[65] = 0xb4;
|
||||||
|
ide->buffer[66] = 0xb4;
|
||||||
|
ide->buffer[71] = 30;
|
||||||
|
ide->buffer[72] = 30;
|
||||||
|
ide->buffer[80] = 0x1e; /*ATA-1 to ATA-4 supported*/
|
||||||
|
ide->buffer[81] = 0x18; /*ATA-4 revision 18 supported*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -451,8 +511,8 @@ static off64_t ide_get_sector(IDE *ide)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint32_t heads = ide->hpc;
|
uint32_t heads = ide->t_hpc;
|
||||||
uint32_t sectors = ide->spt;
|
uint32_t sectors = ide->t_spt;
|
||||||
|
|
||||||
return ((((off64_t) ide->cylinder * heads) + ide->head) *
|
return ((((off64_t) ide->cylinder * heads) + ide->head) *
|
||||||
sectors) + (ide->sector - 1) + ide->skip512;
|
sectors) + (ide->sector - 1) + ide->skip512;
|
||||||
@@ -471,11 +531,11 @@ static void ide_next_sector(IDE *ide)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ide->sector++;
|
ide->sector++;
|
||||||
if (ide->sector == (ide->spt + 1))
|
if (ide->sector == (ide->t_spt + 1))
|
||||||
{
|
{
|
||||||
ide->sector = 1;
|
ide->sector = 1;
|
||||||
ide->head++;
|
ide->head++;
|
||||||
if (ide->head == ide->hpc)
|
if (ide->head == ide->t_hpc)
|
||||||
{
|
{
|
||||||
ide->head = 0;
|
ide->head = 0;
|
||||||
ide->cylinder++;
|
ide->cylinder++;
|
||||||
@@ -539,12 +599,24 @@ static int ide_set_features(IDE *ide)
|
|||||||
{
|
{
|
||||||
uint8_t features, features_data;
|
uint8_t features, features_data;
|
||||||
uint8_t mode, submode;
|
uint8_t mode, submode;
|
||||||
|
|
||||||
|
int bus, dma;
|
||||||
|
|
||||||
features = ide->cylprecomp;
|
features = ide->cylprecomp;
|
||||||
features_data = ide->secount;
|
features_data = ide->secount;
|
||||||
|
|
||||||
|
if (ide_drive_is_cdrom(ide)) {
|
||||||
|
bus = cdrom_drives[atapi_cdrom_drives[ide->channel]].bus_type;
|
||||||
|
dma = (bus == CDROM_BUS_ATAPI_PIO_AND_DMA);
|
||||||
|
} else {
|
||||||
|
bus = hdd[ide->hdd_num].bus;
|
||||||
|
dma = (bus == HDD_BUS_IDE_PIO_AND_DMA);
|
||||||
|
}
|
||||||
|
|
||||||
ide_log("Features code %02X\n", features);
|
ide_log("Features code %02X\n", features);
|
||||||
|
|
||||||
|
pclog("IDE %02X: Set features: %02X, %02X\n", ide->channel, features, features_data);
|
||||||
|
|
||||||
switch(features)
|
switch(features)
|
||||||
{
|
{
|
||||||
case 0x03: /* Set transfer mode. */
|
case 0x03: /* Set transfer mode. */
|
||||||
@@ -561,6 +633,7 @@ static int ide_set_features(IDE *ide)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ide->mdma_mode = -1;
|
ide->mdma_mode = -1;
|
||||||
|
pclog("IDE %02X: Setting DPIO mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x01: /* PIO mode */
|
case 0x01: /* PIO mode */
|
||||||
@@ -569,20 +642,35 @@ static int ide_set_features(IDE *ide)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ide->mdma_mode = -1;
|
ide->mdma_mode = -1;
|
||||||
|
pclog("IDE %02X: Setting PIO mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x04: /* Multiword DMA mode */
|
case 0x02: /* Singleword DMA mode */
|
||||||
if (!PCI || (hdd[ide->hdd_num].bus != HDD_BUS_IDE_PIO_AND_DMA) || (ide->board >= 2) || (submode > 2))
|
if (!PCI || !dma || (ide->board >= 2) || (submode > 2))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ide->mdma_mode = (1 << submode);
|
ide->mdma_mode = (1 << submode);
|
||||||
|
pclog("IDE %02X: Setting SDMA mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x04: /* Multiword DMA mode */
|
||||||
|
if (!PCI || !dma || (ide->board >= 2) || (submode > 2))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ide->mdma_mode = (1 << submode) | 0x100;
|
||||||
|
pclog("IDE %02X: Setting MDMA mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 0x66: /* Disable reverting to power on defaults. */
|
||||||
|
case 0xCC: /* Enable reverting to power on defaults. */
|
||||||
|
return 1;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -667,11 +755,7 @@ void ide_reset(void)
|
|||||||
|
|
||||||
ide_set_signature(&ide_drives[d]);
|
ide_set_signature(&ide_drives[d]);
|
||||||
|
|
||||||
if (ide_drives[d].type == IDE_HDD)
|
ide_drives[d].mdma_mode = -1;
|
||||||
{
|
|
||||||
ide_drives[d].mdma_mode = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ide_drives[d].error = 1;
|
ide_drives[d].error = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -679,11 +763,7 @@ void ide_reset(void)
|
|||||||
{
|
{
|
||||||
ide_set_signature(&ide_drives[d | 8]);
|
ide_set_signature(&ide_drives[d | 8]);
|
||||||
|
|
||||||
if (ide_drives[d | 8].type == IDE_HDD)
|
ide_drives[d | 8].mdma_mode = -1;
|
||||||
{
|
|
||||||
ide_drives[d | 8].mdma_mode = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ide_drives[d | 8].error = 1;
|
ide_drives[d | 8].error = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -696,6 +776,22 @@ void ide_reset(void)
|
|||||||
ide_qua_disable_cond();
|
ide_qua_disable_cond();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ide_reset_hard(void)
|
||||||
|
{
|
||||||
|
int d;
|
||||||
|
|
||||||
|
for (d = 0; d < (IDE_NUM+XTIDE_NUM); d++)
|
||||||
|
{
|
||||||
|
ide_drives[d].t_spt = ide_drives[d].spt;
|
||||||
|
ide_drives[d].t_hpc = ide_drives[d].hpc;
|
||||||
|
ide_drives[d].specify_success = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ide_reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int idetimes = 0;
|
int idetimes = 0;
|
||||||
|
|
||||||
void ide_write_data(int ide_board, uint32_t val, int length)
|
void ide_write_data(int ide_board, uint32_t val, int length)
|
||||||
@@ -980,6 +1076,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|||||||
case WIN_READ:
|
case WIN_READ:
|
||||||
case WIN_READ_NORETRY:
|
case WIN_READ_NORETRY:
|
||||||
case WIN_READ_DMA:
|
case WIN_READ_DMA:
|
||||||
|
case WIN_READ_DMA_ALT:
|
||||||
if (ide_drive_is_cdrom(ide))
|
if (ide_drive_is_cdrom(ide))
|
||||||
{
|
{
|
||||||
cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT;
|
cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT;
|
||||||
@@ -1020,6 +1117,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case WIN_WRITE_DMA:
|
case WIN_WRITE_DMA:
|
||||||
|
case WIN_WRITE_DMA_ALT:
|
||||||
if (ide_drive_is_cdrom(ide))
|
if (ide_drive_is_cdrom(ide))
|
||||||
{
|
{
|
||||||
cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT;
|
cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT;
|
||||||
@@ -1655,57 +1753,52 @@ void callbackide(int ide_board)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case WIN_READ_DMA:
|
case WIN_READ_DMA:
|
||||||
|
case WIN_READ_DMA_ALT:
|
||||||
if (ide_drive_is_cdrom(ide) || (ide->board >= 2))
|
if (ide_drive_is_cdrom(ide) || (ide->board >= 2))
|
||||||
{
|
{
|
||||||
|
pclog("IDE %i: DMA read aborted (bad device or board)\n", ide->channel);
|
||||||
goto abort_cmd;
|
goto abort_cmd;
|
||||||
}
|
}
|
||||||
if (!ide->specify_success)
|
if (!ide->specify_success)
|
||||||
{
|
{
|
||||||
|
pclog("IDE %i: DMA read aborted (SPECIFY failed)\n", ide->channel);
|
||||||
goto id_not_found;
|
goto id_not_found;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ide->do_initial_read)
|
ide->sector_pos = 0;
|
||||||
|
if (ide->secount)
|
||||||
{
|
{
|
||||||
ide->do_initial_read = 0;
|
ide->sector_pos = ide->secount;
|
||||||
ide->sector_pos = 0;
|
|
||||||
if (ide->secount)
|
|
||||||
{
|
|
||||||
hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->secount, ide->sector_buffer);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hdd_image_read(ide->hdd_num, ide_get_sector(ide), 256, ide->sector_buffer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ide->sector_pos = 256;
|
||||||
|
}
|
||||||
|
hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->sector_pos, ide->sector_buffer);
|
||||||
|
|
||||||
ide->pos=0;
|
ide->pos=0;
|
||||||
|
|
||||||
if (ide_bus_master_read)
|
if (ide_bus_master_read)
|
||||||
{
|
{
|
||||||
if (ide_bus_master_read(ide_board, &ide->sector_buffer[ide->sector_pos*512], 512))
|
if (ide_bus_master_read(ide_board, ide->sector_buffer, ide->sector_pos * 512))
|
||||||
{
|
{
|
||||||
idecallback[ide_board]=6LL*IDE_TIME; /*DMA not performed, try again later*/
|
// idecallback[ide_board]=6LL*IDE_TIME; /*DMA not performed, try again later*/
|
||||||
|
pclog("IDE %i: DMA read aborted (failed)\n", ide->channel);
|
||||||
|
goto abort_cmd;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*DMA successful*/
|
/*DMA successful*/
|
||||||
ide->sector_pos++;
|
pclog("IDE %i: DMA read successful\n", ide->channel);
|
||||||
ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT;
|
|
||||||
|
|
||||||
ide->secount = (ide->secount - 1) & 0xff;
|
ide->atastat = READY_STAT | DSC_STAT;
|
||||||
if (ide->secount)
|
|
||||||
{
|
ide_irq_raise(ide);
|
||||||
ide_next_sector(ide);
|
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0);
|
||||||
ide->atastat = BUSY_STAT;
|
|
||||||
idecallback[ide_board]=6LL*IDE_TIME;
|
|
||||||
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ide_irq_raise(ide);
|
|
||||||
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
pclog("IDE %i: DMA read aborted (no bus master)\n", ide->channel);
|
||||||
|
goto abort_cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -1788,42 +1881,46 @@ void callbackide(int ide_board)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case WIN_WRITE_DMA:
|
case WIN_WRITE_DMA:
|
||||||
|
case WIN_WRITE_DMA_ALT:
|
||||||
if (ide_drive_is_cdrom(ide) || (ide_board >= 2))
|
if (ide_drive_is_cdrom(ide) || (ide_board >= 2))
|
||||||
{
|
{
|
||||||
|
pclog("IDE %i: DMA write aborted (bad device type or board)\n", ide->channel);
|
||||||
goto abort_cmd;
|
goto abort_cmd;
|
||||||
}
|
}
|
||||||
if (!ide->specify_success)
|
if (!ide->specify_success)
|
||||||
{
|
{
|
||||||
|
pclog("IDE %i: DMA write aborted (SPECIFY failed)\n", ide->channel);
|
||||||
goto id_not_found;
|
goto id_not_found;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ide_bus_master_write)
|
if (ide_bus_master_read)
|
||||||
{
|
{
|
||||||
if (ide_bus_master_write(ide_board, (uint8_t *)ide->buffer, 512))
|
if (ide->secount)
|
||||||
|
ide->sector_pos = ide->secount;
|
||||||
|
else
|
||||||
|
ide->sector_pos = 256;
|
||||||
|
|
||||||
|
if (ide_bus_master_write(ide_board, ide->sector_buffer, ide->sector_pos * 512))
|
||||||
{
|
{
|
||||||
idecallback[ide_board]=6LL*IDE_TIME; /*DMA not performed, try again later*/
|
pclog("IDE %i: DMA write aborted (failed)\n", ide->channel);
|
||||||
|
// idecallback[ide_board]=6LL*IDE_TIME; /*DMA not performed, try again later*/
|
||||||
|
goto abort_cmd;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*DMA successful*/
|
/*DMA successful*/
|
||||||
hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer);
|
pclog("IDE %i: DMA write successful\n", ide->channel);
|
||||||
|
|
||||||
ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT;
|
hdd_image_write(ide->hdd_num, ide_get_sector(ide), ide->sector_pos, ide->sector_buffer);
|
||||||
|
|
||||||
ide->secount = (ide->secount - 1) & 0xff;
|
ide->atastat = READY_STAT | DSC_STAT;
|
||||||
if (ide->secount)
|
|
||||||
{
|
ide_irq_raise(ide);
|
||||||
ide_next_sector(ide);
|
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0);
|
||||||
ide->atastat = BUSY_STAT;
|
|
||||||
idecallback[ide_board]=6LL*IDE_TIME;
|
|
||||||
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ide_irq_raise(ide);
|
|
||||||
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
pclog("IDE %i: DMA write aborted (no bus master)\n", ide->channel);
|
||||||
|
goto abort_cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -1937,8 +2034,9 @@ void callbackide(int ide_board)
|
|||||||
full_size /= ide->secount;
|
full_size /= ide->secount;
|
||||||
ide->specify_success = 1;
|
ide->specify_success = 1;
|
||||||
hdd_image_specify(ide->hdd_num, ide->head + 1, ide->secount);
|
hdd_image_specify(ide->hdd_num, ide->head + 1, ide->secount);
|
||||||
ide->spt=ide->secount;
|
ide->t_spt=ide->secount;
|
||||||
ide->hpc=ide->head+1;
|
ide->t_hpc=ide->head;
|
||||||
|
ide->t_hpc++;
|
||||||
ide->atastat = READY_STAT | DSC_STAT;
|
ide->atastat = READY_STAT | DSC_STAT;
|
||||||
ide_irq_raise(ide);
|
ide_irq_raise(ide);
|
||||||
return;
|
return;
|
||||||
@@ -1967,7 +2065,7 @@ void callbackide(int ide_board)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case WIN_SET_FEATURES:
|
case WIN_SET_FEATURES:
|
||||||
if ((ide->type == IDE_NONE) || ide_drive_is_cdrom(ide))
|
if ((ide->type == IDE_NONE)/* || ide_drive_is_cdrom(ide)*/)
|
||||||
{
|
{
|
||||||
goto abort_cmd;
|
goto abort_cmd;
|
||||||
}
|
}
|
||||||
@@ -1978,6 +2076,10 @@ void callbackide(int ide_board)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (ide_drive_is_cdrom(ide)) {
|
||||||
|
cdrom[cdrom_id].status = READY_STAT | DSC_STAT;
|
||||||
|
cdrom[cdrom_id].pos = 0;
|
||||||
|
}
|
||||||
ide->atastat = READY_STAT | DSC_STAT;
|
ide->atastat = READY_STAT | DSC_STAT;
|
||||||
ide_irq_raise(ide);
|
ide_irq_raise(ide);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ typedef struct {
|
|||||||
int pos;
|
int pos;
|
||||||
int packlen;
|
int packlen;
|
||||||
int spt,hpc;
|
int spt,hpc;
|
||||||
|
int t_spt,t_hpc;
|
||||||
int tracks;
|
int tracks;
|
||||||
int packetstatus;
|
int packetstatus;
|
||||||
uint8_t asc;
|
uint8_t asc;
|
||||||
@@ -83,6 +84,7 @@ extern void ide_set_side(int controller, uint16_t port);
|
|||||||
extern void ide_init_first(void);
|
extern void ide_init_first(void);
|
||||||
extern void ide_init(void);
|
extern void ide_init(void);
|
||||||
extern void ide_reset(void);
|
extern void ide_reset(void);
|
||||||
|
extern void ide_reset_hard(void);
|
||||||
|
|
||||||
extern void ide_xtide_init(void);
|
extern void ide_xtide_init(void);
|
||||||
|
|
||||||
|
|||||||
4
src/pc.c
4
src/pc.c
@@ -546,7 +546,7 @@ again2:
|
|||||||
|
|
||||||
hdc_init(hdc_name);
|
hdc_init(hdc_name);
|
||||||
|
|
||||||
ide_reset();
|
ide_reset_hard();
|
||||||
|
|
||||||
cdrom_hard_reset();
|
cdrom_hard_reset();
|
||||||
|
|
||||||
@@ -685,7 +685,7 @@ pc_reset_hard_init(void)
|
|||||||
ide_ter_init();
|
ide_ter_init();
|
||||||
if (ide_enable[3])
|
if (ide_enable[3])
|
||||||
ide_qua_init();
|
ide_qua_init();
|
||||||
ide_reset();
|
ide_reset_hard();
|
||||||
|
|
||||||
/* Reset and reconfigure the SCSI layer. */
|
/* Reset and reconfigure the SCSI layer. */
|
||||||
scsi_card_init();
|
scsi_card_init();
|
||||||
|
|||||||
71
src/piix.c
71
src/piix.c
@@ -494,33 +494,6 @@ int piix_bus_master_get_eot(int channel)
|
|||||||
return piix_busmaster[channel].eot;
|
return piix_busmaster[channel].eot;
|
||||||
}
|
}
|
||||||
|
|
||||||
int piix_bus_master_dma_read_ex(int channel, uint8_t *data)
|
|
||||||
{
|
|
||||||
int transferred = 0;
|
|
||||||
|
|
||||||
if (!(piix_busmaster[channel].status & 1))
|
|
||||||
return 1; /*DMA disabled*/
|
|
||||||
|
|
||||||
mem_invalidate_range(piix_busmaster[channel].addr, piix_busmaster[channel].addr + piix_busmaster[channel].count - 1);
|
|
||||||
|
|
||||||
memcpy(&ram[piix_busmaster[channel].addr], data, piix_busmaster[channel].count);
|
|
||||||
transferred += piix_busmaster[channel].count;
|
|
||||||
piix_busmaster[channel].addr += piix_busmaster[channel].count;
|
|
||||||
piix_busmaster[channel].addr %= (mem_size * 1024);
|
|
||||||
piix_busmaster[channel].count = 0;
|
|
||||||
|
|
||||||
if (piix_busmaster[channel].eot) /*End of transfer?*/
|
|
||||||
{
|
|
||||||
piix_busmaster[channel].status &= ~1;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
piix_bus_master_next_addr(channel);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int piix_bus_master_dma_read(int channel, uint8_t *data, int transfer_length)
|
int piix_bus_master_dma_read(int channel, uint8_t *data, int transfer_length)
|
||||||
{
|
{
|
||||||
int transferred = 0;
|
int transferred = 0;
|
||||||
@@ -530,11 +503,6 @@ int piix_bus_master_dma_read(int channel, uint8_t *data, int transfer_length)
|
|||||||
|
|
||||||
while (transferred < transfer_length)
|
while (transferred < transfer_length)
|
||||||
{
|
{
|
||||||
if ((piix_busmaster[channel].count < (transfer_length - transferred)) && piix_busmaster[channel].eot && (transfer_length == 512))
|
|
||||||
{
|
|
||||||
fatal("DMA on channel %i - Read count less than %04X! Addr %08X Count %04X EOT %i\n", channel, transfer_length, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot);
|
|
||||||
}
|
|
||||||
|
|
||||||
mem_invalidate_range(piix_busmaster[channel].addr, piix_busmaster[channel].addr + transfer_length - 1);
|
mem_invalidate_range(piix_busmaster[channel].addr, piix_busmaster[channel].addr + transfer_length - 1);
|
||||||
|
|
||||||
if (piix_busmaster[channel].count < (transfer_length - transferred))
|
if (piix_busmaster[channel].count < (transfer_length - transferred))
|
||||||
@@ -575,11 +543,6 @@ int piix_bus_master_dma_write(int channel, uint8_t *data, int transfer_length)
|
|||||||
|
|
||||||
while (transferred < transfer_length)
|
while (transferred < transfer_length)
|
||||||
{
|
{
|
||||||
if ((piix_busmaster[channel].count < (transfer_length - transferred)) && piix_busmaster[channel].eot && (transfer_length == 512))
|
|
||||||
{
|
|
||||||
fatal("DMA on channel %i - Write count less than %04X! Addr %08X Count %04X EOT %i\n", channel, transfer_length, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (piix_busmaster[channel].count < (transfer_length - transferred))
|
if (piix_busmaster[channel].count < (transfer_length - transferred))
|
||||||
{
|
{
|
||||||
memcpy(data + transferred, &ram[piix_busmaster[channel].addr], piix_busmaster[channel].count);
|
memcpy(data + transferred, &ram[piix_busmaster[channel].addr], piix_busmaster[channel].count);
|
||||||
@@ -617,40 +580,6 @@ void piix_bus_master_set_irq(int channel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static int reset_reg = 0;
|
|
||||||
|
|
||||||
static uint8_t rc_read(uint16_t port, void *priv)
|
|
||||||
{
|
|
||||||
return reset_reg & 0xfb;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rc_write(uint16_t port, uint8_t val, void *priv)
|
|
||||||
{
|
|
||||||
if (!(reset_reg & 4) && (val & 4))
|
|
||||||
{
|
|
||||||
if (reset_reg & 2)
|
|
||||||
{
|
|
||||||
pc_reset_hard();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (piix_type == 3)
|
|
||||||
{
|
|
||||||
piix3_reset();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
piix_reset();
|
|
||||||
}
|
|
||||||
ide_reset();
|
|
||||||
softresetx86();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reset_reg = val;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void piix_reset(void)
|
void piix_reset(void)
|
||||||
{
|
{
|
||||||
memset(card_piix, 0, 256);
|
memset(card_piix, 0, 256);
|
||||||
|
|||||||
@@ -25,4 +25,4 @@ extern void piix_bus_master_write(uint16_t port, uint8_t val, void *priv);
|
|||||||
|
|
||||||
extern int piix_bus_master_get_count(int channel);
|
extern int piix_bus_master_get_count(int channel);
|
||||||
|
|
||||||
extern int piix_bus_master_dma_read_ex(int channel, uint8_t *data);
|
extern int piix_bus_master_dma_read(int channel, uint8_t *data, int transfer_length);
|
||||||
|
|||||||
@@ -2614,7 +2614,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W
|
|||||||
{
|
{
|
||||||
hdd_ptr->bus = HDD_BUS_IDE_PIO_ONLY;
|
hdd_ptr->bus = HDD_BUS_IDE_PIO_ONLY;
|
||||||
max_spt = 63;
|
max_spt = 63;
|
||||||
max_hpc = 16;
|
max_hpc = 255;
|
||||||
}
|
}
|
||||||
SendMessage(h, CB_SETCURSEL, hdd_ptr->bus, 0);
|
SendMessage(h, CB_SETCURSEL, hdd_ptr->bus, 0);
|
||||||
max_tracks = 266305;
|
max_tracks = 266305;
|
||||||
@@ -3160,7 +3160,7 @@ hdd_add_file_open_error:
|
|||||||
case HDD_BUS_IDE_PIO_ONLY:
|
case HDD_BUS_IDE_PIO_ONLY:
|
||||||
case HDD_BUS_IDE_PIO_AND_DMA:
|
case HDD_BUS_IDE_PIO_AND_DMA:
|
||||||
max_spt = 63;
|
max_spt = 63;
|
||||||
max_hpc = 16;
|
max_hpc = 255;
|
||||||
max_tracks = 266305;
|
max_tracks = 266305;
|
||||||
break;
|
break;
|
||||||
case HDD_BUS_SCSI_REMOVABLE:
|
case HDD_BUS_SCSI_REMOVABLE:
|
||||||
|
|||||||
Reference in New Issue
Block a user