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:
@@ -1068,6 +1068,10 @@ pc_reset_hard_init(void)
|
||||
|
||||
/* Reset the Hard Disk Controller module. */
|
||||
hdc_reset();
|
||||
|
||||
/* Reset the CD-ROM Controller module. */
|
||||
cdrom_interface_reset();
|
||||
|
||||
/* Reset and reconfigure the SCSI layer. */
|
||||
scsi_card_init();
|
||||
|
||||
|
||||
@@ -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;
|
||||
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 {
|
||||
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)
|
||||
|
||||
41
src/config.c
41
src/config.c
@@ -61,6 +61,7 @@
|
||||
#include <86box/scsi.h>
|
||||
#include <86box/scsi_device.h>
|
||||
#include <86box/cdrom.h>
|
||||
#include <86box/cdrom_interface.h>
|
||||
#include <86box/zip.h>
|
||||
#include <86box/mo.h>
|
||||
#include <86box/sound.h>
|
||||
@@ -904,6 +905,15 @@ load_storage_controllers(void)
|
||||
p = NULL;
|
||||
}
|
||||
|
||||
p = ini_section_get_string(cat, "cdrom_interface", NULL);
|
||||
if (p != NULL)
|
||||
cdrom_interface_current = cdrom_interface_get_from_internal_name(p);
|
||||
|
||||
if (free_p) {
|
||||
free(p);
|
||||
p = NULL;
|
||||
}
|
||||
|
||||
ide_ter_enabled = !!ini_section_get_int(cat, "ide_ter", 0);
|
||||
ide_qua_enabled = !!ini_section_get_int(cat, "ide_qua", 0);
|
||||
|
||||
@@ -1321,8 +1331,13 @@ load_floppy_and_cdrom_drives(void)
|
||||
|
||||
sprintf(temp, "cdrom_%02i_speed", c + 1);
|
||||
cdrom[c].speed = ini_section_get_int(cat, temp, 8);
|
||||
sprintf(temp, "cdrom_%02i_early", c + 1);
|
||||
cdrom[c].early = ini_section_get_int(cat, temp, 0);
|
||||
|
||||
sprintf(temp, "cdrom_%02i_type", c + 1);
|
||||
p = ini_section_get_string(cat, temp, (c == 1) ? "86BOX_CD-ROM_1.00" : "none");
|
||||
cdrom_set_type(c, cdrom_get_from_internal_name(p));
|
||||
if (cdrom_get_type(c) > KNOWN_CDROM_DRIVE_TYPES)
|
||||
cdrom_set_type(c, KNOWN_CDROM_DRIVE_TYPES);
|
||||
ini_section_delete_var(cat, temp);
|
||||
|
||||
/* Default values, needed for proper operation of the Settings dialog. */
|
||||
cdrom[c].ide_channel = cdrom[c].scsi_device_id = c + 2;
|
||||
@@ -2470,6 +2485,12 @@ save_storage_controllers(void)
|
||||
ini_section_set_string(cat, "hdc",
|
||||
hdc_get_internal_name(hdc_current));
|
||||
|
||||
if (cdrom_interface_current == 0)
|
||||
ini_section_delete_var(cat, "cdrom_interface");
|
||||
else
|
||||
ini_section_set_string(cat, "cdrom_interface",
|
||||
cdrom_interface_get_internal_name(cdrom_interface_current));
|
||||
|
||||
if (ide_ter_enabled == 0)
|
||||
ini_section_delete_var(cat, "ide_ter");
|
||||
else
|
||||
@@ -2717,17 +2738,25 @@ save_floppy_and_cdrom_drives(void)
|
||||
ini_section_set_int(cat, temp, cdrom[c].speed);
|
||||
}
|
||||
|
||||
sprintf(temp, "cdrom_%02i_early", c + 1);
|
||||
if ((cdrom[c].bus_type == 0) || (cdrom[c].early == 0)) {
|
||||
sprintf(temp, "cdrom_%02i_type", c + 1);
|
||||
if ((cdrom[c].bus_type == 0) || (cdrom[c].bus_type == CDROM_BUS_MITSUMI)) {
|
||||
ini_section_delete_var(cat, temp);
|
||||
} else {
|
||||
ini_section_set_int(cat, temp, cdrom[c].early);
|
||||
ini_section_set_string(cat, temp,
|
||||
cdrom_get_internal_name(cdrom_get_type(c)));
|
||||
}
|
||||
|
||||
sprintf(temp, "cdrom_%02i_parameters", c + 1);
|
||||
if (cdrom[c].bus_type == 0) {
|
||||
ini_section_delete_var(cat, temp);
|
||||
} else {
|
||||
} else { /*In case one wants an ATAPI drive on SCSI and vice-versa.*/
|
||||
if (cdrom[c].bus_type == CDROM_BUS_ATAPI) {
|
||||
if (cdrom_drive_types[cdrom_get_type(c)].bus_type == BUS_TYPE_SCSI)
|
||||
cdrom[c].bus_type = CDROM_BUS_SCSI;
|
||||
} else if (cdrom[c].bus_type == CDROM_BUS_SCSI) {
|
||||
if (cdrom_drive_types[cdrom_get_type(c)].bus_type == BUS_TYPE_IDE)
|
||||
cdrom[c].bus_type = CDROM_BUS_ATAPI;
|
||||
}
|
||||
sprintf(tmp2, "%u, %s", cdrom[c].sound_on,
|
||||
hdd_bus_to_string(cdrom[c].bus_type, 1));
|
||||
ini_section_set_string(cat, temp, tmp2);
|
||||
|
||||
@@ -60,6 +60,54 @@ enum {
|
||||
CDROM_BUS_USB
|
||||
};
|
||||
|
||||
#define KNOWN_CDROM_DRIVE_TYPES 30
|
||||
#define BUS_TYPE_ALL 0
|
||||
#define BUS_TYPE_IDE 1
|
||||
#define BUS_TYPE_SCSI 2
|
||||
|
||||
static const struct
|
||||
{
|
||||
const char vendor[9];
|
||||
const char model[17];
|
||||
const char revision[5];
|
||||
const char *name;
|
||||
const char *internal_name;
|
||||
const int bus_type;
|
||||
} cdrom_drive_types[] =
|
||||
{
|
||||
{ "86BOX", "CD-ROM", "1.00", "(ATAPI/SCSI) 86BOX CD-ROM 1.00", "86BOX_CD-ROM_1.00", BUS_TYPE_ALL},
|
||||
{ "AZT", "CDA46802I", "1.15", "(ATAPI) AZT CDA46802I 1.15", "AZT_CDA46802I_1.15", BUS_TYPE_IDE},
|
||||
{ "BTC", "CD-ROM BCD36XH", "U1.0", "(ATAPI) BTC CD-ROM BCD36XH U1.0", "BTC_CD-ROM_BCD36XH_U1.0", BUS_TYPE_IDE},
|
||||
{ "GOLDSTAR", "CRD-8160B", "3.14", "(ATAPI) GOLDSTAR CRD-8160B 3.14", "GOLDSTAR_CRD-8160B_3.14", BUS_TYPE_IDE},
|
||||
{ "HITACHI", "CDR-8130", "0020", "(ATAPI) HITACHI CDR-8130 0020", "HITACHI_CDR-8130_0020", BUS_TYPE_IDE},
|
||||
{ "KENWOOD", "CD-ROM UCR-421", "208E", "(ATAPI) KENWOOD CD-ROM UCR-421 208E", "KENWOOD_CD-ROM_UCR-421_208E", BUS_TYPE_IDE},
|
||||
{ "MATSHITA", "CD-ROM CR-587", "7S13", "(ATAPI) MATSHITA CD-ROM CR-587 7S13", "MATSHITA_CD-ROM_CR-587_7S13", BUS_TYPE_IDE},
|
||||
{ "MATSHITA", "CD-ROM CR-588", "LS15", "(ATAPI) MATSHITA CD-ROM CR-588 LS15", "MATSHITA_CD-ROM_CR-588_LS15", BUS_TYPE_IDE},
|
||||
{ "MITSUMI", "CRMC-FX4820T", "D02A", "(ATAPI) MITSUMI CRMC-FX4820T D02A", "MITSUMI_CRMC-FX4820T_D02A", BUS_TYPE_IDE},
|
||||
{ "NEC", "CD-ROM DRIVE:260", "1.00", "(ATAPI) NEC CD-ROM DRIVE:260 1.00", "NEC_CD-ROM_DRIVE260_1.00", BUS_TYPE_IDE},
|
||||
{ "NEC", "CD-ROM DRIVE:260", "1.01", "(ATAPI) NEC CD-ROM DRIVE:260 1.01", "NEC_CD-ROM_DRIVE260_1.01", BUS_TYPE_IDE},
|
||||
{ "NEC", "CDR-1300A", "1.05", "(ATAPI) NEC CDR-1300A 1.05", "NEC_CDR-1300A_1.05", BUS_TYPE_IDE},
|
||||
{ "PHILIPS", "CD-ROM PCA403CD", "U31P", "(ATAPI) PHILIPS CD-ROM PCA403CD U31P", "PHILIPS_CD-ROM_PCA403CD_U31P", BUS_TYPE_IDE},
|
||||
{ "SONY", "CD-ROM CDU76", "1.0i", "(ATAPI) SONY CD-ROM CDU76 1.0i", "SONY_CD-ROM_CDU76_1.0i", BUS_TYPE_IDE},
|
||||
{ "SONY", "CD-ROM CDU311", "3.0h", "(ATAPI) SONY CD-ROM CDU311 3.0h", "SONY_CD-ROM_CDU311_3.0h", BUS_TYPE_IDE},
|
||||
{ "TOSHIBA", "CD-ROM XM-5702B", "TA70", "(ATAPI) TOSHIBA CD-ROM XM-5702B TA70", "TOSHIBA_CD-ROM_XM-5702B_TA70", BUS_TYPE_IDE},
|
||||
{ "CHINON", "CD-ROM CDS-431", "H42 ", "(SCSI) CHINON CD-ROM CDS-431 H42", "CHINON_CD-ROM_CDS-431_H42", BUS_TYPE_SCSI},
|
||||
{ "DEC", "RRD45 (C) DEC", "0436", "(SCSI) DEC RRD45 0436", "DEC_RRD45_0436", BUS_TYPE_SCSI},
|
||||
{ "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},
|
||||
{ "NEC", "CD-ROM DRIVE:74", "1.00", "(SCSI) NEC CD-ROM DRIVE:74 1.00", "NEC_CD-ROM_DRIVE74_1.00", BUS_TYPE_SCSI},
|
||||
{ "NEC", "CD-ROM DRIVE:464", "1.05", "(SCSI) NEC CD-ROM DRIVE:464 1.05", "NEC_CD-ROM_DRIVE464_1.05", BUS_TYPE_SCSI},
|
||||
{ "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},
|
||||
{ "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},
|
||||
{ "PHILIPS", "CDD2600", "1.07", "(SCSI) PHILIPS CDD2600 1.07", "PHILIPS_CDD2600_1.07", BUS_TYPE_SCSI},
|
||||
{ "PIONEER", "CD-ROM DRM-604X", "2403", "(SCSI) PIONEER CD-ROM DRM-604X 2403", "PIONEER_CD-ROM_DRM-604X_2403", BUS_TYPE_SCSI},
|
||||
{ "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},
|
||||
{ "TEAC", "CD-R55S", "1.0R", "(SCSI) TEAC CD-R55S 1.0R", "TEAC_CD-R55S_1.0R", BUS_TYPE_SCSI},
|
||||
{ "TOSHIBA", "CD-ROM DRIVE:XM", "3433", "(SCSI) TOSHIBA CD-ROM DRIVE:XM 3433", "TOSHIBA_CD-ROM_DRIVEXM_3433", BUS_TYPE_SCSI},
|
||||
{ "TOSHIBA", "CD-ROM XM-3301TA", "0272", "(SCSI) TOSHIBA CD-ROM XM-3301TA 0272", "TOSHIBA_CD-ROM_XM-3301TA_0272", BUS_TYPE_SCSI},
|
||||
{ "TOSHIBA", "CD-ROM XM-5701TA", "3136", "(SCSI) TOSHIBA CD-ROM XM-5701TA 3136", "TOSHIBA_CD-ROM_XM-5701TA_3136", BUS_TYPE_SCSI},
|
||||
{ "", "", "", "", "", -1},
|
||||
};
|
||||
|
||||
/* To shut up the GCC compilers. */
|
||||
struct cdrom;
|
||||
|
||||
@@ -113,7 +161,7 @@ typedef struct cdrom {
|
||||
|
||||
uint32_t sound_on, cdrom_capacity,
|
||||
early, seek_pos,
|
||||
seek_diff, cd_end;
|
||||
seek_diff, cd_end, type;
|
||||
|
||||
int host_drive, prev_host_drive,
|
||||
cd_buflen, audio_op;
|
||||
@@ -132,6 +180,13 @@ typedef struct cdrom {
|
||||
|
||||
extern cdrom_t cdrom[CDROM_NUM];
|
||||
|
||||
extern char *cdrom_getname(int type);
|
||||
|
||||
extern char *cdrom_get_internal_name(int type);
|
||||
extern int cdrom_get_from_internal_name(char *s);
|
||||
extern void cdrom_set_type(int model, int type);
|
||||
extern int cdrom_get_type(int model);
|
||||
|
||||
extern int cdrom_lba_to_msf_accurate(int lba);
|
||||
extern double cdrom_seek_time(cdrom_t *dev);
|
||||
extern void cdrom_stop(cdrom_t *dev);
|
||||
@@ -139,20 +194,24 @@ 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_toshiba_audio_play(cdrom_t *dev, uint32_t pos, int type);
|
||||
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_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 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);
|
||||
extern int cdrom_read_toc_sony(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf, int max_len);
|
||||
extern void cdrom_get_track_buffer(cdrom_t *dev, uint8_t *buf);
|
||||
extern void cdrom_get_q(cdrom_t *dev, uint8_t *buf, int *curtoctrk, uint8_t mode);
|
||||
extern uint8_t cdrom_mitsumi_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len);
|
||||
extern int cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf,
|
||||
int cdrom_sector_type, int cdrom_sector_flags, int *len);
|
||||
extern void cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, int type);
|
||||
int cdrom_sector_type, int cdrom_sector_flags, int *len, uint8_t vendor_type);
|
||||
extern uint8_t cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, int type);
|
||||
|
||||
extern void cdrom_seek(cdrom_t *dev, uint32_t pos);
|
||||
extern void cdrom_seek(cdrom_t *dev, uint32_t pos, uint8_t vendor_type);
|
||||
|
||||
extern void cdrom_close_handler(uint8_t id);
|
||||
extern void cdrom_insert(uint8_t id);
|
||||
|
||||
31
src/include/86box/cdrom_interface.h
Normal file
31
src/include/86box/cdrom_interface.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Definitions for the common CD-ROM interface controller handler.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: TheCollector1995
|
||||
*
|
||||
* Copyright 2022 TheCollector1995.
|
||||
*/
|
||||
#ifndef EMU_CDROM_INTERFACE_H
|
||||
#define EMU_CDROM_INTERFACE_H
|
||||
|
||||
extern int cdrom_interface_current;
|
||||
|
||||
extern void cdrom_interface_reset(void);
|
||||
|
||||
extern char *cdrom_interface_get_internal_name(int cdinterface);
|
||||
extern int cdrom_interface_get_from_internal_name(char *s);
|
||||
extern int cdrom_interface_has_config(int cdinterface);
|
||||
extern const device_t *cdrom_interface_get_device(int cdinterface);
|
||||
extern int cdrom_interface_get_flags(int cdinterface);
|
||||
extern int cdrom_interface_available(int cdinterface);
|
||||
|
||||
#endif /*EMU_CDROM_INTERFACE_H*/
|
||||
@@ -49,6 +49,10 @@ typedef struct {
|
||||
packet_len, pos;
|
||||
|
||||
double callback;
|
||||
|
||||
mode_sense_pages_t ms_pages_saved_sony;
|
||||
mode_sense_pages_t ms_drive_status_pages_saved;
|
||||
int sony_vendor;
|
||||
} scsi_cdrom_t;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -53,6 +53,8 @@
|
||||
#define GPCMD_SEEK_6 0x0b
|
||||
#define GPCMD_IOMEGA_SET_PROTECTION_MODE 0x0c
|
||||
#define GPCMD_IOMEGA_EJECT 0x0d /* ATAPI only? */
|
||||
#define GPCMD_NO_OPERATION_TOSHIBA 0x0d /* Toshiba Vendor Unique command */
|
||||
#define GPCMD_NO_OPERATION_NEC 0x0d /* NEC Vendor Unique command */
|
||||
#define GPCMD_INQUIRY 0x12
|
||||
#define GPCMD_VERIFY_6 0x13
|
||||
#define GPCMD_MODE_SELECT_6 0x15
|
||||
@@ -64,7 +66,7 @@
|
||||
#define GPCMD_PREVENT_REMOVAL 0x1e
|
||||
#define GPCMD_READ_FORMAT_CAPACITIES 0x23
|
||||
#define GPCMD_READ_CDROM_CAPACITY 0x25
|
||||
#define GPCMD_CHINON_UNKNOWN 0x26
|
||||
#define GPCMD_UNKNOWN_CHINON 0x26 /*Chinon Vendor Unique command*/
|
||||
#define GPCMD_READ_10 0x28
|
||||
#define GPCMD_READ_GENERATION 0x29
|
||||
#define GPCMD_WRITE_10 0x2a
|
||||
@@ -100,23 +102,51 @@
|
||||
#define GPCMD_PLAY_CD_OLD 0xb4
|
||||
#define GPCMD_READ_CD_OLD 0xb8
|
||||
#define GPCMD_READ_CD_MSF 0xb9
|
||||
#define GPCMD_SCAN 0xba
|
||||
#define GPCMD_AUDIO_SCAN 0xba
|
||||
#define GPCMD_SET_SPEED 0xbb
|
||||
#define GPCMD_PLAY_CD 0xbc
|
||||
#define GPCMD_MECHANISM_STATUS 0xbd
|
||||
#define GPCMD_READ_CD 0xbe
|
||||
#define GPCMD_SEND_DVD_STRUCTURE 0xbf /* This is for writing only, irrelevant to 86Box. */
|
||||
#define GPCMD_CHINON_EJECT 0xc0 /* Chinon Vendor Unique command */
|
||||
#define GPCMD_AUDIO_TRACK_SEARCH 0xc0 /* Toshiba Vendor Unique command */
|
||||
#define GPCMD_TOSHIBA_PLAY_AUDIO 0xc1 /* Toshiba Vendor Unique command */
|
||||
#define GPCMD_EJECT_CHINON 0xc0 /* Chinon Vendor Unique command */
|
||||
#define GPCMD_AUDIO_TRACK_SEARCH_TOSHIBA 0xc0 /* Toshiba Vendor Unique command */
|
||||
#define GPCMD_UNKNOWN_SONY 0xc0 /* Sony Vendor Unique command */
|
||||
#define GPCMD_PLAY_AUDIO_TOSHIBA 0xc1 /* Toshiba Vendor Unique command */
|
||||
#define GPCMD_READ_TOC_SONY 0xc1 /* Sony Vendor Unique command */
|
||||
#define GPCMD_PAUSE_RESUME_ALT 0xc2
|
||||
#define GPCMD_STILL 0xc2 /* Toshiba Vendor Unique command */
|
||||
#define GPCMD_CADDY_EJECT 0xc4 /* Toshiba Vendor Unique command */
|
||||
#define GPCMD_CHINON_STOP 0xc6 /* Chinon Vendor Unique command */
|
||||
#define GPCMD_READ_SUBCODEQ_PLAYING_STATUS 0xc6 /* Toshiba Vendor Unique command */
|
||||
#define GPCMD_READ_SUBCHANNEL_MATSUSHITA 0xc2 /* Matsushita Vendor Unique command */
|
||||
#define GPCMD_READ_SUBCHANNEL_SONY 0xc2 /* Sony Vendor Unique command */
|
||||
#define GPCMD_STILL_TOSHIBA 0xc2 /* Toshiba Vendor Unique command */
|
||||
#define GPCMD_READ_TOC_MATSUSHITA 0xc3 /* Matsushita Vendor Unique command */
|
||||
#define GPCMD_READ_HEADER_SONY 0xc3 /* Sony Vendor Unique command */
|
||||
#define GPCMD_SET_STOP_TIME_TOSHIBA 0xc3 /* Toshiba Vendor Unique command */
|
||||
#define GPCMD_READ_HEADER_MATSUSHITA 0xc4 /* Matsushita Vendor Unique command */
|
||||
#define GPCMD_PLAYBACK_STATUS_TOSHIBA 0xc4 /* Sony Vendor Unique command */
|
||||
#define GPCMD_CADDY_EJECT_TOSHIBA 0xc4 /* Toshiba Vendor Unique command */
|
||||
#define GPCMD_PAUSE_SONY 0xc5 /* Sony Vendor Unique command */
|
||||
#define GPCMD_PLAY_AUDIO_MATSUSHITA 0xc5 /* Matsushita Vendor Unique command */
|
||||
#define GPCMD_STOP_CHINON 0xc6 /* Chinon Vendor Unique command */
|
||||
#define GPCMD_PLAT_TRACK_SONY 0xc6 /* Sony Vendor Unique command */
|
||||
#define GPCMD_READ_SUBCODEQ_PLAYING_STATUS_TOSHIBA 0xc6 /* Toshiba Vendor Unique command */
|
||||
#define GPCMD_PLAY_AUDIO_MSF_MATSUSHITA 0xc7 /* Matsushita Vendor Unique command*/
|
||||
#define GPCMD_PLAY_MSF_SONY 0xc7 /* Sony Vendor Unique command*/
|
||||
#define GPCMD_READ_DISC_INFORMATION_TOSHIBA 0xc7 /* Toshiba Vendor Unique command */
|
||||
#define GPCMD_SCAN_ALT 0xcd /* Should be equivalent to 0xba */
|
||||
#define GPCMD_PLAY_AUDIO_TRACK_INDEX_MATSUSHITA 0xc8 /* Matsushita Vendor Unique command */
|
||||
#define GPCMD_PLAY_AUDIO_SONY 0xc8 /* Sony Vendor Unique command */
|
||||
#define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10_MATSUSHITA 0xc9 /*Matsushita Vendor Unique command */
|
||||
#define GPCMD_PLAYBACK_CONTROL_SONY 0xc9 /* Sony Vendor Unique command */
|
||||
#define GPCMD_PAUSE_RESUME_MATSUSHITA 0xcb /* Matsushita Vendor Unique command */
|
||||
#define GPCMD_SCAN_PIONEER 0xcd /* Should be equivalent to 0xba */
|
||||
#define GPCMD_AUDIO_TRACK_SEARCH_NEC 0xd8 /* NEC Vendor Unique command */
|
||||
#define GPCMD_PLAY_AUDIO_NEC 0xd9 /* NEC Vendor Unique command */
|
||||
#define GPCMD_STILL_NEC 0xda /* NEC Vendor Unique command */
|
||||
#define GPCMD_SET_SPEED_ALT 0xda /* Should be equivalent to 0xbb */
|
||||
#define GPCMD_SET_STOP_TIME_NEC 0xdb /* NEC Vendor Unique command */
|
||||
#define GPCMD_CADDY_EJECT_NEC 0xdc /* NEC Vendor Unique command */
|
||||
#define GPCMD_READ_SUBCODEQ_PLAYING_STATUS_NEC 0xdd /* NEC Vendor Unique command */
|
||||
#define GPCMD_READ_DISC_INFORMATION_NEC 0xde /* NEC Vendor Unique command */
|
||||
#define GPCMD_PLAY_AUDIO_12_MATSUSHITA 0xe5 /* Matsushita Vendor Unique command */
|
||||
#define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12_MATSUSHITA 0xe9 /* Matsushita Vendor Unique command */
|
||||
|
||||
/* Mode page codes for mode sense/set */
|
||||
#define GPMODE_R_W_ERROR_PAGE 0x01
|
||||
@@ -125,6 +155,8 @@
|
||||
#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
|
||||
@@ -139,6 +171,8 @@
|
||||
#define GPMODEP_RIGID_DISK_PAGE 0x0000000000000010LL
|
||||
#define GPMODEP_FLEXIBLE_DISK_PAGE 0x0000000000000020LL
|
||||
#define GPMODEP_CACHING_PAGE 0x0000000000000100LL
|
||||
#define GPMODEP_CDROM_PAGE_SONY 0x0000000000000200LL
|
||||
#define GPMODEP_CDROM_AUDIO_PAGE_SONY 0x0000000000000400LL
|
||||
#define GPMODEP_CDROM_PAGE 0x0000000000002000LL
|
||||
#define GPMODEP_CDROM_AUDIO_PAGE 0x0000000000004000LL
|
||||
#define GPMODEP_CAPABILITIES_PAGE 0x0000040000000000LL
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
extern "C" {
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/cdrom.h>
|
||||
}
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
@@ -48,14 +49,16 @@ void
|
||||
Harddrives::populateRemovableBuses(QAbstractItemModel *model)
|
||||
{
|
||||
model->removeRows(0, model->rowCount());
|
||||
model->insertRows(0, 3);
|
||||
model->insertRows(0, 4);
|
||||
model->setData(model->index(0, 0), QObject::tr("Disabled"));
|
||||
model->setData(model->index(1, 0), QObject::tr("ATAPI"));
|
||||
model->setData(model->index(2, 0), QObject::tr("SCSI"));
|
||||
model->setData(model->index(3, 0), QObject::tr("Mitsumi"));
|
||||
|
||||
model->setData(model->index(0, 0), HDD_BUS_DISABLED, Qt::UserRole);
|
||||
model->setData(model->index(1, 0), HDD_BUS_ATAPI, Qt::UserRole);
|
||||
model->setData(model->index(2, 0), HDD_BUS_SCSI, Qt::UserRole);
|
||||
model->setData(model->index(3, 0), CDROM_BUS_MITSUMI, Qt::UserRole);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -143,6 +146,9 @@ Harddrives::BusChannelName(uint8_t bus, uint8_t channel)
|
||||
case HDD_BUS_SCSI:
|
||||
busName = QString("SCSI (%1:%2)").arg(channel >> 4).arg(channel & 15, 2, 10, QChar('0'));
|
||||
break;
|
||||
case CDROM_BUS_MITSUMI:
|
||||
busName = QString("Mitsumi");
|
||||
break;
|
||||
}
|
||||
|
||||
return busName;
|
||||
|
||||
@@ -29,6 +29,7 @@ extern uint64_t tsc;
|
||||
#include <86box/cartridge.h>
|
||||
#include <86box/cassette.h>
|
||||
#include <86box/cdrom.h>
|
||||
#include <86box/cdrom_interface.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/scsi.h>
|
||||
@@ -300,6 +301,8 @@ MachineStatus::iterateCDROM(const std::function<void(int)> &cb)
|
||||
continue;
|
||||
if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !hasSCSI() && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0))
|
||||
continue;
|
||||
if ((cdrom[i].bus_type == CDROM_BUS_MITSUMI) && (cdrom_interface_current == 0))
|
||||
continue;
|
||||
if (cdrom[i].bus_type != 0) {
|
||||
cb(i);
|
||||
}
|
||||
|
||||
@@ -593,6 +593,9 @@ MediaMenu::cdromUpdateMenu(int i)
|
||||
case CDROM_BUS_SCSI:
|
||||
busName = "SCSI";
|
||||
break;
|
||||
case CDROM_BUS_MITSUMI:
|
||||
busName = "Mitsumi";
|
||||
break;
|
||||
}
|
||||
|
||||
// menu->setTitle(tr("CD-ROM %1 (%2): %3").arg(QString::number(i+1), busName, name.isEmpty() ? tr("(empty)") : name));
|
||||
|
||||
@@ -20,6 +20,15 @@
|
||||
#include "ui_qt_settingsfloppycdrom.h"
|
||||
|
||||
extern "C" {
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/cdrom.h>
|
||||
@@ -59,6 +68,7 @@ setCDROMBus(QAbstractItemModel *model, const QModelIndex &idx, uint8_t bus, uint
|
||||
break;
|
||||
case CDROM_BUS_ATAPI:
|
||||
case CDROM_BUS_SCSI:
|
||||
case CDROM_BUS_MITSUMI:
|
||||
icon = ProgSettings::loadIcon("/cdrom.ico");
|
||||
break;
|
||||
}
|
||||
@@ -88,6 +98,18 @@ setCDROMEarly(QAbstractItemModel *model, const QModelIndex &idx, bool early)
|
||||
model->setData(i, early, Qt::UserRole);
|
||||
}
|
||||
|
||||
static void
|
||||
setCDROMType(QAbstractItemModel *model, const QModelIndex &idx, int type)
|
||||
{
|
||||
auto i = idx.siblingAtColumn(2);
|
||||
if (idx.siblingAtColumn(0).data(Qt::UserRole).toUInt() == CDROM_BUS_DISABLED) {
|
||||
model->setData(i, QCoreApplication::translate("", "None"));
|
||||
} else if (idx.siblingAtColumn(0).data(Qt::UserRole).toUInt() != CDROM_BUS_MITSUMI) {
|
||||
model->setData(i, QObject::tr(cdrom_getname(type)));
|
||||
}
|
||||
model->setData(i, type, Qt::UserRole);
|
||||
}
|
||||
|
||||
SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::SettingsFloppyCDROM)
|
||||
@@ -134,18 +156,36 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent)
|
||||
Models::AddEntry(model, QString("%1x").arg(i + 1), i + 1);
|
||||
}
|
||||
|
||||
model = ui->comboBoxCDROMType->model();
|
||||
i = 0;
|
||||
while (true) {
|
||||
QString name = tr(cdrom_getname(i));
|
||||
if (name.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
|
||||
Models::AddEntry(model, name, i);
|
||||
++i;
|
||||
}
|
||||
|
||||
model = new QStandardItemModel(0, 3, this);
|
||||
ui->tableViewCDROM->setModel(model);
|
||||
model->setHeaderData(0, Qt::Horizontal, tr("Bus"));
|
||||
model->setHeaderData(1, Qt::Horizontal, tr("Speed"));
|
||||
model->setHeaderData(2, Qt::Horizontal, tr("Earlier drive"));
|
||||
model->setHeaderData(2, Qt::Horizontal, tr("Type"));
|
||||
model->insertRows(0, CDROM_NUM);
|
||||
for (int i = 0; i < CDROM_NUM; i++) {
|
||||
auto idx = model->index(i, 0);
|
||||
int type = cdrom_get_type(i);
|
||||
setCDROMBus(model, idx, cdrom[i].bus_type, cdrom[i].res);
|
||||
setCDROMSpeed(model, idx.siblingAtColumn(1), cdrom[i].speed);
|
||||
setCDROMEarly(model, idx.siblingAtColumn(2), cdrom[i].early);
|
||||
Harddrives::busTrackClass->device_track(1, DEV_CDROM, cdrom[i].bus_type, cdrom[i].bus_type == CDROM_BUS_ATAPI ? cdrom[i].ide_channel : cdrom[i].scsi_device_id);
|
||||
setCDROMType(model, idx.siblingAtColumn(2), type);
|
||||
if (cdrom[i].bus_type == CDROM_BUS_ATAPI)
|
||||
Harddrives::busTrackClass->device_track(1, DEV_CDROM, cdrom[i].bus_type, cdrom[i].ide_channel);
|
||||
else if (cdrom[i].bus_type == CDROM_BUS_SCSI)
|
||||
Harddrives::busTrackClass->device_track(1, DEV_CDROM, cdrom[i].bus_type, cdrom[i].scsi_device_id);
|
||||
else if (cdrom[i].bus_type == CDROM_BUS_MITSUMI)
|
||||
Harddrives::busTrackClass->device_track(1, DEV_CDROM, cdrom[i].bus_type, 0);
|
||||
}
|
||||
ui->tableViewCDROM->resizeColumnsToContents();
|
||||
ui->tableViewCDROM->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
|
||||
@@ -183,7 +223,7 @@ SettingsFloppyCDROM::save()
|
||||
cdrom[i].bus_type = model->index(i, 0).data(Qt::UserRole).toUInt();
|
||||
cdrom[i].res = model->index(i, 0).data(Qt::UserRole + 1).toUInt();
|
||||
cdrom[i].speed = model->index(i, 1).data(Qt::UserRole).toUInt();
|
||||
cdrom[i].early = model->index(i, 2).data(Qt::UserRole).toUInt();
|
||||
cdrom_set_type(i, model->index(i, 2).data(Qt::UserRole).toInt());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,12 +242,12 @@ SettingsFloppyCDROM::onCDROMRowChanged(const QModelIndex ¤t)
|
||||
uint8_t bus = current.siblingAtColumn(0).data(Qt::UserRole).toUInt();
|
||||
uint8_t channel = current.siblingAtColumn(0).data(Qt::UserRole + 1).toUInt();
|
||||
uint8_t speed = current.siblingAtColumn(1).data(Qt::UserRole).toUInt();
|
||||
bool early = current.siblingAtColumn(2).data(Qt::UserRole).toBool();
|
||||
int type = current.siblingAtColumn(2).data(Qt::UserRole).toInt();
|
||||
|
||||
ui->comboBoxBus->setCurrentIndex(-1);
|
||||
auto *model = ui->comboBoxBus->model();
|
||||
auto* model = ui->comboBoxBus->model();
|
||||
auto match = model->match(model->index(0, 0), Qt::UserRole, bus);
|
||||
if (!match.isEmpty()) {
|
||||
if (! match.isEmpty()) {
|
||||
ui->comboBoxBus->setCurrentIndex(match.first().row());
|
||||
}
|
||||
|
||||
@@ -218,7 +258,7 @@ SettingsFloppyCDROM::onCDROMRowChanged(const QModelIndex ¤t)
|
||||
}
|
||||
|
||||
ui->comboBoxSpeed->setCurrentIndex(speed == 0 ? 7 : speed - 1);
|
||||
ui->checkBoxEarlierDrive->setChecked(early);
|
||||
ui->comboBoxCDROMType->setCurrentIndex(type);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -250,9 +290,10 @@ SettingsFloppyCDROM::on_comboBoxBus_currentIndexChanged(int index)
|
||||
|
||||
int bus = ui->comboBoxBus->currentData().toInt();
|
||||
bool enabled = (bus != CDROM_BUS_DISABLED);
|
||||
ui->comboBoxChannel->setEnabled(enabled);
|
||||
ui->comboBoxSpeed->setEnabled(enabled);
|
||||
ui->checkBoxEarlierDrive->setEnabled(enabled);
|
||||
ui->comboBoxChannel->setEnabled((bus == CDROM_BUS_MITSUMI) ? 0 : enabled);
|
||||
ui->comboBoxSpeed->setEnabled((bus == CDROM_BUS_MITSUMI) ? 0 : enabled);
|
||||
ui->comboBoxCDROMType->setEnabled((bus == CDROM_BUS_MITSUMI) ? 0 : enabled);
|
||||
|
||||
Harddrives::populateBusChannels(ui->comboBoxChannel->model(), bus);
|
||||
}
|
||||
|
||||
@@ -267,13 +308,25 @@ void
|
||||
SettingsFloppyCDROM::on_comboBoxBus_activated(int)
|
||||
{
|
||||
auto i = ui->tableViewCDROM->selectionModel()->currentIndex().siblingAtColumn(0);
|
||||
uint8_t bus_type = ui->comboBoxBus->currentData().toUInt();
|
||||
|
||||
Harddrives::busTrackClass->device_track(0, DEV_CDROM, ui->tableViewCDROM->model()->data(i, Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, Qt::UserRole + 1).toInt());
|
||||
ui->comboBoxChannel->setCurrentIndex(ui->comboBoxBus->currentData().toUInt() == CDROM_BUS_ATAPI ? Harddrives::busTrackClass->next_free_ide_channel() : Harddrives::busTrackClass->next_free_scsi_id());
|
||||
if (bus_type == CDROM_BUS_ATAPI)
|
||||
ui->comboBoxChannel->setCurrentIndex(Harddrives::busTrackClass->next_free_ide_channel());
|
||||
else if (bus_type == CDROM_BUS_SCSI)
|
||||
ui->comboBoxChannel->setCurrentIndex(Harddrives::busTrackClass->next_free_scsi_id());
|
||||
else if (bus_type == CDROM_BUS_MITSUMI)
|
||||
ui->comboBoxChannel->setCurrentIndex(0);
|
||||
|
||||
setCDROMBus(
|
||||
ui->tableViewCDROM->model(),
|
||||
ui->tableViewCDROM->selectionModel()->currentIndex(),
|
||||
ui->comboBoxBus->currentData().toUInt(),
|
||||
bus_type,
|
||||
ui->comboBoxChannel->currentData().toUInt());
|
||||
setCDROMType(
|
||||
ui->tableViewCDROM->model(),
|
||||
ui->tableViewCDROM->selectionModel()->currentIndex(),
|
||||
ui->comboBoxCDROMType->currentData().toUInt());
|
||||
Harddrives::busTrackClass->device_track(1, DEV_CDROM, ui->tableViewCDROM->model()->data(i, Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, Qt::UserRole + 1).toInt());
|
||||
}
|
||||
|
||||
@@ -291,8 +344,12 @@ SettingsFloppyCDROM::on_comboBoxChannel_activated(int)
|
||||
}
|
||||
|
||||
void
|
||||
SettingsFloppyCDROM::on_checkBoxEarlierDrive_stateChanged(int arg1)
|
||||
SettingsFloppyCDROM::on_comboBoxCDROMType_activated(int)
|
||||
{
|
||||
auto idx = ui->tableViewCDROM->selectionModel()->currentIndex();
|
||||
setCDROMEarly(ui->tableViewCDROM->model(), idx.siblingAtColumn(2), (arg1 == Qt::Checked) ? true : false);
|
||||
setCDROMType(
|
||||
ui->tableViewCDROM->model(),
|
||||
ui->tableViewCDROM->selectionModel()->currentIndex(),
|
||||
ui->comboBoxCDROMType->currentData().toUInt());
|
||||
ui->tableViewCDROM->resizeColumnsToContents();
|
||||
ui->tableViewCDROM->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ public:
|
||||
void save();
|
||||
|
||||
private slots:
|
||||
void on_comboBoxCDROMType_activated(int index);
|
||||
void on_comboBoxChannel_activated(int index);
|
||||
void on_comboBoxBus_activated(int index);
|
||||
void on_comboBoxSpeed_activated(int index);
|
||||
@@ -27,8 +28,6 @@ private slots:
|
||||
void onFloppyRowChanged(const QModelIndex ¤t);
|
||||
void onCDROMRowChanged(const QModelIndex ¤t);
|
||||
|
||||
void on_checkBoxEarlierDrive_stateChanged(int arg1);
|
||||
|
||||
private:
|
||||
Ui::SettingsFloppyCDROM *ui;
|
||||
};
|
||||
|
||||
@@ -115,16 +115,20 @@
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Bus:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Channel:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="comboBoxBus"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
@@ -132,25 +136,24 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Bus:</string>
|
||||
<string>Type:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="comboBoxBus"/>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QComboBox" name="comboBoxChannel"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="comboBoxSpeed"/>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QCheckBox" name="checkBoxEarlierDrive">
|
||||
<property name="text">
|
||||
<string>Earlier drive</string>
|
||||
</property>
|
||||
</widget>
|
||||
<item row="2" column="1" colspan="3">
|
||||
<widget class="QComboBox" name="comboBoxCDROMType"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
|
||||
@@ -25,6 +25,7 @@ extern "C" {
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/fdc_ext.h>
|
||||
#include <86box/cdrom_interface.h>
|
||||
#include <86box/scsi.h>
|
||||
#include <86box/scsi_device.h>
|
||||
#include <86box/cassette.h>
|
||||
@@ -59,6 +60,7 @@ SettingsStorageControllers::save()
|
||||
}
|
||||
hdc_current = ui->comboBoxHD->currentData().toInt();
|
||||
fdc_type = ui->comboBoxFD->currentData().toInt();
|
||||
cdrom_interface_current = ui->comboBoxCDInterface->currentData().toInt();
|
||||
ide_ter_enabled = ui->checkBoxTertiaryIDE->isChecked() ? 1 : 0;
|
||||
ide_qua_enabled = ui->checkBoxQuaternaryIDE->isChecked() ? 1 : 0;
|
||||
cassette_enable = ui->checkBoxCassette->isChecked() ? 1 : 0;
|
||||
@@ -131,6 +133,35 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId)
|
||||
ui->comboBoxFD->setCurrentIndex(-1);
|
||||
ui->comboBoxFD->setCurrentIndex(selectedRow);
|
||||
|
||||
/*CD interface controller config*/
|
||||
model = ui->comboBoxCDInterface->model();
|
||||
removeRows = model->rowCount();
|
||||
c = 0;
|
||||
selectedRow = 0;
|
||||
while (true) {
|
||||
/* Skip "internal" if machine doesn't have it. */
|
||||
QString name = DeviceConfig::DeviceName(cdrom_interface_get_device(c), cdrom_interface_get_internal_name(c), 1);
|
||||
if (name.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (cdrom_interface_available(c)) {
|
||||
auto *cdrom_interface_dev = cdrom_interface_get_device(c);
|
||||
|
||||
if (device_is_valid(cdrom_interface_dev, machineId)) {
|
||||
int row = Models::AddEntry(model, name, c);
|
||||
if (c == cdrom_interface_current) {
|
||||
selectedRow = row - removeRows;
|
||||
}
|
||||
}
|
||||
}
|
||||
c++;
|
||||
}
|
||||
model->removeRows(0, removeRows);
|
||||
ui->comboBoxCDInterface->setEnabled(model->rowCount() > 0);
|
||||
ui->comboBoxCDInterface->setCurrentIndex(-1);
|
||||
ui->comboBoxCDInterface->setCurrentIndex(selectedRow);
|
||||
|
||||
for (int i = 0; i < SCSI_BUS_MAX; ++i) {
|
||||
auto *cbox = findChild<QComboBox *>(QString("comboBoxSCSI%1").arg(i + 1));
|
||||
model = cbox->model();
|
||||
@@ -187,6 +218,14 @@ SettingsStorageControllers::on_comboBoxFD_currentIndexChanged(int index)
|
||||
ui->pushButtonFD->setEnabled(hdc_has_config(ui->comboBoxFD->currentData().toInt()) > 0);
|
||||
}
|
||||
|
||||
void SettingsStorageControllers::on_comboBoxCDInterface_currentIndexChanged(int index)
|
||||
{
|
||||
if (index < 0) {
|
||||
return;
|
||||
}
|
||||
ui->pushButtonCDInterface->setEnabled(cdrom_interface_has_config(ui->comboBoxCDInterface->currentData().toInt()) > 0);
|
||||
}
|
||||
|
||||
void
|
||||
SettingsStorageControllers::on_checkBoxTertiaryIDE_stateChanged(int arg1)
|
||||
{
|
||||
|
||||
@@ -32,10 +32,12 @@ private slots:
|
||||
void on_pushButtonTertiaryIDE_clicked();
|
||||
void on_pushButtonFD_clicked();
|
||||
void on_pushButtonHD_clicked();
|
||||
void on_pushButtonCDInterface_clicked();
|
||||
void on_checkBoxQuaternaryIDE_stateChanged(int arg1);
|
||||
void on_checkBoxTertiaryIDE_stateChanged(int arg1);
|
||||
void on_comboBoxFD_currentIndexChanged(int index);
|
||||
void on_comboBoxHD_currentIndexChanged(int index);
|
||||
void on_comboBoxCDInterface_currentIndexChanged(int index);
|
||||
|
||||
private:
|
||||
Ui::SettingsStorageControllers *ui;
|
||||
|
||||
@@ -49,6 +49,23 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>CD-ROM Controller:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="comboBoxCDInterface"/>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QPushButton" name="pushButtonCDInterface">
|
||||
<property name="text">
|
||||
<string>Configure</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="comboBoxHD">
|
||||
<property name="sizePolicy">
|
||||
@@ -69,21 +86,21 @@
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="comboBoxFD"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="checkBoxTertiaryIDE">
|
||||
<property name="text">
|
||||
<string>Tertiary IDE Controller</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="checkBoxQuaternaryIDE">
|
||||
<property name="text">
|
||||
<string>Quaternary IDE Controller</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<item row="3" column="2">
|
||||
<widget class="QPushButton" name="pushButtonTertiaryIDE">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
@@ -93,7 +110,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<item row="4" column="2">
|
||||
<widget class="QPushButton" name="pushButtonQuaternaryIDE">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -598,7 +598,7 @@ ncr_write(uint16_t port, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case 2: /* Mode register */
|
||||
ncr_log("Write: Mode register, val=%02x\n", val & MODE_DMA);
|
||||
ncr_log("Write: Mode register, val=%02x.\n", val);
|
||||
if ((val & MODE_ARBITRATE) && !(ncr->mode & MODE_ARBITRATE)) {
|
||||
ncr->icr &= ~ICR_ARB_LOST;
|
||||
ncr->icr |= ICR_ARB_IN_PROGRESS;
|
||||
@@ -741,12 +741,7 @@ ncr_read(uint16_t port, void *priv)
|
||||
break;
|
||||
|
||||
case 2: /* Mode register */
|
||||
if (((ncr->mode & 0x30) == 0x30) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1)))
|
||||
ncr->mode = 0;
|
||||
if (((ncr->mode & 0x20) == 0x20) && (ncr_dev->type == 0))
|
||||
ncr->mode = 0;
|
||||
|
||||
ncr_log("Read: Mode register\n");
|
||||
ncr_log("Read: Mode register = %02x.\n", ncr->mode);
|
||||
ret = ncr->mode;
|
||||
break;
|
||||
|
||||
@@ -761,10 +756,10 @@ ncr_read(uint16_t port, void *priv)
|
||||
ncr_bus_read(ncr_dev);
|
||||
ncr_log("NCR cur bus stat=%02x\n", ncr->cur_bus & 0xff);
|
||||
ret |= (ncr->cur_bus & 0xff);
|
||||
if ((ncr->icr & ICR_SEL) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1)))
|
||||
ret |= 0x02;
|
||||
if ((ncr->icr & ICR_BSY) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1)))
|
||||
ret |= 0x40;
|
||||
if (ncr->icr & ICR_SEL)
|
||||
ret |= BUS_SEL;
|
||||
if (ncr->icr & ICR_BSY)
|
||||
ret |= BUS_BSY;
|
||||
break;
|
||||
|
||||
case 5: /* Bus and Status register */
|
||||
@@ -783,9 +778,9 @@ ncr_read(uint16_t port, void *priv)
|
||||
ncr_bus_read(ncr_dev);
|
||||
bus = ncr->cur_bus;
|
||||
|
||||
if ((bus & BUS_ACK) || ((ncr->icr & ICR_ACK) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1))))
|
||||
if ((bus & BUS_ACK) || (ncr->icr & ICR_ACK))
|
||||
ret |= STATUS_ACK;
|
||||
if ((bus & BUS_ATN) || ((ncr->icr & ICR_ATN) && ((ncr_dev->type == 1) && (ncr_dev->bios_ver == 1))))
|
||||
if ((bus & BUS_ATN) || (ncr->icr & ICR_ATN))
|
||||
ret |= 0x02;
|
||||
|
||||
if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA)) {
|
||||
@@ -885,6 +880,13 @@ memio_read(uint32_t addr, void *priv)
|
||||
ncr_log("NCR status ctrl read=%02x\n", ncr_dev->status_ctrl & STATUS_BUFFER_NOT_READY);
|
||||
if (!ncr_dev->ncr_busy)
|
||||
ret |= STATUS_53C80_ACCESSIBLE;
|
||||
if (ncr->mode & 0x30) { /*Parity bits*/
|
||||
if (!(ncr->mode & MODE_DMA)) { /*This is to avoid RTBios 8.10R BIOS problems with the hard disk and detection.*/
|
||||
ret |= 0x01; /*If the parity bits are set, bit 0 of the 53c400 status port should be set as well.*/
|
||||
ncr->mode = 0; /*Required by RTASPI10.SYS otherwise it won't initialize.*/
|
||||
}
|
||||
}
|
||||
ncr_log("NCR 53c400 status = %02x.\n", ret);
|
||||
break;
|
||||
|
||||
case 0x3981: /* block counter register*/
|
||||
@@ -948,6 +950,7 @@ memio_write(uint32_t addr, uint8_t val, void *priv)
|
||||
case 0x3980:
|
||||
switch (addr) {
|
||||
case 0x3980: /* Control */
|
||||
ncr_log("NCR 53c400 control = %02x, mode = %02x.\n", val, ncr->mode);
|
||||
if ((val & CTRL_DATA_DIR) && !(ncr_dev->status_ctrl & CTRL_DATA_DIR)) {
|
||||
ncr_dev->buffer_host_pos = MIN(128, dev->buffer_length);
|
||||
ncr_dev->status_ctrl |= STATUS_BUFFER_NOT_READY;
|
||||
|
||||
@@ -126,9 +126,10 @@ typedef struct {
|
||||
get_pos_info_t get_pos_info;
|
||||
|
||||
scb_t scb;
|
||||
int adapter_reset;
|
||||
int scb_id;
|
||||
int adapter_id;
|
||||
int assign;
|
||||
int present[8];
|
||||
|
||||
int cmd_status;
|
||||
int cir_status;
|
||||
@@ -380,7 +381,7 @@ spock_read(uint16_t port, void *p)
|
||||
break;
|
||||
}
|
||||
|
||||
spock_log("spock_read: port=%04x val=%02x %04x(%05x):%04x %02x\n", port, temp, CS, cs, cpu_state.pc, BH);
|
||||
spock_log("spock_read: port=%04x val=%02x %04x(%05x):%04x.\n", port, temp, CS, cs, cpu_state.pc);
|
||||
return temp;
|
||||
}
|
||||
|
||||
@@ -436,11 +437,14 @@ spock_get_len(spock_t *scsi, scb_t *scb)
|
||||
static void
|
||||
spock_process_imm_cmd(spock_t *scsi)
|
||||
{
|
||||
int i;
|
||||
int i, j = 0;
|
||||
int adapter_id, phys_id, lun_id;
|
||||
|
||||
scsi->assign = 0;
|
||||
|
||||
switch (scsi->command & CMD_MASK) {
|
||||
case CMD_ASSIGN:
|
||||
scsi->assign = 1;
|
||||
adapter_id = (scsi->command >> 16) & 15;
|
||||
phys_id = (scsi->command >> 20) & 7;
|
||||
lun_id = (scsi->command >> 24) & 7;
|
||||
@@ -458,10 +462,10 @@ spock_process_imm_cmd(spock_t *scsi)
|
||||
if (phys_id != scsi->adapter_id) {
|
||||
scsi->dev_id[adapter_id].phys_id = phys_id;
|
||||
scsi->dev_id[adapter_id].lun_id = lun_id;
|
||||
spock_log("Assign: adapter dev=%x scsi ID=%i LUN=%i\n", adapter_id, scsi->dev_id[adapter_id].phys_id, scsi->dev_id[adapter_id].lun_id);
|
||||
spock_log("Assign: adapter dev=%x scsi ID=%i LUN=%i.\n", adapter_id, scsi->dev_id[adapter_id].phys_id, scsi->dev_id[adapter_id].lun_id);
|
||||
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
|
||||
} else { /*Can not assign adapter*/
|
||||
spock_log("Assign: PUN=%d, cannot assign adapter\n", phys_id);
|
||||
spock_log("Assign: PUN=%d, cannot assign adapter.\n", phys_id);
|
||||
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_FAIL);
|
||||
}
|
||||
}
|
||||
@@ -481,18 +485,25 @@ spock_process_imm_cmd(spock_t *scsi)
|
||||
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
|
||||
break;
|
||||
case CMD_RESET:
|
||||
spock_log("Reset Command\n");
|
||||
spock_log("Reset Command, attention = %d.\n", scsi->attention & 0x0f);
|
||||
if ((scsi->attention & 0x0f) == 0x0f) { /*Adapter reset*/
|
||||
for (i = 0; i < 8; i++)
|
||||
for (i = 0; i < 8; i++) {
|
||||
scsi_device_reset(&scsi_devices[scsi->bus][i]);
|
||||
spock_log("Adapter Reset\n");
|
||||
}
|
||||
|
||||
if (!scsi->adapter_reset) /*The early 1990 bios must have its boot drive
|
||||
set to ID 6 according https://www.ardent-tool.com/IBM_SCSI/SCSI-A.html */
|
||||
scsi->adapter_reset = 1;
|
||||
for (i = 6; i > -1; i--) {
|
||||
if (scsi_device_present(&scsi_devices[scsi->bus][i])) {
|
||||
spock_log("Adapter Reset, SCSI reset present devices=%d, phys ID=%d, type=%04x.\n", j, scsi->dev_id[i].phys_id, scsi_devices[scsi->bus][i].type);
|
||||
scsi->present[j] = i;
|
||||
j++;
|
||||
} else {
|
||||
spock_log("Adapter Reset, SCSI reset not present devices=%d, phys ID=%d, type=%04x.\n", j, scsi->dev_id[i].phys_id, scsi_devices[scsi->bus][i].type);
|
||||
}
|
||||
}
|
||||
|
||||
scsi->scb_state = 0;
|
||||
}
|
||||
|
||||
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
|
||||
break;
|
||||
|
||||
@@ -505,7 +516,7 @@ spock_process_imm_cmd(spock_t *scsi)
|
||||
static void
|
||||
spock_execute_cmd(spock_t *scsi, scb_t *scb)
|
||||
{
|
||||
int c;
|
||||
int c, j;
|
||||
int old_scb_state;
|
||||
|
||||
if (scsi->in_reset) {
|
||||
@@ -519,8 +530,8 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
|
||||
|
||||
if (scsi->in_reset == 1) {
|
||||
scsi->basic_ctrl |= CTRL_IRQ_ENA;
|
||||
spock_set_irq(scsi, 0x0f, IRQ_TYPE_RESET_COMPLETE);
|
||||
} else
|
||||
}
|
||||
|
||||
spock_set_irq(scsi, 0x0f, IRQ_TYPE_RESET_COMPLETE);
|
||||
|
||||
/*Reset device mappings*/
|
||||
@@ -532,6 +543,16 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
|
||||
scsi->dev_id[c].phys_id = -1;
|
||||
|
||||
scsi->in_reset = 0;
|
||||
|
||||
for (c = 6; c > -1; c--) {
|
||||
if (scsi_device_present(&scsi_devices[scsi->bus][c])) {
|
||||
spock_log("Reset, SCSI reset present devices=%d, phys ID=%d, type=%04x.\n", j, scsi->dev_id[c].phys_id, scsi_devices[scsi->bus][c].type);
|
||||
scsi->present[j] = c;
|
||||
j++;
|
||||
} else {
|
||||
spock_log("Reset, SCSI reset not present devices=%d, phys ID=%d, type=%04x.\n", j, scsi->dev_id[c].phys_id, scsi_devices[scsi->bus][c].type);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -584,11 +605,11 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
|
||||
" SCB chain address = %08x\n"
|
||||
" Block count = %04x\n"
|
||||
" Block length = %04x\n"
|
||||
" SCB id = %d, Phys id = %d\n",
|
||||
" SCB id = %d, Phys id = %d, Spock CMD = %08x, CMD Mask = %02x.\n",
|
||||
scb->command, scb->enable, scb->lba_addr,
|
||||
scb->sge.sys_buf_addr, scb->sge.sys_buf_byte_count,
|
||||
scb->term_status_block_addr, scb->scb_chain_addr,
|
||||
scb->block_count, scb->block_length, scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id);
|
||||
scb->block_count, scb->block_length, scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id, scsi->command, scb->command & 0xc0);
|
||||
|
||||
switch (scb->command & CMD_MASK) {
|
||||
case CMD_GET_COMPLETE_STATUS:
|
||||
@@ -662,10 +683,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
|
||||
break;
|
||||
|
||||
case CMD_DEVICE_INQUIRY:
|
||||
if (scb->command != CMD_DEVICE_INQUIRY)
|
||||
scsi->cdb_id = scsi->scb_id;
|
||||
else
|
||||
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
|
||||
scsi->cdb_id = scsi->assign ? scsi->dev_id[scsi->scb_id].phys_id : scsi->present[scsi->scb_id];
|
||||
spock_log("Device Inquiry, ID=%d\n", scsi->cdb_id);
|
||||
scsi->cdb[0] = GPCMD_INQUIRY;
|
||||
scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/
|
||||
@@ -681,12 +699,9 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
|
||||
return;
|
||||
|
||||
case CMD_SEND_OTHER_SCSI:
|
||||
if (scb->command != CMD_SEND_OTHER_SCSI)
|
||||
scsi->cdb_id = scsi->scb_id;
|
||||
else
|
||||
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
|
||||
spock_log("Send Other SCSI, SCB ID=%d, PHYS ID=%d, reset=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id, scsi->adapter_reset);
|
||||
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);
|
||||
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;
|
||||
@@ -694,11 +709,8 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
|
||||
return;
|
||||
|
||||
case CMD_READ_DEVICE_CAPACITY:
|
||||
if (scb->command != CMD_READ_DEVICE_CAPACITY)
|
||||
scsi->cdb_id = scsi->scb_id;
|
||||
else
|
||||
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
|
||||
spock_log("Device Capacity, SCB ID=%d, PHYS ID=%d, reset=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id, scsi->adapter_reset);
|
||||
scsi->cdb_id = scsi->assign ? scsi->dev_id[scsi->scb_id].phys_id : scsi->present[scsi->scb_id];
|
||||
spock_log("Device Capacity, SCB ID=%d, PHYS ID=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id);
|
||||
scsi->cdb[0] = GPCMD_READ_CDROM_CAPACITY;
|
||||
scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/
|
||||
scsi->cdb[2] = 0; /*LBA*/
|
||||
@@ -715,11 +727,8 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
|
||||
return;
|
||||
|
||||
case CMD_READ_DATA:
|
||||
if (scb->command != CMD_READ_DATA)
|
||||
scsi->cdb_id = scsi->scb_id;
|
||||
else
|
||||
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
|
||||
spock_log("Device Read Data, SCB ID=%d, PHYS ID=%d, reset=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id, scsi->adapter_reset);
|
||||
scsi->cdb_id = scsi->assign ? scsi->dev_id[scsi->scb_id].phys_id : scsi->present[scsi->scb_id];
|
||||
spock_log("Device Read Data, SCB ID=%d, PHYS ID=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id);
|
||||
scsi->cdb[0] = GPCMD_READ_10;
|
||||
scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/
|
||||
scsi->cdb[2] = (scb->lba_addr >> 24) & 0xff; /*LBA*/
|
||||
@@ -736,10 +745,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
|
||||
return;
|
||||
|
||||
case CMD_WRITE_DATA:
|
||||
if (scb->command != CMD_WRITE_DATA)
|
||||
scsi->cdb_id = scsi->scb_id;
|
||||
else
|
||||
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
|
||||
scsi->cdb_id = scsi->assign ? scsi->dev_id[scsi->scb_id].phys_id : scsi->present[scsi->scb_id];
|
||||
spock_log("Device Write Data\n");
|
||||
scsi->cdb[0] = GPCMD_WRITE_10;
|
||||
scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/
|
||||
@@ -757,10 +763,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
|
||||
return;
|
||||
|
||||
case CMD_VERIFY:
|
||||
if (scb->command != CMD_VERIFY)
|
||||
scsi->cdb_id = scsi->scb_id;
|
||||
else
|
||||
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
|
||||
scsi->cdb_id = scsi->assign ? scsi->dev_id[scsi->scb_id].phys_id : scsi->present[scsi->scb_id];
|
||||
spock_log("Device Verify\n");
|
||||
scsi->cdb[0] = GPCMD_VERIFY_10;
|
||||
scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/
|
||||
@@ -779,10 +782,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
|
||||
return;
|
||||
|
||||
case CMD_REQUEST_SENSE:
|
||||
if (scb->command != CMD_REQUEST_SENSE)
|
||||
scsi->cdb_id = scsi->scb_id;
|
||||
else
|
||||
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
|
||||
scsi->cdb_id = scsi->assign ? scsi->dev_id[scsi->scb_id].phys_id : scsi->present[scsi->scb_id];
|
||||
spock_log("Device Request Sense, ID=%d\n", scsi->cdb_id);
|
||||
scsi->cdb[0] = GPCMD_REQUEST_SENSE;
|
||||
scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/
|
||||
@@ -802,7 +802,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
|
||||
if (scsi_device_present(&scsi_devices[scsi->bus][scsi->cdb_id])) {
|
||||
if (scsi->last_status == SCSI_STATUS_OK) {
|
||||
scsi->scb_state = 3;
|
||||
spock_log("Status is Good on device ID %d, reset = %d\n", scsi->scb_id, scsi->adapter_reset);
|
||||
spock_log("Status is Good on device ID %d, cdb id = %d.\n", scsi->scb_id, scsi->cdb_id);
|
||||
} else if (scsi->last_status == SCSI_STATUS_CHECK_CONDITION) {
|
||||
uint16_t term_stat_block_addr7 = (0xc << 8) | 2;
|
||||
uint16_t term_stat_block_addr8 = 0x20;
|
||||
@@ -811,7 +811,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
|
||||
|
||||
spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL);
|
||||
scsi->scb_state = 0;
|
||||
spock_log("Status Check Condition on device ID %d, reset = %d\n", scsi->scb_id, scsi->adapter_reset);
|
||||
spock_log("Status Check Condition on device ID %d, cdb id = %d.\n", scsi->attention & 0x0f, scsi->cdb_id);
|
||||
dma_bm_write(scb->term_status_block_addr + 0x7 * 2, (uint8_t *) &term_stat_block_addr7, 2, 2);
|
||||
dma_bm_write(scb->term_status_block_addr + 0x8 * 2, (uint8_t *) &term_stat_block_addr8, 2, 2);
|
||||
dma_bm_write(scb->term_status_block_addr + 0xb * 2, (uint8_t *) &term_stat_block_addrb, 2, 2);
|
||||
@@ -822,7 +822,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
|
||||
uint16_t term_stat_block_addr8 = 0x10;
|
||||
spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL);
|
||||
scsi->scb_state = 0;
|
||||
spock_log("Status Check Condition on device ID %d on no device, reset = %d\n", scsi->scb_id, scsi->adapter_reset);
|
||||
spock_log("Status Check Condition on device ID %d on no device\n", scsi->scb_id);
|
||||
dma_bm_write(scb->term_status_block_addr + 0x7 * 2, (uint8_t *) &term_stat_block_addr7, 2, 2);
|
||||
dma_bm_write(scb->term_status_block_addr + 0x8 * 2, (uint8_t *) &term_stat_block_addr8, 2, 2);
|
||||
}
|
||||
@@ -837,7 +837,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
|
||||
} else {
|
||||
spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_SCB_COMPLETE);
|
||||
scsi->scb_state = 0;
|
||||
spock_log("Complete SCB\n");
|
||||
spock_log("Complete SCB ID = %d.\n", scsi->attention & 0x0f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -856,12 +856,12 @@ spock_process_scsi(spock_t *scsi, scb_t *scb)
|
||||
break;
|
||||
|
||||
case SCSI_STATE_SELECT:
|
||||
spock_log("Selecting ID %d\n", scsi->cdb_id);
|
||||
spock_log("Selecting ID %d, SCB ID %d, LUN %d, adapter id = %d.\n", scsi->cdb_id, scsi->scb_id, scsi->dev_id[scsi->scb_id].lun_id, scsi->attention);
|
||||
if ((scsi->cdb_id != (uint8_t) -1) && scsi_device_present(&scsi_devices[scsi->bus][scsi->cdb_id])) {
|
||||
scsi->scsi_state = SCSI_STATE_SEND_COMMAND;
|
||||
spock_log("Device selected at ID %i\n", scsi->cdb_id);
|
||||
spock_log("Device selected at ID %i.\n", scsi->cdb_id);
|
||||
} else {
|
||||
spock_log("Device selection failed at ID %i\n", scsi->cdb_id);
|
||||
spock_log("Device selection failed at ID %i.\n", scsi->cdb_id);
|
||||
scsi->scsi_state = SCSI_STATE_IDLE;
|
||||
if (!scsi->cmd_timer) {
|
||||
spock_log("Callback to reset\n");
|
||||
@@ -985,6 +985,7 @@ spock_callback(void *priv)
|
||||
scsi->cir[3] = scsi->cir_pending[3];
|
||||
scsi->cir_status = 0;
|
||||
|
||||
spock_log("SCSI attention = %02x.\n", scsi->attention_pending);
|
||||
switch (scsi->attention >> 4) {
|
||||
case 1: /*Immediate command*/
|
||||
scsi->cmd_status = 0x0a;
|
||||
@@ -1007,7 +1008,7 @@ spock_callback(void *priv)
|
||||
scsi->scb_addr = scsi->cir[0] | (scsi->cir[1] << 8) | (scsi->cir[2] << 16) | (scsi->cir[3] << 24);
|
||||
scsi->scb_id = scsi->attention & 0x0f;
|
||||
scsi->cmd_timer = SPOCK_TIME * 2;
|
||||
spock_log("Start SCB at ID = %d\n", scsi->scb_id);
|
||||
spock_log("Start SCB at ID = %d, attention = %02x\n", scsi->scb_id, scsi->attention >> 4);
|
||||
scsi->scb_state = 1;
|
||||
break;
|
||||
|
||||
@@ -1019,7 +1020,7 @@ spock_callback(void *priv)
|
||||
|
||||
case 0x0e: /*EOI*/
|
||||
scsi->irq_status = 0;
|
||||
spock_clear_irq(scsi, scsi->attention & 0xf);
|
||||
spock_clear_irq(scsi, scsi->attention & 0x0f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1049,10 +1050,9 @@ spock_mca_write(int port, uint8_t val, void *priv)
|
||||
|
||||
if (scsi->pos_regs[2] & 1) {
|
||||
io_sethandler((((scsi->pos_regs[2] >> 1) & 7) * 8) + 0x3540, 0x0008, spock_read, spock_readw, NULL, spock_write, spock_writew, NULL, scsi);
|
||||
if ((scsi->pos_regs[2] >> 4) == 0x0f)
|
||||
mem_mapping_disable(&scsi->bios_rom.mapping);
|
||||
else {
|
||||
if ((scsi->pos_regs[2] & 0xf0) != 0xf0) {
|
||||
mem_mapping_set_addr(&scsi->bios_rom.mapping, ((scsi->pos_regs[2] >> 4) * 0x2000) + 0xc0000, 0x8000);
|
||||
mem_mapping_enable(&scsi->bios_rom.mapping);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1089,10 +1089,10 @@ spock_mca_reset(void *priv)
|
||||
scsi->basic_ctrl = 0;
|
||||
|
||||
/* Reset all devices on controller reset. */
|
||||
for (i = 0; i < 8; i++)
|
||||
for (i = 0; i < 8; i++) {
|
||||
scsi_device_reset(&scsi_devices[scsi->bus][i]);
|
||||
|
||||
scsi->adapter_reset = 0;
|
||||
scsi->present[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
@@ -1175,7 +1175,7 @@ static const device_config_t spock_rom_config[] = {
|
||||
},
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t spock_device = {
|
||||
|
||||
Reference in New Issue
Block a user