Overhauled CD-ROM selection for SCSI and ATAPI, including model and vendor specific commands.
Fixed the Spock SCSI ID selection. Fixed CD Audio on NCR 5380-based SCSI controllers. Added a proprietary CD-ROM controller selection (not hooked up yet). All on qt only.
This commit is contained in:
@@ -23,9 +23,12 @@
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/config.h>
|
||||
#include <86box/cdrom.h>
|
||||
#include <86box/cdrom_image.h>
|
||||
#include <86box/cdrom_interface.h>
|
||||
#include <86box/cdrom_mitsumi.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/scsi.h>
|
||||
#include <86box/scsi_device.h>
|
||||
@@ -43,9 +46,6 @@
|
||||
#define MIN_SEEK 2000
|
||||
#define MAX_SEEK 333333
|
||||
|
||||
#define CD_BCD(x) (((x) % 10) | (((x) / 10) << 4))
|
||||
#define CD_DCB(x) ((((x) &0xf0) >> 4) * 10 + ((x) &0x0f))
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
uint8_t user_data[2048],
|
||||
@@ -94,6 +94,8 @@ static uint8_t extra_buffer[296];
|
||||
|
||||
cdrom_t cdrom[CDROM_NUM];
|
||||
|
||||
int cdrom_interface_current;
|
||||
|
||||
#ifdef ENABLE_CDROM_LOG
|
||||
int cdrom_do_log = ENABLE_CDROM_LOG;
|
||||
|
||||
@@ -112,6 +114,145 @@ cdrom_log(const char *fmt, ...)
|
||||
# define cdrom_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static const device_t cdrom_interface_none_device = {
|
||||
.name = "None",
|
||||
.internal_name = "none",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
static const struct {
|
||||
const device_t *device;
|
||||
} controllers[] = {
|
||||
// clang-format off
|
||||
{ &cdrom_interface_none_device },
|
||||
{ NULL }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
/* Reset the CD-ROM Interface, whichever one that is. */
|
||||
void
|
||||
cdrom_interface_reset(void)
|
||||
{
|
||||
cdrom_log("CD-ROM Interface: reset(current=%d)\n",
|
||||
cdrom_interface_current);
|
||||
|
||||
/* If we have a valid controller, add its device. */
|
||||
if (!controllers[cdrom_interface_current].device)
|
||||
return;
|
||||
|
||||
device_add(controllers[cdrom_interface_current].device);
|
||||
}
|
||||
|
||||
char *
|
||||
cdrom_interface_get_internal_name(int cdinterface)
|
||||
{
|
||||
return device_get_internal_name(controllers[cdinterface].device);
|
||||
}
|
||||
|
||||
int
|
||||
cdrom_interface_get_from_internal_name(char *s)
|
||||
{
|
||||
int c = 0;
|
||||
|
||||
while (controllers[c].device != NULL) {
|
||||
if (!strcmp((char *) controllers[c].device->internal_name, s))
|
||||
return c;
|
||||
c++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const device_t *
|
||||
cdrom_interface_get_device(int cdinterface)
|
||||
{
|
||||
return (controllers[cdinterface].device);
|
||||
}
|
||||
|
||||
int
|
||||
cdrom_interface_has_config(int cdinterface)
|
||||
{
|
||||
const device_t *dev = cdrom_interface_get_device(cdinterface);
|
||||
|
||||
if (dev == NULL)
|
||||
return (0);
|
||||
|
||||
if (!device_has_config(dev))
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
cdrom_interface_get_flags(int cdinterface)
|
||||
{
|
||||
return (controllers[cdinterface].device->flags);
|
||||
}
|
||||
|
||||
int
|
||||
cdrom_interface_available(int cdinterface)
|
||||
{
|
||||
return (device_available(controllers[cdinterface].device));
|
||||
}
|
||||
|
||||
char *
|
||||
cdrom_getname(int type)
|
||||
{
|
||||
return (char *) cdrom_drive_types[type].name;
|
||||
}
|
||||
|
||||
char *
|
||||
cdrom_get_internal_name(int type)
|
||||
{
|
||||
return (char *) cdrom_drive_types[type].internal_name;
|
||||
}
|
||||
|
||||
int
|
||||
cdrom_get_from_internal_name(char *s)
|
||||
{
|
||||
int c = 0;
|
||||
|
||||
while (strlen(cdrom_drive_types[c].internal_name)) {
|
||||
if (!strcmp((char *) cdrom_drive_types[c].internal_name, s))
|
||||
return c;
|
||||
c++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
cdrom_set_type(int model, int type)
|
||||
{
|
||||
cdrom[model].type = type;
|
||||
}
|
||||
|
||||
int
|
||||
cdrom_get_type(int model)
|
||||
{
|
||||
return cdrom[model].type;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
bin2bcd(int x)
|
||||
{
|
||||
return (x % 10) | ((x / 10) << 4);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
bcd2bin(int x)
|
||||
{
|
||||
return (x >> 4) * 10 + (x & 0x0f);
|
||||
}
|
||||
|
||||
int
|
||||
cdrom_lba_to_msf_accurate(int lba)
|
||||
{
|
||||
@@ -258,12 +399,26 @@ cdrom_stop(cdrom_t *dev)
|
||||
}
|
||||
|
||||
void
|
||||
cdrom_seek(cdrom_t *dev, uint32_t pos)
|
||||
cdrom_seek(cdrom_t *dev, uint32_t pos, uint8_t vendor_type)
|
||||
{
|
||||
int m, s, f;
|
||||
|
||||
if (!dev)
|
||||
return;
|
||||
|
||||
cdrom_log("CD-ROM %i: Seek to LBA %08X\n", dev->id, pos);
|
||||
cdrom_log("CD-ROM %i: Seek to LBA %08X, vendor type = %02x.\n", dev->id, pos, vendor_type);
|
||||
|
||||
switch (vendor_type) {
|
||||
case 0x40:
|
||||
m = bcd2bin((pos >> 24) & 0xff);
|
||||
s = bcd2bin((pos >> 16) & 0xff);
|
||||
f = bcd2bin((pos >> 8) & 0xff);
|
||||
pos = MSFtoLBA(m, s, f) - 150;
|
||||
break;
|
||||
case 0x80:
|
||||
pos = bcd2bin((pos >> 24) & 0xff);
|
||||
break;
|
||||
}
|
||||
|
||||
dev->seek_pos = pos;
|
||||
cdrom_stop(dev);
|
||||
@@ -323,18 +478,6 @@ cdrom_audio_callback(cdrom_t *dev, int16_t *output, int len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
bin2bcd(int x)
|
||||
{
|
||||
return (x % 10) | ((x / 10) << 4);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
bcd2bin(int x)
|
||||
{
|
||||
return (x >> 4) * 10 + (x & 0x0f);
|
||||
}
|
||||
|
||||
static void
|
||||
msf_from_bcd(int *m, int *s, int *f)
|
||||
{
|
||||
@@ -365,20 +508,22 @@ cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf)
|
||||
/* Track-relative audio play. */
|
||||
dev->ops->get_track_info(dev, ismsf & 0xff, 0, &ti);
|
||||
pos += MSFtoLBA(ti.m, ti.s, ti.f) - 150;
|
||||
} else if (ismsf == 2) {
|
||||
} else if ((ismsf == 2) || (ismsf == 3)) {
|
||||
dev->ops->get_track_info(dev, pos, 0, &ti);
|
||||
pos = MSFtoLBA(ti.m, ti.s, ti.f) - 150;
|
||||
/* We have to end at the *end* of the specified track,
|
||||
not at the beginning. */
|
||||
dev->ops->get_track_info(dev, len, 1, &ti);
|
||||
len = MSFtoLBA(ti.m, ti.s, ti.f) - 150;
|
||||
if (ismsf == 2) {
|
||||
/* We have to end at the *end* of the specified track,
|
||||
not at the beginning. */
|
||||
dev->ops->get_track_info(dev, len, 1, &ti);
|
||||
len = MSFtoLBA(ti.m, ti.s, ti.f) - 150;
|
||||
}
|
||||
} else if (ismsf == 1) {
|
||||
m = (pos >> 16) & 0xff;
|
||||
s = (pos >> 8) & 0xff;
|
||||
f = pos & 0xff;
|
||||
|
||||
/* NEC CDR-260 speaks BCD. */
|
||||
if ((dev->bus_type == CDROM_BUS_ATAPI) && dev->early)
|
||||
if (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.01") || (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.00"))) /*NEC*/
|
||||
msf_from_bcd(&m, &s, &f);
|
||||
|
||||
if (pos == 0xffffff) {
|
||||
@@ -392,7 +537,7 @@ cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf)
|
||||
f = len & 0xff;
|
||||
|
||||
/* NEC CDR-260 speaks BCD. */
|
||||
if ((dev->bus_type == CDROM_BUS_ATAPI) && dev->early)
|
||||
if (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.01") || (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.00"))) /*NEC*/
|
||||
msf_from_bcd(&m, &s, &f);
|
||||
|
||||
len = MSFtoLBA(m, s, f) - 150;
|
||||
@@ -434,33 +579,41 @@ cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit)
|
||||
switch (type) {
|
||||
case 0x00:
|
||||
if (pos == 0xffffffff) {
|
||||
cdrom_log("CD-ROM %i: Search from current position\n", dev->id);
|
||||
cdrom_log("CD-ROM %i: (type 0) Search from current position\n", dev->id);
|
||||
pos = dev->seek_pos;
|
||||
}
|
||||
dev->seek_pos = pos;
|
||||
break;
|
||||
case 0x40:
|
||||
m = CD_DCB((pos >> 24) & 0xff);
|
||||
s = CD_DCB((pos >> 16) & 0xff);
|
||||
f = CD_DCB((pos >> 8) & 0xff);
|
||||
m = bcd2bin((pos >> 24) & 0xff);
|
||||
s = bcd2bin((pos >> 16) & 0xff);
|
||||
f = bcd2bin((pos >> 8) & 0xff);
|
||||
if (pos == 0xffffffff) {
|
||||
cdrom_log("CD-ROM %i: Search from current position\n", dev->id);
|
||||
cdrom_log("CD-ROM %i: (type 1) Search from current position\n", dev->id);
|
||||
pos = dev->seek_pos;
|
||||
} else
|
||||
pos = MSFtoLBA(m, s, f) - 150;
|
||||
|
||||
dev->seek_pos = pos;
|
||||
break;
|
||||
case 0x80:
|
||||
if (pos == 0xffffffff) {
|
||||
cdrom_log("CD-ROM %i: (type 2) Search from current position\n", dev->id);
|
||||
pos = dev->seek_pos;
|
||||
}
|
||||
dev->seek_pos = (pos >> 24) & 0xff;
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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->cd_buflen = 0;
|
||||
dev->cd_status = playbit ? CD_STATUS_PLAYING : CD_STATUS_PAUSED;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
cdrom_toshiba_audio_play(cdrom_t *dev, uint32_t pos, int type)
|
||||
cdrom_audio_play_toshiba(cdrom_t *dev, uint32_t pos, int type)
|
||||
{
|
||||
int m = 0, s = 0, f = 0;
|
||||
|
||||
@@ -468,31 +621,85 @@ cdrom_toshiba_audio_play(cdrom_t *dev, uint32_t pos, int type)
|
||||
return 0;
|
||||
|
||||
/*Preliminary support, revert if too incomplete*/
|
||||
cdrom_log("Toshiba Play Audio: MSF = %06x, cdstatus = %02x\n", pos, dev->cd_status);
|
||||
switch (type) {
|
||||
case 0x00:
|
||||
dev->cd_end = pos;
|
||||
break;
|
||||
case 0x40:
|
||||
m = CD_DCB((pos >> 24) & 0xff);
|
||||
s = CD_DCB((pos >> 16) & 0xff);
|
||||
f = CD_DCB((pos >> 8) & 0xff);
|
||||
m = bcd2bin((pos >> 24) & 0xff);
|
||||
s = bcd2bin((pos >> 16) & 0xff);
|
||||
f = bcd2bin((pos >> 8) & 0xff);
|
||||
pos = MSFtoLBA(m, s, f) - 150;
|
||||
dev->cd_end = pos;
|
||||
break;
|
||||
case 0x80:
|
||||
dev->cd_end = (pos >> 24) & 0xff;
|
||||
break;
|
||||
case 0xc0:
|
||||
if (pos == 0xffffffff) {
|
||||
cdrom_log("CD-ROM %i: Playing from current position\n", dev->id);
|
||||
pos = dev->cd_end;
|
||||
}
|
||||
dev->cd_end = pos;
|
||||
break;
|
||||
}
|
||||
|
||||
cdrom_log("Toshiba/NEC Play Audio: MSF = %06x, type = %02x, cdstatus = %02x\n", pos, type, dev->cd_status);
|
||||
|
||||
/* 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_buflen = 0;
|
||||
dev->cd_status = CD_STATUS_PLAYING;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
cdrom_audio_scan(cdrom_t *dev, uint32_t pos, int type)
|
||||
{
|
||||
int m = 0, s = 0, f = 0;
|
||||
|
||||
if (dev->cd_status == CD_STATUS_DATA_ONLY)
|
||||
return 0;
|
||||
|
||||
cdrom_log("Audio Scan: MSF = %06x, type = %02x\n", pos, type);
|
||||
switch (type) {
|
||||
case 0x00:
|
||||
if (pos == 0xffffffff) {
|
||||
cdrom_log("CD-ROM %i: (type 0) Search from current position\n", dev->id);
|
||||
pos = dev->seek_pos;
|
||||
}
|
||||
dev->seek_pos = pos;
|
||||
break;
|
||||
case 0x40:
|
||||
m = bcd2bin((pos >> 24) & 0xff);
|
||||
s = bcd2bin((pos >> 16) & 0xff);
|
||||
f = bcd2bin((pos >> 8) & 0xff);
|
||||
if (pos == 0xffffffff) {
|
||||
cdrom_log("CD-ROM %i: (type 1) Search from current position\n", dev->id);
|
||||
pos = dev->seek_pos;
|
||||
} else
|
||||
pos = MSFtoLBA(m, s, f) - 150;
|
||||
|
||||
dev->seek_pos = pos;
|
||||
break;
|
||||
case 0x80:
|
||||
dev->seek_pos = (pos >> 24) & 0xff;
|
||||
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;
|
||||
}
|
||||
|
||||
dev->cd_buflen = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
cdrom_audio_pause_resume(cdrom_t *dev, uint8_t resume)
|
||||
{
|
||||
@@ -509,7 +716,6 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf)
|
||||
uint32_t dat;
|
||||
|
||||
dev->ops->get_subchannel(dev, dev->seek_pos, &subc);
|
||||
cdrom_log("CD-ROM %i: Returned subchannel at %02i:%02i.%02i\n", subc.abs_m, subc.abs_s, subc.abs_f);
|
||||
|
||||
if (dev->cd_status == CD_STATUS_DATA_ONLY)
|
||||
ret = 0x15;
|
||||
@@ -522,8 +728,12 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf)
|
||||
ret = 0x13;
|
||||
}
|
||||
|
||||
if (b[pos] > 1)
|
||||
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);
|
||||
|
||||
if (b[pos] > 1) {
|
||||
cdrom_log("B[%i] = %02x, ret = %02x.\n", pos, b[pos], ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
b[pos++] = subc.attr;
|
||||
b[pos++] = subc.track;
|
||||
@@ -533,7 +743,7 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf)
|
||||
b[pos] = 0;
|
||||
|
||||
/* NEC CDR-260 speaks BCD. */
|
||||
if ((dev->bus_type == CDROM_BUS_ATAPI) && dev->early) {
|
||||
if (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.01") || (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.00"))) /*NEC*/ {
|
||||
m = subc.abs_m;
|
||||
s = subc.abs_s;
|
||||
f = subc.abs_f;
|
||||
@@ -552,7 +762,7 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf)
|
||||
b[pos] = 0;
|
||||
|
||||
/* NEC CDR-260 speaks BCD. */
|
||||
if ((dev->bus_type == CDROM_BUS_ATAPI) && dev->early) {
|
||||
if (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.01") || (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.00"))) /*NEC*/ {
|
||||
m = subc.rel_m;
|
||||
s = subc.rel_s;
|
||||
f = subc.rel_f;
|
||||
@@ -583,6 +793,78 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
cdrom_get_current_subchannel_sony(cdrom_t *dev, uint8_t *b, int msf)
|
||||
{
|
||||
subchannel_t subc;
|
||||
int pos = 0, m, s, f;
|
||||
uint32_t dat;
|
||||
|
||||
dev->ops->get_subchannel(dev, dev->seek_pos, &subc);
|
||||
|
||||
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);
|
||||
|
||||
b[pos++] = subc.attr;
|
||||
b[pos++] = subc.track;
|
||||
b[pos++] = 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;
|
||||
} 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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
cdrom_get_audio_status_sony(cdrom_t *dev, uint8_t *b, int msf)
|
||||
{
|
||||
uint8_t ret;
|
||||
subchannel_t subc;
|
||||
int m, s, f;
|
||||
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;
|
||||
}
|
||||
|
||||
if (msf) {
|
||||
b[0] = 0;
|
||||
b[1] = subc.abs_m;
|
||||
b[2] = subc.abs_s;
|
||||
b[3] = subc.abs_f;
|
||||
} else {
|
||||
dat = MSFtoLBA(subc.abs_m, subc.abs_s, subc.abs_f) - 150;
|
||||
b[0] = (dat >> 24) & 0xff;
|
||||
b[1] = (dat >> 16) & 0xff;
|
||||
b[2] = (dat >> 8) & 0xff;
|
||||
b[3] = dat & 0xff;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b)
|
||||
{
|
||||
@@ -599,16 +881,14 @@ cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b)
|
||||
ret = (dev->cd_status == CD_STATUS_PLAYING) ? 0x00 : dev->audio_op;
|
||||
|
||||
b[0] = subc.attr;
|
||||
b[1] = CD_BCD(subc.track);
|
||||
b[2] = CD_BCD(subc.index);
|
||||
b[3] = CD_BCD(subc.rel_m);
|
||||
b[4] = CD_BCD(subc.rel_s);
|
||||
b[5] = CD_BCD(subc.rel_f);
|
||||
b[6] = CD_BCD(subc.abs_m);
|
||||
b[7] = CD_BCD(subc.abs_s);
|
||||
b[8] = CD_BCD(subc.abs_f);
|
||||
cdrom_log("CD-ROM %i: Returned subcode-q at %02i:%02i.%02i, track=%02x\n", dev->id, b[3], b[4], b[5], b[1]);
|
||||
|
||||
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);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -670,7 +950,7 @@ read_toc_normal(cdrom_t *dev, unsigned char *b, unsigned char start_track, int m
|
||||
b[len++] = 0;
|
||||
|
||||
/* NEC CDR-260 speaks BCD. */
|
||||
if ((dev->bus_type == CDROM_BUS_ATAPI) && dev->early) {
|
||||
if (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.01") || (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.00"))) { /*NEC*/
|
||||
m = ti.m;
|
||||
s = ti.s;
|
||||
f = ti.f;
|
||||
@@ -720,7 +1000,7 @@ read_toc_session(cdrom_t *dev, unsigned char *b, int msf)
|
||||
b[len++] = 0;
|
||||
|
||||
/* NEC CDR-260 speaks BCD. */
|
||||
if ((dev->bus_type == CDROM_BUS_ATAPI) && dev->early) {
|
||||
if (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.01") || (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.00"))) { /*NEC*/
|
||||
m = ti.m;
|
||||
s = ti.s;
|
||||
f = ti.f;
|
||||
@@ -778,6 +1058,75 @@ read_toc_raw(cdrom_t *dev, unsigned char *b)
|
||||
return len;
|
||||
}
|
||||
|
||||
static int
|
||||
read_toc_sony(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf)
|
||||
{
|
||||
track_info_t ti;
|
||||
int i, len = 4;
|
||||
int m, s, f;
|
||||
int first_track, last_track;
|
||||
uint32_t temp;
|
||||
|
||||
cdrom_log("read_toc_sony(%08X, %08X, %02X, %i)\n", dev, b, start_track, msf);
|
||||
|
||||
dev->ops->get_tracks(dev, &first_track, &last_track);
|
||||
|
||||
/* Byte 2 = Number of the first track */
|
||||
dev->ops->get_track_info(dev, 1, 0, &ti);
|
||||
b[2] = ti.number;
|
||||
cdrom_log(" b[2] = %02X\n", b[2]);
|
||||
|
||||
/* Byte 3 = Number of the last track before the lead-out track */
|
||||
dev->ops->get_track_info(dev, last_track, 0, &ti);
|
||||
b[3] = ti.number;
|
||||
cdrom_log(" b[3] = %02X\n", b[2]);
|
||||
|
||||
if (start_track == 0x00)
|
||||
first_track = 0;
|
||||
else {
|
||||
first_track = -1;
|
||||
for (i = 0; i <= last_track; i++) {
|
||||
dev->ops->get_track_info(dev, i + 1, 0, &ti);
|
||||
if (ti.number >= start_track) {
|
||||
first_track = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
cdrom_log(" first_track = %i, last_track = %i\n", first_track, last_track);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
for (i = first_track; i <= last_track; i++) {
|
||||
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 */
|
||||
|
||||
if (msf) {
|
||||
b[len++] = 0;
|
||||
b[len++] = ti.m;
|
||||
b[len++] = ti.s;
|
||||
b[len++] = ti.f;
|
||||
} else {
|
||||
temp = MSFtoLBA(ti.m, ti.s, ti.f) - 150;
|
||||
b[len++] = temp >> 24;
|
||||
b[len++] = temp >> 16;
|
||||
b[len++] = temp >> 8;
|
||||
b[len++] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int
|
||||
cdrom_read_toc(cdrom_t *dev, unsigned char *b, int type, unsigned char start_track, int msf, int max_len)
|
||||
{
|
||||
@@ -806,6 +1155,21 @@ cdrom_read_toc(cdrom_t *dev, unsigned char *b, int type, unsigned char start_tra
|
||||
return len;
|
||||
}
|
||||
|
||||
int
|
||||
cdrom_read_toc_sony(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf, int max_len)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = read_toc_sony(dev, b, start_track, msf);
|
||||
|
||||
len = MIN(len, max_len);
|
||||
|
||||
b[0] = (uint8_t) (((len - 2) >> 8) & 0xff);
|
||||
b[1] = (uint8_t) ((len - 2) & 0xff);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/* New API calls for Mitsumi CD-ROM. */
|
||||
void
|
||||
cdrom_get_track_buffer(cdrom_t *dev, uint8_t *buf)
|
||||
@@ -841,7 +1205,7 @@ cdrom_get_q(cdrom_t *dev, uint8_t *buf, int *curtoctrk, uint8_t mode)
|
||||
dev->ops->get_track_info(dev, *curtoctrk, 0, &ti);
|
||||
buf[0] = (ti.attr << 4) & 0xf0;
|
||||
buf[1] = ti.number;
|
||||
buf[2] = CD_BCD(*curtoctrk + 1);
|
||||
buf[2] = bin2bcd(*curtoctrk + 1);
|
||||
buf[3] = ti.m;
|
||||
buf[4] = ti.s;
|
||||
buf[5] = ti.f;
|
||||
@@ -888,36 +1252,50 @@ cdrom_mitsumi_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
uint8_t
|
||||
cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, int type)
|
||||
{
|
||||
track_info_t ti;
|
||||
int first_track, last_track;
|
||||
int m = 0, s = 0, f = 0;
|
||||
|
||||
dev->ops->get_tracks(dev, &first_track, &last_track);
|
||||
|
||||
cdrom_log("Read DISC Info TOC Type = %d.\n", type);
|
||||
cdrom_log("Read DISC Info TOC Type = %d, track = %d, first_track = %d, last_track = %d.\n", type, track, first_track, last_track);
|
||||
switch (type) {
|
||||
case 0:
|
||||
b[0] = CD_BCD(first_track);
|
||||
b[1] = CD_BCD(last_track);
|
||||
b[0] = bin2bcd(first_track);
|
||||
b[1] = bin2bcd(last_track);
|
||||
b[2] = 0;
|
||||
b[3] = 0;
|
||||
cdrom_log("CD-ROM %i: Returned Toshiba/NEC disc information (type 0) at %02i:%02i\n", dev->id, b[0], b[1]);
|
||||
break;
|
||||
case 1:
|
||||
dev->ops->get_track_info(dev, 0xAA, 0, &ti);
|
||||
b[0] = CD_BCD(ti.m);
|
||||
b[1] = CD_BCD(ti.s);
|
||||
b[2] = CD_BCD(ti.f);
|
||||
dev->ops->get_track_info(dev, 0xaa, 0, &ti);
|
||||
m = ti.m;
|
||||
s = ti.s;
|
||||
f = ti.f;
|
||||
msf_to_bcd(&m, &s, &f);
|
||||
b[0] = m;
|
||||
b[1] = s;
|
||||
b[2] = f;
|
||||
b[3] = 0;
|
||||
cdrom_log("CD-ROM %i: Returned Toshiba/NEC disc information (type 1) at %02i:%02i.%02i, track=%d\n", dev->id, b[0], b[1], b[2], bcd2bin(track));
|
||||
break;
|
||||
case 2:
|
||||
dev->ops->get_track_info(dev, CD_DCB(track), 0, &ti);
|
||||
b[0] = CD_BCD(ti.m);
|
||||
b[1] = CD_BCD(ti.s);
|
||||
b[2] = CD_BCD(ti.f);
|
||||
if (track > bin2bcd(last_track))
|
||||
return 0;
|
||||
|
||||
dev->ops->get_track_info(dev, bcd2bin(track), 0, &ti);
|
||||
m = ti.m;
|
||||
s = ti.s;
|
||||
f = ti.f;
|
||||
msf_to_bcd(&m, &s, &f);
|
||||
b[0] = m;
|
||||
b[1] = s;
|
||||
b[2] = f;
|
||||
b[3] = ti.attr;
|
||||
cdrom_log("CD-ROM %i: Returned Toshiba disc information at %02i:%02i.%02i, track=%d\n", dev->id, b[0], b[1], b[2], CD_DCB(track));
|
||||
cdrom_log("CD-ROM %i: Returned Toshiba/NEC disc information (type 2) at %02i:%02i.%02i, track=%d, m=%02i,s=%02i,f=%02i, tno=%02x.\n", dev->id, b[0], b[1], b[2], bcd2bin(track), m, s, f, ti.attr);
|
||||
break;
|
||||
case 3:
|
||||
b[0] = 0x00; /*TODO: correct it further, mark it as CD-Audio/CD-ROM disc for now*/
|
||||
@@ -926,6 +1304,8 @@ cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, in
|
||||
b[3] = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1203,7 +1583,7 @@ read_mode2_xa_form2(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t
|
||||
|
||||
int
|
||||
cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type,
|
||||
int cdrom_sector_flags, int *len)
|
||||
int cdrom_sector_flags, int *len, uint8_t vendor_type)
|
||||
{
|
||||
uint8_t *b, *temp_b;
|
||||
uint32_t msf, lba;
|
||||
@@ -1224,8 +1604,23 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int c
|
||||
lba = MSFtoLBA(m, s, f) - 150;
|
||||
msf = sector;
|
||||
} else {
|
||||
lba = sector;
|
||||
msf = cdrom_lba_to_msf_accurate(sector);
|
||||
switch (vendor_type) {
|
||||
case 0x00:
|
||||
lba = sector;
|
||||
msf = cdrom_lba_to_msf_accurate(sector);
|
||||
break;
|
||||
case 0x40:
|
||||
m = bcd2bin((sector >> 24) & 0xff);
|
||||
s = bcd2bin((sector >> 16) & 0xff);
|
||||
f = bcd2bin((sector >> 8) & 0xff);
|
||||
lba = MSFtoLBA(m, s, f) - 150;
|
||||
msf = sector;
|
||||
break;
|
||||
case 0x80:
|
||||
lba = bcd2bin((sector >> 24) & 0xff);
|
||||
msf = sector;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->ops->track_type)
|
||||
|
||||
Reference in New Issue
Block a user