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_SET_MULTIPLE_MODE 0xC6
|
||||
#define WIN_READ_DMA 0xC8
|
||||
#define WIN_READ_DMA_ALT 0xC9
|
||||
#define WIN_WRITE_DMA 0xCA
|
||||
#define WIN_WRITE_DMA_ALT 0xCB
|
||||
#define WIN_STANDBYNOW1 0xE0
|
||||
#define WIN_IDLENOW1 0xE1
|
||||
#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)
|
||||
{
|
||||
uint32_t c, h, s;
|
||||
uint32_t d;
|
||||
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);
|
||||
#endif
|
||||
|
||||
device_identify[6] = (ide->hdd_num / 10) + 0x30;
|
||||
device_identify[7] = (ide->hdd_num % 10) + 0x30;
|
||||
ide_log("IDE Identify: %s\n", device_identify);
|
||||
|
||||
memset(ide->buffer, 0, 512);
|
||||
d_spt = ide->spt;
|
||||
if (ide->hpc <= 16) {
|
||||
/* 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;
|
||||
}
|
||||
|
||||
c = hdd[ide->hdd_num].tracks; /* Cylinders */
|
||||
h = hdd[ide->hdd_num].hpc; /* Heads */
|
||||
/* 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 */
|
||||
|
||||
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[6] = hdd[ide->hdd_num].spt; /* Sectors */
|
||||
#endif
|
||||
|
||||
ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */
|
||||
ide_padstr((char *) (ide->buffer + 23), EMU_VERSION, 8); /* Firmware */
|
||||
ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */
|
||||
ide->buffer[20] = 3; /*Buffer type*/
|
||||
ide->buffer[21] = 512; /*Buffer size*/
|
||||
ide->buffer[47] = 16; /*Max sectors on multiple transfer command*/
|
||||
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 */
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ide->buffer[47] = 16 | 0x8000; /*Max sectors on multiple transfer command*/
|
||||
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[50] = 0x4000; /* Capabilities */
|
||||
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))
|
||||
{
|
||||
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[61] = ((hdd[ide->hdd_num].tracks * hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt) >> 16) & 0x0FFF;
|
||||
ide->buffer[60] = full_size & 0xFFFF; /* Total addressable sectors (LBA) */
|
||||
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))
|
||||
{
|
||||
ide->buffer[52] = 2 << 8; /*DMA timing mode*/
|
||||
ide->buffer[53] |= 2;
|
||||
|
||||
ide->buffer[62] = 7;
|
||||
ide->buffer[63] = 7;
|
||||
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)
|
||||
{
|
||||
char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 };
|
||||
|
||||
uint8_t cdrom_id;
|
||||
int32_t d;
|
||||
|
||||
memset(ide->buffer, 0, 512);
|
||||
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 + 23), EMU_VERSION, 8); /* Firmware */
|
||||
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[51] = 2 << 8; /*PIO timing mode*/
|
||||
|
||||
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[52] = 2 << 8; /*DMA timing mode*/
|
||||
ide->buffer[53] = 3;
|
||||
ide->buffer[62] = 7;
|
||||
ide->buffer[63] = 7;
|
||||
ide->buffer[73] = 6;
|
||||
ide->buffer[74] = 9;
|
||||
ide->buffer[80] = 0x10; /*ATA/ATAPI-4 supported*/
|
||||
if (ide->mdma_mode != -1)
|
||||
{
|
||||
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
|
||||
{
|
||||
uint32_t heads = ide->hpc;
|
||||
uint32_t sectors = ide->spt;
|
||||
uint32_t heads = ide->t_hpc;
|
||||
uint32_t sectors = ide->t_spt;
|
||||
|
||||
return ((((off64_t) ide->cylinder * heads) + ide->head) *
|
||||
sectors) + (ide->sector - 1) + ide->skip512;
|
||||
@@ -471,11 +531,11 @@ static void ide_next_sector(IDE *ide)
|
||||
else
|
||||
{
|
||||
ide->sector++;
|
||||
if (ide->sector == (ide->spt + 1))
|
||||
if (ide->sector == (ide->t_spt + 1))
|
||||
{
|
||||
ide->sector = 1;
|
||||
ide->head++;
|
||||
if (ide->head == ide->hpc)
|
||||
if (ide->head == ide->t_hpc)
|
||||
{
|
||||
ide->head = 0;
|
||||
ide->cylinder++;
|
||||
@@ -540,11 +600,23 @@ static int ide_set_features(IDE *ide)
|
||||
uint8_t features, features_data;
|
||||
uint8_t mode, submode;
|
||||
|
||||
int bus, dma;
|
||||
|
||||
features = ide->cylprecomp;
|
||||
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);
|
||||
|
||||
pclog("IDE %02X: Set features: %02X, %02X\n", ide->channel, features, features_data);
|
||||
|
||||
switch(features)
|
||||
{
|
||||
case 0x03: /* Set transfer mode. */
|
||||
@@ -561,6 +633,7 @@ static int ide_set_features(IDE *ide)
|
||||
return 0;
|
||||
}
|
||||
ide->mdma_mode = -1;
|
||||
pclog("IDE %02X: Setting DPIO mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode);
|
||||
break;
|
||||
|
||||
case 0x01: /* PIO mode */
|
||||
@@ -569,20 +642,35 @@ static int ide_set_features(IDE *ide)
|
||||
return 0;
|
||||
}
|
||||
ide->mdma_mode = -1;
|
||||
pclog("IDE %02X: Setting PIO mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode);
|
||||
break;
|
||||
|
||||
case 0x04: /* Multiword DMA mode */
|
||||
if (!PCI || (hdd[ide->hdd_num].bus != HDD_BUS_IDE_PIO_AND_DMA) || (ide->board >= 2) || (submode > 2))
|
||||
case 0x02: /* Singleword DMA mode */
|
||||
if (!PCI || !dma || (ide->board >= 2) || (submode > 2))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
ide->mdma_mode = (1 << submode);
|
||||
pclog("IDE %02X: Setting SDMA mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode);
|
||||
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:
|
||||
return 0;
|
||||
}
|
||||
|
||||
case 0x66: /* Disable reverting to power on defaults. */
|
||||
case 0xCC: /* Enable reverting to power on defaults. */
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -667,11 +755,7 @@ void ide_reset(void)
|
||||
|
||||
ide_set_signature(&ide_drives[d]);
|
||||
|
||||
if (ide_drives[d].type == IDE_HDD)
|
||||
{
|
||||
ide_drives[d].mdma_mode = 0;
|
||||
}
|
||||
|
||||
ide_drives[d].mdma_mode = -1;
|
||||
ide_drives[d].error = 1;
|
||||
}
|
||||
|
||||
@@ -679,11 +763,7 @@ void ide_reset(void)
|
||||
{
|
||||
ide_set_signature(&ide_drives[d | 8]);
|
||||
|
||||
if (ide_drives[d | 8].type == IDE_HDD)
|
||||
{
|
||||
ide_drives[d | 8].mdma_mode = 0;
|
||||
}
|
||||
|
||||
ide_drives[d | 8].mdma_mode = -1;
|
||||
ide_drives[d | 8].error = 1;
|
||||
}
|
||||
|
||||
@@ -696,6 +776,22 @@ void ide_reset(void)
|
||||
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;
|
||||
|
||||
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_NORETRY:
|
||||
case WIN_READ_DMA:
|
||||
case WIN_READ_DMA_ALT:
|
||||
if (ide_drive_is_cdrom(ide))
|
||||
{
|
||||
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;
|
||||
|
||||
case WIN_WRITE_DMA:
|
||||
case WIN_WRITE_DMA_ALT:
|
||||
if (ide_drive_is_cdrom(ide))
|
||||
{
|
||||
cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT;
|
||||
@@ -1655,57 +1753,52 @@ void callbackide(int ide_board)
|
||||
return;
|
||||
|
||||
case WIN_READ_DMA:
|
||||
case WIN_READ_DMA_ALT:
|
||||
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;
|
||||
}
|
||||
if (!ide->specify_success)
|
||||
{
|
||||
pclog("IDE %i: DMA read aborted (SPECIFY failed)\n", ide->channel);
|
||||
goto id_not_found;
|
||||
}
|
||||
|
||||
if (ide->do_initial_read)
|
||||
ide->sector_pos = 0;
|
||||
if (ide->secount)
|
||||
{
|
||||
ide->do_initial_read = 0;
|
||||
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);
|
||||
}
|
||||
ide->sector_pos = ide->secount;
|
||||
}
|
||||
else
|
||||
{
|
||||
ide->sector_pos = 256;
|
||||
}
|
||||
hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->sector_pos, ide->sector_buffer);
|
||||
|
||||
ide->pos=0;
|
||||
|
||||
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
|
||||
{
|
||||
/*DMA successful*/
|
||||
ide->sector_pos++;
|
||||
ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT;
|
||||
pclog("IDE %i: DMA read successful\n", ide->channel);
|
||||
|
||||
ide->secount = (ide->secount - 1) & 0xff;
|
||||
if (ide->secount)
|
||||
{
|
||||
ide_next_sector(ide);
|
||||
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);
|
||||
}
|
||||
ide->atastat = READY_STAT | DSC_STAT;
|
||||
|
||||
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;
|
||||
@@ -1788,42 +1881,46 @@ void callbackide(int ide_board)
|
||||
return;
|
||||
|
||||
case WIN_WRITE_DMA:
|
||||
case WIN_WRITE_DMA_ALT:
|
||||
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;
|
||||
}
|
||||
if (!ide->specify_success)
|
||||
{
|
||||
pclog("IDE %i: DMA write aborted (SPECIFY failed)\n", ide->channel);
|
||||
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
|
||||
{
|
||||
/*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;
|
||||
if (ide->secount)
|
||||
{
|
||||
ide_next_sector(ide);
|
||||
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);
|
||||
}
|
||||
ide->atastat = READY_STAT | DSC_STAT;
|
||||
|
||||
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;
|
||||
@@ -1937,8 +2034,9 @@ void callbackide(int ide_board)
|
||||
full_size /= ide->secount;
|
||||
ide->specify_success = 1;
|
||||
hdd_image_specify(ide->hdd_num, ide->head + 1, ide->secount);
|
||||
ide->spt=ide->secount;
|
||||
ide->hpc=ide->head+1;
|
||||
ide->t_spt=ide->secount;
|
||||
ide->t_hpc=ide->head;
|
||||
ide->t_hpc++;
|
||||
ide->atastat = READY_STAT | DSC_STAT;
|
||||
ide_irq_raise(ide);
|
||||
return;
|
||||
@@ -1967,7 +2065,7 @@ void callbackide(int ide_board)
|
||||
return;
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -1978,6 +2076,10 @@ void callbackide(int ide_board)
|
||||
}
|
||||
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_irq_raise(ide);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ typedef struct {
|
||||
int pos;
|
||||
int packlen;
|
||||
int spt,hpc;
|
||||
int t_spt,t_hpc;
|
||||
int tracks;
|
||||
int packetstatus;
|
||||
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(void);
|
||||
extern void ide_reset(void);
|
||||
extern void ide_reset_hard(void);
|
||||
|
||||
extern void ide_xtide_init(void);
|
||||
|
||||
|
||||
4
src/pc.c
4
src/pc.c
@@ -546,7 +546,7 @@ again2:
|
||||
|
||||
hdc_init(hdc_name);
|
||||
|
||||
ide_reset();
|
||||
ide_reset_hard();
|
||||
|
||||
cdrom_hard_reset();
|
||||
|
||||
@@ -685,7 +685,7 @@ pc_reset_hard_init(void)
|
||||
ide_ter_init();
|
||||
if (ide_enable[3])
|
||||
ide_qua_init();
|
||||
ide_reset();
|
||||
ide_reset_hard();
|
||||
|
||||
/* Reset and reconfigure the SCSI layer. */
|
||||
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;
|
||||
}
|
||||
|
||||
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 transferred = 0;
|
||||
@@ -530,11 +503,6 @@ int piix_bus_master_dma_read(int channel, uint8_t *data, int 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);
|
||||
|
||||
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)
|
||||
{
|
||||
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))
|
||||
{
|
||||
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)
|
||||
{
|
||||
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_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;
|
||||
max_spt = 63;
|
||||
max_hpc = 16;
|
||||
max_hpc = 255;
|
||||
}
|
||||
SendMessage(h, CB_SETCURSEL, hdd_ptr->bus, 0);
|
||||
max_tracks = 266305;
|
||||
@@ -3160,7 +3160,7 @@ hdd_add_file_open_error:
|
||||
case HDD_BUS_IDE_PIO_ONLY:
|
||||
case HDD_BUS_IDE_PIO_AND_DMA:
|
||||
max_spt = 63;
|
||||
max_hpc = 16;
|
||||
max_hpc = 255;
|
||||
max_tracks = 266305;
|
||||
break;
|
||||
case HDD_BUS_SCSI_REMOVABLE:
|
||||
|
||||
Reference in New Issue
Block a user