Compare commits

...

11 Commits

Author SHA1 Message Date
2b3ceea4f5 Move CD blank media to separate status field.
Some checks failed
CMake (macos) / Qt 5 GUI, Debug, NDR, x86_64 (push) Has been cancelled
CMake (macos) / SDL GUI, Debug, NDR, x86_64 (push) Has been cancelled
CMake (macos) / Qt 5 GUI, Debug, ODR, arm64 (push) Has been cancelled
CMake (macos) / SDL GUI, Debug, ODR, arm64 (push) Has been cancelled
CMake (macos) / Qt 5 GUI, Debug, ODR, x86_64 (push) Has been cancelled
CMake (macos) / SDL GUI, Debug, ODR, x86_64 (push) Has been cancelled
CMake (macos) / Qt 5 GUI, Dev, NDR, arm64 (push) Has been cancelled
CMake (macos) / SDL GUI, Dev, NDR, arm64 (push) Has been cancelled
CMake (macos) / Qt 5 GUI, Dev, NDR, x86_64 (push) Has been cancelled
CMake (macos) / SDL GUI, Dev, NDR, x86_64 (push) Has been cancelled
CMake (macos) / Qt 5 GUI, Dev, ODR, arm64 (push) Has been cancelled
CMake (macos) / SDL GUI, Dev, ODR, arm64 (push) Has been cancelled
CMake (macos) / Qt 5 GUI, Dev, ODR, x86_64 (push) Has been cancelled
CMake (macos) / SDL GUI, Dev, ODR, x86_64 (push) Has been cancelled
CMake (Windows) / Qt 5 GUI, Debug, NDR, CLANGARM64 (push) Has been cancelled
CMake (Windows) / Qt 5 GUI, Debug, NDR, MINGW64 (push) Has been cancelled
CMake (Windows) / Qt 5 GUI, Debug, ODR, CLANGARM64 (push) Has been cancelled
CMake (Windows) / Qt 5 GUI, Debug, ODR, MINGW64 (push) Has been cancelled
CMake (Windows) / Qt 5 GUI, Dev, NDR, CLANGARM64 (push) Has been cancelled
CMake (Windows) / Qt 5 GUI, Dev, NDR, MINGW64 (push) Has been cancelled
CMake (Windows) / Qt 5 GUI, Dev, ODR, CLANGARM64 (push) Has been cancelled
CMake (Windows) / Qt 5 GUI, Dev, ODR, MINGW64 (push) Has been cancelled
CodeQL Analysis (Linux) / Qt 5 GUI, Debug, NDR, x86_64 (push) Has been cancelled
CodeQL Analysis (Linux) / SDL GUI, Debug, NDR, x86_64 (push) Has been cancelled
CodeQL Analysis (Linux) / Qt 5 GUI, Debug, ODR, x86_64 (push) Has been cancelled
CodeQL Analysis (Linux) / SDL GUI, Debug, ODR, x86_64 (push) Has been cancelled
CodeQL Analysis (macos) / Qt 5 GUI, Debug, NDR, x86_64 (push) Has been cancelled
CodeQL Analysis (macos) / Qt 5 GUI, Debug, ODR, x86_64 (push) Has been cancelled
CodeQL Analysis (Windows) / Qt 5 GUI, Debug, NDR, MINGW64 (push) Has been cancelled
CodeQL Analysis (Windows) / Qt 5 GUI, Debug, ODR, MINGW64 (push) Has been cancelled
2025-09-24 06:55:37 +01:00
6498914df9 Implement READ ATIP command. 2025-09-24 04:43:33 +01:00
864bd03c99 Implement READ PMA command. 2025-09-24 04:41:11 +01:00
ea339fb2ec Return invalid field if asked for a TOC and disc is a blank disc in CD drives. 2025-09-24 04:13:41 +01:00
7efcbddc80 Implement READ DISC INFORMATION for blank CD-R. 2025-09-24 04:09:47 +01:00
2d20d55a65 Change the CD-R status number. 2025-09-24 03:26:50 +01:00
f534b35257 Implement inserting blank media into drive. 2025-09-24 02:51:13 +01:00
6029b563e2 Add skeleton for writable cdrom image file. 2025-09-24 02:19:12 +01:00
cc570f2a9c Add dummy UI option to add blank media to Yamaha drive. 2025-09-24 01:42:42 +01:00
49f462c3cf Add mode pages for the Yamaha drive. 2025-09-23 22:14:54 +01:00
c33e98d7e0 Add Yamaha CRW8424E drive model. 2025-09-23 19:30:41 +01:00
9 changed files with 544 additions and 16 deletions

View File

@@ -24,6 +24,7 @@ add_library(cdrom OBJECT
cdrom_image.c
cdrom_image_viso.c
cdrom_mke.c
cdrom_image_writable.c
)
if(NOT WIN32)
target_include_directories(86Box PRIVATE PkgConfig::SNDFILE)

View File

@@ -12,6 +12,7 @@
*
* Copyright 2018-2021 Miran Grca.
*/
#include <inttypes.h>
#ifdef ENABLE_CDROM_LOG
#include <stdarg.h>
@@ -26,6 +27,7 @@
#include <86box/config.h>
#include <86box/cdrom.h>
#include <86box/cdrom_image.h>
#include <86box/cdrom_image_writable.h>
#include <86box/cdrom_interface.h>
#ifdef USE_CDROM_MITSUMI
#include <86box/cdrom_mitsumi.h>
@@ -2147,6 +2149,65 @@ cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b)
return ret;
}
int
cdrom_read_pma(const cdrom_t *dev, uint8_t *b, const int max_len)
{
if (max_len < 4)
return -1;
// This is exactly what a blank CD-R returns, no PMA, seems only CD-RWs have PMA?
b[0] = 0x00; /* PMA Data Length (MSB) */
b[1] = 0x02; /* PMA Data Length (LSB) */
b[2] = 0x00; /* Reserved */
b[3] = 0x00; /* Reserved */
return 4;
}
int
cdrom_read_atip(const cdrom_t *dev, uint8_t *b, const int max_len)
{
if (max_len < 28)
return -1;
b[ 0] = 0x00; /* ATIP Data Length (MSB) */
b[ 1] = 0x1a; /* ATIP Data Length (LSB) */
b[ 2] = 0x00; /* Reserved */
b[ 3] = 0x00; /* Reserved */
// Special Information 1
b[ 4] = 0xd0; /* Indicative Target Writing Power, Reference Speed */
b[ 5] = 0x00; /* URU */
b[ 6] = 0x98; /* 1, Disc Type, Disc Sub-Type, A1 Valid, A2 Valid, A3 Valid*/
b[ 7] = 0x00; /* Reserved*/
// Special Information 2
b[ 8] = 0x61; /* ATIP Start Time of Lead-in (Min) */
b[ 9] = 0x1a; /* ATIP Start Time of Lead-in (Sec) */
b[10] = 0x42; /* ATIP Start Time of Lead-in (Frame) */
b[11] = 0x00; /* Reserved */
// Special Information 3
b[12] = 0x4f; /* ATIP Last Possible Start of Lead-out (Min) */
b[13] = 0x3b; /* ATIP Last Possible Start of Lead-out (Sec) */
b[14] = 0x47; /* ATIP Last Possible Start of Lead-out (Frame) */
b[15] = 0x00; /* Reserved */
// Additional Information 1
b[16] = 0x00; /* A1 Values */
b[17] = 0x00; /* A1 Values */
b[18] = 0x80; /* A1 Values */
b[19] = 0x00; /* Reserved */
// Additional Information 2
b[20] = 0x00; /* A2 Values */
b[21] = 0x80; /* A2 Values */
b[22] = 0x00; /* A2 Values */
b[23] = 0x00; /* Reserved */
// Additional Information 3
b[24] = 0x00; /* A3 Values */
b[25] = 0x80; /* A3 Values */
b[26] = 0x80; /* A3 Values */
b[27] = 0x00; /* Reserved */
return 28;
}
int
cdrom_read_toc(const cdrom_t *dev, uint8_t *b, const int type,
const uint8_t start_track, const int msf, const int max_len)
@@ -2740,6 +2801,45 @@ cdrom_read_disc_information(const cdrom_t *dev, uint8_t *buffer)
int ls_last = 0;
int t_b0 = -1;
if (dev->blank_media == CD_BLANK_CDR) {
memset(buffer, 0x00, 34);
buffer[ 0] = 0x00; /* Disc Information Length (MSB) */
buffer[ 1] = 0x20; /* Disc Information Lenght (LSB) */
buffer[ 2] = 0x00; /* Reserved, Erasable, State of Last Session, Disc Status */
buffer[ 3] = 0x01; /* Number of First Track on Disc */
buffer[ 4] = 0x01; /* Number of Sessions (LSB) */
buffer[ 5] = 0x01; /* First track number in last session (LSB) */
buffer[ 6] = 0x01; /* Last track number in last session (LSB) */
buffer[ 7] = 0x00; /* DID_V, DBC_V, URU, DAC_V, Reserved, Dbit, BG format Status */
buffer[ 8] = 0xff; /* Disc type */
buffer[ 9] = 0x00; /* Number Of Sessions (MSB) */
buffer[10] = 0x00; /* First Track Number in Last Session (MSB) */
buffer[11] = 0x00; /* Last Track Number in Last Session (MSB) */
buffer[12] = 0x00; /* Disc identification (MSB...) */
buffer[13] = 0x00; /* ... */
buffer[14] = 0x00; /* ... */
buffer[15] = 0x00; /* Disc identification (...LSB) */
buffer[16] = 0x00; /* Last session Lead-In Start Address (MSB...) */
buffer[17] = 0x61; /* ... */
buffer[18] = 0x1a; /* ... */
buffer[19] = 0x42; /* Last session Lead-In Start Address (...LSB) */
buffer[20] = 0x00; /* Last Possible Start Time for Start of Lead-out (MSB) */
buffer[21] = 0x4f; /* ... */
buffer[22] = 0x3b; /* ... */
buffer[23] = 0x47; /* Last Possible Start Time for Start of Lead-out (...LSB) */
buffer[24] = 0x00; /* Disc barcode (MSB...) */
buffer[25] = 0x00; /* ... */
buffer[26] = 0x00; /* ... */
buffer[27] = 0x00; /* ... */
buffer[28] = 0x00; /* ... */
buffer[29] = 0x00; /* ... */
buffer[30] = 0x00; /* ... */
buffer[31] = 0x00; /* Disc barcode (...LSB) */
return;
}
dev->ops->get_raw_track_info(dev->local, &num, rti);
for (int i = 0; i < num; i++)
@@ -2996,6 +3096,37 @@ cdrom_update_status(cdrom_t *dev)
}
}
int
cdrom_insert_blank(cdrom_t *dev, const char *fn)
{
int ret = 0;
// Create new image
dev->local = wimage_open(dev, dev->image_path);
// Clear cached sectors
dev->cached_sector = -1;
// If new image could not be created
if (dev->local == NULL) {
dev->ops = NULL;
dev->image_path[0] = 0;
ret = 1;
} else {
// All looking good, reset state
dev->seek_pos = 0;
dev->cd_buflen = 0;
dev->cd_status = CD_STATUS_DATA_ONLY;
dev->blank_media = CD_BLANK_CDR;
dev->cdrom_capacity = 0;
cdrom_log(dev->log, "Blank CD-R created\n");
cdrom_insert(dev->id);
}
return ret;
}
int
cdrom_load(cdrom_t *dev, const char *fn, const int skip_insert)
{
@@ -3092,6 +3223,7 @@ cdrom_hard_reset(void)
dev->is_chinon = !strcmp(vendor, "CHINON");
dev->is_pioneer = !strcmp(vendor, "PIONEER");
dev->is_plextor = !strcmp(vendor, "PLEXTOR");
dev->is_yamaha = !strcmp(vendor, "YAMAHA");
dev->is_sony = (dev->bus_type == CDROM_BUS_SCSI) &&
(!strcmp(vendor, "DEC") ||
!strcmp(vendor, "ShinaKen") ||

View File

@@ -0,0 +1,197 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* CD-R(W) writable image file handling module.
*
* Authors: Nat Portillo, <claunia@claunia.com>
*
* Copyright 2025 Nat Portillo.
*/
#define __STDC_FORMAT_MACROS
#include <ctype.h>
#include <inttypes.h>
#ifdef ENABLE_IMAGE_LOG
#include <stdarg.h>
#endif
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <86box/log.h>
#include <86box/cdrom.h>
#include <86box/cdrom_image_writable.h>
#include <sndfile.h>
#define MAX_LINE_LENGTH 512
#define MAX_FILENAME_LENGTH 256
#define CROSS_LEN 512
static char temp_keyword[1024];
typedef struct track_index_t {
int64_t start;
uint64_t length;
uint64_t file_start;
uint64_t file_length;
wtrack_file_t *file;
} track_index_t;
typedef struct track_t {
uint8_t session;
uint8_t attr;
uint8_t tno;
uint8_t point;
uint8_t extra[4];
uint8_t mode;
uint8_t form;
uint8_t subch_type;
uint8_t skip;
uint8_t max_index;
uint32_t sector_size;
track_index_t idx[100];
} track_t;
typedef struct cd_image_t {
cdrom_t *dev;
void *log;
int has_audio;
int32_t tracks_num;
track_t *tracks;
} cd_image_t;
#ifdef ENABLE_IMAGE_LOG
int image_do_log = ENABLE_IMAGE_LOG;
void
image_log(void *priv, const char *fmt, ...)
{
va_list ap;
if (image_do_log) {
va_start(ap, fmt);
log_out(priv, fmt, ap);
va_end(ap);
}
}
static char *cit[4] = { "SPECIAL", "NONE", "ZERO", "NORMAL" };
#else
# define image_log(priv, fmt, ...)
#endif
static int
wimage_get_track_info(const void *local, const uint32_t track,
const int end, track_info_t *ti)
{
// TODO: Not implemented
return -1;
}
static void
wimage_get_raw_track_info(const void *local, int *num, uint8_t *buffer)
{
// TODO: Not implemented
}
static int
wimage_is_track_pre(const void *local, const uint32_t sector)
{
// TODO: Not implemented
return -1;
}
static int
wimage_read_sector(const void *local, uint8_t *buffer,
const uint32_t sector)
{
// TODO: Not implemented
return -1;
}
static uint8_t
wimage_get_track_type(const void *local, const uint32_t sector)
{
// TODO: Not implemented
return 0;
}
static uint32_t
wimage_get_last_block(const void *local)
{
// TODO: Not implemented
return 0;
}
static int
wimage_read_dvd_structure(const void *local, const uint8_t layer, const uint8_t format,
uint8_t *buffer, uint32_t *info)
{
// TODO: Not implemented
return -1;
}
static int
wimage_is_dvd(const void *local)
{
// TODO: Not implemented
return 0;
}
static int
wimage_has_audio(const void *local)
{
// TODO: Not implemented
return 0;
}
static void
wimage_close(void *local)
{
// TODO: Not implemented
}
static const cdrom_ops_t image_ops = {
wimage_get_track_info,
wimage_get_raw_track_info,
wimage_is_track_pre,
wimage_read_sector,
wimage_get_track_type,
wimage_get_last_block,
wimage_read_dvd_structure,
wimage_is_dvd,
wimage_has_audio,
NULL,
wimage_close,
NULL
};
/* Public functions. */
void *
wimage_open(cdrom_t *dev, const char *path)
{
cd_image_t *img = (cd_image_t *) calloc(1, sizeof(cd_image_t));
dev->ops = &image_ops;
// TODO: Not implemented
return img;
}

View File

@@ -31,7 +31,10 @@
#define CD_STATUS_HOLD 8
#define CD_STATUS_DVD_REJECTED 16
#define CD_STATUS_HAS_AUDIO 0xc
#define CD_STATUS_MASK 0x1f
#define CD_STATUS_MASK 0x2f
#define CD_BLANK_NOT 0x00
#define CD_BLANK_CDR 0x01
/* Medium changed flag. */
#define CD_STATUS_TRANSITION 0x40
@@ -184,6 +187,7 @@ static const struct cdrom_drive_types_s {
{ "TOSHIBA", "CD-ROM XM-6402B", "1008", "toshiba_6402b", BUS_TYPE_IDE, 0, 32, 96, 0, 0, { 4, 2, 2, 2 } },
{ "TOSHIBA", "CD-ROM XM-6702B", "1007", "toshiba_6720b", BUS_TYPE_IDE, 0, 48, 96, 0, 0, { 4, 2, 2, 2 } },
{ "TOSHIBA", "DVD-ROM SD-M1802", "1051", "toshiba_m1802", BUS_TYPE_IDE, 0, 48, 96, 0, 1, { 4, 2, 2, 2 } },
{ "YAMAHA", "CRW8424E", "1.0g", "yamaha_crw8424", BUS_TYPE_IDE, 0, 24, 36, 0, 0, { 4, 2, 2, -1 } },
{ "CHINON", "CD-ROM CDS-431", "H42 ", "chinon_431", BUS_TYPE_SCSI, 1, 1, 36, 1, 0, { -1, -1, -1, -1 } },
{ "CHINON", "CD-ROM CDX-435", "M62 ", "chinon_435", BUS_TYPE_SCSI, 1, 2, 36, 1, 0, { -1, -1, -1, -1 } },
{ "DEC", "RRD45 (C) DEC", "0436", "dec_45", BUS_TYPE_SCSI, 1, 4, 36, 0, 0, { -1, -1, -1, -1 } },
@@ -307,6 +311,7 @@ typedef struct cdrom {
Bit 1 = DMA supportd. */
uint8_t cd_status; /* Struct variable reserved for
media status. */
uint8_t blank_media;
uint8_t speed;
uint8_t cur_speed;
@@ -343,6 +348,7 @@ typedef struct cdrom {
void (*insert)(void *priv);
void (*close)(void *priv);
void (*insert_blank)(void *priv);
uint32_t (*get_volume)(void *p, int channel);
uint32_t (*get_channel)(void *p, int channel);
@@ -359,6 +365,7 @@ typedef struct cdrom {
int32_t is_plextor;
int32_t is_sony;
int32_t is_toshiba;
int32_t is_yamaha;
int32_t c2_first;
int32_t cur_buf;
@@ -441,6 +448,8 @@ 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(const cdrom_t *dev, uint8_t *b, const int type,
const uint8_t start_track, const int msf, const int max_len);
extern int cdrom_read_pma(const cdrom_t *dev, uint8_t *b, const int max_len);
extern int cdrom_read_atip(const cdrom_t *dev, uint8_t *b, const int max_len);
extern int cdrom_read_toc_sony(const cdrom_t *dev, uint8_t *b, const uint8_t start_track,
const int msf, const int max_len);
#ifdef USE_CDROM_MITSUMI
@@ -472,6 +481,7 @@ extern void cdrom_exit(const uint8_t id);
extern int cdrom_is_empty(const uint8_t id);
extern void cdrom_eject(const uint8_t id);
extern void cdrom_reload(const uint8_t id);
extern int cdrom_insert_blank(cdrom_t *dev, const char *fn);
extern void cdrom_compute_ecc_block(cdrom_t *dev, uint8_t *parity, const uint8_t *data,
uint32_t major_count, uint32_t minor_count,

View File

@@ -0,0 +1,34 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* CD-R(W) writable image file handling module.
*
* Authors: Nat Portillo, <claunia@claunia.com>
*
* Copyright 2025 Nat Portillo.
*/
#ifndef CDROM_IMAGE_WRITABLE_H
#define CDROM_IMAGE_WRITABLE_H
/* Track file struct. */
typedef struct wtrack_file_t {
int (*read)(void *priv, uint8_t *buffer, uint64_t seek, size_t count);
uint64_t (*get_length)(void *priv);
void (*close)(void *priv);
char fn[260];
FILE *fp;
void *priv;
void *log;
int motorola;
} wtrack_file_t;
extern void *wimage_open(cdrom_t *dev, const char *path);
#endif /*CDROM_IMAGE_WRITABLE_H*/

View File

@@ -163,21 +163,22 @@
#define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12_MATSUSHITA 0xe9 /* Matsushita Vendor Unique command */
/* Mode page codes for mode sense/set */
#define GPMODE_UNIT_ATN_PAGE 0x00
#define GPMODE_R_W_ERROR_PAGE 0x01
#define GPMODE_DISCONNECT_PAGE 0x02 /* Disconnect/reconnect page */
#define GPMODE_FORMAT_DEVICE_PAGE 0x03
#define GPMODE_RIGID_DISK_PAGE 0x04 /* Rigid disk geometry page */
#define GPMODE_FLEXIBLE_DISK_PAGE 0x05
#define GPMODE_CACHING_PAGE 0x08
#define GPMODE_CDROM_PAGE_SONY 0x08
#define GPMODE_CDROM_AUDIO_PAGE_SONY 0x09
#define GPMODE_CDROM_PAGE 0x0d
#define GPMODE_CDROM_AUDIO_PAGE 0x0e
#define GPMODE_CAPABILITIES_PAGE 0x2a
#define GPMODE_IOMEGA_PAGE 0x2f
#define GPMODE_UNK_VENDOR_PAGE 0x30
#define GPMODE_ALL_PAGES 0x3f
#define GPMODE_UNIT_ATN_PAGE 0x00
#define GPMODE_R_W_ERROR_PAGE 0x01
#define GPMODE_DISCONNECT_PAGE 0x02 /* Disconnect/reconnect page */
#define GPMODE_FORMAT_DEVICE_PAGE 0x03
#define GPMODE_RIGID_DISK_PAGE 0x04 /* Rigid disk geometry page */
#define GPMODE_FLEXIBLE_DISK_PAGE 0x05
#define GPMODE_CDROM_WRITE_PARAMETERS_PAGE 0x05
#define GPMODE_CACHING_PAGE 0x08
#define GPMODE_CDROM_PAGE_SONY 0x08
#define GPMODE_CDROM_AUDIO_PAGE_SONY 0x09
#define GPMODE_CDROM_PAGE 0x0d
#define GPMODE_CDROM_AUDIO_PAGE 0x0e
#define GPMODE_CAPABILITIES_PAGE 0x2a
#define GPMODE_IOMEGA_PAGE 0x2f
#define GPMODE_UNK_VENDOR_PAGE 0x30
#define GPMODE_ALL_PAGES 0x3f
/* Mode page codes for presence */
#define GPMODEP_UNIT_ATN_PAGE 0x0000000000000001LL

View File

@@ -162,6 +162,9 @@ MediaMenu::refresh(QMenu *parentMenu)
cdromMutePos = menu->children().count();
menu->addAction(QIcon(":/settings/qt/icons/cdrom_mute.ico"), tr("&Mute"), [this, i]() { cdromMute(i); })->setCheckable(true);
menu->addSeparator();
// Can make it only appear if the drive is a Yamaha?
menu->addAction(tr("Add &blank disc"), [this, i]() { cdromInsertBlank(i); })->setCheckable(false);
menu->addSeparator();
menu->addAction(getIconWithIndicator(QIcon(":/settings/qt/icons/cdrom_image.ico"), pixmap_size, QIcon::Normal, Browse), tr("&Image..."), [this, i]() { cdromMount(i, 0, nullptr); })->setCheckable(false);
menu->addAction(getIconWithIndicator(QIcon(":/settings/qt/icons/cdrom_folder.ico"), pixmap_size, QIcon::Normal, Browse), tr("&Folder..."), [this, i]() { cdromMount(i, 1, nullptr); })->setCheckable(false);
menu->addSeparator();
@@ -608,6 +611,53 @@ MediaMenu::cdromMount(int i, int dir, const QString &arg)
cdromMount(i, filename);
}
void
MediaMenu::cdromInsertBlank(int i)
{
// Check if drive is empty
if (!cdrom_is_empty(i)) {
QMessageBox::information(parentWidget, tr("Drive not empty"), tr("The drive must be empty to add a blank disc."));
return;
}
cdrom_t *drv = &cdrom[i];
/* (claunia) TODO: Temporarily disabled because a KDE thumbnailer makes it crash while debugging on my machine, until later
// Ask user for cuesheet file location
QString cueFileName = QFileDialog::getSaveFileName(
parentWidget,
tr("CD-R(W) cuesheet image"),
QString(),
tr("Cuesheet files (*.cue)")
);
if (cueFileName.isEmpty()) {
return;
}
// Ensure .cue extension
if (!cueFileName.endsWith(".cue", Qt::CaseInsensitive)) {
cueFileName += ".cue";
}
QFile cueFile(cueFileName);
if (cueFile.exists()) {
QMessageBox::StandardButton reply = QMessageBox::question(
parentWidget,
tr("Replace file"),
tr("The file '%1' already exists. Do you want to replace it?").arg(cueFileName),
QMessageBox::Yes | QMessageBox::No
);
if (reply != QMessageBox::Yes) {
return;
}
}
// Add a blank disc
cdrom_insert_blank(drv, cueFileName.toUtf8());
*/
cdrom_insert_blank(drv, "/home/claunia/foo_86box.cue"); // (claunia) Temporary hardcoded path until the above is fixed
ui_sb_update_icon_state(SB_CDROM | i, 1);
}
void
MediaMenu::cdromEject(int i)
{

View File

@@ -45,6 +45,7 @@ public:
void cdromMute(int i);
void cdromMount(int i, int dir, const QString &arg);
void cdromMount(int i, const QString &filename);
void cdromInsertBlank(int i);
void cdromEject(int i);
void cdromReload(int index, int slot);
void updateImageHistory(int index, int slot, ui::MediaType type);

View File

@@ -131,6 +131,12 @@ static uint64_t scsi_cdrom_ms_page_flags_sony_scsi = (GPMODEP_R_W_ERROR_PAGE | G
(1ULL << 0x0fULL) | GPMODEP_CAPABILITIES_PAGE |
GPMODEP_ALL_PAGES);
static uint64_t scsi_cdrom_ms_page_flags_yamaha = (GPMODEP_R_W_ERROR_PAGE | GPMODEP_DISCONNECT_PAGE |
GPMODEP_FLEXIBLE_DISK_PAGE | GPMODEP_CACHING_PAGE |
GPMODEP_CDROM_PAGE_SONY | GPMODEP_CDROM_AUDIO_PAGE_SONY |
GPMODEP_CAPABILITIES_PAGE | GPMODEP_ALL_PAGES);
static uint64_t scsi_cdrom_drive_status_page_flags = ((1ULL << 0x01ULL) | (1ULL << 0x02ULL) |
(1ULL << 0x0fULL) | GPMODEP_ALL_PAGES);
@@ -241,6 +247,56 @@ static const mode_sense_pages_t scsi_cdrom_ms_pages_changeable_sony_scsi = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 } }
};
static const mode_sense_pages_t scsi_cdrom_ms_pages_default_yamaha = {
{ [0x01] = { GPMODE_R_W_ERROR_PAGE, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00 },
[0x02] = { GPMODE_DISCONNECT_PAGE, 0x0e, 0x10, 0xf0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00 },
[0x05] = { GPMODE_CDROM_WRITE_PARAMETERS_PAGE, 0x36, 0x00, 0xc7, 0x0a, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x96, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20,
0x20, 0x20, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
[0x08] = { GPMODE_CACHING_PAGE, 0x0a, 0x04, 0x00, 0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff },
[0x0d] = { GPMODE_CDROM_PAGE, 0x06, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x4b },
[0x0e] = { GPMODE_CDROM_AUDIO_PAGE, 0x0e, 0x04, 0x00, 0x00, 0x00, 0x00, 0x4b,
0x01, 0xff, 0x02, 0xff, 0x00, 0x00, 0x00,
0x00 },
[0x2a] = { GPMODE_CAPABILITIES_PAGE, 0x14, 0x07, 0x07, 0x71, 0x6f, 0x29, 0x03,
0x0b, 0x06, 0x01, 0x00, 0x10, 0x00, 0x10,
0x8a, 0x00, 0x00, 0x05, 0x83, 0x05, 0x83 } }
};
// Not true values, need to check real hardware
static const mode_sense_pages_t scsi_cdrom_ms_pages_changeable_yamaha = {
{
[0x01] = { GPMODE_R_W_ERROR_PAGE, 0x06, 0x85, 0xff, 0x00, 0x00, 0x00, 0x00 },
[0x02] = { GPMODE_DISCONNECT_PAGE, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
0x00 },
[0x05] = { GPMODE_CDROM_WRITE_PARAMETERS_PAGE, 0x36, 0x5f, 0xff, 0x0f, 0x00, 0x00, 0x3f,
0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00 },
[0x08] = { GPMODE_CACHING_PAGE, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 },
[0x0d] = { GPMODE_CDROM_PAGE, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
[0x0e] = { GPMODE_CDROM_AUDIO_PAGE, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0f, 0xff, 0x0f, 0xff, 0x00, 0x00, 0x00,
0x00 },
[0x2a] = { GPMODE_CAPABILITIES_PAGE, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
};
// clang-format on
static gesn_cdb_t *gesn_cdb;
@@ -1176,6 +1232,17 @@ scsi_cdrom_insert(void *priv)
}
}
static void
scsi_cdrom_insert_blank(void *priv)
{
scsi_cdrom_t *dev = (scsi_cdrom_t *) priv;
if ((dev == NULL) /*|| (dev->drv == NULL)*/)
return;
scsi_cdrom_log(dev->log, "Inserting blank disc\n");
}
static int
scsi_command_check_ready(const scsi_cdrom_t *dev, const uint8_t *cdb)
{
@@ -2575,6 +2642,12 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb)
if (dev->drv->ops == NULL)
scsi_cdrom_not_ready(dev);
else if (toc_format < 3) {
// Blank discs return invalid field when asked for a TOC
if (dev->drv->blank_media) {
scsi_cdrom_invalid_field(dev, toc_format);
break;
}
len = cdrom_read_toc(dev->drv, dev->buffer, toc_format, cdb[6], msf, max_len);
/* If the returned length is -1, this means cdrom_read_toc() has encountered an error. */
if (len == -1)
@@ -2585,6 +2658,16 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb)
scsi_cdrom_set_buf_len(dev, BufLen, &len);
scsi_cdrom_data_command_finish(dev, len, len, len, 0);
}
} else if (toc_format == 3 && dev->drv->blank_media == CD_BLANK_CDR) {
len = cdrom_read_pma(dev->drv, dev->buffer, max_len);
scsi_cdrom_set_buf_len(dev, BufLen, &len);
scsi_cdrom_data_command_finish(dev, len, len, len, 0);
} else if (toc_format == 4 && dev->drv->blank_media == CD_BLANK_CDR) {
len = cdrom_read_atip(dev->drv, dev->buffer, max_len);
scsi_cdrom_set_buf_len(dev, BufLen, &len);
scsi_cdrom_data_command_finish(dev, len, len, len, 0);
} else
scsi_cdrom_invalid_field(dev, toc_format);
break;
@@ -3578,6 +3661,14 @@ atapi_out:
dev->buffer[6] = 8;
len = 8;
// Undo the overflow if disc capacity is blank
if (dev->drv->blank_media) {
dev->buffer[0] = 0x00;
dev->buffer[1] = 0x00;
dev->buffer[2] = 0x00;
dev->buffer[3] = 0x00;
}
scsi_cdrom_log(dev->log, "CD-ROM Capacity: %08X\n",
dev->drv->cdrom_capacity - 1);
@@ -3932,6 +4023,7 @@ scsi_cdrom_drive_reset(const int c)
drv->get_volume = scsi_cdrom_get_volume;
drv->get_channel = scsi_cdrom_get_channel;
drv->close = scsi_cdrom_close;
drv->insert_blank = scsi_cdrom_insert_blank;
drv->sector_size = 2048;
(void) scsi_cdrom_update_sector_flags(dev);
@@ -3973,6 +4065,10 @@ scsi_cdrom_drive_reset(const int c)
dev->ven_cmd_is_data[0xc6] = 1;
dev->ven_cmd_is_data[0xc7] = 1;
dev->use_cdb_9 = 1;
} else if (dev->drv->is_yamaha) {
dev->ms_page_flags = scsi_cdrom_ms_page_flags_yamaha;
dev->ms_pages_default = scsi_cdrom_ms_pages_default_yamaha;
dev->ms_pages_changeable = scsi_cdrom_ms_pages_changeable_yamaha;
}
if (dev->tf == NULL)
@@ -4025,6 +4121,12 @@ scsi_cdrom_drive_reset(const int c)
id->write = NULL;
id->interrupt_drq = dev->drv->is_early;
if (dev->drv->is_yamaha) {
dev->ms_page_flags = scsi_cdrom_ms_page_flags_yamaha;
dev->ms_pages_default = scsi_cdrom_ms_pages_default_yamaha;
dev->ms_pages_changeable = scsi_cdrom_ms_pages_changeable_yamaha;
}
valid = 1;
ide_atapi_attach(id);