From 7c6381b2ea18750494657edb86982cde004ca962 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 20 Sep 2023 20:29:32 +0200 Subject: [PATCH] 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. --- src/cdrom/cdrom.c | 146 +++++++++--- src/include/86box/cdrom.h | 43 ++-- src/include/86box/scsi_spock.h | 1 + src/scsi/scsi.c | 1 + src/scsi/scsi_cdrom.c | 391 +++++++++++++++++++++++---------- src/scsi/scsi_spock.c | 57 +++-- 6 files changed, 454 insertions(+), 185 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index fa16dbf2c..c09bf874b 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -571,7 +571,6 @@ cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf) dev->cd_end = len; dev->cd_status = CD_STATUS_PLAYING; dev->cd_buflen = 0; - return 1; } @@ -624,6 +623,52 @@ cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit) return 1; } +uint8_t +cdrom_audio_track_search_pioneer(cdrom_t *dev, uint32_t pos, uint8_t playbit) +{ + int m = 0; + int s = 0; + int f = 0; + + if (dev->cd_status == CD_STATUS_DATA_ONLY) + return 0; + + f = bcd2bin((pos >> 24) & 0xff); + s = bcd2bin((pos >> 16) & 0xff); + m = bcd2bin((pos >> 8) & 0xff); + if (pos == 0xffffffff) { + pos = dev->seek_pos; + } else + pos = MSFtoLBA(m, s, f) - 150; + + dev->seek_pos = pos; + + dev->cd_buflen = 0; + dev->cd_status = playbit ? CD_STATUS_PLAYING : CD_STATUS_PAUSED; + return 1; +} + +uint8_t +cdrom_audio_play_pioneer(cdrom_t *dev, uint32_t pos) +{ + int m = 0; + int s = 0; + int f = 0; + + if (dev->cd_status == CD_STATUS_DATA_ONLY) + return 0; + + f = bcd2bin((pos >> 24) & 0xff); + s = bcd2bin((pos >> 16) & 0xff); + m = bcd2bin((pos >> 8) & 0xff); + pos = MSFtoLBA(m, s, f) - 150; + dev->cd_end = pos; + + dev->cd_buflen = 0; + dev->cd_status = CD_STATUS_PLAYING; + return 1; +} + uint8_t cdrom_audio_play_toshiba(cdrom_t *dev, uint32_t pos, int type) { @@ -664,7 +709,6 @@ cdrom_audio_play_toshiba(cdrom_t *dev, uint32_t pos, int type) /* Unlike standard commands, if there's a data track on an Audio CD (mixed mode) the playback continues with the audio muted (Toshiba CD-ROM SCSI-2 manual reference). */ - dev->cd_buflen = 0; dev->cd_status = CD_STATUS_PLAYING; return 1; @@ -751,7 +795,7 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf) ret = 0x13; } - cdrom_log("CD-ROM %i: Returned subchannel at %02i:%02i.%02i, ret = %02x, seek pos = %08x, cd_end = %08x.\n", dev->id, subc.abs_m, subc.abs_s, subc.abs_f, ret, dev->seek_pos, dev->cd_end); + cdrom_log("CD-ROM %i: Returned subchannel absolute at %02i:%02i.%02i, relative at %02i:%02i.%02i, ret = %02x, seek pos = %08x, cd_end = %08x.\n", dev->id, subc.abs_m, subc.abs_s, subc.abs_f, subc.rel_m, subc.rel_s, subc.rel_f, ret, dev->seek_pos, dev->cd_end); if (b[pos] > 1) { cdrom_log("B[%i] = %02x, ret = %02x.\n", pos, b[pos], ret); @@ -820,36 +864,62 @@ void cdrom_get_current_subchannel_sony(cdrom_t *dev, uint8_t *b, int msf) { subchannel_t subc; - int pos = 0; uint32_t dat; dev->ops->get_subchannel(dev, dev->seek_pos, &subc); - cdrom_log("CD-ROM %i: Returned subchannel at %02i:%02i.%02i, seek pos = %08x, cd_end = %08x.\n", dev->id, subc.abs_m, subc.abs_s, subc.abs_f, dev->seek_pos, dev->cd_end); + cdrom_log("CD-ROM %i: Returned subchannel at %02i:%02i.%02i, seek pos = %08x, cd_end = %08x, msf = %x.\n", dev->id, subc.abs_m, subc.abs_s, subc.abs_f, dev->seek_pos, dev->cd_end, msf); - b[pos++] = subc.attr; - b[pos++] = subc.track; - b[pos++] = subc.index; + b[0] = subc.attr; + b[1] = subc.track; + b[2] = subc.index; if (msf) { - b[pos++] = subc.rel_m; - b[pos++] = subc.rel_s; - b[pos++] = subc.rel_f; - b[pos++] = subc.abs_m; - b[pos++] = subc.abs_s; - b[pos++] = subc.abs_f; + b[3] = subc.rel_m; + b[4] = subc.rel_s; + b[5] = subc.rel_f; + b[6] = subc.abs_m; + b[7] = subc.abs_s; + b[8] = subc.abs_f; } else { dat = MSFtoLBA(subc.rel_m, subc.rel_s, subc.rel_f); - b[pos++] = (dat >> 16) & 0xff; - b[pos++] = (dat >> 8) & 0xff; - b[pos++] = dat & 0xff; + b[3] = (dat >> 16) & 0xff; + b[4] = (dat >> 8) & 0xff; + b[5] = dat & 0xff; dat = MSFtoLBA(subc.abs_m, subc.abs_s, subc.abs_f) - 150; - b[pos++] = (dat >> 16) & 0xff; - b[pos++] = (dat >> 8) & 0xff; - b[pos++] = dat & 0xff; + b[6] = (dat >> 16) & 0xff; + b[7] = (dat >> 8) & 0xff; + b[8] = dat & 0xff; } } +uint8_t +cdrom_get_audio_status_pioneer(cdrom_t *dev, uint8_t *b) +{ + uint8_t ret; + subchannel_t subc; + uint32_t dat; + + dev->ops->get_subchannel(dev, dev->seek_pos, &subc); + + if (dev->cd_status == CD_STATUS_DATA_ONLY) + ret = 0x05; + else { + if (dev->cd_status == CD_STATUS_PLAYING) + ret = dev->sound_on ? 0x00 : 0x02; + else if (dev->cd_status == CD_STATUS_PAUSED) + ret = 0x01; + else + ret = 0x03; + } + + b[0] = 0; + b[1] = bin2bcd(subc.abs_m); + b[2] = bin2bcd(subc.abs_s); + b[3] = bin2bcd(subc.abs_f); + + return ret; +} uint8_t cdrom_get_audio_status_sony(cdrom_t *dev, uint8_t *b, int msf) @@ -887,17 +957,36 @@ cdrom_get_audio_status_sony(cdrom_t *dev, uint8_t *b, int msf) return ret; } -uint8_t -cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b) +void +cdrom_get_current_subcodeq(cdrom_t *dev, uint8_t *b) { - uint8_t ret; + uint8_t ret; subchannel_t subc; dev->ops->get_subchannel(dev, dev->seek_pos, &subc); - cdrom_log("Get Current Subcode-q Play Status = %02x, op = %02x.\n", dev->cd_status, dev->audio_op); + b[0] = subc.attr; + b[1] = bin2bcd(subc.track); + b[2] = bin2bcd(subc.index); + b[3] = bin2bcd(subc.rel_m); + b[4] = bin2bcd(subc.rel_s); + b[5] = bin2bcd(subc.rel_f); + b[6] = bin2bcd(subc.abs_m); + b[7] = bin2bcd(subc.abs_s); + b[8] = bin2bcd(subc.abs_f); +} - if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->cd_status == CD_STATUS_PLAYING_COMPLETED)) +uint8_t +cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b) +{ + uint8_t ret; + subchannel_t subc; + + dev->ops->get_subchannel(dev, dev->seek_pos, &subc); + + if ((dev->cd_status == CD_STATUS_DATA_ONLY) || + (dev->cd_status == CD_STATUS_PLAYING_COMPLETED) || + (dev->cd_status == CD_STATUS_STOPPED)) ret = 0x03; else ret = (dev->cd_status == CD_STATUS_PLAYING) ? 0x00 : dev->audio_op; @@ -957,9 +1046,7 @@ read_toc_normal(cdrom_t *dev, unsigned char *b, unsigned char start_track, int m /* No suitable starting track, return with error. */ if (first_track == -1) { -#ifdef ENABLE_CDROM_LOG cdrom_log(" [ERROR] No suitable track found\n"); -#endif return -1; } @@ -1128,9 +1215,7 @@ read_toc_sony(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf /* No suitable starting track, return with error. */ if (first_track == -1) { -#ifdef ENABLE_CDROM_LOG cdrom_log(" [ERROR] No suitable track found\n"); -#endif return -1; } @@ -1138,8 +1223,8 @@ read_toc_sony(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf cdrom_log(" tracks(%i) = %02X, %02X, %i:%02i.%02i\n", i, ti.attr, ti.number, ti.m, ti.s, ti.f); dev->ops->get_track_info(dev, i + 1, 0, &ti); - b[len++] = ti.attr; b[len++] = ti.number; /* track number */ + b[len++] = ti.attr; if (msf) { b[len++] = 0; @@ -1154,7 +1239,6 @@ read_toc_sony(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf b[len++] = temp; } } - return len; } diff --git a/src/include/86box/cdrom.h b/src/include/86box/cdrom.h index bd17449b1..5c9b9fc4f 100644 --- a/src/include/86box/cdrom.h +++ b/src/include/86box/cdrom.h @@ -60,7 +60,7 @@ enum { CDROM_BUS_USB = 8 }; -#define KNOWN_CDROM_DRIVE_TYPES 35 +#define KNOWN_CDROM_DRIVE_TYPES 41 #define BUS_TYPE_IDE CDROM_BUS_ATAPI #define BUS_TYPE_SCSI CDROM_BUS_SCSI #define BUS_TYPE_BOTH -2 @@ -99,17 +99,23 @@ static const struct { "CHINON", "CD-ROM CDS-431", "H42 ", "(SCSI) CHINON CD-ROM CDS-431 H42", "CHINON_CD-ROM_CDS-431_H42", BUS_TYPE_SCSI }, /*22*/ { "DEC", "RRD45 (C) DEC", "0436", "(SCSI) DEC RRD45 0436", "DEC_RRD45_0436", BUS_TYPE_SCSI }, /*23*/ { "MATSHITA", "CD-ROM CR-501", "1.0b", "(SCSI) MATSHITA CD-ROM CR-501 1.0b", "MATSHITA_CD-ROM_CR-501_1.0b", BUS_TYPE_SCSI }, /*24*/ - { "NEC", "CD-ROM DRIVE:75", "1.00", "(SCSI) NEC CD-ROM DRIVE:75 1.00", "NEC_CD-ROM_DRIVE75_1.00", BUS_TYPE_SCSI }, /*25*/ - { "NEC", "CD-ROM DRIVE:464", "1.05", "(SCSI) NEC CD-ROM DRIVE:464 1.05", "NEC_CD-ROM_DRIVE464_1.05", BUS_TYPE_SCSI }, /*26*/ - { "SONY", "CD-ROM CDU-541", "1.0i", "(SCSI) SONY CD-ROM CDU-541 1.0i", "SONY_CD-ROM_CDU-541_1.0i", BUS_TYPE_SCSI }, /*27*/ - { "SONY", "CD-ROM CDU-76S", "1.00", "(SCSI) SONY CD-ROM CDU-76S 1.00", "SONY_CD-ROM_CDU-76S_1.00", BUS_TYPE_SCSI }, /*28*/ - { "PHILIPS", "CDD2600", "1.07", "(SCSI) PHILIPS CDD2600 1.07", "PHILIPS_CDD2600_1.07", BUS_TYPE_SCSI }, /*29*/ - { "PIONEER", "CD-ROM DRM-604X", "2403", "(SCSI) PIONEER CD-ROM DRM-604X 2403", "PIONEER_CD-ROM_DRM-604X_2403", BUS_TYPE_SCSI }, /*30*/ - { "PLEXTOR", "CD-ROM PX-32TS", "1.03", "(SCSI) PLEXTOR CD-ROM PX-32TS 1.03", "PLEXTOR_CD-ROM_PX-32TS_1.03", BUS_TYPE_SCSI }, /*31*/ - { "TEAC", "CD-R55S", "1.0R", "(SCSI) TEAC CD-R55S 1.0R", "TEAC_CD-R55S_1.0R", BUS_TYPE_SCSI }, /*32*/ - { "TOSHIBA", "CD-ROM DRIVE:XM", "3433", "(SCSI) TOSHIBA CD-ROM DRIVE:XM 3433", "TOSHIBA_CD-ROM_DRIVEXM_3433", BUS_TYPE_SCSI }, /*33*/ - { "TOSHIBA", "CD-ROM XM-3301TA", "0272", "(SCSI) TOSHIBA CD-ROM XM-3301TA 0272", "TOSHIBA_CD-ROM_XM-3301TA_0272", BUS_TYPE_SCSI }, /*34*/ - { "TOSHIBA", "CD-ROM XM-5701TA", "3136", "(SCSI) TOSHIBA CD-ROM XM-5701TA 3136", "TOSHIBA_CD-ROM_XM-5701TA_3136", BUS_TYPE_SCSI }, /*35*/ + { "NEC", "CD-ROM DRIVE:38", "1.03", "(SCSI) NEC CD-ROM DRIVE:38 1.03", "NEC_CD-ROM_DRIVE38_1.03", BUS_TYPE_SCSI }, /*25*/ + { "NEC", "CD-ROM DRIVE:211", "1.00", "(SCSI) NEC CD-ROM DRIVE:211 1.00", "NEC_CD-ROM_DRIVE211_1.00", BUS_TYPE_SCSI }, /*26*/ + { "NEC", "CD-ROM DRIVE:464", "1.05", "(SCSI) NEC CD-ROM DRIVE:464 1.05", "NEC_CD-ROM_DRIVE464_1.05", BUS_TYPE_SCSI }, /*27*/ + { "SONY", "CD-ROM CDU-541", "1.0i", "(SCSI) SONY CD-ROM CDU-541 1.0i", "SONY_CD-ROM_CDU-541_1.0i", BUS_TYPE_SCSI }, /*28*/ + { "SONY", "CD-ROM CDU-561", "1.8k", "(SCSI) SONY CD-ROM CDU-561 1.8k", "SONY_CD-ROM_CDU-561_1.8k", BUS_TYPE_SCSI }, /*29*/ + { "SONY", "CD-ROM CDU-76S", "1.00", "(SCSI) SONY CD-ROM CDU-76S 1.00", "SONY_CD-ROM_CDU-76S_1.00", BUS_TYPE_SCSI }, /*30*/ + { "PHILIPS", "CDD2600", "1.07", "(SCSI) PHILIPS CDD2600 1.07", "PHILIPS_CDD2600_1.07", BUS_TYPE_SCSI }, /*31*/ + { "PIONEER", "CD-ROM DRM-604X", "2403", "(SCSI) PIONEER CD-ROM DRM-604X 2403", "PIONEER_CD-ROM_DRM-604X_2403", BUS_TYPE_SCSI }, /*32*/ + { "PLEXTOR", "CD-ROM PX-32TS", "1.03", "(SCSI) PLEXTOR CD-ROM PX-32TS 1.03", "PLEXTOR_CD-ROM_PX-32TS_1.03", BUS_TYPE_SCSI }, /*33*/ + { "TEAC", "CD 50", "1.00", "(SCSI) TEAC CD 50 1.00", "TEAC_CD_50_1.00", BUS_TYPE_SCSI }, /*34*/ + { "TEAC", "CD-ROM R55S", "1.0R", "(SCSI) TEAC CD-ROM R55S 1.0R", "TEAC_CD-ROM_R55S_1.0R", BUS_TYPE_SCSI }, /*35*/ + { "TEXEL", "CD-ROM DM-XX24", "1.00", "(SCSI) TEXEL CD-ROM DM-XX24 1.00", "TEXEL_CD-ROM_DM-XX24_1.00", BUS_TYPE_SCSI }, /*36*/ + { "TOSHIBA", "CD-ROM DRIVE:XM", "3433", "(SCSI) TOSHIBA CD-ROM DRIVE:XM 3433", "TOSHIBA_CD-ROM_DRIVEXM_3433", BUS_TYPE_SCSI }, /*37*/ + { "TOSHIBA", "CD-ROM XM-3201B", "3232", "(SCSI) TOSHIBA CD-ROM XM-3201B 3232", "TOSHIBA_CD-ROM_XM-3201B_3232", BUS_TYPE_SCSI }, /*38*/ + { "TOSHIBA", "CD-ROM XM-3301TA", "0272", "(SCSI) TOSHIBA CD-ROM XM-3301TA 0272", "TOSHIBA_CD-ROM_XM-3301TA_0272", BUS_TYPE_SCSI }, /*39*/ + { "TOSHIBA", "CD-ROM XM-5701TA", "3136", "(SCSI) TOSHIBA CD-ROM XM-5701TA 3136", "TOSHIBA_CD-ROM_XM-5701TA_3136", BUS_TYPE_SCSI }, /*40*/ + { "TOSHIBA", "DVD-ROM SD-M1401", "1008", "(SCSI) TOSHIBA DVD-ROM SD-M1401 1008", "TOSHIBA_DVD-ROM_SD-M1401_1008", BUS_TYPE_SCSI }, /*41*/ { "", "", "", "", "", BUS_TYPE_NONE }, }; @@ -186,15 +192,16 @@ typedef struct cdrom { int prev_host_drive; int cd_buflen; int audio_op; + int sony_msf; const cdrom_ops_t *ops; void *image; - void (*insert)(void *priv); - void (*close)(void *priv); - uint32_t (*get_volume)(void *priv, int channel); - uint32_t (*get_channel)(void *priv, int channel); + void (*insert)(void *p); + void (*close)(void *p); + uint32_t (*get_volume)(void *p, int channel); + uint32_t (*get_channel)(void *p, int channel); int16_t cd_buffer[BUF_SIZE]; } cdrom_t; @@ -215,12 +222,16 @@ extern int cdrom_is_pre(cdrom_t *dev, uint32_t lba); extern int cdrom_audio_callback(cdrom_t *dev, int16_t *output, int len); extern uint8_t cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf); extern uint8_t cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit); +extern uint8_t cdrom_audio_track_search_pioneer(cdrom_t *dev, uint32_t pos, uint8_t playbit); +extern uint8_t cdrom_audio_play_pioneer(cdrom_t *dev, uint32_t pos); extern uint8_t cdrom_audio_play_toshiba(cdrom_t *dev, uint32_t pos, int type); extern void cdrom_audio_pause_resume(cdrom_t *dev, uint8_t resume); extern uint8_t cdrom_audio_scan(cdrom_t *dev, uint32_t pos, int type); +extern uint8_t cdrom_get_audio_status_pioneer(cdrom_t *dev, uint8_t *b); extern uint8_t cdrom_get_audio_status_sony(cdrom_t *dev, uint8_t *b, int msf); extern uint8_t cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf); extern void cdrom_get_current_subchannel_sony(cdrom_t *dev, uint8_t *b, int msf); +extern void cdrom_get_current_subcodeq(cdrom_t *dev, uint8_t *b); extern uint8_t cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b); extern int cdrom_read_toc(cdrom_t *dev, unsigned char *b, int type, unsigned char start_track, int msf, int max_len); diff --git a/src/include/86box/scsi_spock.h b/src/include/86box/scsi_spock.h index bfa579c82..057271772 100644 --- a/src/include/86box/scsi_spock.h +++ b/src/include/86box/scsi_spock.h @@ -22,5 +22,6 @@ #define SCSI_SPOCK_H extern const device_t spock_device; +extern const device_t tribble_device; #endif /*SCSI_SPOCK_H*/ diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index 8357ba647..8f5bffbd9 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -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, }, diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index d9699dda7..cca446a7a 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -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]; } diff --git a/src/scsi/scsi_spock.c b/src/scsi/scsi_spock.c index d70afca76..6ce79f097 100644 --- a/src/scsi/scsi_spock.c +++ b/src/scsi/scsi_spock.c @@ -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 +};