diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 4be61c13f..f6c7e9297 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -3450,3 +3450,9 @@ cdrom_reload(const uint8_t id) config_save(); } + +int +cdrom_send_cuesheet(cdrom_t *dev, const uint8_t *buffer, int len) +{ + return dev->ops->send_cuesheet(dev->local, buffer, len); +} \ No newline at end of file diff --git a/src/cdrom/cdrom_image.c b/src/cdrom/cdrom_image.c index 816a563d8..d9051ac8b 100644 --- a/src/cdrom/cdrom_image.c +++ b/src/cdrom/cdrom_image.c @@ -2658,6 +2658,7 @@ static const cdrom_ops_t image_ops = { image_has_audio, NULL, image_close, + NULL, NULL }; diff --git a/src/cdrom/cdrom_image_writable.c b/src/cdrom/cdrom_image_writable.c index 9697f959f..8effdf171 100644 --- a/src/cdrom/cdrom_image_writable.c +++ b/src/cdrom/cdrom_image_writable.c @@ -68,6 +68,17 @@ typedef struct cd_image_t { track_t *tracks; } cd_image_t; +typedef struct raw_cuesheet_t { + uint8_t ctl_adr; + uint8_t tno; + uint8_t index; + uint8_t data_form; + uint8_t scms; + uint8_t amin; + uint8_t asec; + uint8_t aframe; +} raw_cuesheet_t; + #ifdef ENABLE_IMAGE_LOG int image_do_log = ENABLE_IMAGE_LOG; @@ -168,6 +179,14 @@ wimage_close(void *local) // TODO: Not implemented } +static int +wimage_send_cuesheet(const void *local, const uint8_t *buffer, const int len) +{ + const raw_cuesheet_t* rc = (raw_cuesheet_t*) buffer; + + return 0; +} + static const cdrom_ops_t image_ops = { wimage_get_track_info, wimage_get_raw_track_info, @@ -180,7 +199,8 @@ static const cdrom_ops_t image_ops = { wimage_has_audio, NULL, wimage_close, - NULL + NULL, + wimage_send_cuesheet }; /* Public functions. */ diff --git a/src/include/86box/cdrom.h b/src/include/86box/cdrom.h index c52bd6826..d536470a8 100644 --- a/src/include/86box/cdrom.h +++ b/src/include/86box/cdrom.h @@ -293,6 +293,8 @@ typedef struct cdrom_ops_t { int (*is_empty)(const void *local); void (*close)(void *local); void (*load)(const void *local); + int (*send_cuesheet)(const void *local, const uint8_t *buffer, + int len); } cdrom_ops_t; typedef struct cdrom { @@ -488,6 +490,7 @@ extern void cdrom_compute_ecc_block(cdrom_t *dev, uint8_t *parity, co uint32_t major_mult, uint32_t minor_inc, int m2f1); extern unsigned long cdrom_crc32(unsigned long crc, const unsigned char *buf, size_t len); +extern int cdrom_send_cuesheet(cdrom_t *dev, const uint8_t *buffer, int len); extern int cdrom_assigned_letters; diff --git a/src/include/86box/scsi_device.h b/src/include/86box/scsi_device.h index d200aa0a4..a720ca925 100644 --- a/src/include/86box/scsi_device.h +++ b/src/include/86box/scsi_device.h @@ -92,6 +92,7 @@ #define GPCMD_READ_TRACK_INFORMATION 0x52 #define GPCMD_MODE_SELECT_10 0x55 #define GPCMD_MODE_SENSE_10 0x5a +#define GPCMD_SEND_CUE_SHEET 0x5d #define GPCMD_PLAY_AUDIO_12 0xa5 #define GPCMD_READ_12 0xa8 #define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12 0xa9 diff --git a/src/qt/dummy_cdrom_ioctl.c b/src/qt/dummy_cdrom_ioctl.c index 8dffc6758..b9ebbb9f1 100644 --- a/src/qt/dummy_cdrom_ioctl.c +++ b/src/qt/dummy_cdrom_ioctl.c @@ -215,7 +215,8 @@ static const cdrom_ops_t ioctl_ops = { ioctl_has_audio, ioctl_is_empty, ioctl_close, - ioctl_load + ioctl_load, + NULL }; /* Public functions. */ diff --git a/src/qt/win_cdrom_ioctl.c b/src/qt/win_cdrom_ioctl.c index 6bc2df27c..cb6ccf8c9 100644 --- a/src/qt/win_cdrom_ioctl.c +++ b/src/qt/win_cdrom_ioctl.c @@ -817,7 +817,8 @@ static const cdrom_ops_t ioctl_ops = { ioctl_has_audio, ioctl_is_empty, ioctl_close, - ioctl_load + ioctl_load, + NULL }; /* Public functions. */ diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 571f32d39..7e7328fe6 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -98,6 +98,7 @@ uint8_t scsi_cdrom_command_flags[0x100] = { [0x51 ... 0x52] = IMPLEMENTED | CHECK_READY, [0x55] = IMPLEMENTED, [0x5a] = IMPLEMENTED, + [0x5d] = IMPLEMENTED | CHECK_READY, [0xa5] = IMPLEMENTED | CHECK_READY, [0xa8 ... 0xa9] = IMPLEMENTED | CHECK_READY, [0xad] = IMPLEMENTED, @@ -3002,6 +3003,19 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb) scsi_cdrom_data_command_finish(dev, len, len, len, 1); break; + case GPCMD_SEND_CUE_SHEET: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_OUT); + + len = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; + scsi_cdrom_buf_alloc(dev, 65536); + + scsi_cdrom_set_buf_len(dev, BufLen, &len); + + dev->total_length = len; + + scsi_cdrom_data_command_finish(dev, len, len, len, 1); + break; + case GPCMD_GET_CONFIGURATION: scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); @@ -3858,7 +3872,18 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc) } } break; + case GPCMD_SEND_CUE_SHEET: + int data_length = dev->current_cdb[5] << 16 | + dev->current_cdb[7] << 8 | + dev->current_cdb[8]; + int ret = cdrom_send_cuesheet(dev->drv, dev->buffer, data_length); + if (ret) { + scsi_cdrom_invalid_field_pl(dev, 0); + } + + scsi_cdrom_buf_free(dev); + break; default: break; } diff --git a/src/unix/dummy_cdrom_ioctl.c b/src/unix/dummy_cdrom_ioctl.c index af8679ecc..1bfaa57ba 100644 --- a/src/unix/dummy_cdrom_ioctl.c +++ b/src/unix/dummy_cdrom_ioctl.c @@ -213,7 +213,8 @@ static const cdrom_ops_t ioctl_ops = { ioctl_has_audio, ioctl_is_empty, ioctl_close, - ioctl_load + ioctl_load, + NULL }; /* Public functions. */