SCSI changes and fixes:

1. Added the Tribble 16-bit IBM SCSI adapter.
2. Reworked the vendor unique commands to counter audio issues as well as adding some undocumented commands (thanks to the source code of xmcd!), plus replacing the NEC CD-ROM DRIVE:75 with the :38 one.
This commit is contained in:
TC1995
2023-09-20 20:29:32 +02:00
parent f324116eaf
commit 7c6381b2ea
6 changed files with 454 additions and 185 deletions

View File

@@ -86,6 +86,7 @@ static SCSI_CARD scsi_cards[] = {
{ &buslogic_640a_device, },
{ &ncr53c90_mca_device, },
{ &spock_device, },
{ &tribble_device, },
{ &buslogic_958d_pci_device, },
{ &ncr53c810_pci_device, },
{ &ncr53c815_pci_device, },

View File

@@ -335,7 +335,7 @@ static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_default_sony_scsi =
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ GPMODE_CDROM_PAGE_SONY, 2, 1, 0 },
{ GPMODE_CDROM_PAGE_SONY, 2, 0, 5 },
{ GPMODE_CDROM_AUDIO_PAGE_SONY | 0x80, 0xE, 5, 0, 0, 0, 0, 0, 1, 255, 2, 255, 0, 0, 0, 0 },
{ 0, 0 },
{ 0, 0 },
@@ -585,7 +585,10 @@ scsi_cdrom_get_channel(void *priv, int channel)
return channel + 1;
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00"))
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-561_1.8k") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEXEL_CD-ROM_DM-XX24_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436"))
return dev->ms_pages_saved_sony.pages[dev->sony_vendor ? GPMODE_CDROM_AUDIO_PAGE_SONY : GPMODE_CDROM_AUDIO_PAGE][channel ? 10 : 8];
else
return dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE][channel ? 10 : 8];
@@ -599,7 +602,10 @@ scsi_cdrom_get_volume(void *priv, int channel)
return 255;
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00"))
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-561_1.8k") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEXEL_CD-ROM_DM-XX24_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436"))
return dev->ms_pages_saved_sony.pages[dev->sony_vendor ? GPMODE_CDROM_AUDIO_PAGE_SONY : GPMODE_CDROM_AUDIO_PAGE][channel ? 11 : 9];
else
return dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE][channel ? 11 : 9];
@@ -612,7 +618,10 @@ scsi_cdrom_mode_sense_load(scsi_cdrom_t *dev)
char file_name[512];
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) {
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-561_1.8k") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEXEL_CD-ROM_DM-XX24_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) {
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));
@@ -654,7 +663,10 @@ scsi_cdrom_mode_sense_save(scsi_cdrom_t *dev)
memset(file_name, 0, 512);
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) {
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-561_1.8k") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEXEL_CD-ROM_DM-XX24_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) {
sprintf(file_name, "scsi_cdrom_%02i_mode_sense_sony_bin", dev->id);
fp = plat_fopen(nvr_path(file_name), "wb");
if (fp) {
@@ -731,7 +743,10 @@ static uint8_t
scsi_cdrom_mode_sense_read(scsi_cdrom_t *dev, uint8_t page_control, uint8_t page, uint8_t pos)
{
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) {
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-561_1.8k") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEXEL_CD-ROM_DM-XX24_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) {
switch (page_control) {
case 0:
case 3:
@@ -979,45 +994,73 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev)
case 0xc6:
case 0xc7:
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_DRIVEXM_3433") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-3201B_3232") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-3301TA_0272") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-5701TA_3136")) {
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-5701TA_3136") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_DVD-ROM_SD-M1401_1008")) {
bytes_per_second = 176.0 * 1024.0;
bytes_per_second *= (double) dev->drv->cur_speed;
break;
}
break;
fallthrough;
case 0xc0:
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-561_1.8k") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEXEL_CD-ROM_DM-XX24_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) {
bytes_per_second = 176.0 * 1024.0;
bytes_per_second *= (double) dev->drv->cur_speed;
break;
}
fallthrough;
case 0xc1:
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) {
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-561_1.8k") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEXEL_CD-ROM_DM-XX24_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) {
bytes_per_second = 176.0 * 1024.0;
bytes_per_second *= (double) dev->drv->cur_speed;
break;
}
break;
fallthrough;
case 0xc2:
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) {
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-561_1.8k") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEXEL_CD-ROM_DM-XX24_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) {
dev->callback += 40.0;
bytes_per_second = 176.0 * 1024.0;
bytes_per_second *= (double) dev->drv->cur_speed;
break;
}
break;
fallthrough;
case 0xc3:
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) {
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-561_1.8k") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEXEL_CD-ROM_DM-XX24_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) {
bytes_per_second = 176.0 * 1024.0;
bytes_per_second *= (double) dev->drv->cur_speed;
break;
}
break;
fallthrough;
case 0xdd:
case 0xde:
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE75_1.00") ||
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE38_1.03") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE211_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE464_1.05")) {
bytes_per_second = 176.0 * 1024.0;
bytes_per_second *= (double) dev->drv->cur_speed;
break;
}
break;
fallthrough;
default:
bytes_per_second = scsi_cdrom_bus_speed(dev);
if (bytes_per_second == 0.0) {
@@ -1809,7 +1852,8 @@ begin:
break;
case 0xDA: /*GPCMD_SPEED_ALT*/
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE75_1.00") ||
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE38_1.03") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE211_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE464_1.05")) { /*GPCMD_STILL_NEC*/
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
cdrom_audio_pause_resume(dev->drv, 0x00);
@@ -1904,14 +1948,16 @@ begin:
dev->current_cdb[0] = cdb[0];
goto begin;
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) { /*GPCMD_PLAY_MSF_SONY*/
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-561_1.8k") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEXEL_CD-ROM_DM-XX24_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) { /*GPCMD_PLAY_MSF_SONY*/
cdb[0] = GPCMD_PLAY_AUDIO_MSF;
dev->current_cdb[0] = cdb[0];
dev->sony_vendor = 1;
goto begin;
} /*GPCMD_READ_DISC_INFORMATION_TOSHIBA*/
scsi_cdrom_illegal_opcode(dev);
break;
fallthrough;
case 0xDE: /*GPCMD_READ_DISC_INFORMATION_NEC*/
scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN);
scsi_cdrom_buf_alloc(dev, 4);
@@ -2040,11 +2086,13 @@ begin:
dev->drv->seek_diff = ABS((int) (pos - dev->sector_pos));
if ((cdb[0] == GPCMD_READ_10) || (cdb[0] == GPCMD_READ_12)) {
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE75_1.00") ||
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE211_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE464_1.05") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_DRIVEXM_3433") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-3201B_3232") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-3301TA_0272") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-5701TA_3136"))
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-5701TA_3136") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_DVD-ROM_SD-M1401_1008"))
ret = scsi_cdrom_read_blocks(dev, &alloc_length, 1, cdb[9] & 0xc0);
else
ret = scsi_cdrom_read_blocks(dev, &alloc_length, 1, 0);
@@ -2119,7 +2167,10 @@ begin:
}
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) {
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-561_1.8k") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEXEL_CD-ROM_DM-XX24_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) {
if (!(scsi_cdrom_mode_sense_page_flags_sony & (1LL << (uint64_t) (cdb[2] & 0x3f)))) {
scsi_cdrom_invalid_field(dev);
scsi_cdrom_buf_free(dev);
@@ -2425,16 +2476,25 @@ begin:
scsi_cdrom_data_command_finish(dev, len, len, max_len, 0);
break;
case 0xC0: /*GPCMD_UNKNOWN_SONY*/
case 0xC0: /*GPCMD_SET_ADDRESS_FORMAT_SONY*/
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) {
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-561_1.8k") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEXEL_CD-ROM_DM-XX24_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) {
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
dev->sony_vendor = 1;
dev->drv->sony_msf = cdb[8] & 1;
scsi_cdrom_command_complete(dev);
dev->sony_vendor = 1;
break;
} /*GPCMD_AUDIO_TRACK_SEARCH_TOSHIBA and GPCMD_EJECT_CHINON*/
scsi_cdrom_illegal_opcode(dev);
break;
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) { /*GPCMD_MAGAZINE_EJECT_PIONEER*/
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
scsi_cdrom_stop(sc);
cdrom_eject(dev->id);
scsi_cdrom_command_complete(dev);
break;
} /*GPCMD_AUDIO_TRACK_SEARCH_TOSHIBA and GPCMD_EJECT_CHINON*/
fallthrough;
case 0xD8: /*GPCMD_AUDIO_TRACK_SEARCH_NEC*/
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "CHINON_CD-ROM_CDS-431_H42")) {
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
@@ -2461,15 +2521,12 @@ begin:
case 0xC1: /*GPCMD_READ_TOC_SONY*/
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) {
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-561_1.8k") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEXEL_CD-ROM_DM-XX24_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) {
scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN);
if (strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) {
dev->sony_vendor = 0;
} else {
msf = dev->ms_pages_saved_sony.pages[GPMODE_CDROM_PAGE_SONY][2] & 0x01;
dev->sony_vendor = 1;
}
msf = dev->ms_pages_saved_sony.pages[GPMODE_CDROM_PAGE_SONY][2] & 0x01;
dev->sony_vendor = 1;
max_len = cdb[7];
max_len <<= 8;
@@ -2482,7 +2539,7 @@ begin:
return;
}
len = cdrom_read_toc_sony(dev->drv, dev->buffer, cdb[5], msf, max_len);
len = cdrom_read_toc_sony(dev->drv, dev->buffer, cdb[5], msf || dev->drv->sony_msf, max_len);
if (len == -1) {
/* If the returned length is -1, this means cdrom_read_toc_sony() has encountered an error. */
scsi_cdrom_invalid_field(dev);
@@ -2494,9 +2551,28 @@ begin:
scsi_cdrom_data_command_finish(dev, len, len, len, 0);
return;
} /*GPCMD_PLAY_AUDIO_TOSHIBA*/
scsi_cdrom_illegal_opcode(dev);
break;
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) { /*GPCMD_READ_TOC_PIONEER*/
scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN);
scsi_cdrom_buf_alloc(dev, 4);
if (!dev->drv->ops) {
scsi_cdrom_not_ready(dev);
return;
}
ret = cdrom_read_disc_info_toc(dev->drv, dev->buffer, cdb[2], cdb[1] & 3);
len = 4;
if (!ret) {
scsi_cdrom_invalid_field(dev);
scsi_cdrom_buf_free(dev);
return;
}
scsi_cdrom_set_buf_len(dev, BufLen, &len);
scsi_cdrom_data_command_finish(dev, len, len, len, 0);
return;
} /*GPCMD_PLAY_AUDIO_TOSHIBA*/
fallthrough;
case 0xD9: /*GPCMD_PLAY_AUDIO_NEC*/
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) {
@@ -2529,8 +2605,6 @@ begin:
len = (cdb[7] << 8) | cdb[8];
break;
case GPCMD_PLAY_AUDIO_12:
/* This is apparently deprecated in the ATAPI spec, and apparently
has been since 1995 (!). Hence I'm having to guess most of it. */
msf = 0;
pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5];
len = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9];
@@ -2579,7 +2653,6 @@ begin:
case GPCMD_READ_SUBCHANNEL:
scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN);
dev->sony_vendor = 0;
max_len = cdb[7];
max_len <<= 8;
@@ -2658,7 +2731,10 @@ begin:
case 0xC6:
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) {
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-561_1.8k") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEXEL_CD-ROM_DM-XX24_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) {
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
dev->sony_vendor = 1;
@@ -2683,8 +2759,7 @@ begin:
scsi_cdrom_illegal_mode(dev);
break;
} /*GPCMD_READ_SUBCODEQ_PLAYING_STATUS_TOSHIBA and GPCMD_STOP_CHINON*/
scsi_cdrom_illegal_opcode(dev);
break;
fallthrough;
case 0xDD: /*GPCMD_READ_SUBCODEQ_PLAYING_STATUS_NEC*/
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "CHINON_CD-ROM_CDS-431_H42")) {
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
@@ -2796,7 +2871,10 @@ begin:
dev->current_cdb[0] = cdb[0];
goto begin;
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) { /*GPCMD_PLAYBACK_STATUS_SONY*/
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-561_1.8k") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEXEL_CD-ROM_DM-XX24_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) { /*GPCMD_PLAYBACK_STATUS_SONY*/
scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN);
dev->sony_vendor = 1;
@@ -2807,14 +2885,14 @@ begin:
scsi_cdrom_buf_alloc(dev, 18);
len = max_len;
len = 18;
memset(dev->buffer, 0, 10);
memset(dev->buffer, 0, 18);
dev->buffer[0] = 0x00; /*Reserved*/
dev->buffer[1] = 0x00; /*Reserved*/
dev->buffer[2] = cdb[7]; /*Audio Status data length*/
dev->buffer[3] = cdb[8]; /*Audio Status data length*/
dev->buffer[4] = cdrom_get_audio_status_sony(dev->drv, &dev->buffer[6], msf); /*Audio status*/
dev->buffer[2] = 0x00; /*Audio Status data length*/
dev->buffer[3] = 0x00; /*Audio Status data length*/
dev->buffer[4] = cdrom_get_audio_status_sony(dev->drv, &dev->buffer[6], msf || dev->drv->sony_msf); /*Audio status*/
dev->buffer[5] = 0x00;
scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[4]);
@@ -2825,8 +2903,7 @@ begin:
scsi_cdrom_data_command_finish(dev, len, len, len, 0);
break;
} /*GPCMD_CADDY_EJECT_TOSHIBA and GPCMD_CADDY_EJECT_NEC*/
scsi_cdrom_illegal_opcode(dev);
break;
fallthrough;
case 0xDC:
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
scsi_cdrom_stop(sc);
@@ -2914,7 +2991,8 @@ begin:
dev->buffer[3] = 0x02;
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "86BOX_CD-ROM_1.00")) {
dev->buffer[2] = 0x05;
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_DRIVEXM_3433")) {
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_DRIVEXM_3433") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-561_1.8k")) {
dev->buffer[2] = 0x02;
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-3301TA_0272")) {
dev->buffer[2] = 0x02;
@@ -2923,7 +3001,10 @@ begin:
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "CHINON_CD-ROM_CDS-431_H42")) {
dev->buffer[3] = 0x01;
dev->buffer[2] = 0x02;
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i")) {
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEXEL_CD-ROM_DM-XX24_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-3201B_3232") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) {
dev->buffer[3] = 0x01;
dev->buffer[2] = 0x02;
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) {
@@ -2932,11 +3013,9 @@ begin:
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "MATSHITA_CD-ROM_CR-501_1.0b")) {
dev->buffer[3] = 0x01;
dev->buffer[2] = 0x02;
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE75_1.00")) {
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE38_1.03")) {
dev->buffer[3] = 0x01;
dev->buffer[2] = 0x02;
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) {
dev->buffer[2] = 0x02;
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE464_1.05")) {
dev->buffer[2] = 0x02;
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) {
@@ -2955,12 +3034,12 @@ begin:
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PLEXTOR_CD-ROM_PX-32TS_1.03")) {
dev->buffer[6] = 0x01; /* 16-bit transfers supported */
dev->buffer[7] = 0x20; /* Wide bus supported */
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEAC_CD-R55S_1.0R")) {
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEAC_CD-ROM_R55S_1.0R") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEAC_CD_50_1.00")) {
dev->buffer[6] = 0x01; /* 16-bit transfers supported */
dev->buffer[7] = 0x20; /* Wide bus supported */
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) {
dev->buffer[7] = 0x98; /* Linked Command and Relative Addressing supported */
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_DRIVEXM_3433")) {
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_DRIVEXM_3433") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-3201B_3232")) {
dev->buffer[4] = 91; /* Always 91 on Toshiba SCSI-2 CD-ROM drives from 1990*/
dev->buffer[7] = 0x88; /* Linked Command and Relative Addressing supported */
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-3301TA_0272")) {
@@ -2984,12 +3063,13 @@ begin:
ide_padstr8(dev->buffer + 32, 4, cdrom_drive_types[dev->drv->type].revision); /* Revision */
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) {
dev->buffer[36] = 0x20;
ide_padstr8(dev->buffer + 37, 10, "1993/01/01"); /* Date */
ide_padstr8(dev->buffer + 37, 10, "1991/01/01"); /* Date */
}
}
idx = 36;
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_DRIVEXM_3433") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-3201B_3232") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-3301TA_0272") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-5701TA_3136")) /*Toshiba only*/
idx = 96;
@@ -3038,7 +3118,10 @@ atapi_out:
dev->current_cdb[0] = cdb[0];
goto begin;
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) { /*GPCMD_READ_HEADER_SONY*/
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-561_1.8k") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEXEL_CD-ROM_DM-XX24_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) { /*GPCMD_READ_HEADER_SONY*/
scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN);
dev->sony_vendor = 1;
@@ -3061,8 +3144,6 @@ atapi_out:
scsi_cdrom_data_command_finish(dev, len, len, len, 0);
return;
} /*GPCMD_SET_STOP_TIME_TOSHIBA and GPCMD_SET_STOP_TIME_NEC*/
scsi_cdrom_illegal_opcode(dev);
break;
case 0xDB:
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
scsi_cdrom_command_complete(dev);
@@ -3075,34 +3156,63 @@ atapi_out:
goto begin;
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) { /*GPCMD_READ_SUBCHANNEL_SONY*/
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-561_1.8k") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEXEL_CD-ROM_DM-XX24_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) { /*GPCMD_READ_SUBCHANNEL_SONY*/
scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN);
dev->sony_vendor = !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403") ? 0 : 1;
dev->sony_vendor = 1;
max_len = cdb[7];
max_len <<= 8;
max_len |= cdb[8];
if (strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403"))
msf = dev->ms_pages_saved_sony.pages[GPMODE_CDROM_PAGE_SONY][2] & 0x01;
msf = dev->ms_pages_saved_sony.pages[GPMODE_CDROM_PAGE_SONY][2] & 0x01;
scsi_cdrom_buf_alloc(dev, 32);
scsi_cdrom_log("CD-ROM %i: Getting sub-channel type (%s), code-q = %02x\n", dev->id, msf ? "MSF" : "LBA", cdb[2] & 0x40);
scsi_cdrom_log("CD-ROM %i: Getting sub-channel type (%s)\n", dev->id, msf ? "MSF" : "LBA");
if (cdb[2] & 0x40) {
scsi_cdrom_buf_alloc(dev, 9);
memset(dev->buffer, 0, 9);
len = 9;
cdrom_get_current_subchannel_sony(dev->drv, dev->buffer, msf || dev->drv->sony_msf);
len = MIN(len, max_len);
scsi_cdrom_set_buf_len(dev, BufLen, &len);
scsi_cdrom_data_command_finish(dev, len, len, len, 0);
} else {
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
scsi_cdrom_log("CD-ROM %i: Drive Status All done - callback set\n", dev->id);
dev->packet_status = PHASE_COMPLETE;
dev->callback = 20.0 * CDROM_TIME;
scsi_cdrom_set_callback(dev);
}
break;
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) { /*GPCMD_READ_SUBCODEQ_PIONEER*/
scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN);
if (!(cdb[2] & 0x40))
alloc_length = 4;
else
alloc_length = 24;
alloc_length = cdb[1] & 0x1f;
len = 9;
len = alloc_length;
if (!dev->drv->ops) {
scsi_cdrom_not_ready(dev);
return;
}
memset(dev->buffer, 0, 24);
cdrom_get_current_subchannel_sony(dev->drv, dev->buffer, msf);
if (!alloc_length) {
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
scsi_cdrom_log("CD-ROM %i: Subcode Q All done - callback set\n", dev->id);
dev->packet_status = PHASE_COMPLETE;
dev->callback = 20.0 * CDROM_TIME;
scsi_cdrom_set_callback(dev);
break;
}
len = MIN(len, max_len);
scsi_cdrom_set_buf_len(dev, BufLen, &len);
scsi_cdrom_buf_alloc(dev, len);
len = MIN(len, alloc_length);
memset(dev->buffer, 0, len);
cdrom_get_current_subcodeq(dev->drv, &dev->buffer[1]);
scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[0]);
scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length);
scsi_cdrom_data_command_finish(dev, len, len, len, 0);
break;
}
@@ -3130,11 +3240,13 @@ atapi_out:
}
dev->drv->seek_diff = ABS((int) (pos - dev->drv->seek_pos));
if (cdb[0] == GPCMD_SEEK_10) {
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE75_1.00") ||
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE211_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE464_1.05") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_DRIVEXM_3433") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-3201B_3232") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-3301TA_0272") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-5701TA_3136"))
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-5701TA_3136") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_DVD-ROM_SD-M1401_1008"))
cdrom_seek(dev->drv, pos, cdb[9] & 0xc0);
else
cdrom_seek(dev->drv, pos, 0);
@@ -3181,36 +3293,57 @@ atapi_out:
dev->current_cdb[0] = cdb[0];
goto begin;
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) { /*GPCMD_PAUSE_SONY*/
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-561_1.8k") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEXEL_CD-ROM_DM-XX24_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) { /*GPCMD_PAUSE_SONY*/
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
dev->sony_vendor = 1;
cdrom_audio_pause_resume(dev->drv, !(cdb[1] & 0x10));
scsi_cdrom_command_complete(dev);
break;
}
scsi_cdrom_illegal_opcode(dev);
break;
fallthrough;
case 0xC8:
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "MATSHITA_CD-ROM_CR-501_1.0b")) { /*GPCMD_PLAY_AUDIO_TRACK_INDEX_MATSUSHITA*/
cdb[0] = GPCMD_PLAY_AUDIO_TRACK_INDEX;
dev->current_cdb[0] = cdb[0];
goto begin;
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) { /*GPCMD_PLAY_AUDIO_SONY*/
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-561_1.8k") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEXEL_CD-ROM_DM-XX24_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) { /*GPCMD_PLAY_AUDIO_SONY*/
cdb[0] = GPCMD_PLAY_AUDIO_10;
dev->current_cdb[0] = cdb[0];
dev->sony_vendor = 1;
goto begin;
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) { /*GPCMD_AUDIO_TRACK_SEARCH_PIONEER*/
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) {
scsi_cdrom_illegal_mode(dev);
break;
}
pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5];
ret = cdrom_audio_track_search_pioneer(dev->drv, pos, cdb[1] & 1);
dev->drv->audio_op = (cdb[1] & 1) ? 0x03 : 0x02;
if (ret)
scsi_cdrom_command_complete(dev);
else
scsi_cdrom_illegal_mode(dev);
}
scsi_cdrom_illegal_opcode(dev);
break;
fallthrough;
case 0xC9:
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "MATSHITA_CD-ROM_CR-501_1.0b")) { /*GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10_MATSUSHITA*/
cdb[0] = GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10;
dev->current_cdb[0] = cdb[0];
goto begin;
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) { /*GPCMD_PLAYBACK_CONTROL_SONY*/
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-561_1.8k") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEXEL_CD-ROM_DM-XX24_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) { /*GPCMD_PLAYBACK_CONTROL_SONY*/
scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_OUT);
dev->sony_vendor = 1;
@@ -3220,9 +3353,22 @@ atapi_out:
scsi_cdrom_set_buf_len(dev, BufLen, &len);
scsi_cdrom_data_command_finish(dev, len, len, len, 1);
break;
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) { /*GPCMD_PLAY_AUDIO_PIONEER*/
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) {
scsi_cdrom_illegal_mode(dev);
break;
}
pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5];
ret = cdrom_audio_play_pioneer(dev->drv, pos);
if (ret)
scsi_cdrom_command_complete(dev);
else
scsi_cdrom_illegal_mode(dev);
break;
}
scsi_cdrom_illegal_opcode(dev);
break;
fallthrough;
case 0xCA:
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) { /*GPCMD_PAUSE_PIONEER*/
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
@@ -3230,35 +3376,33 @@ atapi_out:
scsi_cdrom_command_complete(dev);
break;
}
scsi_cdrom_illegal_opcode(dev);
break;
fallthrough;
case 0xCB:
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "MATSHITA_CD-ROM_CR-501_1.0b")) { /*GPCMD_PAUSE_RESUME_MATSUSHITA*/
cdb[0] = GPCMD_PAUSE_RESUME;
dev->current_cdb[0] = cdb[0];
goto begin;
} else if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) { /*GPCMD_STOP_PIONEER*/
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
scsi_cdrom_stop(sc);
scsi_cdrom_command_complete(dev);
break;
}
scsi_cdrom_illegal_opcode(dev);
break;
fallthrough;
case 0xCC:
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) {
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) { /*GPCMD_PLAYBACK_STATUS_PIONEER*/
scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN);
max_len = cdb[7];
max_len <<= 8;
max_len |= cdb[8];
scsi_cdrom_buf_alloc(dev, 18);
scsi_cdrom_buf_alloc(dev, 6);
len = max_len;
len = 6;
memset(dev->buffer, 0, 10);
dev->buffer[0] = 0x00; /*Reserved*/
dev->buffer[1] = 0x00; /*Reserved*/
dev->buffer[2] = cdb[7]; /*Audio Status data length*/
dev->buffer[3] = cdb[8]; /*Audio Status data length*/
dev->buffer[4] = cdrom_get_audio_status_sony(dev->drv, &dev->buffer[6], msf); /*Audio status*/
dev->buffer[5] = 0x00;
memset(dev->buffer, 0, 6);
dev->buffer[0] = cdrom_get_audio_status_pioneer(dev->drv, &dev->buffer[1]); /*Audio status*/
scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[4]);
@@ -3268,8 +3412,7 @@ atapi_out:
scsi_cdrom_data_command_finish(dev, len, len, len, 0);
break;
}
scsi_cdrom_illegal_opcode(dev);
break;
fallthrough;
case 0xE0:
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) { /*GPCMD_DRIVE_STATUS_PIONEER*/
scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN);
@@ -3305,24 +3448,21 @@ atapi_out:
scsi_cdrom_data_command_finish(dev, len, len, alloc_length, 0);
return;
}
scsi_cdrom_illegal_opcode(dev);
break;
fallthrough;
case 0xE5:
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "MATSHITA_CD-ROM_CR-501_1.0b")) { /*GPCMD_PLAY_AUDIO_12_MATSUSHITA*/
cdb[0] = GPCMD_PLAY_AUDIO_12;
dev->current_cdb[0] = cdb[0];
goto begin;
}
scsi_cdrom_illegal_opcode(dev);
break;
fallthrough;
case 0xE9:
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "MATSHITA_CD-ROM_CR-501_1.0b")) { /*GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12_MATSUSHITA*/
cdb[0] = GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12;
dev->current_cdb[0] = cdb[0];
goto begin;
}
scsi_cdrom_illegal_opcode(dev);
break;
fallthrough;
default:
scsi_cdrom_illegal_opcode(dev);
break;
@@ -3401,7 +3541,10 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc)
pos += 2;
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) {
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-561_1.8k") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEXEL_CD-ROM_DM-XX24_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) {
if (!(scsi_cdrom_mode_sense_page_flags_sony & (1LL << ((uint64_t) page)))) {
scsi_cdrom_log("CD-ROM %i: Unimplemented page %02X\n", dev->id, page);
error |= 1;
@@ -3444,7 +3587,10 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc)
pos += page_len;
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00"))
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-561_1.8k") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEXEL_CD-ROM_DM-XX24_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436"))
val = scsi_cdrom_mode_sense_pages_default_sony_scsi.pages[page][0] & 0x80;
else if (dev->drv->bus_type == CDROM_BUS_SCSI)
val = scsi_cdrom_mode_sense_pages_default_scsi.pages[page][0] & 0x80;
@@ -3466,7 +3612,10 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc)
break;
case 0xC9:
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) {
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-561_1.8k") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TEXEL_CD-ROM_DM-XX24_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "DEC_RRD45_0436")) {
for (i = 0; i < 18; i++) {
dev->ms_pages_saved_sony.pages[GPMODE_CDROM_AUDIO_PAGE_SONY][i] = dev->buffer[i];
}

View File

@@ -135,7 +135,7 @@ typedef struct {
int cir_status;
uint8_t pacing;
uint8_t irq_state;
uint8_t buf[0x600];
struct {
@@ -159,6 +159,7 @@ typedef struct {
int scb_state;
int in_reset;
int in_invalid;
int spock_16bit;
uint64_t temp_period;
double media_period;
@@ -247,18 +248,18 @@ spock_rethink_irqs(spock_t *scsi)
if (irq_pending) {
spock_log("IRQ issued\n");
scsi->irq_inactive = 0;
picint(1 << scsi->irq);
picintlevel(1 << scsi->irq, &scsi->irq_state);
} else {
/* No IRQs pending, clear IRQ state */
spock_log("IRQ cleared\n");
scsi->irq_status = 0;
scsi->irq_inactive = 1;
scsi->status &= ~STATUS_IRQ;
picintc(1 << scsi->irq);
picintclevel(1 << scsi->irq, &scsi->irq_state);
}
} else {
spock_log("IRQ disabled\n");
picintc(1 << scsi->irq);
picintclevel(1 << scsi->irq, &scsi->irq_state);
}
}
@@ -674,9 +675,9 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
spock_log("Get POS Info\n");
get_pos_info_t *get_pos_info = &scsi->get_pos_info;
get_pos_info->pos = 0x8eff;
get_pos_info->pos = scsi->spock_16bit ? 0x8efe : 0x8eff;
get_pos_info->pos1 = scsi->pos_regs[3] | (scsi->pos_regs[2] << 8);
get_pos_info->pos2 = 0x0e | (scsi->pos_regs[4] << 8);
get_pos_info->pos2 = scsi->irq | (scsi->pos_regs[4] << 8);
get_pos_info->pos3 = 1 << 12;
get_pos_info->pos4 = (7 << 8) | 8;
get_pos_info->pos5 = (16 << 8) | scsi->pacing;
@@ -716,7 +717,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
case CMD_SEND_OTHER_SCSI:
scsi->cdb_id = scsi->assign ? scsi->dev_id[scsi->scb_id].phys_id : scsi->present[scsi->scb_id];
dma_bm_read(scsi->scb_addr + 0x18, scsi->cdb, 12, 2);
spock_log("Send Other SCSI, SCB ID=%d, PHYS ID=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id);
spock_log("Send Other SCSI, SCB ID=%d, PHYS ID=%d, CDB[0]=%02x, CDB_ID=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id, scsi->cdb[0], scsi->cdb_id);
scsi->cdb[1] = (scsi->cdb[1] & 0x1f) | (scsi->dev_id[scsi->scb_id].lun_id << 5); /*Patch correct LUN into command*/
scsi->cdb_len = (scb->lba_addr & 0xff) ? (scb->lba_addr & 0xff) : 6;
scsi->scsi_state = SCSI_STATE_SELECT;
@@ -916,7 +917,7 @@ spock_process_scsi(spock_t *scsi, scb_t *scb)
scsi_device_command_phase0(sd, scsi->temp_cdb);
spock_log("SCSI ID %i: Current CDB[0] = %02x, LUN = %i, data len = %i, max len = %i, phase val = %02x\n", scsi->cdb_id, scsi->temp_cdb[0], scsi->temp_cdb[1] >> 5, sd->buffer_length, spock_get_len(scsi, scb), sd->phase);
if (sd->phase != SCSI_PHASE_STATUS && sd->buffer_length > 0) {
if ((sd->phase != SCSI_PHASE_STATUS) && (sd->buffer_length > 0)) {
p = scsi_device_get_callback(sd);
if (p <= 0.0)
spock_add_to_period(scsi, sd->buffer_length);
@@ -969,9 +970,9 @@ spock_process_scsi(spock_t *scsi, scb_t *scb)
scsi->scsi_state = SCSI_STATE_IDLE;
spock_log("State to idle, cmd timer %d\n", scsi->cmd_timer);
if (!scsi->cmd_timer) {
if (!scsi->cmd_timer)
scsi->cmd_timer = 1;
}
spock_add_to_period(scsi, 1);
break;
}
@@ -1056,7 +1057,7 @@ spock_callback(void *priv)
period = 0.2 * ((double) scsi->temp_period);
timer_on_auto(&scsi->callback_timer, (scsi->media_period + period + 10.0));
spock_log("Temporary period: %lf us (%" PRIi64 " periods)\n", scsi->callback_timer.period, scsi->temp_period);
spock_log("Temporary period: %lf us (%" PRIi64 " periods), media period = %lf\n", scsi->callback_timer.period, scsi->temp_period, scsi->media_period);
}
static void
@@ -1081,6 +1082,7 @@ spock_mca_write(int port, uint8_t val, void *priv)
mem_mapping_enable(&scsi->bios_rom.mapping);
}
}
spock_log("[%04X:%08X]: POS Write Port = %x, val = %02x, rom addr = %05x\n", CS, cpu_state.pc, port & 7, val, ((scsi->pos_regs[2] >> 4) * 0x2000) + 0xc0000);
}
static uint8_t
@@ -1088,6 +1090,8 @@ spock_mca_read(int port, void *priv)
{
const spock_t *scsi = (spock_t *) priv;
spock_log("[%04X:%08X]: POS Read Port = %x, val = %02x\n", CS, cpu_state.pc,
port & 7, scsi->pos_regs[port & 7]);
return scsi->pos_regs[port & 7];
}
@@ -1118,10 +1122,14 @@ spock_mca_reset(void *priv)
scsi_device_reset(&scsi_devices[scsi->bus][i]);
scsi->present[i] = 0;
}
spock_log("Reset.\n");
mem_mapping_disable(&scsi->bios_rom.mapping);
spock_mca_write(0x102, 0, scsi);
}
static void *
spock_init(UNUSED(const device_t *info))
spock_init(const device_t *info)
{
spock_t *scsi = malloc(sizeof(spock_t));
memset(scsi, 0x00, sizeof(spock_t));
@@ -1131,23 +1139,24 @@ spock_init(UNUSED(const device_t *info))
scsi->irq = 14;
scsi->bios_ver = device_get_config_int("bios_ver");
scsi->spock_16bit = info->local & 0xff;
switch (scsi->bios_ver) {
case 1:
rom_init_interleaved(&scsi->bios_rom, SPOCK_U68_1991_ROM, SPOCK_U69_1991_ROM,
0xc8000, 0x8000, 0x7fff, 0x4000, MEM_MAPPING_EXTERNAL);
break;
case 0:
rom_init_interleaved(&scsi->bios_rom, SPOCK_U68_1990_ROM, SPOCK_U69_1990_ROM,
0xc8000, 0x8000, 0x7fff, 0x4000, MEM_MAPPING_EXTERNAL);
break;
case 1:
rom_init_interleaved(&scsi->bios_rom, SPOCK_U68_1991_ROM, SPOCK_U69_1991_ROM,
0xc8000, 0x8000, 0x7fff, 0x4000, MEM_MAPPING_EXTERNAL);
break;
default:
break;
}
mem_mapping_disable(&scsi->bios_rom.mapping);
scsi->pos_regs[0] = 0xff;
scsi->pos_regs[0] = scsi->spock_16bit ? 0xfe : 0xff;
scsi->pos_regs[1] = 0x8e;
mca_add(spock_mca_read, spock_mca_write, spock_mca_feedb, spock_mca_reset, scsi);
@@ -1218,3 +1227,17 @@ const device_t spock_device = {
.force_redraw = NULL,
.config = spock_rom_config
};
const device_t tribble_device = {
.name = "IBM PS/2 SCSI Adapter (Tribble)",
.internal_name = "tribble",
.flags = DEVICE_MCA,
.local = 1,
.init = spock_init,
.close = spock_close,
.reset = NULL,
{ .available = spock_available },
.speed_changed = NULL,
.force_redraw = NULL,
.config = spock_rom_config
};