Massive IDE clean-ups, and finally implemented ATAPI hard disks.

This commit is contained in:
OBattler
2023-10-28 22:00:23 +02:00
parent 26d9fa4daa
commit b474e3d056
19 changed files with 2005 additions and 1702 deletions

View File

@@ -1055,7 +1055,8 @@ pc_send_cad(void)
void
pc_send_cae(void)
{
pc_send_ca(1);
// pc_send_ca(1);
picint(1 << 14);
}
void

View File

@@ -1600,7 +1600,10 @@ piix_init(const device_t *info)
dev->port_92 = device_add(&port_92_pci_device);
if (cpu_busspeed > 50000000)
cpu_set_isa_pci_div(4);
else
cpu_set_isa_pci_div(3);
dma_alias_set();

View File

@@ -30,6 +30,7 @@
#include <86box/mem.h>
#include <86box/smram.h>
#include <86box/pic.h>
#include <86box/timer.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/port_92.h>

View File

@@ -876,6 +876,7 @@ load_hard_disks(void)
break;
case HDD_BUS_SCSI:
case HDD_BUS_ATAPI:
max_spt = 255;
max_hpc = 255;
max_tracks = 266305;
@@ -893,6 +894,8 @@ load_hard_disks(void)
switch (hdd[c].bus) {
case HDD_BUS_IDE:
case HDD_BUS_ESDI:
case HDD_BUS_ATAPI:
case HDD_BUS_SCSI:
sprintf(tmp2, "1997_5400rpm");
break;
default:
@@ -925,7 +928,7 @@ load_hard_disks(void)
/* IDE */
sprintf(temp, "hdd_%02i_ide_channel", c + 1);
if (hdd[c].bus == HDD_BUS_IDE) {
if ((hdd[c].bus == HDD_BUS_IDE) || (hdd[c].bus == HDD_BUS_ATAPI)) {
sprintf(tmp2, "%01u:%01u", c >> 1, c & 1);
p = ini_section_get_string(cat, temp, tmp2);
sscanf(p, "%01u:%01u", &board, &dev);
@@ -2396,7 +2399,7 @@ save_hard_disks(void)
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_ide_channel", c + 1);
if (!hdd_is_valid(c) || (hdd[c].bus != HDD_BUS_IDE))
if (!hdd_is_valid(c) || ((hdd[c].bus != HDD_BUS_IDE) && (hdd[c].bus != HDD_BUS_ATAPI)))
ini_section_delete_var(cat, temp);
else {
sprintf(tmp2, "%01u:%01u", hdd[c].ide_channel >> 1, hdd[c].ide_channel & 1);

View File

@@ -24,6 +24,7 @@
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/machine.h>
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>

File diff suppressed because it is too large Load Diff

View File

@@ -40,6 +40,7 @@
#include <86box/io.h>
#include <86box/mem.h>
#include <86box/rom.h>
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>

View File

@@ -49,6 +49,8 @@
# include <unistd.h>
#endif
#define IDE_ATAPI_IS_EARLY id->sc->pad0
mo_drive_t mo_drives[MO_NUM];
/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */
@@ -443,11 +445,11 @@ mo_init(mo_t *dev)
dev->drv->bus_mode |= 1;
mo_log("MO %i: Bus type %i, bus mode %i\n", dev->id, dev->drv->bus_type, dev->drv->bus_mode);
if (dev->drv->bus_type < MO_BUS_SCSI) {
dev->phase = 1;
dev->request_length = 0xEB14;
dev->tf->phase = 1;
dev->tf->request_length = 0xEB14;
}
dev->status = READY_STAT | DSC_STAT;
dev->pos = 0;
dev->tf->status = READY_STAT | DSC_STAT;
dev->tf->pos = 0;
dev->packet_status = PHASE_NONE;
mo_sense_key = mo_asc = mo_ascq = dev->unit_attention = 0;
}
@@ -477,36 +479,9 @@ mo_current_mode(mo_t *dev)
if (!mo_supports_pio(dev) && mo_supports_dma(dev))
return 2;
if (mo_supports_pio(dev) && mo_supports_dma(dev)) {
mo_log("MO %i: Drive supports both, setting to %s\n", dev->id, (dev->features & 1) ? "DMA" : "PIO");
return (dev->features & 1) ? 2 : 1;
}
return 0;
}
/* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */
int
mo_atapi_phase_to_scsi(mo_t *dev)
{
if (dev->status & 8) {
switch (dev->phase & 3) {
case 0:
return 0;
case 1:
return 2;
case 2:
return 1;
case 3:
return 7;
default:
break;
}
} else {
if ((dev->phase & 3) == 3)
return 3;
else
return 4;
mo_log("MO %i: Drive supports both, setting to %s\n", dev->id,
(dev->tf->features & 1) ? "DMA" : "PIO");
return (dev->tf->features & 1) ? 2 : 1;
}
return 0;
@@ -622,7 +597,7 @@ mo_update_request_length(mo_t *dev, int len, int block_len)
int bt;
int min_len = 0;
dev->max_transfer_len = dev->request_length;
dev->max_transfer_len = dev->tf->request_length;
/* For media access commands, make sure the requested DRQ length matches the block length. */
switch (dev->current_cdb[0]) {
@@ -666,9 +641,9 @@ mo_update_request_length(mo_t *dev, int len, int block_len)
dev->max_transfer_len = 65534;
if ((len <= dev->max_transfer_len) && (len >= min_len))
dev->request_length = dev->max_transfer_len = len;
dev->tf->request_length = dev->max_transfer_len = len;
else if (len > dev->max_transfer_len)
dev->request_length = dev->max_transfer_len;
dev->tf->request_length = dev->max_transfer_len;
return;
}
@@ -699,9 +674,9 @@ mo_command_common(mo_t *dev)
double bytes_per_second;
double period;
dev->status = BUSY_STAT;
dev->phase = 1;
dev->pos = 0;
dev->tf->status = BUSY_STAT;
dev->tf->phase = 1;
dev->tf->pos = 0;
if (dev->packet_status == PHASE_COMPLETE)
dev->callback = 0.0;
else {
@@ -763,8 +738,8 @@ static void
mo_data_command_finish(mo_t *dev, int len, int block_len, int alloc_len, int direction)
{
mo_log("MO %i: Finishing command (%02X): %i, %i, %i, %i, %i\n",
dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length);
dev->pos = 0;
dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->tf->request_length);
dev->tf->pos = 0;
if (alloc_len >= 0) {
if (alloc_len < len)
len = alloc_len;
@@ -793,7 +768,8 @@ mo_data_command_finish(mo_t *dev, int len, int block_len, int alloc_len, int dir
}
mo_log("MO %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n",
dev->id, dev->packet_status, dev->request_length, dev->packet_len, dev->pos, dev->phase);
dev->id, dev->packet_status, dev->tf->request_length, dev->packet_len, dev->tf->pos,
dev->tf->phase);
}
static void
@@ -818,12 +794,12 @@ static void
mo_cmd_error(mo_t *dev)
{
mo_set_phase(dev, SCSI_PHASE_STATUS);
dev->error = ((mo_sense_key & 0xf) << 4) | ABRT_ERR;
dev->tf->error = ((mo_sense_key & 0xf) << 4) | ABRT_ERR;
if (dev->unit_attention)
dev->error |= MCR_ERR;
dev->status = READY_STAT | ERR_STAT;
dev->phase = 3;
dev->pos = 0;
dev->tf->error |= MCR_ERR;
dev->tf->status = READY_STAT | ERR_STAT;
dev->tf->phase = 3;
dev->tf->pos = 0;
dev->packet_status = PHASE_ERROR;
dev->callback = 50.0 * MO_TIME;
mo_set_callback(dev);
@@ -835,12 +811,12 @@ static void
mo_unit_attention(mo_t *dev)
{
mo_set_phase(dev, SCSI_PHASE_STATUS);
dev->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR;
dev->tf->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR;
if (dev->unit_attention)
dev->error |= MCR_ERR;
dev->status = READY_STAT | ERR_STAT;
dev->phase = 3;
dev->pos = 0;
dev->tf->error |= MCR_ERR;
dev->tf->status = READY_STAT | ERR_STAT;
dev->tf->phase = 3;
dev->tf->pos = 0;
dev->packet_status = PHASE_ERROR;
dev->callback = 50.0 * MO_TIME;
mo_set_callback(dev);
@@ -928,7 +904,7 @@ mo_invalid_field(mo_t *dev)
mo_asc = ASC_INV_FIELD_IN_CMD_PACKET;
mo_ascq = 0;
mo_cmd_error(dev);
dev->status = 0x53;
dev->tf->status = 0x53;
}
static void
@@ -938,7 +914,7 @@ mo_invalid_field_pl(mo_t *dev)
mo_asc = ASC_INV_FIELD_IN_PARAMETER_LIST;
mo_ascq = 0;
mo_cmd_error(dev);
dev->status = 0x53;
dev->tf->status = 0x53;
}
static int
@@ -1112,7 +1088,8 @@ mo_pre_execution_check(mo_t *dev, uint8_t *cdb)
int ready = 0;
if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) {
mo_log("MO %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id, ((dev->request_length >> 5) & 7));
mo_log("MO %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id,
((dev->tf->request_length >> 5) & 7));
mo_invalid_lun(dev);
return 0;
}
@@ -1202,11 +1179,11 @@ mo_reset(scsi_common_t *sc)
mo_t *dev = (mo_t *) sc;
mo_rezero(dev);
dev->status = 0;
dev->tf->status = 0;
dev->callback = 0.0;
mo_set_callback(dev);
dev->phase = 1;
dev->request_length = 0xEB14;
dev->tf->phase = 1;
dev->tf->request_length = 0xEB14;
dev->packet_status = PHASE_NONE;
dev->unit_attention = 0;
dev->cur_lun = SCSI_LUN_USE_CDB;
@@ -1303,10 +1280,10 @@ mo_command(scsi_common_t *sc, uint8_t *cdb)
if (dev->drv->bus_type == MO_BUS_SCSI) {
BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length;
dev->status &= ~ERR_STAT;
dev->tf->status &= ~ERR_STAT;
} else {
BufLen = &blen;
dev->error = 0;
dev->tf->error = 0;
}
dev->packet_len = 0;
@@ -1319,7 +1296,7 @@ mo_command(scsi_common_t *sc, uint8_t *cdb)
if (cdb[0] != 0) {
mo_log("MO %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n",
dev->id, cdb[0], mo_sense_key, mo_asc, mo_ascq, dev->unit_attention);
mo_log("MO %i: Request length: %04X\n", dev->id, dev->request_length);
mo_log("MO %i: Request length: %04X\n", dev->id, dev->tf->request_length);
mo_log("MO %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id,
cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7],
@@ -1857,10 +1834,10 @@ mo_command(scsi_common_t *sc, uint8_t *cdb)
}
#if 0
mo_log("MO %i: Phase: %02X, request length: %i\n", dev->id, dev->phase, dev->request_length);
mo_log("MO %i: Phase: %02X, request length: %i\n", dev->id, dev->tf->phase, dev->tf->request_length);
#endif
if (mo_atapi_phase_to_scsi(dev) == SCSI_PHASE_STATUS)
if ((dev->packet_status == PHASE_COMPLETE) || (dev->packet_status == PHASE_ERROR))
mo_buf_free(dev);
}
@@ -2099,6 +2076,9 @@ mo_drive_reset(int c)
dev->cur_lun = SCSI_LUN_USE_CDB;
if (mo_drives[c].bus_type == MO_BUS_SCSI) {
if (!dev->tf)
dev->tf = (ide_tf_t *) calloc(1, sizeof(ide_tf_t));
/* SCSI MO, attach to the SCSI bus. */
sd = &scsi_devices[scsi_bus][scsi_id];
@@ -2117,6 +2097,8 @@ mo_drive_reset(int c)
that's not attached to anything. */
if (id) {
id->sc = (scsi_common_t *) dev;
dev->tf = id->tf;
IDE_ATAPI_IS_EARLY = 0;
id->get_max = mo_get_max;
id->get_timings = mo_get_timings;
id->identify = mo_identify;
@@ -2203,6 +2185,9 @@ mo_close(void)
if (dev) {
mo_disk_unload(dev);
if (dev->tf)
free(dev->tf);
free(dev);
mo_drives[c].priv = NULL;
}

View File

@@ -36,6 +36,8 @@
#include <86box/hdc_ide.h>
#include <86box/zip.h>
#define IDE_ATAPI_IS_EARLY id->sc->pad0
zip_drive_t zip_drives[ZIP_NUM];
/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */
@@ -588,11 +590,11 @@ zip_init(zip_t *dev)
dev->drv->bus_mode |= 1;
zip_log("ZIP %i: Bus type %i, bus mode %i\n", dev->id, dev->drv->bus_type, dev->drv->bus_mode);
if (dev->drv->bus_type < ZIP_BUS_SCSI) {
dev->phase = 1;
dev->request_length = 0xEB14;
dev->tf->phase = 1;
dev->tf->request_length = 0xEB14;
}
dev->status = READY_STAT | DSC_STAT;
dev->pos = 0;
dev->tf->status = READY_STAT | DSC_STAT;
dev->tf->pos = 0;
dev->packet_status = PHASE_NONE;
zip_sense_key = zip_asc = zip_ascq = dev->unit_attention = 0;
}
@@ -622,36 +624,9 @@ zip_current_mode(zip_t *dev)
if (!zip_supports_pio(dev) && zip_supports_dma(dev))
return 2;
if (zip_supports_pio(dev) && zip_supports_dma(dev)) {
zip_log("ZIP %i: Drive supports both, setting to %s\n", dev->id, (dev->features & 1) ? "DMA" : "PIO");
return (dev->features & 1) ? 2 : 1;
}
return 0;
}
/* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */
int
zip_atapi_phase_to_scsi(zip_t *dev)
{
if (dev->status & 8) {
switch (dev->phase & 3) {
case 0:
return 0;
case 1:
return 2;
case 2:
return 1;
case 3:
return 7;
default:
break;
}
} else {
if ((dev->phase & 3) == 3)
return 3;
else
return 4;
zip_log("ZIP %i: Drive supports both, setting to %s\n", dev->id,
(dev->tf->features & 1) ? "DMA" : "PIO");
return (dev->tf->features & 1) ? 2 : 1;
}
return 0;
@@ -791,7 +766,7 @@ zip_update_request_length(zip_t *dev, int len, int block_len)
int bt;
int min_len = 0;
dev->max_transfer_len = dev->request_length;
dev->max_transfer_len = dev->tf->request_length;
/* For media access commands, make sure the requested DRQ length matches the block length. */
switch (dev->current_cdb[0]) {
@@ -835,9 +810,9 @@ zip_update_request_length(zip_t *dev, int len, int block_len)
dev->max_transfer_len = 65534;
if ((len <= dev->max_transfer_len) && (len >= min_len))
dev->request_length = dev->max_transfer_len = len;
dev->tf->request_length = dev->max_transfer_len = len;
else if (len > dev->max_transfer_len)
dev->request_length = dev->max_transfer_len;
dev->tf->request_length = dev->max_transfer_len;
return;
}
@@ -868,9 +843,9 @@ zip_command_common(zip_t *dev)
double bytes_per_second;
double period;
dev->status = BUSY_STAT;
dev->phase = 1;
dev->pos = 0;
dev->tf->status = BUSY_STAT;
dev->tf->phase = 1;
dev->tf->pos = 0;
if (dev->packet_status == PHASE_COMPLETE)
dev->callback = 0.0;
else {
@@ -932,8 +907,8 @@ static void
zip_data_command_finish(zip_t *dev, int len, int block_len, int alloc_len, int direction)
{
zip_log("ZIP %i: Finishing command (%02X): %i, %i, %i, %i, %i\n",
dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length);
dev->pos = 0;
dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->tf->request_length);
dev->tf->pos = 0;
if (alloc_len >= 0) {
if (alloc_len < len)
len = alloc_len;
@@ -962,7 +937,8 @@ zip_data_command_finish(zip_t *dev, int len, int block_len, int alloc_len, int d
}
zip_log("ZIP %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n",
dev->id, dev->packet_status, dev->request_length, dev->packet_len, dev->pos, dev->phase);
dev->id, dev->packet_status, dev->tf->request_length, dev->packet_len, dev->tf->pos,
dev->tf->phase);
}
static void
@@ -987,12 +963,12 @@ static void
zip_cmd_error(zip_t *dev)
{
zip_set_phase(dev, SCSI_PHASE_STATUS);
dev->error = ((zip_sense_key & 0xf) << 4) | ABRT_ERR;
dev->tf->error = ((zip_sense_key & 0xf) << 4) | ABRT_ERR;
if (dev->unit_attention)
dev->error |= MCR_ERR;
dev->status = READY_STAT | ERR_STAT;
dev->phase = 3;
dev->pos = 0;
dev->tf->error |= MCR_ERR;
dev->tf->status = READY_STAT | ERR_STAT;
dev->tf->phase = 3;
dev->tf->pos = 0;
dev->packet_status = PHASE_ERROR;
dev->callback = 50.0 * ZIP_TIME;
zip_set_callback(dev);
@@ -1004,12 +980,12 @@ static void
zip_unit_attention(zip_t *dev)
{
zip_set_phase(dev, SCSI_PHASE_STATUS);
dev->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR;
dev->tf->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR;
if (dev->unit_attention)
dev->error |= MCR_ERR;
dev->status = READY_STAT | ERR_STAT;
dev->phase = 3;
dev->pos = 0;
dev->tf->error |= MCR_ERR;
dev->tf->status = READY_STAT | ERR_STAT;
dev->tf->phase = 3;
dev->tf->pos = 0;
dev->packet_status = PHASE_ERROR;
dev->callback = 50.0 * ZIP_TIME;
zip_set_callback(dev);
@@ -1097,7 +1073,7 @@ zip_invalid_field(zip_t *dev)
zip_asc = ASC_INV_FIELD_IN_CMD_PACKET;
zip_ascq = 0;
zip_cmd_error(dev);
dev->status = 0x53;
dev->tf->status = 0x53;
}
static void
@@ -1107,7 +1083,7 @@ zip_invalid_field_pl(zip_t *dev)
zip_asc = ASC_INV_FIELD_IN_PARAMETER_LIST;
zip_ascq = 0;
zip_cmd_error(dev);
dev->status = 0x53;
dev->tf->status = 0x53;
}
static void
@@ -1184,7 +1160,8 @@ zip_pre_execution_check(zip_t *dev, uint8_t *cdb)
int ready = 0;
if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) {
zip_log("ZIP %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id, ((dev->request_length >> 5) & 7));
zip_log("ZIP %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id,
((dev->tf->request_length >> 5) & 7));
zip_invalid_lun(dev);
return 0;
}
@@ -1274,11 +1251,11 @@ zip_reset(scsi_common_t *sc)
zip_t *dev = (zip_t *) sc;
zip_rezero(dev);
dev->status = 0;
dev->tf->status = 0;
dev->callback = 0.0;
zip_set_callback(dev);
dev->phase = 1;
dev->request_length = 0xEB14;
dev->tf->phase = 1;
dev->tf->request_length = 0xEB14;
dev->packet_status = PHASE_NONE;
dev->unit_attention = 0;
dev->cur_lun = SCSI_LUN_USE_CDB;
@@ -1374,10 +1351,10 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
if (dev->drv->bus_type == ZIP_BUS_SCSI) {
BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length;
dev->status &= ~ERR_STAT;
dev->tf->status &= ~ERR_STAT;
} else {
BufLen = &blen;
dev->error = 0;
dev->tf->error = 0;
}
dev->packet_len = 0;
@@ -1388,7 +1365,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
if (cdb[0] != 0) {
zip_log("ZIP %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n",
dev->id, cdb[0], zip_sense_key, zip_asc, zip_ascq, dev->unit_attention);
zip_log("ZIP %i: Request length: %04X\n", dev->id, dev->request_length);
zip_log("ZIP %i: Request length: %04X\n", dev->id, dev->tf->request_length);
zip_log("ZIP %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id,
cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7],
@@ -1465,8 +1442,9 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
break;
case GPCMD_REQUEST_SENSE:
/* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE
should forget about the not ready, and report unit attention straight away. */
/* If there's a unit attention condition and there's a buffered not
ready, a standalone REQUEST SENSE should forget about the not
ready, and report unit attention straight away. */
zip_set_phase(dev, SCSI_PHASE_DATA_IN);
max_len = cdb[4];
@@ -1507,7 +1485,14 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
switch (cdb[0]) {
case GPCMD_READ_6:
dev->sector_len = cdb[4];
dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]);
/*
For READ (6) and WRITE (6), a length of 0 indicates a
transfer of 256 sectors.
*/
if (dev->sector_len == 0)
dev->sector_len = 256;
dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) |
(((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]);
zip_log("ZIP %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos);
break;
case GPCMD_READ_10:
@@ -1516,14 +1501,21 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
zip_log("ZIP %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos);
break;
case GPCMD_READ_12:
dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]);
dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]);
dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) |
(((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]);
dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) |
(((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]);
break;
default:
break;
}
if (dev->sector_pos >= dev->drv->medium_size) {
zip_lba_out_of_range(dev);
return;
}
if (!dev->sector_len) {
zip_set_phase(dev, SCSI_PHASE_STATUS);
/* zip_log("ZIP %i: All done - callback set\n", dev->id); */
@@ -1534,9 +1526,13 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
}
max_len = dev->sector_len;
dev->requested_blocks = max_len; /* If we're reading all blocks in one go for DMA, why not also for PIO, it should NOT
matter anyway, this step should be identical and only the way the read dat is
transferred to the host should be different. */
/*
If we're reading all blocks in one go for DMA, why not also for
PIO, it should NOT matter anyway, this step should be identical
and only the way the read dat is transferred to the host should
be different.
*/
dev->requested_blocks = max_len;
dev->packet_len = max_len * alloc_length;
zip_buf_alloc(dev, dev->packet_len);
@@ -1558,10 +1554,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
zip_data_command_finish(dev, alloc_length, 512, alloc_length, 0);
if (dev->packet_status != PHASE_COMPLETE)
ui_sb_update_icon(SB_ZIP | dev->id, 1);
else
ui_sb_update_icon(SB_ZIP | dev->id, 0);
ui_sb_update_icon(SB_ZIP | dev->id, dev->packet_status != PHASE_COMPLETE);
return;
case GPCMD_VERIFY_6:
@@ -1590,9 +1583,14 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
case GPCMD_VERIFY_6:
case GPCMD_WRITE_6:
dev->sector_len = cdb[4];
/*
For READ (6) and WRITE (6), a length of 0 indicates a
transfer of 256 sectors.
*/
if (dev->sector_len == 0)
dev->sector_len = 256; /* For READ (6) and WRITE (6), a length of 0 indicates a transfer of 256 sector. */
dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]);
dev->sector_len = 256;
dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) |
(((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]);
break;
case GPCMD_VERIFY_10:
case GPCMD_WRITE_10:
@@ -1604,17 +1602,17 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
case GPCMD_VERIFY_12:
case GPCMD_WRITE_12:
case GPCMD_WRITE_AND_VERIFY_12:
dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]);
dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]);
dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) |
(((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]);
dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) |
(((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]);
break;
default:
break;
}
if ((dev->sector_pos >= dev->drv->medium_size) /* ||
((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)*/
) {
if (dev->sector_pos >= dev->drv->medium_size) {
zip_lba_out_of_range(dev);
return;
}
@@ -1629,9 +1627,13 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
}
max_len = dev->sector_len;
dev->requested_blocks = max_len; /* If we're writing all blocks in one go for DMA, why not also for PIO, it should NOT
matter anyway, this step should be identical and only the way the read dat is
transferred to the host should be different. */
/*
If we're writing all blocks in one go for DMA, why not also for
PIO, it should NOT matter anyway, this step should be identical
and only the way the read dat is transferred to the host should
be different.
*/
dev->requested_blocks = max_len;
dev->packet_len = max_len * alloc_length;
zip_buf_alloc(dev, dev->packet_len);
@@ -1643,10 +1645,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
zip_data_command_finish(dev, dev->packet_len, 512, dev->packet_len, 1);
if (dev->packet_status != PHASE_COMPLETE)
ui_sb_update_icon(SB_ZIP | dev->id, 1);
else
ui_sb_update_icon(SB_ZIP | dev->id, 0);
ui_sb_update_icon(SB_ZIP | dev->id, dev->packet_status != PHASE_COMPLETE);
return;
case GPCMD_WRITE_SAME_10:
@@ -1665,9 +1664,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
dev->sector_len = (cdb[7] << 8) | cdb[8];
dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5];
if ((dev->sector_pos >= dev->drv->medium_size) /* ||
((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)*/
) {
if (dev->sector_pos >= dev->drv->medium_size) {
zip_lba_out_of_range(dev);
return;
}
@@ -1693,10 +1690,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
zip_data_command_finish(dev, 512, 512, alloc_length, 1);
if (dev->packet_status != PHASE_COMPLETE)
ui_sb_update_icon(SB_ZIP | dev->id, 1);
else
ui_sb_update_icon(SB_ZIP | dev->id, 0);
ui_sb_update_icon(SB_ZIP | dev->id, dev->packet_status != PHASE_COMPLETE);
return;
case GPCMD_MODE_SENSE_6:
@@ -2034,10 +2028,10 @@ atapi_out:
}
#if 0
zip_log("ZIP %i: Phase: %02X, request length: %i\n", dev->id, dev->phase, dev->request_length);
zip_log("ZIP %i: Phase: %02X, request length: %i\n", dev->id, dev->tf->phase, dev->tf->request_length);
#endif
if (zip_atapi_phase_to_scsi(dev) == SCSI_PHASE_STATUS)
if ((dev->packet_status == PHASE_COMPLETE) || (dev->packet_status == PHASE_ERROR))
zip_buf_free(dev);
}
@@ -2321,6 +2315,9 @@ zip_drive_reset(int c)
dev->cur_lun = SCSI_LUN_USE_CDB;
if (zip_drives[c].bus_type == ZIP_BUS_SCSI) {
if (!dev->tf)
dev->tf = (ide_tf_t *) calloc(1, sizeof(ide_tf_t));
/* SCSI ZIP, attach to the SCSI bus. */
sd = &scsi_devices[scsi_bus][scsi_id];
@@ -2339,6 +2336,8 @@ zip_drive_reset(int c)
that's not attached to anything. */
if (id) {
id->sc = (scsi_common_t *) dev;
dev->tf = id->tf;
IDE_ATAPI_IS_EARLY = 0;
id->get_max = zip_get_max;
id->get_timings = zip_get_timings;
id->identify = zip_identify;
@@ -2425,6 +2424,9 @@ zip_close(void)
if (dev) {
zip_disk_unload(dev);
if (dev->tf)
free(dev->tf);
free(dev);
zip_drives[c].priv = NULL;
}

View File

@@ -41,13 +41,46 @@ enum {
IDE_ATAPI
};
#ifdef SCSI_DEVICE_H
typedef struct ide_tf_s {
union {
uint8_t cylprecomp;
uint8_t features;
};
union {
uint8_t secount;
uint8_t phase;
};
union {
uint16_t cylinder;
uint16_t request_length;
};
union {
uint8_t atastat;
uint8_t status;
};
uint8_t error;
uint16_t pad;
uint32_t pos;
} ide_tf_t;
#ifdef _TIMER_H_
typedef struct ide_s {
uint8_t selected;
#ifdef ANCIENT_CODE
/* Task file. */
uint8_t cylprecomp;
uint8_t secount;
uint16_t cylinder;
uint8_t atastat;
uint8_t error;
uint16_t pad;
uint32_t pos;
#endif
/* The rest. */
uint8_t selected;
uint8_t command;
uint8_t fdisk;
uint8_t head;
uint8_t sector;
int type;
int board;
int irqstat;
@@ -56,18 +89,12 @@ typedef struct ide_s {
int blockcount;
int hdd_num;
int channel;
int pos;
int sector_pos;
int lba;
int reset;
int mdma_mode;
int do_initial_read;
uint32_t secount;
uint32_t sector;
uint32_t cylinder;
uint32_t head;
uint32_t drive;
uint32_t cylprecomp;
uint32_t cfg_spt;
uint32_t cfg_hpc;
uint32_t lba_addr;
@@ -80,11 +107,19 @@ typedef struct ide_s {
pc_timer_t timer;
/* Task file. */
ide_tf_t * tf;
/* Stuff mostly used by ATAPI */
#ifdef SCSI_DEVICE_H
scsi_common_t *sc;
#else
void * sc;
#endif
int interrupt_drq;
double pending_delay;
#ifdef SCSI_DEVICE_H
int (*get_max)(int ide_has_dma, int type);
int (*get_timings)(int ide_has_dma, int type);
void (*identify)(struct ide_s *ide, int ide_has_dma);
@@ -94,10 +129,22 @@ typedef struct ide_s {
uint8_t (*phase_data_out)(scsi_common_t *sc);
void (*command_stop)(scsi_common_t *sc);
void (*bus_master_error)(scsi_common_t *sc);
#else
void * get_max;
void * get_timings;
void * identify;
void * stop;
void * device_reset;
void * phase_data_out;
void * command_stop;
void * bus_master_error;
#endif
} ide_t;
#ifdef EMU_HDC_H
extern ide_t *ide_drives[IDE_NUM];
#endif
#endif
/* Type:
0 = PIO,
@@ -155,16 +202,9 @@ extern void ide_set_bus_master(int board,
extern void win_cdrom_eject(uint8_t id);
extern void win_cdrom_reload(uint8_t id);
extern void ide_set_base(int board, uint16_t port);
extern void ide_set_side(int board, uint16_t port);
extern void ide_set_base_addr(int board, int base, uint16_t port);
extern void ide_set_handlers(uint8_t board);
extern void ide_remove_handlers(uint8_t board);
extern void ide_pri_enable(void);
extern void ide_pri_disable(void);
extern void ide_sec_enable(void);
extern void ide_sec_disable(void);
extern void ide_handlers(uint8_t board, int set);
extern void ide_board_set_force_ata3(int board, int force_ata3);
#ifdef EMU_ISAPNP_H
@@ -183,4 +223,16 @@ extern void ide_padstr8(uint8_t *buf, int buf_size, const char *src);
extern uint8_t ide_read_ali_75(void);
extern uint8_t ide_read_ali_76(void);
/* Legacy #define's. */
#define ide_set_base(board, port) ide_set_base_addr(board, 0, port)
#define ide_set_side(board, port) ide_set_base_addr(board, 1, port)
#define ide_pri_enable() ide_handlers(0, 1)
#define ide_pri_disable() ide_handlers(0, 0)
#define ide_sec_enable() ide_handlers(1, 1)
#define ide_sec_disable() ide_handlers(1, 0)
#define ide_set_handlers(board) ide_handlers(board, 1)
#define ide_remove_handlers(board) ide_handlers(board, 0)
#endif /*EMU_IDE_H*/

View File

@@ -148,7 +148,8 @@ typedef struct hard_disk_t {
uint8_t scsi_id;
};
uint8_t bus;
uint8_t res; /* Reserved for bus mode */
uint8_t bus_mode; /* Bit 0 = PIO suported;
Bit 1 = DMA supportd. */
uint8_t wp; /* Disk has been mounted READ-ONLY */
uint8_t pad;
uint8_t pad0;

View File

@@ -128,23 +128,35 @@ typedef struct mo_t {
mode_sense_pages_t ms_pages_saved;
mo_drive_t *drv;
#ifdef EMU_IDE_H
ide_tf_t * tf;
#else
void * tf;
#endif
uint8_t *buffer;
uint8_t atapi_cdb[16];
uint8_t current_cdb[16];
uint8_t sense[256];
uint8_t status;
uint8_t phase;
uint8_t error;
uint8_t id;
#ifdef ANCIENT_CODE
/* Task file. */
uint8_t features;
uint8_t phase;
uint16_t request_length;
uint8_t status;
uint8_t error;
uint16_t pad;
uint32_t pos;
#endif
uint8_t id;
uint8_t cur_lun;
uint8_t pad0;
uint8_t pad1;
uint16_t request_length;
uint16_t max_transfer_len;
uint16_t pad2;
int requested_blocks;
int packet_status;
@@ -158,7 +170,6 @@ typedef struct mo_t {
uint32_t sector_pos;
uint32_t sector_len;
uint32_t packet_len;
uint32_t pos;
double callback;
} mo_t;

View File

@@ -27,23 +27,35 @@ typedef struct scsi_cdrom_t {
mode_sense_pages_t ms_pages_saved;
cdrom_t * drv;
#ifdef EMU_IDE_H
ide_tf_t *tf;
#else
void * tf;
#endif
uint8_t *buffer;
uint8_t atapi_cdb[16];
uint8_t current_cdb[16];
uint8_t sense[256];
uint8_t status;
uint8_t phase;
uint8_t error;
uint8_t id;
#ifdef ANCIENT_CODE
/* Task file. */
uint8_t features;
uint8_t phase;
uint16_t request_length;
uint8_t status;
uint8_t error;
uint16_t pad;
uint32_t pos;
#endif
uint8_t id;
uint8_t cur_lun;
uint8_t early;
uint8_t pad1;
uint16_t request_length;
uint16_t max_transfer_len;
uint16_t pad2;
int requested_blocks;
int packet_status;
@@ -57,7 +69,6 @@ typedef struct scsi_cdrom_t {
uint32_t sector_pos;
uint32_t sector_len;
uint32_t packet_len;
uint32_t pos;
double callback;

View File

@@ -348,6 +348,11 @@ typedef struct scsi_common_s {
mode_sense_pages_t ms_pages_saved;
void * priv;
#ifdef EMU_IDE_H
ide_tf_t *tf;
#else
void * tf;
#endif
uint8_t *temp_buffer;
uint8_t atapi_cdb[16]; /* This is atapi_cdb in ATAPI-supporting devices,
@@ -355,17 +360,24 @@ typedef struct scsi_common_s {
uint8_t current_cdb[16];
uint8_t sense[256];
uint8_t status;
uint8_t phase;
uint8_t error;
uint8_t id;
#ifdef ANCIENT_CODE
/* Task file. */
uint8_t features;
uint8_t phase;
uint16_t request_length;
uint8_t status;
uint8_t error;
uint16_t pad;
uint32_t pos;
#endif
uint8_t id;
uint8_t cur_lun;
uint8_t pad0;
uint8_t pad1;
uint16_t request_length;
uint16_t max_transfer_len;
uint16_t pad2;
int requested_blocks;
int packet_status;
@@ -379,7 +391,6 @@ typedef struct scsi_common_s {
uint32_t sector_pos;
uint32_t sector_len;
uint32_t packet_len;
uint32_t pos;
double callback;
} scsi_common_t;

View File

@@ -20,38 +20,48 @@ typedef struct scsi_disk_t {
mode_sense_pages_t ms_pages_saved;
hard_disk_t *drv;
#ifdef EMU_IDE_H
ide_tf_t * tf;
#else
void * tf;
#endif
uint8_t *temp_buffer;
uint8_t pad[16]; /* This is atapi_cdb in ATAPI-supporting devices,
and pad in SCSI-only devices. */
uint8_t atapi_cdb[16];
uint8_t current_cdb[16];
uint8_t sense[256];
uint8_t status;
#ifdef ANCIENT_CODE
/* Task file. */
uint8_t features;
uint8_t phase;
uint8_t error;
uint8_t id;
uint8_t pad0;
uint8_t cur_lun;
uint8_t pad1;
uint8_t pad2;
uint16_t request_length;
uint16_t pad4;
uint8_t status;
uint8_t error;
uint16_t pad;
uint32_t pos;
#endif
uint8_t id;
uint8_t cur_lun;
uint8_t pad0;
uint8_t pad1;
uint16_t max_transfer_len;
uint16_t pad2;
int requested_blocks;
int packet_status;
int total_length;
int do_page_save;
int unit_attention;
int pad5;
int request_pos;
int pad6;
int pad7;
uint32_t sector_pos;
uint32_t sector_len;
uint32_t packet_len;
uint32_t pos;
double callback;
} scsi_disk_t;

View File

@@ -74,23 +74,35 @@ typedef struct zip_t {
mode_sense_pages_t ms_pages_saved;
zip_drive_t *drv;
#ifdef EMU_IDE_H
ide_tf_t * tf;
#else
void * tf;
#endif
uint8_t *buffer;
uint8_t atapi_cdb[16];
uint8_t current_cdb[16];
uint8_t sense[256];
uint8_t status;
uint8_t phase;
uint8_t error;
uint8_t id;
#ifdef ANCIENT_CODE
/* Task file. */
uint8_t features;
uint8_t phase;
uint16_t request_length;
uint8_t status;
uint8_t error;
uint16_t pad;
uint32_t pos;
#endif
uint8_t id;
uint8_t cur_lun;
uint8_t pad0;
uint8_t pad1;
uint16_t request_length;
uint16_t max_transfer_len;
uint16_t pad2;
int requested_blocks;
int packet_status;
@@ -104,7 +116,6 @@ typedef struct zip_t {
uint32_t sector_pos;
uint32_t sector_len;
uint32_t packet_len;
uint32_t pos;
double callback;
} zip_t;

View File

@@ -41,6 +41,8 @@
#include <86box/scsi_cdrom.h>
#include <86box/version.h>
#define IDE_ATAPI_IS_EARLY id->sc->pad0
#pragma pack(push, 1)
typedef struct gesn_cdb_t {
uint8_t opcode;
@@ -516,15 +518,17 @@ scsi_cdrom_init(scsi_cdrom_t *dev)
dev->drv->bus_mode |= 2;
if (dev->drv->bus_type < CDROM_BUS_SCSI)
dev->drv->bus_mode |= 1;
scsi_cdrom_log("CD-ROM %i: Bus type %i, bus mode %i\n", dev->id, dev->drv->bus_type, dev->drv->bus_mode);
scsi_cdrom_log("CD-ROM %i: Bus type %i, bus mode %i\n",
dev->id, dev->drv->bus_type, dev->drv->bus_mode);
dev->sense[0] = 0xf0;
dev->sense[7] = 10;
if ((dev->drv->type == CDROM_TYPE_NEC_260_100) || (dev->drv->type == CDROM_TYPE_NEC_260_101)) /*NEC only*/
dev->status = READY_STAT | DSC_STAT;
/* NEC only */
if ((dev->drv->type == CDROM_TYPE_NEC_260_100) || (dev->drv->type == CDROM_TYPE_NEC_260_101))
dev->tf->status = READY_STAT | DSC_STAT;
else
dev->status = 0;
dev->pos = 0;
dev->tf->status = 0;
dev->tf->pos = 0;
dev->packet_status = PHASE_NONE;
scsi_cdrom_sense_key = scsi_cdrom_asc = scsi_cdrom_ascq = dev->unit_attention = 0;
dev->drv->cur_speed = dev->drv->speed;
@@ -541,37 +545,9 @@ scsi_cdrom_current_mode(scsi_cdrom_t *dev)
return 2;
else if (dev->drv->bus_type == CDROM_BUS_ATAPI) {
scsi_cdrom_log("CD-ROM %i: ATAPI drive, setting to %s\n", dev->id,
(dev->features & 1) ? "DMA" : "PIO",
(dev->tf->features & 1) ? "DMA" : "PIO",
dev->id);
return (dev->features & 1) ? 2 : 1;
}
return 0;
}
/* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */
int
scsi_cdrom_atapi_phase_to_scsi(scsi_cdrom_t *dev)
{
if (dev->status & 8) {
switch (dev->phase & 3) {
case 0:
return 0;
case 1:
return 2;
case 2:
return 1;
case 3:
return 7;
default:
break;
}
} else {
if ((dev->phase & 3) == 3)
return 3;
else
return 4;
return (dev->tf->features & 1) ? 2 : 1;
}
return 0;
@@ -617,7 +593,8 @@ scsi_cdrom_get_volume(void *priv, int channel)
case CDROM_TYPE_SONY_CDU561_18k:
case CDROM_TYPE_SONY_CDU76S_100:
case CDROM_TYPE_TEXEL_DMXX24_100:
ret = dev->ms_pages_saved_sony.pages[dev->sony_vendor ? GPMODE_CDROM_AUDIO_PAGE_SONY : GPMODE_CDROM_AUDIO_PAGE][channel ? 11 : 9];
ret = dev->ms_pages_saved_sony.pages[dev->sony_vendor ? GPMODE_CDROM_AUDIO_PAGE_SONY :
GPMODE_CDROM_AUDIO_PAGE][channel ? 11 : 9];
break;
default:
ret = dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE][channel ? 11 : 9];
@@ -640,13 +617,15 @@ scsi_cdrom_mode_sense_load(scsi_cdrom_t *dev)
case CDROM_TYPE_SONY_CDU76S_100:
case CDROM_TYPE_TEXEL_DMXX24_100:
memset(&dev->ms_pages_saved_sony, 0, sizeof(mode_sense_pages_t));
memcpy(&dev->ms_pages_saved_sony, &scsi_cdrom_mode_sense_pages_default_sony_scsi, sizeof(mode_sense_pages_t));
memcpy(&dev->ms_pages_saved_sony, &scsi_cdrom_mode_sense_pages_default_sony_scsi,
sizeof(mode_sense_pages_t));
memset(file_name, 0, 512);
sprintf(file_name, "scsi_cdrom_%02i_mode_sense_sony_bin", dev->id);
fp = plat_fopen(nvr_path(file_name), "rb");
if (fp) {
if (fread(dev->ms_pages_saved_sony.pages[GPMODE_CDROM_AUDIO_PAGE_SONY], 1, 0x10, fp) != 0x10)
if (fread(dev->ms_pages_saved_sony.pages[GPMODE_CDROM_AUDIO_PAGE_SONY], 1,
0x10, fp) != 0x10)
fatal("scsi_cdrom_mode_sense_load(): Error reading data\n");
fclose(fp);
}
@@ -654,9 +633,11 @@ scsi_cdrom_mode_sense_load(scsi_cdrom_t *dev)
default:
memset(&dev->ms_pages_saved, 0, sizeof(mode_sense_pages_t));
if (dev->drv->bus_type == CDROM_BUS_SCSI)
memcpy(&dev->ms_pages_saved, &scsi_cdrom_mode_sense_pages_default_scsi, sizeof(mode_sense_pages_t));
memcpy(&dev->ms_pages_saved, &scsi_cdrom_mode_sense_pages_default_scsi,
sizeof(mode_sense_pages_t));
else
memcpy(&dev->ms_pages_saved, &scsi_cdrom_mode_sense_pages_default, sizeof(mode_sense_pages_t));
memcpy(&dev->ms_pages_saved, &scsi_cdrom_mode_sense_pages_default,
sizeof(mode_sense_pages_t));
memset(file_name, 0, 512);
if (dev->drv->bus_type == CDROM_BUS_SCSI)
@@ -839,14 +820,14 @@ scsi_cdrom_mode_sense(scsi_cdrom_t *dev, uint8_t *buf, uint32_t pos, uint8_t pag
else {
if ((i == GPMODE_CAPABILITIES_PAGE) && (j == 4)) {
buf[pos] = scsi_cdrom_mode_sense_read(dev, page_control, i, 2 + j) & 0x1f;
/* The early CD-ROM drives we emulate (NEC CDR-260 for ATAPI and early vendor SCSI CD-ROM models) are
caddy drives, the later ones are tray drives. */
if (dev->drv->bus_type == CDROM_BUS_SCSI) {
/* The early CD-ROM drives we emulate (NEC CDR-260 for ATAPI and
early vendor SCSI CD-ROM models) are caddy drives, the later
ones are tray drives. */
if (dev->drv->bus_type == CDROM_BUS_SCSI)
buf[pos++] |= ((dev->drv->type == CDROM_TYPE_86BOX_100) ? 0x20 : 0x00);
} else {
else
buf[pos++] |= ((dev->drv->type == CDROM_TYPE_NEC_260_100) ||
((dev->drv->type == CDROM_TYPE_NEC_260_101)) ? 0x00 : 0x20);
}
} else if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 6) && (j <= 7)) {
if (j & 1)
buf[pos++] = ((dev->drv->speed * 176) & 0xff);
@@ -881,7 +862,7 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len)
int32_t min_len = 0;
double dlen;
dev->max_transfer_len = dev->request_length;
dev->max_transfer_len = dev->tf->request_length;
/* For media access commands, make sure the requested DRQ length matches the block length. */
switch (dev->current_cdb[0]) {
@@ -936,9 +917,9 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len)
dev->max_transfer_len = 65534;
if ((len <= dev->max_transfer_len) && (len >= min_len))
dev->request_length = dev->max_transfer_len = len;
dev->tf->request_length = dev->max_transfer_len = len;
else if (len > dev->max_transfer_len)
dev->request_length = dev->max_transfer_len;
dev->tf->request_length = dev->max_transfer_len;
return;
}
@@ -969,9 +950,10 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev)
double bytes_per_second = 0.0;
double period;
dev->status = BUSY_STAT;
dev->phase = 1;
dev->pos = 0;
/* MAP: BUSY_STAT, no DRQ, phase 1. */
dev->tf->status = BUSY_STAT;
dev->tf->phase = 1;
dev->tf->pos = 0;
dev->callback = 0;
scsi_cdrom_log("CD-ROM %i: Current speed: %ix\n", dev->id, dev->drv->cur_speed);
@@ -1000,14 +982,10 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev)
dev->callback += period;
fallthrough;
case 0x25:
case 0x42:
case 0x43:
case 0x44:
case 0x51:
case 0x52:
case 0x42 ... 0x44:
case 0x51 ... 0x52:
case 0xad:
case 0xb8:
case 0xb9:
case 0xb8 ... 0xb9:
case 0xbe:
if (dev->current_cdb[0] == 0x42)
dev->callback += 40.0;
@@ -1015,8 +993,7 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev)
bytes_per_second = 176.0 * 1024.0;
bytes_per_second *= (double) dev->drv->cur_speed;
break;
case 0xc6:
case 0xc7:
case 0xc6 ... 0xc7:
switch (dev->drv->type) {
case CDROM_TYPE_TOSHIBA_XM_3433:
case CDROM_TYPE_TOSHIBA_XM3201B_3232:
@@ -1050,8 +1027,7 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev)
bytes_per_second *= (double) dev->drv->cur_speed;
break;
}
case 0xc2:
case 0xc3:
case 0xc2 ... 0xc3:
switch (dev->drv->type) {
case CDROM_TYPE_DEC_RRD45_0436:
case CDROM_TYPE_SONY_CDU541_10i:
@@ -1065,8 +1041,7 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev)
bytes_per_second *= (double) dev->drv->cur_speed;
break;
}
case 0xdd:
case 0xde:
case 0xdd ... 0xde:
switch (dev->drv->type) {
case CDROM_TYPE_NEC_38_103:
case CDROM_TYPE_NEC_211_100:
@@ -1100,7 +1075,7 @@ scsi_cdrom_command_complete(scsi_cdrom_t *dev)
ui_sb_update_icon(SB_CDROM | dev->id, 0);
dev->packet_status = PHASE_COMPLETE;
scsi_cdrom_command_common(dev);
dev->phase = 3;
dev->tf->phase = 3;
}
static void
@@ -1108,7 +1083,7 @@ scsi_cdrom_command_read(scsi_cdrom_t *dev)
{
dev->packet_status = PHASE_DATA_IN;
scsi_cdrom_command_common(dev);
dev->phase = !(dev->packet_status & 0x01) << 1;
dev->tf->phase = !(dev->packet_status & 0x01) << 1;
}
static void
@@ -1123,7 +1098,7 @@ scsi_cdrom_command_write(scsi_cdrom_t *dev)
{
dev->packet_status = PHASE_DATA_OUT;
scsi_cdrom_command_common(dev);
dev->phase = !(dev->packet_status & 0x01) << 1;
dev->tf->phase = !(dev->packet_status & 0x01) << 1;
}
static void
@@ -1142,8 +1117,9 @@ static void
scsi_cdrom_data_command_finish(scsi_cdrom_t *dev, int len, int block_len, int alloc_len, int direction)
{
scsi_cdrom_log("CD-ROM %i: Finishing command (%02X): %i, %i, %i, %i, %i\n",
dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length);
dev->pos = 0;
dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction,
dev->tf->request_length);
dev->tf->pos = 0;
if (alloc_len >= 0) {
if (alloc_len < len)
len = alloc_len;
@@ -1172,7 +1148,8 @@ scsi_cdrom_data_command_finish(scsi_cdrom_t *dev, int len, int block_len, int al
}
scsi_cdrom_log("CD-ROM %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n",
dev->id, dev->packet_status, dev->request_length, dev->packet_len, dev->pos, dev->phase);
dev->id, dev->packet_status, dev->tf->request_length, dev->packet_len, dev->tf->pos,
dev->tf->phase);
}
static void
@@ -1197,12 +1174,12 @@ static void
scsi_cdrom_cmd_error(scsi_cdrom_t *dev)
{
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
dev->error = ((scsi_cdrom_sense_key & 0xf) << 4) | ABRT_ERR;
dev->tf->error = ((scsi_cdrom_sense_key & 0xf) << 4) | ABRT_ERR;
if (dev->unit_attention)
dev->error |= MCR_ERR;
dev->status = READY_STAT | ERR_STAT;
dev->phase = 3;
dev->pos = 0;
dev->tf->error |= MCR_ERR;
dev->tf->status = READY_STAT | ERR_STAT;
dev->tf->phase = 3;
dev->tf->pos = 0;
dev->packet_status = PHASE_ERROR;
dev->callback = 50.0 * CDROM_TIME;
scsi_cdrom_set_callback(dev);
@@ -1214,12 +1191,12 @@ static void
scsi_cdrom_unit_attention(scsi_cdrom_t *dev)
{
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
dev->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR;
dev->tf->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR;
if (dev->unit_attention)
dev->error |= MCR_ERR;
dev->status = READY_STAT | ERR_STAT;
dev->phase = 3;
dev->pos = 0;
dev->tf->error |= MCR_ERR;
dev->tf->status = READY_STAT | ERR_STAT;
dev->tf->phase = 3;
dev->tf->pos = 0;
dev->packet_status = PHASE_ERROR;
dev->callback = 50.0 * CDROM_TIME;
scsi_cdrom_set_callback(dev);
@@ -1298,7 +1275,7 @@ scsi_cdrom_invalid_field(scsi_cdrom_t *dev)
scsi_cdrom_asc = ASC_INV_FIELD_IN_CMD_PACKET;
scsi_cdrom_ascq = 0;
scsi_cdrom_cmd_error(dev);
dev->status = 0x53;
dev->tf->status = 0x53;
}
static void
@@ -1308,7 +1285,7 @@ scsi_cdrom_invalid_field_pl(scsi_cdrom_t *dev)
scsi_cdrom_asc = ASC_INV_FIELD_IN_PARAMETER_LIST;
scsi_cdrom_ascq = 0;
scsi_cdrom_cmd_error(dev);
dev->status = 0x53;
dev->tf->status = 0x53;
}
static void
@@ -1575,7 +1552,7 @@ scsi_cdrom_pre_execution_check(scsi_cdrom_t *dev, uint8_t *cdb)
if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) {
scsi_cdrom_log("CD-ROM %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n",
dev->id, ((dev->request_length >> 5) & 7));
dev->id, ((dev->tf->request_length >> 5) & 7));
scsi_cdrom_invalid_lun(dev);
return 0;
}
@@ -1674,11 +1651,11 @@ scsi_cdrom_reset(scsi_common_t *sc)
return;
scsi_cdrom_rezero(dev);
dev->status = 0;
dev->tf->status = 0;
dev->callback = 0.0;
scsi_cdrom_set_callback(dev);
dev->phase = 1;
dev->request_length = 0xEB14;
dev->tf->phase = 1;
dev->tf->request_length = 0xeb14;
dev->packet_status = PHASE_NONE;
dev->unit_attention = 0xff;
dev->cur_lun = SCSI_LUN_USE_CDB;
@@ -1793,10 +1770,10 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb)
if (dev->drv->bus_type == CDROM_BUS_SCSI) {
BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length;
dev->status &= ~ERR_STAT;
dev->tf->status &= ~ERR_STAT;
} else {
BufLen = &blen;
dev->error = 0;
dev->tf->error = 0;
}
dev->packet_len = 0;
@@ -1814,11 +1791,12 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb)
if (cdb[0] != 0) {
scsi_cdrom_log("CD-ROM %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n",
dev->id, cdb[0], scsi_cdrom_sense_key, scsi_cdrom_asc, scsi_cdrom_ascq, dev->unit_attention);
scsi_cdrom_log("CD-ROM %i: Request length: %04X\n", dev->id, dev->request_length);
dev->id, cdb[0], scsi_cdrom_sense_key, scsi_cdrom_asc, scsi_cdrom_ascq,
dev->unit_attention);
scsi_cdrom_log("CD-ROM %i: Request length: %04X\n", dev->id, dev->tf->request_length);
scsi_cdrom_log("CD-ROM %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id,
cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7],
scsi_cdrom_log("CD-ROM %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
dev->id, cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7],
cdb[8], cdb[9], cdb[10], cdb[11]);
}
@@ -3727,9 +3705,10 @@ atapi_out:
break;
}
/* scsi_cdrom_log("CD-ROM %i: Phase: %02X, request length: %i\n", dev->phase, dev->request_length); */
/* scsi_cdrom_log("CD-ROM %i: Phase: %02X, request length: %i\n", dev->tf->phase,
dev->tf->request_length); */
if (scsi_cdrom_atapi_phase_to_scsi(dev) == SCSI_PHASE_STATUS)
if ((dev->packet_status == PHASE_COMPLETE) || (dev->packet_status == PHASE_ERROR))
scsi_cdrom_buf_free(dev);
}
@@ -3905,6 +3884,9 @@ scsi_cdrom_close(void *priv)
{
scsi_cdrom_t *dev = (scsi_cdrom_t *) priv;
if (dev->tf)
free(dev->tf);
if (dev)
free(dev);
}
@@ -4086,6 +4068,7 @@ scsi_cdrom_drive_reset(int c)
ide_t *id;
uint8_t scsi_bus = (drv->scsi_device_id >> 4) & 0x0f;
uint8_t scsi_id = drv->scsi_device_id & 0x0f;
uint8_t valid = 0;
if (drv->bus_type == CDROM_BUS_SCSI) {
/* Make sure to ignore any SCSI CD-ROM drive that has an out of range SCSI bus. */
@@ -4118,9 +4101,12 @@ scsi_cdrom_drive_reset(int c)
drv->get_channel = scsi_cdrom_get_channel;
drv->close = scsi_cdrom_close;
scsi_cdrom_init(dev);
if (drv->bus_type == CDROM_BUS_SCSI) {
valid = 1;
if (!dev->tf)
dev->tf = (ide_tf_t *) calloc(1, sizeof(ide_tf_t));
/* SCSI CD-ROM, attach to the SCSI bus. */
sd = &scsi_devices[scsi_bus][scsi_id];
@@ -4140,7 +4126,12 @@ scsi_cdrom_drive_reset(int c)
otherwise, we do nothing - it's going to be a drive
that's not attached to anything. */
if (id) {
valid = 1;
id->sc = (scsi_common_t *) dev;
dev->tf = id->tf;
if ((dev->drv->type == CDROM_TYPE_NEC_260_100) || (dev->drv->type == CDROM_TYPE_NEC_260_101))
IDE_ATAPI_IS_EARLY = 1;
id->get_max = scsi_cdrom_get_max;
id->get_timings = scsi_cdrom_get_timings;
id->identify = scsi_cdrom_identify;
@@ -4158,4 +4149,7 @@ scsi_cdrom_drive_reset(int c)
scsi_cdrom_log("ATAPI CD-ROM drive %i attached to IDE channel %i\n", c, cdrom[c].ide_channel);
}
if (valid)
scsi_cdrom_init(dev);
}

View File

@@ -23,6 +23,7 @@
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/hdd.h>
#include <86box/hdc_ide.h>
#include <86box/scsi.h>
#include <86box/scsi_device.h>
#include <86box/plat_unused.h>
@@ -37,7 +38,7 @@ scsi_device_target_command(scsi_device_t *dev, uint8_t *cdb)
if (dev->command) {
dev->command(dev->sc, cdb);
if (dev->sc->status & ERR_STAT)
if (dev->sc->tf->status & ERR_STAT)
return SCSI_STATUS_CHECK_CONDITION;
else
return SCSI_STATUS_OK;
@@ -140,7 +141,7 @@ scsi_device_command_phase1(scsi_device_t *dev)
} else
scsi_device_command_stop(dev);
if (dev->sc->status & ERR_STAT)
if (dev->sc->tf->status & ERR_STAT)
dev->status = SCSI_STATUS_CHECK_CONDITION;
else
dev->status = SCSI_STATUS_OK;

File diff suppressed because it is too large Load Diff