|
|
|
|
@@ -9,7 +9,7 @@
|
|
|
|
|
* Implementation of the IDE emulation for hard disks and ATAPI
|
|
|
|
|
* CD-ROM devices.
|
|
|
|
|
*
|
|
|
|
|
* Version: @(#)hdc_ide.c 1.0.10 2018/03/17
|
|
|
|
|
* Version: @(#)hdc_ide.c 1.0.11 2018/03/18
|
|
|
|
|
*
|
|
|
|
|
* Authors: Miran Grca, <mgrca8@gmail.com>
|
|
|
|
|
* Sarah Walker, <tommowalker@tommowalker.co.uk>
|
|
|
|
|
@@ -66,16 +66,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Bits of 'atastat' */
|
|
|
|
|
#define ERR_STAT 0x01
|
|
|
|
|
#define DRQ_STAT 0x08 /* Data request */
|
|
|
|
|
#define DSC_STAT 0x10
|
|
|
|
|
#define SERVICE_STAT 0x10
|
|
|
|
|
#define READY_STAT 0x40
|
|
|
|
|
#define BUSY_STAT 0x80
|
|
|
|
|
#define ERR_STAT 0x01
|
|
|
|
|
#define DRQ_STAT 0x08 /* Data request */
|
|
|
|
|
#define DSC_STAT 0x10
|
|
|
|
|
#define SERVICE_STAT 0x10
|
|
|
|
|
#define READY_STAT 0x40
|
|
|
|
|
#define BUSY_STAT 0x80
|
|
|
|
|
|
|
|
|
|
/* Bits of 'error' */
|
|
|
|
|
#define ABRT_ERR 0x04 /* Command aborted */
|
|
|
|
|
#define MCR_ERR 0x08 /* Media change request */
|
|
|
|
|
#define ABRT_ERR 0x04 /* Command aborted */
|
|
|
|
|
#define MCR_ERR 0x08 /* Media change request */
|
|
|
|
|
|
|
|
|
|
/* ATA Commands */
|
|
|
|
|
#define WIN_NOP 0x00
|
|
|
|
|
@@ -92,31 +92,32 @@
|
|
|
|
|
#define WIN_SEEK 0x70
|
|
|
|
|
#define WIN_DRIVE_DIAGNOSTICS 0x90 /* Execute Drive Diagnostics */
|
|
|
|
|
#define WIN_SPECIFY 0x91 /* Initialize Drive Parameters */
|
|
|
|
|
#define WIN_PACKETCMD 0xA0 /* Send a packet command. */
|
|
|
|
|
#define WIN_PIDENTIFY 0xA1 /* Identify ATAPI device */
|
|
|
|
|
#define WIN_READ_MULTIPLE 0xC4
|
|
|
|
|
#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
|
|
|
|
|
#define WIN_CHECKPOWERMODE1 0xE5
|
|
|
|
|
#define WIN_SLEEP1 0xE6
|
|
|
|
|
#define WIN_IDENTIFY 0xEC /* Ask drive to identify itself */
|
|
|
|
|
#define WIN_SET_FEATURES 0xEF
|
|
|
|
|
#define WIN_READ_NATIVE_MAX 0xF8
|
|
|
|
|
#define WIN_PACKETCMD 0xa0 /* Send a packet command. */
|
|
|
|
|
#define WIN_PIDENTIFY 0xa1 /* Identify ATAPI device */
|
|
|
|
|
#define WIN_READ_MULTIPLE 0xc4
|
|
|
|
|
#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
|
|
|
|
|
#define WIN_CHECKPOWERMODE1 0xe5
|
|
|
|
|
#define WIN_SLEEP1 0xe6
|
|
|
|
|
#define WIN_IDENTIFY 0xec /* Ask drive to identify itself */
|
|
|
|
|
#define WIN_SET_FEATURES 0xef
|
|
|
|
|
#define WIN_READ_NATIVE_MAX 0xf8
|
|
|
|
|
|
|
|
|
|
#define FEATURE_SET_TRANSFER_MODE 0x03
|
|
|
|
|
#define FEATURE_ENABLE_IRQ_OVERLAPPED 0x5d
|
|
|
|
|
#define FEATURE_ENABLE_IRQ_SERVICE 0x5e
|
|
|
|
|
#define FEATURE_DISABLE_REVERT 0x66
|
|
|
|
|
#define FEATURE_ENABLE_REVERT 0xcc
|
|
|
|
|
#define FEATURE_DISABLE_IRQ_OVERLAPPED 0xdd
|
|
|
|
|
#define FEATURE_DISABLE_IRQ_SERVICE 0xde
|
|
|
|
|
|
|
|
|
|
#define FEATURE_SET_TRANSFER_MODE 0x03
|
|
|
|
|
#define FEATURE_ENABLE_IRQ_OVERLAPPED 0x5d
|
|
|
|
|
#define FEATURE_ENABLE_IRQ_SERVICE 0x5e
|
|
|
|
|
#define FEATURE_DISABLE_REVERT 0x66
|
|
|
|
|
#define FEATURE_ENABLE_REVERT 0xcc
|
|
|
|
|
#define FEATURE_DISABLE_IRQ_OVERLAPPED 0xdd
|
|
|
|
|
#define FEATURE_DISABLE_IRQ_SERVICE 0xde
|
|
|
|
|
|
|
|
|
|
enum
|
|
|
|
|
{
|
|
|
|
|
@@ -658,8 +659,8 @@ void ide_set_signature(IDE *ide)
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom_set_signature(cdrom_id);
|
|
|
|
|
ide->secount = cdrom[cdrom_id].phase;
|
|
|
|
|
ide->cylinder = cdrom[cdrom_id].request_length;
|
|
|
|
|
ide->secount = cdrom[cdrom_id]->phase;
|
|
|
|
|
ide->cylinder = cdrom[cdrom_id]->request_length;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
@@ -852,7 +853,7 @@ void ide_reset(void)
|
|
|
|
|
}
|
|
|
|
|
else if ((d < 8) && ide_drive_is_cdrom(&ide_drives[d]))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[d]].status = READY_STAT | DSC_STAT;
|
|
|
|
|
cdrom[atapi_cdrom_drives[d]]->status = READY_STAT | DSC_STAT;
|
|
|
|
|
}
|
|
|
|
|
ide_drives[d].atastat = READY_STAT | DSC_STAT;
|
|
|
|
|
ide_drives[d].service = 0;
|
|
|
|
|
@@ -1053,7 +1054,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
ide_log("ATAPI transfer mode: %s\n", (val & 1) ? "DMA" : "PIO");
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].features = val;
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->features = val;
|
|
|
|
|
}
|
|
|
|
|
ide->cylprecomp = val;
|
|
|
|
|
|
|
|
|
|
@@ -1063,7 +1064,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide_other))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].features = val;
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]]->features = val;
|
|
|
|
|
}
|
|
|
|
|
ide_other->cylprecomp = val;
|
|
|
|
|
return;
|
|
|
|
|
@@ -1077,7 +1078,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
ide_log("Sector count write: %i\n", val);
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].phase = val;
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->phase = val;
|
|
|
|
|
}
|
|
|
|
|
ide->secount = val;
|
|
|
|
|
|
|
|
|
|
@@ -1089,7 +1090,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
else if (ide_drive_is_cdrom(ide_other))
|
|
|
|
|
{
|
|
|
|
|
ide_log("Other sector count write: %i\n", val);
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].phase = val;
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]]->phase = val;
|
|
|
|
|
}
|
|
|
|
|
ide_other->secount = val;
|
|
|
|
|
return;
|
|
|
|
|
@@ -1109,8 +1110,8 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length &= 0xFF00;
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length |= val;
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->request_length &= 0xFF00;
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->request_length |= val;
|
|
|
|
|
}
|
|
|
|
|
ide->cylinder = (ide->cylinder & 0xFF00) | val;
|
|
|
|
|
ide->lba_addr = (ide->lba_addr & 0xFFF00FF) | (val << 8);
|
|
|
|
|
@@ -1122,8 +1123,8 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide_other))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].request_length &= 0xFF00;
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].request_length |= val;
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]]->request_length &= 0xFF00;
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]]->request_length |= val;
|
|
|
|
|
}
|
|
|
|
|
ide_other->cylinder = (ide_other->cylinder&0xFF00) | val;
|
|
|
|
|
ide_other->lba_addr = (ide_other->lba_addr&0xFFF00FF) | (val << 8);
|
|
|
|
|
@@ -1137,8 +1138,8 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length &= 0xFF;
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length |= (val << 8);
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->request_length &= 0xFF;
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->request_length |= (val << 8);
|
|
|
|
|
}
|
|
|
|
|
ide->cylinder = (ide->cylinder & 0xFF) | (val << 8);
|
|
|
|
|
ide->lba_addr = (ide->lba_addr & 0xF00FFFF) | (val << 16);
|
|
|
|
|
@@ -1150,8 +1151,8 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide_other))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].request_length &= 0xFF;
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].request_length |= (val << 8);
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]]->request_length &= 0xFF;
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]]->request_length |= (val << 8);
|
|
|
|
|
}
|
|
|
|
|
ide_other->cylinder = (ide_other->cylinder & 0xFF) | (val << 8);
|
|
|
|
|
ide_other->lba_addr = (ide_other->lba_addr & 0xF00FFFF) | (val << 16);
|
|
|
|
|
@@ -1183,11 +1184,11 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].status = READY_STAT | DSC_STAT;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].error = 1;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].phase = 1;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].request_length = 0xEB14;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].callback = 0LL;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->status = READY_STAT | DSC_STAT;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->error = 1;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->phase = 1;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->request_length = 0xEB14;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->callback = 0LL;
|
|
|
|
|
ide->cylinder = 0xEB14;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1202,11 +1203,11 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide_other))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide_other->channel]].status = READY_STAT | DSC_STAT;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide_other->channel]].error = 1;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide_other->channel]].phase = 1;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide_other->channel]].request_length = 0xEB14;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide_other->channel]].callback = 0LL;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide_other->channel]]->status = READY_STAT | DSC_STAT;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide_other->channel]]->error = 1;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide_other->channel]]->phase = 1;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide_other->channel]]->request_length = 0xEB14;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide_other->channel]]->callback = 0LL;
|
|
|
|
|
ide->cylinder = 0xEB14;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1244,7 +1245,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].error = 0;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->error = 0;
|
|
|
|
|
}
|
|
|
|
|
if (((val >= WIN_RESTORE) && (val <= 0x1F)) || ((val >= WIN_SEEK) && (val <= 0x7F)))
|
|
|
|
|
{
|
|
|
|
|
@@ -1254,7 +1255,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].status = READY_STAT;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->status = READY_STAT;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
@@ -1267,7 +1268,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
}
|
|
|
|
|
if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].callback = 100LL*IDE_TIME;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->callback = 100LL*IDE_TIME;
|
|
|
|
|
}
|
|
|
|
|
idecallback[ide_board]=40000LL * TIMER_USEC /*100LL*IDE_TIME*/;
|
|
|
|
|
timer_update_outstanding();
|
|
|
|
|
@@ -1282,7 +1283,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
@@ -1295,7 +1296,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].callback = 100LL*IDE_TIME;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->callback = 100LL*IDE_TIME;
|
|
|
|
|
}
|
|
|
|
|
idecallback[ide_board]=100LL*IDE_TIME;
|
|
|
|
|
timer_update_outstanding();
|
|
|
|
|
@@ -1319,7 +1320,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
@@ -1332,7 +1333,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].callback = 200LL*IDE_TIME;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->callback = 200LL*IDE_TIME;
|
|
|
|
|
}
|
|
|
|
|
idecallback[ide_board]=200LL*IDE_TIME;
|
|
|
|
|
timer_update_outstanding();
|
|
|
|
|
@@ -1355,8 +1356,8 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].status = DRQ_STAT | DSC_STAT | READY_STAT;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].pos = 0;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->status = DRQ_STAT | DSC_STAT | READY_STAT;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->pos = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
@@ -1373,7 +1374,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
@@ -1386,7 +1387,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].callback = 200LL*IDE_TIME;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->callback = 200LL*IDE_TIME;
|
|
|
|
|
}
|
|
|
|
|
idecallback[ide_board]=200LL*IDE_TIME;
|
|
|
|
|
timer_update_outstanding();
|
|
|
|
|
@@ -1400,7 +1401,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
@@ -1413,7 +1414,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].callback = 200LL*IDE_TIME;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->callback = 200LL*IDE_TIME;
|
|
|
|
|
}
|
|
|
|
|
idecallback[ide_board]=200LL*IDE_TIME;
|
|
|
|
|
timer_update_outstanding();
|
|
|
|
|
@@ -1438,7 +1439,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
@@ -1451,7 +1452,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].callback = 30LL*IDE_TIME;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->callback = 30LL*IDE_TIME;
|
|
|
|
|
}
|
|
|
|
|
idecallback[ide_board]=30LL*IDE_TIME;
|
|
|
|
|
timer_update_outstanding();
|
|
|
|
|
@@ -1461,14 +1462,14 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
if (ide_drive_is_zip(ide))
|
|
|
|
|
zip[atapi_zip_drives[ide->channel]].status = BUSY_STAT;
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT;
|
|
|
|
|
else
|
|
|
|
|
ide->atastat = BUSY_STAT;
|
|
|
|
|
|
|
|
|
|
if (ide_drive_is_zip(ide_other))
|
|
|
|
|
zip[atapi_zip_drives[ide_other->channel]].status = BUSY_STAT;
|
|
|
|
|
else if (ide_drive_is_cdrom(ide_other))
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide_other->channel]].status = BUSY_STAT;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide_other->channel]]->status = BUSY_STAT;
|
|
|
|
|
else
|
|
|
|
|
ide_other->atastat = BUSY_STAT;
|
|
|
|
|
|
|
|
|
|
@@ -1476,7 +1477,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
if (ide_drive_is_zip(ide))
|
|
|
|
|
zip[atapi_zip_drives[ide->channel]].callback = 200LL * IDE_TIME;
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].callback = 200LL * IDE_TIME;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->callback = 200LL * IDE_TIME;
|
|
|
|
|
idecallback[ide_board] = 200LL * IDE_TIME;
|
|
|
|
|
timer_update_outstanding();
|
|
|
|
|
return;
|
|
|
|
|
@@ -1492,7 +1493,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
if (ide_drive_is_zip(ide))
|
|
|
|
|
zip[atapi_zip_drives[ide->channel]].status = BUSY_STAT;
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT;
|
|
|
|
|
else
|
|
|
|
|
ide->atastat = BUSY_STAT;
|
|
|
|
|
timer_process();
|
|
|
|
|
@@ -1509,7 +1510,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
@@ -1522,7 +1523,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].callback = 200LL*IDE_TIME;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->callback = 200LL*IDE_TIME;
|
|
|
|
|
}
|
|
|
|
|
idecallback[ide_board]=200LL*IDE_TIME;
|
|
|
|
|
timer_update_outstanding();
|
|
|
|
|
@@ -1535,14 +1536,14 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
|
|
|
|
zip[atapi_zip_drives[ide->channel]].packet_status = ZIP_PHASE_IDLE;
|
|
|
|
|
zip[atapi_zip_drives[ide->channel]].pos=0;
|
|
|
|
|
zip[atapi_zip_drives[ide->channel]].phase = 1;
|
|
|
|
|
zip[atapi_zip_drives[ide->channel]].status = READY_STAT | DRQ_STAT | (zip[cur_ide[ide_board]].status & ERR_STAT);
|
|
|
|
|
zip[atapi_zip_drives[ide->channel]].status = READY_STAT | DRQ_STAT | (zip[atapi_zip_drives[ide->channel]].status & ERR_STAT);
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].packet_status = CDROM_PHASE_IDLE;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].pos=0;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].phase = 1;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].status = READY_STAT | DRQ_STAT | (cdrom[cur_ide[ide_board]].status & ERR_STAT);
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->packet_status = CDROM_PHASE_IDLE;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->pos=0;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->phase = 1;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->status = READY_STAT | DRQ_STAT | (cdrom[atapi_cdrom_drives[ide->channel]]->status & ERR_STAT);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
@@ -1564,8 +1565,8 @@ ide_bad_command:
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].status = READY_STAT | ERR_STAT | DSC_STAT;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].error = ABRT_ERR;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->status = READY_STAT | ERR_STAT | DSC_STAT;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->error = ABRT_ERR;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
@@ -1587,7 +1588,7 @@ ide_bad_command:
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].callback = 0LL;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->callback = 0LL;
|
|
|
|
|
}
|
|
|
|
|
idecallback[ide_board]=500LL*IDE_TIME;
|
|
|
|
|
timer_update_outstanding();
|
|
|
|
|
@@ -1606,7 +1607,7 @@ ide_bad_command:
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT;
|
|
|
|
|
cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT;
|
|
|
|
|
}
|
|
|
|
|
ide->atastat = ide_other->atastat = BUSY_STAT;
|
|
|
|
|
}
|
|
|
|
|
@@ -1690,8 +1691,8 @@ uint32_t ide_read_data(int ide_board, int length)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].status = READY_STAT | DSC_STAT;
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].packet_status = CDROM_PHASE_IDLE;
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->status = READY_STAT | DSC_STAT;
|
|
|
|
|
cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->packet_status = CDROM_PHASE_IDLE;
|
|
|
|
|
}
|
|
|
|
|
if (ide->command == WIN_READ || ide->command == WIN_READ_NORETRY || ide->command == WIN_READ_MULTIPLE)
|
|
|
|
|
{
|
|
|
|
|
@@ -1753,7 +1754,7 @@ uint8_t readide(int ide_board, uint16_t addr)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].error;
|
|
|
|
|
temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->error;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
@@ -1782,7 +1783,7 @@ uint8_t readide(int ide_board, uint16_t addr)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].phase;
|
|
|
|
|
temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->phase;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
@@ -1807,7 +1808,7 @@ uint8_t readide(int ide_board, uint16_t addr)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length & 0xff;
|
|
|
|
|
temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->request_length & 0xff;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
@@ -1829,7 +1830,7 @@ uint8_t readide(int ide_board, uint16_t addr)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length >> 8;
|
|
|
|
|
temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->request_length >> 8;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
@@ -1858,7 +1859,7 @@ uint8_t readide(int ide_board, uint16_t addr)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
temp = (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0);
|
|
|
|
|
temp = (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
@@ -1880,7 +1881,7 @@ uint8_t readide(int ide_board, uint16_t addr)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
temp = (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0);
|
|
|
|
|
temp = (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
@@ -1962,10 +1963,10 @@ void callbackide(int ide_board)
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom_id = atapi_cdrom_drives[cur_ide[ide_board]];
|
|
|
|
|
cdrom[cdrom_id].status = READY_STAT | DSC_STAT;
|
|
|
|
|
cdrom[cdrom_id].error = 1;
|
|
|
|
|
cdrom[cdrom_id].phase = 1;
|
|
|
|
|
cdrom[cdrom_id].request_length=0xEB14;
|
|
|
|
|
cdrom[cdrom_id]->status = READY_STAT | DSC_STAT;
|
|
|
|
|
cdrom[cdrom_id]->error = 1;
|
|
|
|
|
cdrom[cdrom_id]->phase = 1;
|
|
|
|
|
cdrom[cdrom_id]->request_length=0xEB14;
|
|
|
|
|
ide->cylinder = 0xEB14;
|
|
|
|
|
if (cdrom_drives[cdrom_id].handler->stop)
|
|
|
|
|
{
|
|
|
|
|
@@ -1988,10 +1989,10 @@ void callbackide(int ide_board)
|
|
|
|
|
else if (ide_drive_is_cdrom(ide_other))
|
|
|
|
|
{
|
|
|
|
|
cdrom_id_other = atapi_cdrom_drives[cur_ide[ide_board] ^ 1];
|
|
|
|
|
cdrom[cdrom_id_other].status = READY_STAT | DSC_STAT;
|
|
|
|
|
cdrom[cdrom_id_other].error = 1;
|
|
|
|
|
cdrom[cdrom_id_other].phase = 1;
|
|
|
|
|
cdrom[cdrom_id_other].request_length=0xEB14;
|
|
|
|
|
cdrom[cdrom_id_other]->status = READY_STAT | DSC_STAT;
|
|
|
|
|
cdrom[cdrom_id_other]->error = 1;
|
|
|
|
|
cdrom[cdrom_id_other]->phase = 1;
|
|
|
|
|
cdrom[cdrom_id_other]->request_length=0xEB14;
|
|
|
|
|
ide_other->cylinder = 0xEB14;
|
|
|
|
|
if (cdrom_drives[cdrom_id_other].handler->stop)
|
|
|
|
|
{
|
|
|
|
|
@@ -2048,9 +2049,9 @@ void callbackide(int ide_board)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[cdrom_id].status = READY_STAT | DSC_STAT;
|
|
|
|
|
cdrom[cdrom_id].error = 1;
|
|
|
|
|
cdrom[cdrom_id].phase = 1;
|
|
|
|
|
cdrom[cdrom_id]->status = READY_STAT | DSC_STAT;
|
|
|
|
|
cdrom[cdrom_id]->error = 1;
|
|
|
|
|
cdrom[cdrom_id]->phase = 1;
|
|
|
|
|
cdrom_reset(cdrom_id);
|
|
|
|
|
}
|
|
|
|
|
ide_irq_raise(ide);
|
|
|
|
|
@@ -2070,7 +2071,7 @@ void callbackide(int ide_board)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[cdrom_id].status = READY_STAT | DSC_STAT;
|
|
|
|
|
cdrom[cdrom_id]->status = READY_STAT | DSC_STAT;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
@@ -2088,8 +2089,8 @@ void callbackide(int ide_board)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[cdrom_id].phase = 0xFF;
|
|
|
|
|
cdrom[cdrom_id].status = READY_STAT | DSC_STAT;
|
|
|
|
|
cdrom[cdrom_id]->phase = 0xFF;
|
|
|
|
|
cdrom[cdrom_id]->status = READY_STAT | DSC_STAT;
|
|
|
|
|
}
|
|
|
|
|
ide->secount = 0xFF;
|
|
|
|
|
ide->atastat = READY_STAT | DSC_STAT;
|
|
|
|
|
@@ -2381,8 +2382,8 @@ void callbackide(int ide_board)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[cdrom_id].status = 0;
|
|
|
|
|
cdrom[cdrom_id].error = 1;
|
|
|
|
|
cdrom[cdrom_id]->status = 0;
|
|
|
|
|
cdrom[cdrom_id]->error = 1;
|
|
|
|
|
ide_irq_raise(ide);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
@@ -2402,8 +2403,8 @@ void callbackide(int ide_board)
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide_other))
|
|
|
|
|
{
|
|
|
|
|
cdrom[cdrom_id_other].status = 0;
|
|
|
|
|
cdrom[cdrom_id_other].error = 1;
|
|
|
|
|
cdrom[cdrom_id_other]->status = 0;
|
|
|
|
|
cdrom[cdrom_id_other]->error = 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
@@ -2446,10 +2447,10 @@ void callbackide(int ide_board)
|
|
|
|
|
{
|
|
|
|
|
ide_atapi_identify(ide);
|
|
|
|
|
ide->pos = 0;
|
|
|
|
|
cdrom[cdrom_id].phase = 2;
|
|
|
|
|
cdrom[cdrom_id].pos = 0;
|
|
|
|
|
cdrom[cdrom_id].error = 0;
|
|
|
|
|
cdrom[cdrom_id].status = DRQ_STAT | READY_STAT | DSC_STAT;
|
|
|
|
|
cdrom[cdrom_id]->phase = 2;
|
|
|
|
|
cdrom[cdrom_id]->pos = 0;
|
|
|
|
|
cdrom[cdrom_id]->error = 0;
|
|
|
|
|
cdrom[cdrom_id]->status = DRQ_STAT | READY_STAT | DSC_STAT;
|
|
|
|
|
ide_irq_raise(ide);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@@ -2482,8 +2483,8 @@ void callbackide(int ide_board)
|
|
|
|
|
zip[zip_id].pos = 0;
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide)) {
|
|
|
|
|
cdrom[cdrom_id].status = READY_STAT | DSC_STAT;
|
|
|
|
|
cdrom[cdrom_id].pos = 0;
|
|
|
|
|
cdrom[cdrom_id]->status = READY_STAT | DSC_STAT;
|
|
|
|
|
cdrom[cdrom_id]->pos = 0;
|
|
|
|
|
}
|
|
|
|
|
ide->atastat = READY_STAT | DSC_STAT;
|
|
|
|
|
ide_irq_raise(ide);
|
|
|
|
|
@@ -2545,9 +2546,9 @@ abort_cmd:
|
|
|
|
|
}
|
|
|
|
|
else if (ide_drive_is_cdrom(ide))
|
|
|
|
|
{
|
|
|
|
|
cdrom[cdrom_id].status = READY_STAT | ERR_STAT | DSC_STAT;
|
|
|
|
|
cdrom[cdrom_id].error = ABRT_ERR;
|
|
|
|
|
cdrom[cdrom_id].pos = 0;
|
|
|
|
|
cdrom[cdrom_id]->status = READY_STAT | ERR_STAT | DSC_STAT;
|
|
|
|
|
cdrom[cdrom_id]->error = ABRT_ERR;
|
|
|
|
|
cdrom[cdrom_id]->pos = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
@@ -2888,7 +2889,7 @@ ide_sainit(const device_t *info)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return((void *)info);
|
|
|
|
|
return(ide_drives);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|