MKE CD-ROM: Fix disc change detection, move model selection to CD-ROM type, and properly implement support for the up to 4 drives supported by the controller.

This commit is contained in:
OBattler
2025-07-29 22:40:02 +02:00
parent 12deafbe1d
commit c675da4de7
15 changed files with 521 additions and 300 deletions

View File

@@ -1249,6 +1249,26 @@ cdrom_get_type_count(void)
return count;
}
void
cdrom_generate_name_mke(const int type, char *name)
{
char elements[2][512] = { 0 };
memcpy(elements[0], cdrom_drive_types[type].model,
strlen(cdrom_drive_types[type].model) + 1);
char *s = strstr(elements[0], " ");
if (s != NULL)
s[0] = 0x00;
memcpy(elements[1], cdrom_drive_types[type].revision,
strlen(cdrom_drive_types[type].revision) + 1);
s = strstr(elements[1], " ");
if (s != NULL)
s[0] = 0x00;
sprintf(name, "%s%s", elements[0], elements[1]);
}
void
cdrom_get_identify_model(const int type, char *name, const int id)
{

View File

@@ -90,41 +90,51 @@ CR-562-B is classified as Family1 in this driver, so uses the CMD1_ prefix.
#define CMD1_SESSINFO 0x8d
typedef struct mke_t {
bool tray_open;
bool present;
bool tray_open;
uint8_t enable_register;
uint8_t command_buffer[7];
uint8_t command_buffer_pending;
uint8_t command_buffer[7];
uint8_t command_buffer_pending;
uint8_t medium_changed;
uint8_t vol0, vol1, patch0, patch1;
uint8_t mode_select[5];
uint8_t vol0, vol1, patch0, patch1;
uint8_t mode_select[5];
uint8_t data_select;
uint8_t is_sb;
uint8_t media_selected; // temporary hack
uint8_t media_selected; // temporary hack
Fifo8 data_fifo;
Fifo8 info_fifo;
Fifo8 data_fifo;
Fifo8 info_fifo;
Fifo8 errors_fifo;
cdrom_t * cdrom_dev;
cdrom_t *cdrom_dev;
uint32_t sector_type;
uint32_t sector_flags;
uint32_t sector_type;
uint32_t sector_flags;
uint32_t unit_attention;
uint32_t unit_attention;
uint8_t cdbuffer[624240 * 2];
uint8_t cdbuffer[624240 * 2];
uint32_t data_to_push;
uint32_t data_to_push;
pc_timer_t timer;
uint8_t *ver;
char ver[512];
uint8_t is_error;
uint8_t sense[8];
uint8_t temp_buf[65536];
} mke_t;
mke_t mke;
typedef struct mke_interface_t {
mke_t mke[4];
uint8_t is_sb;
uint8_t drvsel;
uint8_t data_select;
} mke_interface_t;
#ifdef ENABLE_MKE_LOG
int mke_do_log = ENABLE_MKE_LOG;
@@ -146,38 +156,169 @@ mke_log(const char *fmt, ...)
#define CHECK_READY() \
{ \
if (mke->cdrom_dev->cd_status == CD_STATUS_EMPTY) { \
fifo8_push(&mke->errors_fifo, 0x03); \
if (!mke_pre_execution_check(mke)) \
return; \
} \
}
#define CHECK_READY_READ() \
{ \
if (mke->cdrom_dev->cd_status == CD_STATUS_EMPTY) { \
fifo8_push(&mke->errors_fifo, 0x03); \
if (!mke_pre_execution_check(mke)) { \
fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); \
return; \
} \
}
static uint8_t temp_buf[65536];
static void
mke_update_sense(mke_t *mke, uint8_t error)
{
/* FreeBSD calls this addrval, but what is it? */
mke->sense[0] = 0x00;
mke->sense[1] = mke->command_buffer[0];
mke->sense[2] = error;
mke->is_error = 1;
}
static void
mke_cdrom_insert(void *priv)
{
mke_t *dev = (mke_t *) priv;
if ((dev == NULL) || (dev->cdrom_dev == NULL))
return;
if (dev->cdrom_dev->ops == NULL) {
dev->medium_changed = 0;
dev->cdrom_dev->cd_status = CD_STATUS_EMPTY;
if (timer_is_enabled(&dev->timer)) {
timer_disable(&dev->timer);
dev->data_to_push = 0;
}
mke_log("Media removal\n");
} else if (dev->cdrom_dev->cd_status & CD_STATUS_TRANSITION) {
dev->medium_changed = 1;
/* Turn off the medium changed status. */
dev->cdrom_dev->cd_status &= ~CD_STATUS_TRANSITION;
mke_log("Media insert\n");
} else {
dev->medium_changed = 0;
dev->cdrom_dev->cd_status |= CD_STATUS_TRANSITION;
mke_log("Media transition\n");
}
}
static int
mke_pre_execution_check(mke_t *mke)
{
int ready = 1;
if ((mke->cdrom_dev->cd_status == CD_STATUS_PLAYING) ||
(mke->cdrom_dev->cd_status == CD_STATUS_PAUSED)) {
ready = 1;
goto skip_ready_check;
}
if (mke->cdrom_dev->cd_status & CD_STATUS_TRANSITION) {
if (mke->command_buffer[0] == 0x82)
ready = 0;
else {
mke_cdrom_insert(mke);
ready = ((mke->cdrom_dev->cd_status != CD_STATUS_EMPTY) && (mke->cdrom_dev->cd_status != CD_STATUS_DVD_REJECTED));
}
} else
ready = ((mke->cdrom_dev->cd_status != CD_STATUS_EMPTY) && (mke->cdrom_dev->cd_status != CD_STATUS_DVD_REJECTED));
skip_ready_check:
/*
If the drive is not ready, there is no reason to keep the
UNIT ATTENTION condition present, as we only use it to mark
disc changes.
*/
if (!ready && (mke->medium_changed > 0))
mke->medium_changed = 0;
/*
If the UNIT ATTENTION condition is set and the command does not allow
execution under it, error out and report the condition.
*/
if (mke->medium_changed == 1) {
/*
Only increment the unit attention phase if the command can
not pass through it.
*/
mke_log("Unit attention now 2\n");
mke->medium_changed++;
mke_update_sense(mke, 0x11); \
return 0;
} else if (mke->medium_changed == 2) {
if (mke->command_buffer[0] != 0x82) {
mke_log("Unit attention now 0\n");
mke->medium_changed = 0;
}
}
/*
Unless the command is REQUEST SENSE, clear the sense. This will *NOT* clear
the UNIT ATTENTION condition if it's set.
*/
if (mke->command_buffer[0] != 0x82) {
memset(mke->sense, 0x00, 8);
mke->is_error = 0;
}
if (!ready && (mke->command_buffer[0] != 0x05)) {
mke_log("Not ready (%02X)\n", mke->command_buffer[0]);
mke_update_sense(mke, 0x03);
return 0;
}
return 1;
}
uint8_t
mke_cdrom_status(cdrom_t *dev, mke_t *mke)
{
uint8_t status = 0;
/*
This bit seems to always be set?
Bit 4 never set?
*/
status |= 2;
if (dev->cd_status == CD_STATUS_PLAYING)
status |= STAT_PLAY;
if (dev->cd_status == CD_STATUS_PAUSED)
status |= STAT_PLAY;
if (mke->is_error)
status |= 0x10;
/* Always set? */
status |= 0x20;
status |= STAT_TRAY;
if (mke->cdrom_dev->cd_status != CD_STATUS_EMPTY) {
status |= STAT_DISK;
status |= STAT_READY;
}
return status;
}
void
mke_get_subq(cdrom_t *dev, uint8_t *b)
mke_get_subq(mke_t *mke, uint8_t *b)
{
cdrom_get_current_subchannel_sony(dev, temp_buf, 1);
cdrom_t *dev = mke->cdrom_dev;
cdrom_get_current_subchannel_sony(dev, mke->temp_buf, 1);
/* ? */
b[0] = 0x80;
b[1] = ((temp_buf[0] & 0xf) << 4) | ((temp_buf[0] & 0xf0) >> 4);
b[2] = temp_buf[1];
b[3] = temp_buf[2];
b[4] = temp_buf[6];
b[5] = temp_buf[7];
b[6] = temp_buf[8];
b[7] = temp_buf[3];
b[8] = temp_buf[4];
b[9] = temp_buf[5];
b[1] = ((mke->temp_buf[0] & 0xf) << 4) | ((mke->temp_buf[0] & 0xf0) >> 4);
b[2] = mke->temp_buf[1];
b[3] = mke->temp_buf[2];
b[4] = mke->temp_buf[6];
b[5] = mke->temp_buf[7];
b[6] = mke->temp_buf[8];
b[7] = mke->temp_buf[3];
b[8] = mke->temp_buf[4];
b[9] = mke->temp_buf[5];
/* ? */
b[10] = 0;
mke_log("mke_get_subq: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n",
@@ -198,11 +339,13 @@ static void blk_to_msf(int blk, unsigned char *msf)
return;
}
uint8_t mke_read_toc(cdrom_t *dev, unsigned char *b, uint8_t track) {
track_info_t ti;
int last_track;
cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 0, 65536);
last_track = temp_buf[3];
uint8_t mke_read_toc(mke_t *mke, unsigned char *b, uint8_t track) {
cdrom_t *dev = mke->cdrom_dev;
track_info_t ti;
int last_track;
cdrom_read_toc(dev, mke->temp_buf, CD_TOC_NORMAL, 0, 0, 65536);
last_track = mke->temp_buf[3];
/* Should we allow +1 here? */
if (track > last_track)
return 0;
@@ -222,16 +365,17 @@ uint8_t mke_read_toc(cdrom_t *dev, unsigned char *b, uint8_t track) {
uint8_t
mke_disc_info(cdrom_t *dev, unsigned char *b)
mke_disc_info(mke_t *mke, unsigned char *b)
{
uint8_t disc_type_buf[34];
int first_track;
int last_track;
cdrom_t *dev = mke->cdrom_dev;
uint8_t disc_type_buf[34];
int first_track;
int last_track;
cdrom_read_toc(dev, temp_buf, CD_TOC_NORMAL, 0, 2 << 8, 65536);
cdrom_read_toc(dev, mke->temp_buf, CD_TOC_NORMAL, 0, 2 << 8, 65536);
cdrom_read_disc_information(dev, disc_type_buf);
first_track = temp_buf[2];
last_track = temp_buf[3];
first_track = mke->temp_buf[2];
last_track = mke->temp_buf[3];
b[0] = disc_type_buf[8];
b[1] = first_track;
@@ -260,41 +404,15 @@ mke_disc_capacity(cdrom_t *dev, unsigned char *b)
return 1;
}
uint8_t
mke_cdrom_status(cdrom_t *dev, mke_t *mke)
{
uint8_t status = 0;
/*
This bit seems to always be set?
Bit 4 never set?
*/
status |= 2;
if (dev->cd_status == CD_STATUS_PLAYING)
status |= STAT_PLAY;
if (dev->cd_status == CD_STATUS_PAUSED)
status |= STAT_PLAY;
if (fifo8_num_used(&mke->errors_fifo))
status |= 0x10;
/* Always set? */
status |= 0x20;
status |= STAT_TRAY;
if (mke->cdrom_dev->cd_status != CD_STATUS_EMPTY) {
status |= STAT_DISK;
status |= STAT_READY;
}
return status;
}
void
mke_read_multisess(mke_t *mke)
{
if ((temp_buf[9] != 0) || (temp_buf[10] != 0) || (temp_buf[11] != 0)) {
if ((mke->temp_buf[9] != 0) || (mke->temp_buf[10] != 0) || (mke->temp_buf[11] != 0)) {
/* Multi-session disc. */
fifo8_push(&mke->info_fifo, 0x80);
fifo8_push(&mke->info_fifo, temp_buf[9]);
fifo8_push(&mke->info_fifo, temp_buf[10]);
fifo8_push(&mke->info_fifo, temp_buf[11]);
fifo8_push(&mke->info_fifo, mke->temp_buf[9]);
fifo8_push(&mke->info_fifo, mke->temp_buf[10]);
fifo8_push(&mke->info_fifo, mke->temp_buf[11]);
fifo8_push(&mke->info_fifo, 0);
fifo8_push(&mke->info_fifo, 0);
} else {
@@ -407,7 +525,7 @@ mke_command(mke_t *mke, uint8_t value)
buf += mke->cdrom_dev->sector_size;
mke->data_to_push += mke->cdrom_dev->sector_size;
} else {
fifo8_push(&mke->errors_fifo, res == 0 ? 0x10 : 0x05);
mke_update_sense(mke, (res == 0) ? 0x10 : 0x05);
fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke));
break;
}
@@ -423,7 +541,7 @@ mke_command(mke_t *mke, uint8_t value)
break;
} case CMD1_READSUBQ:
CHECK_READY();
mke_get_subq(mke->cdrom_dev, (uint8_t *) &x);
mke_get_subq(mke, (uint8_t *) &x);
fifo8_reset(&mke->info_fifo);
fifo8_push_all(&mke->info_fifo, x, 11);
fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke));
@@ -450,7 +568,7 @@ mke_command(mke_t *mke, uint8_t value)
mke->command_buffer[4];
if (!sector_size) {
fifo8_push(&mke->errors_fifo, 0x0e);
mke_update_sense(mke, 0x0e);
return;
} else {
switch (sector_size) {
@@ -485,7 +603,7 @@ mke_command(mke_t *mke, uint8_t value)
mke->cdrom_dev->sector_size = 2352;
break;
default:
fifo8_push(&mke->errors_fifo, 0x0e);
mke_update_sense(mke, 0x0e);
return;
}
}
@@ -496,7 +614,7 @@ mke_command(mke_t *mke, uint8_t value)
mke->cdrom_dev->sector_size = 2352;
break;
default:
fifo8_push(&mke->errors_fifo, 0x0e);
mke_update_sense(mke, 0x0e);
return;
}
@@ -538,14 +656,14 @@ mke_command(mke_t *mke, uint8_t value)
/* 7 */
mke_log("DISK INFO\n");
CHECK_READY();
mke_disc_info(mke->cdrom_dev, (uint8_t *) &x);
mke_disc_info(mke, (uint8_t *) &x);
fifo8_push_all(&mke->info_fifo, x, 6);
fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke));
break;
case CMD1_READTOC:
CHECK_READY();
fifo8_reset(&mke->info_fifo);
mke_read_toc(mke->cdrom_dev, (uint8_t *) &x, mke->command_buffer[2]);
mke_read_toc(mke, (uint8_t *) &x, mke->command_buffer[2]);
fifo8_push_all(&mke->info_fifo, x, 8);
fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke));
break;
@@ -555,10 +673,8 @@ mke_command(mke_t *mke, uint8_t value)
fifo8_reset(&mke->info_fifo);
if (cdrom_audio_play(mke->cdrom_dev, mke->command_buffer[1], mke->command_buffer[3], 2))
fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke));
else {
fifo8_push(&mke->errors_fifo, 0x0E);
fifo8_push(&mke->errors_fifo, 0x10);
}
else
mke_update_sense(mke, 0x10);
break;
case CMD1_PLAY_MSF:
CHECK_READY();
@@ -574,10 +690,9 @@ mke_command(mke_t *mke, uint8_t value)
mke->command_buffer[3];
int len = (mke->command_buffer[4] << 16) | (mke->command_buffer[5] << 8) |
mke->command_buffer[6];
if (!cdrom_audio_play(mke->cdrom_dev, pos, len, msf)) {
fifo8_push(&mke->errors_fifo, 0x0E);
fifo8_push(&mke->errors_fifo, 0x10);
} else
if (!cdrom_audio_play(mke->cdrom_dev, pos, len, msf))
mke_update_sense(mke, 0x10);
else
fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke));
}
break;
@@ -619,21 +734,26 @@ mke_command(mke_t *mke, uint8_t value)
case CMD1_READ_ERR:
fifo8_reset(&mke->info_fifo);
mke_log("CMD: READ ERR\n");
memset(x, 0, 8);
if (fifo8_num_used(&mke->errors_fifo))
fifo8_pop_buf(&mke->errors_fifo, x, fifo8_num_used(&mke->errors_fifo));
fifo8_push_all(&mke->info_fifo, x, 8);
mke_log("ERROR: %02X %02X %02X %02X %02X %02X %02X %02X\n",
mke->sense[0], mke->sense[1], mke->sense[2], mke->sense[3],
mke->sense[4], mke->sense[5], mke->sense[6], mke->sense[7]);
{
uint8_t temp[8];
memset(temp, mke->sense[2], 8);
fifo8_push_all(&mke->info_fifo, mke->sense, 8);
}
mke->is_error = 0;
fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke));
fifo8_reset(&mke->errors_fifo);
break;
case CMD1_READ_VER:
/* SB2CD Expects 12 bytes, but drive only returns 11. */
fifo8_reset(&mke->info_fifo);
fifo8_push_all(&mke->info_fifo, mke->ver, 10);
fifo8_push_all(&mke->info_fifo, (uint8_t *) mke->ver, 10);
fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke));
break;
case CMD1_STATUS:
fifo8_reset(&mke->info_fifo);
CHECK_READY_READ();
fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke));
break;
default:
@@ -653,23 +773,30 @@ mke_command(mke_t *mke, uint8_t value)
void
mke_write(uint16_t port, uint8_t val, void *priv)
{
mke_t *mke = (mke_t *) priv;
mke_interface_t *mki = (mke_interface_t *) priv;
mke_t *mke = &(mki->mke[mki->drvsel & 0x03]);
uint8_t sb[8] = { 0x00, 0x02, 0x01, 0x03 };
mke_log("[%04X:%08X] [W] %04X = %02X\n", CS, cpu_state.pc, port, val);
if (!mke->enable_register || ((port & 0xf) == 3)) switch (port & 0xf) {
/* if (mke->present || ((port & 0x0003) == 0x0003)) */ switch (port & 0x0003) {
case 0:
mke_command(mke, val);
if (mke->present)
mke_command(mke, val);
break;
case 1:
if (mke->is_sb)
mke->data_select = val;
if (mki->is_sb)
mki->data_select = val;
break;
case 2:
mke_reset(mke);
if (mke->present)
mke_reset(mke);
break;
case 3:
mke->enable_register = val;
if (mki->is_sb)
mki->drvsel = (val & 0xfc) | sb[val & 0x03];
else
mki->drvsel = val;
break;
default:
break;
@@ -679,13 +806,14 @@ mke_write(uint16_t port, uint8_t val, void *priv)
uint8_t
mke_read(uint16_t port, void *priv)
{
mke_t *mke = (mke_t *) priv;
uint8_t ret = 0x00;
mke_interface_t *mki = (mke_interface_t *) priv;
mke_t *mke = &(mki->mke[mki->drvsel & 0x03]);
uint8_t ret = 0x00;
if (!mke->enable_register) switch (port & 0xf) {
if (mke->present) switch (port & 0x0003) {
case 0:
/* Info */
if (mke->is_sb && mke->data_select)
if (mki->is_sb && mki->data_select)
ret = fifo8_num_used(&mke->data_fifo) ? fifo8_pop(&mke->data_fifo) : 0x00;
else
ret = fifo8_num_used(&mke->info_fifo) ? fifo8_pop(&mke->info_fifo) : 0x00;
@@ -705,57 +833,27 @@ mke_read(uint16_t port, void *priv)
if (fifo8_num_used(&mke->info_fifo))
/* Status FIFO */
ret ^= 4;
if (fifo8_num_used(&mke->errors_fifo))
if (mke->is_error)
ret ^= 8;
break;
case 2:
/* Data */
if (!mke->is_sb)
if (!mki->is_sb)
ret = fifo8_num_used(&mke->data_fifo) ? fifo8_pop(&mke->data_fifo) : 0x00;
break;
default:
mke_log("MKE Unknown Read Port: %04X\n", port);
ret = 0xff;
break;
}
} else if ((port & 0x0003) == 0x0003)
/* This is needed for the Windows 95 built-in driver to function correctly. */
ret = 0xff;
mke_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, port, ret);
return ret;
}
void
mke_close(void *priv)
{
fifo8_destroy(&mke.info_fifo);
fifo8_destroy(&mke.data_fifo);
fifo8_destroy(&mke.errors_fifo);
timer_disable(&mke.timer);
}
static void
mke_cdrom_insert(void *priv)
{
mke_t *dev = (mke_t *) priv;
if ((dev == NULL) || (dev->cdrom_dev == NULL))
return;
if (dev->cdrom_dev->ops == NULL) {
dev->cdrom_dev->cd_status = CD_STATUS_EMPTY;
if (timer_is_enabled(&dev->timer)) {
timer_disable(&dev->timer);
dev->data_to_push = 0;
fifo8_push(&dev->errors_fifo, 0x15);
}
fifo8_push(&dev->errors_fifo, 0x11);
} else {
/* Turn off the medium changed status. */
dev->cdrom_dev->cd_status &= ~CD_STATUS_TRANSITION;
fifo8_push(&dev->errors_fifo, 0x11);
}
}
uint32_t
mke_get_volume(void *priv, int channel)
{
@@ -772,66 +870,74 @@ mke_get_channel(void *priv, int channel)
return channel == 0 ? dev->patch0 : dev->patch1;
}
void
mke_close(void *priv)
{
mke_interface_t *mki = (mke_interface_t *) calloc(1, sizeof(mke_interface_t));
for (uint8_t i = 0; i < 4; i++) {
mke_t *mke = &(mki->mke[i]);
fifo8_destroy(&mke->info_fifo);
fifo8_destroy(&mke->data_fifo);
timer_disable(&mke->timer);
}
free(mki);
}
void *
mke_init(const device_t *info)
{
mke_t *mke = (mke_t *) calloc(1, sizeof(mke_t));
cdrom_t *dev = NULL;
mke_interface_t *mki = (mke_interface_t *) calloc(1, sizeof(mke_interface_t));
int num = 0;
for (uint8_t i = 0; i < CDROM_NUM; i++) {
if (cdrom[i].bus_type == CDROM_BUS_MKE) {
dev = &cdrom[i];
break;
cdrom_t *dev = &cdrom[i];
mke_t *mke = &(mki->mke[dev->mke_channel]);
mke->present = 1;
cdrom_generate_name_mke(dev->type, mke->ver);
fifo8_create(&mke->info_fifo, 128);
fifo8_create(&mke->data_fifo, 624240 * 2);
fifo8_reset(&mke->info_fifo);
fifo8_reset(&mke->data_fifo);
mke->cdrom_dev = dev;
mke->command_buffer_pending = 7;
mke->sector_type = 0x08 | (1 << 4);
mke->sector_flags = 0x10;
mke->mode_select[2] = 0x08;
mke->patch0 = 0x01;
mke->patch1 = 0x02;
mke->vol0 = 255;
mke->vol1 = 255;
dev->sector_size = 2048;
dev->priv = mke;
dev->insert = mke_cdrom_insert;
dev->get_volume = mke_get_volume;
dev->get_channel = mke_get_channel;
dev->cached_sector = -1;
timer_add(&mke->timer, mke_command_callback, mke, 0);
num++;
if (num == 4)
break;
}
}
if (!dev)
return NULL;
mki->is_sb = info->local;
switch (device_get_config_int("firmware")) {
default:
case 0:
mke->ver = (uint8_t *) "CR-5630.75";
break;
case 1:
mke->ver = (uint8_t *) "CR-5630.80";
break;
case 2:
mke->ver = (uint8_t *) "CR-5620.75";
break;
case 3:
mke->ver = (uint8_t *) "CR-5620.80";
break;
}
fifo8_create(&mke->info_fifo, 128);
fifo8_create(&mke->data_fifo, 624240 * 2);
fifo8_create(&mke->errors_fifo, 8);
fifo8_reset(&mke->info_fifo);
fifo8_reset(&mke->data_fifo);
fifo8_reset(&mke->errors_fifo);
mke->cdrom_dev = dev;
mke->command_buffer_pending = 7;
mke->sector_type = 0x08 | (1 << 4);
mke->sector_flags = 0x10;
mke->mode_select[2] = 0x08;
mke->patch0 = 0x01;
mke->patch1 = 0x02;
mke->vol0 = 255;
mke->vol1 = 255;
mke->is_sb = info->local;
dev->sector_size = 2048;
dev->priv = mke;
dev->insert = mke_cdrom_insert;
dev->get_volume = mke_get_volume;
dev->get_channel = mke_get_channel;
dev->cached_sector = -1;
timer_add(&mke->timer, mke_command_callback, mke, 0);
uint16_t base = device_get_config_hex16("base");
io_sethandler(base, 16, mke_read, NULL, NULL, mke_write, NULL, NULL, mke);
return mke;
io_sethandler(base, 4, mke_read, NULL, NULL, mke_write, NULL, NULL, mki);
return mki;
}
static const device_config_t mke_config[] = {
@@ -860,23 +966,6 @@ static const device_config_t mke_config[] = {
},
.bios = { { 0 } }
},
{
.name = "firmware",
.description = "Firmware Version",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "CR-563 0.75", .value = 0 },
{ .description = "CR-563 0.80", .value = 1 },
{ .description = "CR-562 0.75", .value = 2 },
{ .description = "CR-562 0.80", .value = 3 },
{ .description = "" }
},
.bios = { { 0 } }
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format off
};