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:
OBattler
2017-10-24 04:15:05 +02:00
parent 8cf777e84d
commit 2f2785c1c9
7 changed files with 431 additions and 864 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -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);
} }

View File

@@ -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);

View File

@@ -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();

View File

@@ -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);

View File

@@ -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);

View File

@@ -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: