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 void
pc_send_cae(void) pc_send_cae(void)
{ {
pc_send_ca(1); // pc_send_ca(1);
picint(1 << 14);
} }
void void

View File

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

View File

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

View File

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

View File

@@ -24,6 +24,7 @@
#define HAVE_STDARG_H #define HAVE_STDARG_H
#include <86box/86box.h> #include <86box/86box.h>
#include <86box/machine.h> #include <86box/machine.h>
#include <86box/timer.h>
#include <86box/device.h> #include <86box/device.h>
#include <86box/hdc.h> #include <86box/hdc.h>
#include <86box/hdc_ide.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/io.h>
#include <86box/mem.h> #include <86box/mem.h>
#include <86box/rom.h> #include <86box/rom.h>
#include <86box/timer.h>
#include <86box/device.h> #include <86box/device.h>
#include <86box/hdc.h> #include <86box/hdc.h>
#include <86box/hdc_ide.h> #include <86box/hdc_ide.h>

View File

@@ -49,6 +49,8 @@
# include <unistd.h> # include <unistd.h>
#endif #endif
#define IDE_ATAPI_IS_EARLY id->sc->pad0
mo_drive_t mo_drives[MO_NUM]; mo_drive_t mo_drives[MO_NUM];
/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ /* 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; 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); 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) { if (dev->drv->bus_type < MO_BUS_SCSI) {
dev->phase = 1; dev->tf->phase = 1;
dev->request_length = 0xEB14; dev->tf->request_length = 0xEB14;
} }
dev->status = READY_STAT | DSC_STAT; dev->tf->status = READY_STAT | DSC_STAT;
dev->pos = 0; dev->tf->pos = 0;
dev->packet_status = PHASE_NONE; dev->packet_status = PHASE_NONE;
mo_sense_key = mo_asc = mo_ascq = dev->unit_attention = 0; 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)) if (!mo_supports_pio(dev) && mo_supports_dma(dev))
return 2; return 2;
if (mo_supports_pio(dev) && mo_supports_dma(dev)) { 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"); mo_log("MO %i: Drive supports both, setting to %s\n", dev->id,
return (dev->features & 1) ? 2 : 1; (dev->tf->features & 1) ? "DMA" : "PIO");
} return (dev->tf->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;
} }
return 0; return 0;
@@ -622,7 +597,7 @@ mo_update_request_length(mo_t *dev, int len, int block_len)
int bt; int bt;
int min_len = 0; 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. */ /* For media access commands, make sure the requested DRQ length matches the block length. */
switch (dev->current_cdb[0]) { 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; dev->max_transfer_len = 65534;
if ((len <= dev->max_transfer_len) && (len >= min_len)) 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) else if (len > dev->max_transfer_len)
dev->request_length = dev->max_transfer_len; dev->tf->request_length = dev->max_transfer_len;
return; return;
} }
@@ -699,9 +674,9 @@ mo_command_common(mo_t *dev)
double bytes_per_second; double bytes_per_second;
double period; double period;
dev->status = BUSY_STAT; dev->tf->status = BUSY_STAT;
dev->phase = 1; dev->tf->phase = 1;
dev->pos = 0; dev->tf->pos = 0;
if (dev->packet_status == PHASE_COMPLETE) if (dev->packet_status == PHASE_COMPLETE)
dev->callback = 0.0; dev->callback = 0.0;
else { 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_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", 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->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->tf->request_length);
dev->pos = 0; dev->tf->pos = 0;
if (alloc_len >= 0) { if (alloc_len >= 0) {
if (alloc_len < len) if (alloc_len < len)
len = alloc_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", 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 static void
@@ -818,14 +794,14 @@ static void
mo_cmd_error(mo_t *dev) mo_cmd_error(mo_t *dev)
{ {
mo_set_phase(dev, SCSI_PHASE_STATUS); 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) if (dev->unit_attention)
dev->error |= MCR_ERR; dev->tf->error |= MCR_ERR;
dev->status = READY_STAT | ERR_STAT; dev->tf->status = READY_STAT | ERR_STAT;
dev->phase = 3; dev->tf->phase = 3;
dev->pos = 0; dev->tf->pos = 0;
dev->packet_status = PHASE_ERROR; dev->packet_status = PHASE_ERROR;
dev->callback = 50.0 * MO_TIME; dev->callback = 50.0 * MO_TIME;
mo_set_callback(dev); mo_set_callback(dev);
ui_sb_update_icon(SB_MO | dev->id, 0); ui_sb_update_icon(SB_MO | dev->id, 0);
mo_log("MO %i: [%02X] ERROR: %02X/%02X/%02X\n", dev->id, dev->current_cdb[0], mo_sense_key, mo_asc, mo_ascq); mo_log("MO %i: [%02X] ERROR: %02X/%02X/%02X\n", dev->id, dev->current_cdb[0], mo_sense_key, mo_asc, mo_ascq);
@@ -835,14 +811,14 @@ static void
mo_unit_attention(mo_t *dev) mo_unit_attention(mo_t *dev)
{ {
mo_set_phase(dev, SCSI_PHASE_STATUS); 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) if (dev->unit_attention)
dev->error |= MCR_ERR; dev->tf->error |= MCR_ERR;
dev->status = READY_STAT | ERR_STAT; dev->tf->status = READY_STAT | ERR_STAT;
dev->phase = 3; dev->tf->phase = 3;
dev->pos = 0; dev->tf->pos = 0;
dev->packet_status = PHASE_ERROR; dev->packet_status = PHASE_ERROR;
dev->callback = 50.0 * MO_TIME; dev->callback = 50.0 * MO_TIME;
mo_set_callback(dev); mo_set_callback(dev);
ui_sb_update_icon(SB_MO | dev->id, 0); ui_sb_update_icon(SB_MO | dev->id, 0);
mo_log("MO %i: UNIT ATTENTION\n", dev->id); mo_log("MO %i: UNIT ATTENTION\n", dev->id);
@@ -928,7 +904,7 @@ mo_invalid_field(mo_t *dev)
mo_asc = ASC_INV_FIELD_IN_CMD_PACKET; mo_asc = ASC_INV_FIELD_IN_CMD_PACKET;
mo_ascq = 0; mo_ascq = 0;
mo_cmd_error(dev); mo_cmd_error(dev);
dev->status = 0x53; dev->tf->status = 0x53;
} }
static void static void
@@ -938,7 +914,7 @@ mo_invalid_field_pl(mo_t *dev)
mo_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; mo_asc = ASC_INV_FIELD_IN_PARAMETER_LIST;
mo_ascq = 0; mo_ascq = 0;
mo_cmd_error(dev); mo_cmd_error(dev);
dev->status = 0x53; dev->tf->status = 0x53;
} }
static int static int
@@ -1112,7 +1088,8 @@ mo_pre_execution_check(mo_t *dev, uint8_t *cdb)
int ready = 0; int ready = 0;
if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) { 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); mo_invalid_lun(dev);
return 0; return 0;
} }
@@ -1202,14 +1179,14 @@ mo_reset(scsi_common_t *sc)
mo_t *dev = (mo_t *) sc; mo_t *dev = (mo_t *) sc;
mo_rezero(dev); mo_rezero(dev);
dev->status = 0; dev->tf->status = 0;
dev->callback = 0.0; dev->callback = 0.0;
mo_set_callback(dev); mo_set_callback(dev);
dev->phase = 1; dev->tf->phase = 1;
dev->request_length = 0xEB14; dev->tf->request_length = 0xEB14;
dev->packet_status = PHASE_NONE; dev->packet_status = PHASE_NONE;
dev->unit_attention = 0; dev->unit_attention = 0;
dev->cur_lun = SCSI_LUN_USE_CDB; dev->cur_lun = SCSI_LUN_USE_CDB;
} }
static void static void
@@ -1302,11 +1279,11 @@ mo_command(scsi_common_t *sc, uint8_t *cdb)
uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f;
if (dev->drv->bus_type == MO_BUS_SCSI) { if (dev->drv->bus_type == MO_BUS_SCSI) {
BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length;
dev->status &= ~ERR_STAT; dev->tf->status &= ~ERR_STAT;
} else { } else {
BufLen = &blen; BufLen = &blen;
dev->error = 0; dev->tf->error = 0;
} }
dev->packet_len = 0; dev->packet_len = 0;
@@ -1319,7 +1296,7 @@ mo_command(scsi_common_t *sc, uint8_t *cdb)
if (cdb[0] != 0) { if (cdb[0] != 0) {
mo_log("MO %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", 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); 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, 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], 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 #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 #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); mo_buf_free(dev);
} }
@@ -2099,6 +2076,9 @@ mo_drive_reset(int c)
dev->cur_lun = SCSI_LUN_USE_CDB; dev->cur_lun = SCSI_LUN_USE_CDB;
if (mo_drives[c].bus_type == MO_BUS_SCSI) { 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. */ /* SCSI MO, attach to the SCSI bus. */
sd = &scsi_devices[scsi_bus][scsi_id]; sd = &scsi_devices[scsi_bus][scsi_id];
@@ -2117,6 +2097,8 @@ mo_drive_reset(int c)
that's not attached to anything. */ that's not attached to anything. */
if (id) { if (id) {
id->sc = (scsi_common_t *) dev; id->sc = (scsi_common_t *) dev;
dev->tf = id->tf;
IDE_ATAPI_IS_EARLY = 0;
id->get_max = mo_get_max; id->get_max = mo_get_max;
id->get_timings = mo_get_timings; id->get_timings = mo_get_timings;
id->identify = mo_identify; id->identify = mo_identify;
@@ -2203,6 +2185,9 @@ mo_close(void)
if (dev) { if (dev) {
mo_disk_unload(dev); mo_disk_unload(dev);
if (dev->tf)
free(dev->tf);
free(dev); free(dev);
mo_drives[c].priv = NULL; mo_drives[c].priv = NULL;
} }

View File

@@ -36,6 +36,8 @@
#include <86box/hdc_ide.h> #include <86box/hdc_ide.h>
#include <86box/zip.h> #include <86box/zip.h>
#define IDE_ATAPI_IS_EARLY id->sc->pad0
zip_drive_t zip_drives[ZIP_NUM]; zip_drive_t zip_drives[ZIP_NUM];
/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ /* 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; 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); 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) { if (dev->drv->bus_type < ZIP_BUS_SCSI) {
dev->phase = 1; dev->tf->phase = 1;
dev->request_length = 0xEB14; dev->tf->request_length = 0xEB14;
} }
dev->status = READY_STAT | DSC_STAT; dev->tf->status = READY_STAT | DSC_STAT;
dev->pos = 0; dev->tf->pos = 0;
dev->packet_status = PHASE_NONE; dev->packet_status = PHASE_NONE;
zip_sense_key = zip_asc = zip_ascq = dev->unit_attention = 0; 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)) if (!zip_supports_pio(dev) && zip_supports_dma(dev))
return 2; return 2;
if (zip_supports_pio(dev) && zip_supports_dma(dev)) { 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"); zip_log("ZIP %i: Drive supports both, setting to %s\n", dev->id,
return (dev->features & 1) ? 2 : 1; (dev->tf->features & 1) ? "DMA" : "PIO");
} return (dev->tf->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;
} }
return 0; return 0;
@@ -791,7 +766,7 @@ zip_update_request_length(zip_t *dev, int len, int block_len)
int bt; int bt;
int min_len = 0; 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. */ /* For media access commands, make sure the requested DRQ length matches the block length. */
switch (dev->current_cdb[0]) { 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; dev->max_transfer_len = 65534;
if ((len <= dev->max_transfer_len) && (len >= min_len)) 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) else if (len > dev->max_transfer_len)
dev->request_length = dev->max_transfer_len; dev->tf->request_length = dev->max_transfer_len;
return; return;
} }
@@ -868,9 +843,9 @@ zip_command_common(zip_t *dev)
double bytes_per_second; double bytes_per_second;
double period; double period;
dev->status = BUSY_STAT; dev->tf->status = BUSY_STAT;
dev->phase = 1; dev->tf->phase = 1;
dev->pos = 0; dev->tf->pos = 0;
if (dev->packet_status == PHASE_COMPLETE) if (dev->packet_status == PHASE_COMPLETE)
dev->callback = 0.0; dev->callback = 0.0;
else { 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_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", 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->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->tf->request_length);
dev->pos = 0; dev->tf->pos = 0;
if (alloc_len >= 0) { if (alloc_len >= 0) {
if (alloc_len < len) if (alloc_len < len)
len = alloc_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", 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 static void
@@ -987,12 +963,12 @@ static void
zip_cmd_error(zip_t *dev) zip_cmd_error(zip_t *dev)
{ {
zip_set_phase(dev, SCSI_PHASE_STATUS); 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) if (dev->unit_attention)
dev->error |= MCR_ERR; dev->tf->error |= MCR_ERR;
dev->status = READY_STAT | ERR_STAT; dev->tf->status = READY_STAT | ERR_STAT;
dev->phase = 3; dev->tf->phase = 3;
dev->pos = 0; dev->tf->pos = 0;
dev->packet_status = PHASE_ERROR; dev->packet_status = PHASE_ERROR;
dev->callback = 50.0 * ZIP_TIME; dev->callback = 50.0 * ZIP_TIME;
zip_set_callback(dev); zip_set_callback(dev);
@@ -1004,12 +980,12 @@ static void
zip_unit_attention(zip_t *dev) zip_unit_attention(zip_t *dev)
{ {
zip_set_phase(dev, SCSI_PHASE_STATUS); 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) if (dev->unit_attention)
dev->error |= MCR_ERR; dev->tf->error |= MCR_ERR;
dev->status = READY_STAT | ERR_STAT; dev->tf->status = READY_STAT | ERR_STAT;
dev->phase = 3; dev->tf->phase = 3;
dev->pos = 0; dev->tf->pos = 0;
dev->packet_status = PHASE_ERROR; dev->packet_status = PHASE_ERROR;
dev->callback = 50.0 * ZIP_TIME; dev->callback = 50.0 * ZIP_TIME;
zip_set_callback(dev); zip_set_callback(dev);
@@ -1097,7 +1073,7 @@ zip_invalid_field(zip_t *dev)
zip_asc = ASC_INV_FIELD_IN_CMD_PACKET; zip_asc = ASC_INV_FIELD_IN_CMD_PACKET;
zip_ascq = 0; zip_ascq = 0;
zip_cmd_error(dev); zip_cmd_error(dev);
dev->status = 0x53; dev->tf->status = 0x53;
} }
static void static void
@@ -1107,7 +1083,7 @@ zip_invalid_field_pl(zip_t *dev)
zip_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; zip_asc = ASC_INV_FIELD_IN_PARAMETER_LIST;
zip_ascq = 0; zip_ascq = 0;
zip_cmd_error(dev); zip_cmd_error(dev);
dev->status = 0x53; dev->tf->status = 0x53;
} }
static void static void
@@ -1184,7 +1160,8 @@ zip_pre_execution_check(zip_t *dev, uint8_t *cdb)
int ready = 0; int ready = 0;
if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) { 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); zip_invalid_lun(dev);
return 0; return 0;
} }
@@ -1274,14 +1251,14 @@ zip_reset(scsi_common_t *sc)
zip_t *dev = (zip_t *) sc; zip_t *dev = (zip_t *) sc;
zip_rezero(dev); zip_rezero(dev);
dev->status = 0; dev->tf->status = 0;
dev->callback = 0.0; dev->callback = 0.0;
zip_set_callback(dev); zip_set_callback(dev);
dev->phase = 1; dev->tf->phase = 1;
dev->request_length = 0xEB14; dev->tf->request_length = 0xEB14;
dev->packet_status = PHASE_NONE; dev->packet_status = PHASE_NONE;
dev->unit_attention = 0; dev->unit_attention = 0;
dev->cur_lun = SCSI_LUN_USE_CDB; dev->cur_lun = SCSI_LUN_USE_CDB;
} }
static void static void
@@ -1373,11 +1350,11 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f;
if (dev->drv->bus_type == ZIP_BUS_SCSI) { if (dev->drv->bus_type == ZIP_BUS_SCSI) {
BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length;
dev->status &= ~ERR_STAT; dev->tf->status &= ~ERR_STAT;
} else { } else {
BufLen = &blen; BufLen = &blen;
dev->error = 0; dev->tf->error = 0;
} }
dev->packet_len = 0; dev->packet_len = 0;
@@ -1388,7 +1365,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
if (cdb[0] != 0) { if (cdb[0] != 0) {
zip_log("ZIP %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", 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); 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, 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], 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; break;
case GPCMD_REQUEST_SENSE: case GPCMD_REQUEST_SENSE:
/* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE /* If there's a unit attention condition and there's a buffered not
should forget about the not ready, and report unit attention straight away. */ 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); zip_set_phase(dev, SCSI_PHASE_DATA_IN);
max_len = cdb[4]; max_len = cdb[4];
@@ -1507,7 +1485,14 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
switch (cdb[0]) { switch (cdb[0]) {
case GPCMD_READ_6: case GPCMD_READ_6:
dev->sector_len = cdb[4]; 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); zip_log("ZIP %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos);
break; break;
case GPCMD_READ_10: 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); zip_log("ZIP %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos);
break; break;
case GPCMD_READ_12: 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_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) |
dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); (((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; break;
default: default:
break; break;
} }
if (dev->sector_pos >= dev->drv->medium_size) {
zip_lba_out_of_range(dev);
return;
}
if (!dev->sector_len) { if (!dev->sector_len) {
zip_set_phase(dev, SCSI_PHASE_STATUS); zip_set_phase(dev, SCSI_PHASE_STATUS);
/* zip_log("ZIP %i: All done - callback set\n", dev->id); */ /* 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; 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 If we're reading all blocks in one go for DMA, why not also for
transferred to the host should be different. */ 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; dev->packet_len = max_len * alloc_length;
zip_buf_alloc(dev, dev->packet_len); 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); 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, dev->packet_status != PHASE_COMPLETE);
ui_sb_update_icon(SB_ZIP | dev->id, 1);
else
ui_sb_update_icon(SB_ZIP | dev->id, 0);
return; return;
case GPCMD_VERIFY_6: case GPCMD_VERIFY_6:
@@ -1590,9 +1583,14 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
case GPCMD_VERIFY_6: case GPCMD_VERIFY_6:
case GPCMD_WRITE_6: case GPCMD_WRITE_6:
dev->sector_len = cdb[4]; 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) 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_len = 256;
dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) |
(((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]);
break; break;
case GPCMD_VERIFY_10: case GPCMD_VERIFY_10:
case GPCMD_WRITE_10: case GPCMD_WRITE_10:
@@ -1604,17 +1602,17 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
case GPCMD_VERIFY_12: case GPCMD_VERIFY_12:
case GPCMD_WRITE_12: case GPCMD_WRITE_12:
case GPCMD_WRITE_AND_VERIFY_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_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) |
dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); (((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; break;
default: default:
break; break;
} }
if ((dev->sector_pos >= dev->drv->medium_size) /* || if (dev->sector_pos >= dev->drv->medium_size) {
((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)*/
) {
zip_lba_out_of_range(dev); zip_lba_out_of_range(dev);
return; return;
} }
@@ -1629,9 +1627,13 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
} }
max_len = dev->sector_len; 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 If we're writing all blocks in one go for DMA, why not also for
transferred to the host should be different. */ 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; dev->packet_len = max_len * alloc_length;
zip_buf_alloc(dev, dev->packet_len); 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); 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, dev->packet_status != PHASE_COMPLETE);
ui_sb_update_icon(SB_ZIP | dev->id, 1);
else
ui_sb_update_icon(SB_ZIP | dev->id, 0);
return; return;
case GPCMD_WRITE_SAME_10: 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_len = (cdb[7] << 8) | cdb[8];
dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5];
if ((dev->sector_pos >= dev->drv->medium_size) /* || if (dev->sector_pos >= dev->drv->medium_size) {
((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)*/
) {
zip_lba_out_of_range(dev); zip_lba_out_of_range(dev);
return; return;
} }
@@ -1693,10 +1690,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
zip_data_command_finish(dev, 512, 512, alloc_length, 1); zip_data_command_finish(dev, 512, 512, alloc_length, 1);
if (dev->packet_status != PHASE_COMPLETE) ui_sb_update_icon(SB_ZIP | dev->id, dev->packet_status != PHASE_COMPLETE);
ui_sb_update_icon(SB_ZIP | dev->id, 1);
else
ui_sb_update_icon(SB_ZIP | dev->id, 0);
return; return;
case GPCMD_MODE_SENSE_6: case GPCMD_MODE_SENSE_6:
@@ -2034,10 +2028,10 @@ atapi_out:
} }
#if 0 #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 #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); zip_buf_free(dev);
} }
@@ -2321,6 +2315,9 @@ zip_drive_reset(int c)
dev->cur_lun = SCSI_LUN_USE_CDB; dev->cur_lun = SCSI_LUN_USE_CDB;
if (zip_drives[c].bus_type == ZIP_BUS_SCSI) { 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. */ /* SCSI ZIP, attach to the SCSI bus. */
sd = &scsi_devices[scsi_bus][scsi_id]; sd = &scsi_devices[scsi_bus][scsi_id];
@@ -2339,6 +2336,8 @@ zip_drive_reset(int c)
that's not attached to anything. */ that's not attached to anything. */
if (id) { if (id) {
id->sc = (scsi_common_t *) dev; id->sc = (scsi_common_t *) dev;
dev->tf = id->tf;
IDE_ATAPI_IS_EARLY = 0;
id->get_max = zip_get_max; id->get_max = zip_get_max;
id->get_timings = zip_get_timings; id->get_timings = zip_get_timings;
id->identify = zip_identify; id->identify = zip_identify;
@@ -2425,6 +2424,9 @@ zip_close(void)
if (dev) { if (dev) {
zip_disk_unload(dev); zip_disk_unload(dev);
if (dev->tf)
free(dev->tf);
free(dev); free(dev);
zip_drives[c].priv = NULL; zip_drives[c].priv = NULL;
} }

View File

@@ -41,13 +41,46 @@ enum {
IDE_ATAPI 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 { 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 atastat;
uint8_t error; uint8_t error;
uint16_t pad;
uint32_t pos;
#endif
/* The rest. */
uint8_t selected;
uint8_t command; uint8_t command;
uint8_t fdisk; uint8_t head;
uint8_t sector;
int type; int type;
int board; int board;
int irqstat; int irqstat;
@@ -56,18 +89,12 @@ typedef struct ide_s {
int blockcount; int blockcount;
int hdd_num; int hdd_num;
int channel; int channel;
int pos;
int sector_pos; int sector_pos;
int lba; int lba;
int reset; int reset;
int mdma_mode; int mdma_mode;
int do_initial_read; int do_initial_read;
uint32_t secount;
uint32_t sector;
uint32_t cylinder;
uint32_t head;
uint32_t drive; uint32_t drive;
uint32_t cylprecomp;
uint32_t cfg_spt; uint32_t cfg_spt;
uint32_t cfg_hpc; uint32_t cfg_hpc;
uint32_t lba_addr; uint32_t lba_addr;
@@ -80,11 +107,19 @@ typedef struct ide_s {
pc_timer_t timer; pc_timer_t timer;
/* Task file. */
ide_tf_t * tf;
/* Stuff mostly used by ATAPI */ /* Stuff mostly used by ATAPI */
#ifdef SCSI_DEVICE_H
scsi_common_t *sc; scsi_common_t *sc;
#else
void * sc;
#endif
int interrupt_drq; int interrupt_drq;
double pending_delay; double pending_delay;
#ifdef SCSI_DEVICE_H
int (*get_max)(int ide_has_dma, int type); int (*get_max)(int ide_has_dma, int type);
int (*get_timings)(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); 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); uint8_t (*phase_data_out)(scsi_common_t *sc);
void (*command_stop)(scsi_common_t *sc); void (*command_stop)(scsi_common_t *sc);
void (*bus_master_error)(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; } ide_t;
#ifdef EMU_HDC_H
extern ide_t *ide_drives[IDE_NUM]; extern ide_t *ide_drives[IDE_NUM];
#endif #endif
#endif
/* Type: /* Type:
0 = PIO, 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_eject(uint8_t id);
extern void win_cdrom_reload(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_base_addr(int board, int base, uint16_t port);
extern void ide_set_side(int board, uint16_t port);
extern void ide_set_handlers(uint8_t board); extern void ide_handlers(uint8_t board, int set);
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_board_set_force_ata3(int board, int force_ata3); extern void ide_board_set_force_ata3(int board, int force_ata3);
#ifdef EMU_ISAPNP_H #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_75(void);
extern uint8_t ide_read_ali_76(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*/ #endif /*EMU_IDE_H*/

View File

@@ -148,7 +148,8 @@ typedef struct hard_disk_t {
uint8_t scsi_id; uint8_t scsi_id;
}; };
uint8_t bus; 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 wp; /* Disk has been mounted READ-ONLY */
uint8_t pad; uint8_t pad;
uint8_t pad0; uint8_t pad0;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -41,6 +41,8 @@
#include <86box/scsi_cdrom.h> #include <86box/scsi_cdrom.h>
#include <86box/version.h> #include <86box/version.h>
#define IDE_ATAPI_IS_EARLY id->sc->pad0
#pragma pack(push, 1) #pragma pack(push, 1)
typedef struct gesn_cdb_t { typedef struct gesn_cdb_t {
uint8_t opcode; uint8_t opcode;
@@ -516,15 +518,17 @@ scsi_cdrom_init(scsi_cdrom_t *dev)
dev->drv->bus_mode |= 2; dev->drv->bus_mode |= 2;
if (dev->drv->bus_type < CDROM_BUS_SCSI) if (dev->drv->bus_type < CDROM_BUS_SCSI)
dev->drv->bus_mode |= 1; 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[0] = 0xf0;
dev->sense[7] = 10; dev->sense[7] = 10;
if ((dev->drv->type == CDROM_TYPE_NEC_260_100) || (dev->drv->type == CDROM_TYPE_NEC_260_101)) /*NEC only*/ /* NEC only */
dev->status = READY_STAT | DSC_STAT; 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 else
dev->status = 0; dev->tf->status = 0;
dev->pos = 0; dev->tf->pos = 0;
dev->packet_status = PHASE_NONE; dev->packet_status = PHASE_NONE;
scsi_cdrom_sense_key = scsi_cdrom_asc = scsi_cdrom_ascq = dev->unit_attention = 0; scsi_cdrom_sense_key = scsi_cdrom_asc = scsi_cdrom_ascq = dev->unit_attention = 0;
dev->drv->cur_speed = dev->drv->speed; dev->drv->cur_speed = dev->drv->speed;
@@ -541,37 +545,9 @@ scsi_cdrom_current_mode(scsi_cdrom_t *dev)
return 2; return 2;
else if (dev->drv->bus_type == CDROM_BUS_ATAPI) { else if (dev->drv->bus_type == CDROM_BUS_ATAPI) {
scsi_cdrom_log("CD-ROM %i: ATAPI drive, setting to %s\n", dev->id, 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); dev->id);
return (dev->features & 1) ? 2 : 1; return (dev->tf->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 0; return 0;
@@ -617,7 +593,8 @@ scsi_cdrom_get_volume(void *priv, int channel)
case CDROM_TYPE_SONY_CDU561_18k: case CDROM_TYPE_SONY_CDU561_18k:
case CDROM_TYPE_SONY_CDU76S_100: case CDROM_TYPE_SONY_CDU76S_100:
case CDROM_TYPE_TEXEL_DMXX24_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; break;
default: default:
ret = dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE][channel ? 11 : 9]; 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_SONY_CDU76S_100:
case CDROM_TYPE_TEXEL_DMXX24_100: case CDROM_TYPE_TEXEL_DMXX24_100:
memset(&dev->ms_pages_saved_sony, 0, sizeof(mode_sense_pages_t)); 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); memset(file_name, 0, 512);
sprintf(file_name, "scsi_cdrom_%02i_mode_sense_sony_bin", dev->id); sprintf(file_name, "scsi_cdrom_%02i_mode_sense_sony_bin", dev->id);
fp = plat_fopen(nvr_path(file_name), "rb"); fp = plat_fopen(nvr_path(file_name), "rb");
if (fp) { 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"); fatal("scsi_cdrom_mode_sense_load(): Error reading data\n");
fclose(fp); fclose(fp);
} }
@@ -654,9 +633,11 @@ scsi_cdrom_mode_sense_load(scsi_cdrom_t *dev)
default: default:
memset(&dev->ms_pages_saved, 0, sizeof(mode_sense_pages_t)); memset(&dev->ms_pages_saved, 0, sizeof(mode_sense_pages_t));
if (dev->drv->bus_type == CDROM_BUS_SCSI) 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 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); memset(file_name, 0, 512);
if (dev->drv->bus_type == CDROM_BUS_SCSI) 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 { else {
if ((i == GPMODE_CAPABILITIES_PAGE) && (j == 4)) { if ((i == GPMODE_CAPABILITIES_PAGE) && (j == 4)) {
buf[pos] = scsi_cdrom_mode_sense_read(dev, page_control, i, 2 + j) & 0x1f; 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 /* The early CD-ROM drives we emulate (NEC CDR-260 for ATAPI and
caddy drives, the later ones are tray drives. */ early vendor SCSI CD-ROM models) are caddy drives, the later
if (dev->drv->bus_type == CDROM_BUS_SCSI) { ones are tray drives. */
if (dev->drv->bus_type == CDROM_BUS_SCSI)
buf[pos++] |= ((dev->drv->type == CDROM_TYPE_86BOX_100) ? 0x20 : 0x00); buf[pos++] |= ((dev->drv->type == CDROM_TYPE_86BOX_100) ? 0x20 : 0x00);
} else { else
buf[pos++] |= ((dev->drv->type == CDROM_TYPE_NEC_260_100) || buf[pos++] |= ((dev->drv->type == CDROM_TYPE_NEC_260_100) ||
((dev->drv->type == CDROM_TYPE_NEC_260_101)) ? 0x00 : 0x20); ((dev->drv->type == CDROM_TYPE_NEC_260_101)) ? 0x00 : 0x20);
}
} else if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 6) && (j <= 7)) { } else if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 6) && (j <= 7)) {
if (j & 1) if (j & 1)
buf[pos++] = ((dev->drv->speed * 176) & 0xff); 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; int32_t min_len = 0;
double dlen; 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. */ /* For media access commands, make sure the requested DRQ length matches the block length. */
switch (dev->current_cdb[0]) { 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; dev->max_transfer_len = 65534;
if ((len <= dev->max_transfer_len) && (len >= min_len)) 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) else if (len > dev->max_transfer_len)
dev->request_length = dev->max_transfer_len; dev->tf->request_length = dev->max_transfer_len;
return; return;
} }
@@ -969,10 +950,11 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev)
double bytes_per_second = 0.0; double bytes_per_second = 0.0;
double period; double period;
dev->status = BUSY_STAT; /* MAP: BUSY_STAT, no DRQ, phase 1. */
dev->phase = 1; dev->tf->status = BUSY_STAT;
dev->pos = 0; dev->tf->phase = 1;
dev->callback = 0; dev->tf->pos = 0;
dev->callback = 0;
scsi_cdrom_log("CD-ROM %i: Current speed: %ix\n", dev->id, dev->drv->cur_speed); 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; dev->callback += period;
fallthrough; fallthrough;
case 0x25: case 0x25:
case 0x42: case 0x42 ... 0x44:
case 0x43: case 0x51 ... 0x52:
case 0x44:
case 0x51:
case 0x52:
case 0xad: case 0xad:
case 0xb8: case 0xb8 ... 0xb9:
case 0xb9:
case 0xbe: case 0xbe:
if (dev->current_cdb[0] == 0x42) if (dev->current_cdb[0] == 0x42)
dev->callback += 40.0; 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 = 176.0 * 1024.0;
bytes_per_second *= (double) dev->drv->cur_speed; bytes_per_second *= (double) dev->drv->cur_speed;
break; break;
case 0xc6: case 0xc6 ... 0xc7:
case 0xc7:
switch (dev->drv->type) { switch (dev->drv->type) {
case CDROM_TYPE_TOSHIBA_XM_3433: case CDROM_TYPE_TOSHIBA_XM_3433:
case CDROM_TYPE_TOSHIBA_XM3201B_3232: 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; bytes_per_second *= (double) dev->drv->cur_speed;
break; break;
} }
case 0xc2: case 0xc2 ... 0xc3:
case 0xc3:
switch (dev->drv->type) { switch (dev->drv->type) {
case CDROM_TYPE_DEC_RRD45_0436: case CDROM_TYPE_DEC_RRD45_0436:
case CDROM_TYPE_SONY_CDU541_10i: 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; bytes_per_second *= (double) dev->drv->cur_speed;
break; break;
} }
case 0xdd: case 0xdd ... 0xde:
case 0xde:
switch (dev->drv->type) { switch (dev->drv->type) {
case CDROM_TYPE_NEC_38_103: case CDROM_TYPE_NEC_38_103:
case CDROM_TYPE_NEC_211_100: 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); ui_sb_update_icon(SB_CDROM | dev->id, 0);
dev->packet_status = PHASE_COMPLETE; dev->packet_status = PHASE_COMPLETE;
scsi_cdrom_command_common(dev); scsi_cdrom_command_common(dev);
dev->phase = 3; dev->tf->phase = 3;
} }
static void static void
@@ -1108,7 +1083,7 @@ scsi_cdrom_command_read(scsi_cdrom_t *dev)
{ {
dev->packet_status = PHASE_DATA_IN; dev->packet_status = PHASE_DATA_IN;
scsi_cdrom_command_common(dev); scsi_cdrom_command_common(dev);
dev->phase = !(dev->packet_status & 0x01) << 1; dev->tf->phase = !(dev->packet_status & 0x01) << 1;
} }
static void static void
@@ -1123,7 +1098,7 @@ scsi_cdrom_command_write(scsi_cdrom_t *dev)
{ {
dev->packet_status = PHASE_DATA_OUT; dev->packet_status = PHASE_DATA_OUT;
scsi_cdrom_command_common(dev); scsi_cdrom_command_common(dev);
dev->phase = !(dev->packet_status & 0x01) << 1; dev->tf->phase = !(dev->packet_status & 0x01) << 1;
} }
static void 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_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", 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->id, dev->current_cdb[0], len, block_len, alloc_len, direction,
dev->pos = 0; dev->tf->request_length);
dev->tf->pos = 0;
if (alloc_len >= 0) { if (alloc_len >= 0) {
if (alloc_len < len) if (alloc_len < len)
len = alloc_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", 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 static void
@@ -1197,14 +1174,14 @@ static void
scsi_cdrom_cmd_error(scsi_cdrom_t *dev) scsi_cdrom_cmd_error(scsi_cdrom_t *dev)
{ {
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); 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) if (dev->unit_attention)
dev->error |= MCR_ERR; dev->tf->error |= MCR_ERR;
dev->status = READY_STAT | ERR_STAT; dev->tf->status = READY_STAT | ERR_STAT;
dev->phase = 3; dev->tf->phase = 3;
dev->pos = 0; dev->tf->pos = 0;
dev->packet_status = PHASE_ERROR; dev->packet_status = PHASE_ERROR;
dev->callback = 50.0 * CDROM_TIME; dev->callback = 50.0 * CDROM_TIME;
scsi_cdrom_set_callback(dev); scsi_cdrom_set_callback(dev);
ui_sb_update_icon(SB_CDROM | dev->id, 0); ui_sb_update_icon(SB_CDROM | dev->id, 0);
scsi_cdrom_log("CD-ROM %i: ERROR: %02X/%02X/%02X\n", dev->id, scsi_cdrom_sense_key, scsi_cdrom_asc, scsi_cdrom_ascq); scsi_cdrom_log("CD-ROM %i: ERROR: %02X/%02X/%02X\n", dev->id, scsi_cdrom_sense_key, scsi_cdrom_asc, scsi_cdrom_ascq);
@@ -1214,12 +1191,12 @@ static void
scsi_cdrom_unit_attention(scsi_cdrom_t *dev) scsi_cdrom_unit_attention(scsi_cdrom_t *dev)
{ {
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); 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) if (dev->unit_attention)
dev->error |= MCR_ERR; dev->tf->error |= MCR_ERR;
dev->status = READY_STAT | ERR_STAT; dev->tf->status = READY_STAT | ERR_STAT;
dev->phase = 3; dev->tf->phase = 3;
dev->pos = 0; dev->tf->pos = 0;
dev->packet_status = PHASE_ERROR; dev->packet_status = PHASE_ERROR;
dev->callback = 50.0 * CDROM_TIME; dev->callback = 50.0 * CDROM_TIME;
scsi_cdrom_set_callback(dev); 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_asc = ASC_INV_FIELD_IN_CMD_PACKET;
scsi_cdrom_ascq = 0; scsi_cdrom_ascq = 0;
scsi_cdrom_cmd_error(dev); scsi_cdrom_cmd_error(dev);
dev->status = 0x53; dev->tf->status = 0x53;
} }
static void 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_asc = ASC_INV_FIELD_IN_PARAMETER_LIST;
scsi_cdrom_ascq = 0; scsi_cdrom_ascq = 0;
scsi_cdrom_cmd_error(dev); scsi_cdrom_cmd_error(dev);
dev->status = 0x53; dev->tf->status = 0x53;
} }
static void 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)) { 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", 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); scsi_cdrom_invalid_lun(dev);
return 0; return 0;
} }
@@ -1674,14 +1651,14 @@ scsi_cdrom_reset(scsi_common_t *sc)
return; return;
scsi_cdrom_rezero(dev); scsi_cdrom_rezero(dev);
dev->status = 0; dev->tf->status = 0;
dev->callback = 0.0; dev->callback = 0.0;
scsi_cdrom_set_callback(dev); scsi_cdrom_set_callback(dev);
dev->phase = 1; dev->tf->phase = 1;
dev->request_length = 0xEB14; dev->tf->request_length = 0xeb14;
dev->packet_status = PHASE_NONE; dev->packet_status = PHASE_NONE;
dev->unit_attention = 0xff; dev->unit_attention = 0xff;
dev->cur_lun = SCSI_LUN_USE_CDB; dev->cur_lun = SCSI_LUN_USE_CDB;
} }
static void static void
@@ -1793,10 +1770,10 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb)
if (dev->drv->bus_type == CDROM_BUS_SCSI) { if (dev->drv->bus_type == CDROM_BUS_SCSI) {
BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length;
dev->status &= ~ERR_STAT; dev->tf->status &= ~ERR_STAT;
} else { } else {
BufLen = &blen; BufLen = &blen;
dev->error = 0; dev->tf->error = 0;
} }
dev->packet_len = 0; dev->packet_len = 0;
@@ -1814,11 +1791,12 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb)
if (cdb[0] != 0) { if (cdb[0] != 0) {
scsi_cdrom_log("CD-ROM %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", 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); dev->id, cdb[0], scsi_cdrom_sense_key, scsi_cdrom_asc, scsi_cdrom_ascq,
scsi_cdrom_log("CD-ROM %i: Request length: %04X\n", dev->id, dev->request_length); 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, scsi_cdrom_log("CD-ROM %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], 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]); cdb[8], cdb[9], cdb[10], cdb[11]);
} }
@@ -3727,9 +3705,10 @@ atapi_out:
break; 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); scsi_cdrom_buf_free(dev);
} }
@@ -3905,6 +3884,9 @@ scsi_cdrom_close(void *priv)
{ {
scsi_cdrom_t *dev = (scsi_cdrom_t *) priv; scsi_cdrom_t *dev = (scsi_cdrom_t *) priv;
if (dev->tf)
free(dev->tf);
if (dev) if (dev)
free(dev); free(dev);
} }
@@ -4086,6 +4068,7 @@ scsi_cdrom_drive_reset(int c)
ide_t *id; ide_t *id;
uint8_t scsi_bus = (drv->scsi_device_id >> 4) & 0x0f; uint8_t scsi_bus = (drv->scsi_device_id >> 4) & 0x0f;
uint8_t scsi_id = drv->scsi_device_id & 0x0f; uint8_t scsi_id = drv->scsi_device_id & 0x0f;
uint8_t valid = 0;
if (drv->bus_type == CDROM_BUS_SCSI) { if (drv->bus_type == CDROM_BUS_SCSI) {
/* Make sure to ignore any SCSI CD-ROM drive that has an out of range SCSI bus. */ /* 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->get_channel = scsi_cdrom_get_channel;
drv->close = scsi_cdrom_close; drv->close = scsi_cdrom_close;
scsi_cdrom_init(dev);
if (drv->bus_type == CDROM_BUS_SCSI) { 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. */ /* SCSI CD-ROM, attach to the SCSI bus. */
sd = &scsi_devices[scsi_bus][scsi_id]; 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 otherwise, we do nothing - it's going to be a drive
that's not attached to anything. */ that's not attached to anything. */
if (id) { if (id) {
valid = 1;
id->sc = (scsi_common_t *) dev; 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_max = scsi_cdrom_get_max;
id->get_timings = scsi_cdrom_get_timings; id->get_timings = scsi_cdrom_get_timings;
id->identify = scsi_cdrom_identify; 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); 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/86box.h>
#include <86box/device.h> #include <86box/device.h>
#include <86box/hdd.h> #include <86box/hdd.h>
#include <86box/hdc_ide.h>
#include <86box/scsi.h> #include <86box/scsi.h>
#include <86box/scsi_device.h> #include <86box/scsi_device.h>
#include <86box/plat_unused.h> #include <86box/plat_unused.h>
@@ -37,7 +38,7 @@ scsi_device_target_command(scsi_device_t *dev, uint8_t *cdb)
if (dev->command) { if (dev->command) {
dev->command(dev->sc, cdb); dev->command(dev->sc, cdb);
if (dev->sc->status & ERR_STAT) if (dev->sc->tf->status & ERR_STAT)
return SCSI_STATUS_CHECK_CONDITION; return SCSI_STATUS_CHECK_CONDITION;
else else
return SCSI_STATUS_OK; return SCSI_STATUS_OK;
@@ -140,7 +141,7 @@ scsi_device_command_phase1(scsi_device_t *dev)
} else } else
scsi_device_command_stop(dev); scsi_device_command_stop(dev);
if (dev->sc->status & ERR_STAT) if (dev->sc->tf->status & ERR_STAT)
dev->status = SCSI_STATUS_CHECK_CONDITION; dev->status = SCSI_STATUS_CHECK_CONDITION;
else else
dev->status = SCSI_STATUS_OK; dev->status = SCSI_STATUS_OK;

File diff suppressed because it is too large Load Diff