diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index ae7278742..dd1604801 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -430,26 +430,31 @@ cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit) if (dev->cd_status == CD_STATUS_DATA_ONLY) return 0; + cdrom_log("Audio Track Search: MSF = %06x, type = %02x, playbit = %02x\n", pos, type, playbit); switch (type) { + case 0x00: + if (pos == 0xffffffff) { + cdrom_log("CD-ROM %i: Search from current position\n", dev->id); + pos = dev->seek_pos; + } + break; case 0x40: - cdrom_log("Audio Track Search: MSF = %06x, type = %02x\n", pos, type); m = CD_DCB((pos >> 24) & 0xff); s = CD_DCB((pos >> 16) & 0xff); f = CD_DCB((pos >> 8) & 0xff); - pos = MSFtoLBA(m, s, f) - 150; + if (pos == 0xffffffff) { + cdrom_log("CD-ROM %i: Search from current position\n", dev->id); + pos = dev->seek_pos; + } else + pos = MSFtoLBA(m, s, f) - 150; break; } - /* Do this at this point, since it's at this point that we know the - actual LBA position to start playing from. */ - if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) { - cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos); - cdrom_stop(dev); - return 0; - } + /* 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->seek_pos = pos; - dev->noplay = !playbit; + dev->cd_buflen = 0; dev->cd_status = playbit ? CD_STATUS_PLAYING : CD_STATUS_PAUSED; return 1; } @@ -462,30 +467,29 @@ cdrom_toshiba_audio_play(cdrom_t *dev, uint32_t pos, int type) if (dev->cd_status == CD_STATUS_DATA_ONLY) return 0; - if (dev->cd_status == CD_STATUS_STOPPED || dev->cd_status == CD_STATUS_PAUSED) - dev->cd_status = CD_STATUS_PLAYING; - /*Preliminary support, revert if too incomplete*/ + cdrom_log("Toshiba Play Audio: MSF = %06x, cdstatus = %02x\n", pos, dev->cd_status); switch (type) { case 0x40: - cdrom_log("Toshiba Play Audio: MSF = %06x, type = %02x\n", pos, type); m = CD_DCB((pos >> 24) & 0xff); s = CD_DCB((pos >> 16) & 0xff); f = CD_DCB((pos >> 8) & 0xff); pos = MSFtoLBA(m, s, f) - 150; break; + case 0xc0: + if (pos == 0xffffffff) { + cdrom_log("CD-ROM %i: Playing from current position\n", dev->id); + pos = dev->cd_end; + } + break; } - /* Do this at this point, since it's at this point that we know the - actual LBA position to start playing from. */ - if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) { - cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos); - cdrom_stop(dev); - return 0; - } + /* 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_end = pos; + dev->cd_end = pos; dev->cd_buflen = 0; + dev->cd_status = CD_STATUS_PLAYING; return 1; } @@ -587,15 +591,12 @@ cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b) dev->ops->get_subchannel(dev, dev->seek_pos, &subc); - if (dev->cd_status == CD_STATUS_PLAYING) - ret = 0x00; - else if (dev->cd_status == CD_STATUS_PAUSED) { - if (dev->noplay) - ret = 0x02; - else - ret = 0x01; - } else + cdrom_log("Get Current Subcode-q Play Status = %02x, op = %02x.\n", dev->cd_status, dev->audio_op); + + if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->cd_status == CD_STATUS_PLAYING_COMPLETED)) ret = 0x03; + else + ret = (dev->cd_status == CD_STATUS_PLAYING) ? 0x00 : dev->audio_op; b[0] = subc.attr; b[1] = CD_BCD(subc.track); @@ -895,6 +896,7 @@ cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, in dev->ops->get_tracks(dev, &first_track, &last_track); + cdrom_log("Read DISC Info TOC Type = %d.\n", type); switch (type) { case 0: b[0] = CD_BCD(first_track); diff --git a/src/include/86box/cdrom.h b/src/include/86box/cdrom.h index 72c74a144..f5bfc9026 100644 --- a/src/include/86box/cdrom.h +++ b/src/include/86box/cdrom.h @@ -116,7 +116,7 @@ typedef struct cdrom { seek_diff, cd_end; int host_drive, prev_host_drive, - cd_buflen, noplay; + cd_buflen, audio_op; const cdrom_ops_t *ops; diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 80ff4184a..e736b879d 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -2045,7 +2045,8 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) break; } pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - ret = cdrom_audio_track_search(dev->drv, pos, cdb[9], cdb[1] & 1); + ret = cdrom_audio_track_search(dev->drv, pos, cdb[9] & 0xc0, cdb[1] & 1); + dev->drv->audio_op = (cdb[1] & 1) ? 0x03 : 0x02; if (ret) scsi_cdrom_command_complete(dev); @@ -2061,7 +2062,7 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) break; } pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - ret = cdrom_toshiba_audio_play(dev->drv, pos, cdb[9]); + ret = cdrom_toshiba_audio_play(dev->drv, pos, cdb[9] & 0xc0); if (ret) scsi_cdrom_command_complete(dev); @@ -2388,7 +2389,7 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) if (dev->early) ide_padstr8(dev->buffer + idx, 40, "CD-ROM CDS-431"); /* Product */ else - ide_padstr8(dev->buffer + idx, 40, "XM6201TASUN32XCD1103"); /* Product */ + ide_padstr8(dev->buffer + idx, 40, "CD-ROM DRIVE:XM"); /* Product */ } else { if (dev->early) ide_padstr8(dev->buffer + idx, 40, "CD-ROM DRIVE:260"); /* Product */ @@ -2399,7 +2400,7 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) } #endif idx += 40; - ide_padstr8(dev->buffer + idx, 20, "53R141"); /* Product */ + ide_padstr8(dev->buffer + idx, 20, "53R141"); /* Serial */ idx += 20; break; @@ -2443,8 +2444,8 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) ide_padstr8(dev->buffer + 32, 4, "H42"); /* Revision */ } else { ide_padstr8(dev->buffer + 8, 8, "TOSHIBA"); /* Vendor */ - ide_padstr8(dev->buffer + 16, 16, "XM6201TASUN32XCD"); /* Product */ - ide_padstr8(dev->buffer + 32, 4, "1103"); /* Revision */ + ide_padstr8(dev->buffer + 16, 16, "CD-ROM DRIVE:XM"); /* Product */ + ide_padstr8(dev->buffer + 32, 4, "3433"); /* Revision */ } } else { if (dev->early) { @@ -2492,12 +2493,14 @@ atapi_out: case GPCMD_PAUSE_RESUME: scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); cdrom_audio_pause_resume(dev->drv, cdb[8] & 0x01); + dev->drv->audio_op = (cdb[8] & 0x01) ? 0x03 : 0x01; scsi_cdrom_command_complete(dev); break; case GPCMD_STILL: scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - dev->drv->cd_status = CD_STATUS_PAUSED; + cdrom_audio_pause_resume(dev->drv, 0x00); + dev->drv->audio_op = 0x01; scsi_cdrom_command_complete(dev); break;