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:
@@ -1489,9 +1489,6 @@ pc_reset_hard_init(void)
|
||||
|
||||
fdd_reset();
|
||||
|
||||
/* Reset the CD-ROM Controller module. */
|
||||
cdrom_interface_reset();
|
||||
|
||||
/* Reset and reconfigure the SCSI layer. */
|
||||
scsi_card_init();
|
||||
|
||||
@@ -1499,6 +1496,9 @@ pc_reset_hard_init(void)
|
||||
|
||||
cdrom_hard_reset();
|
||||
|
||||
/* Reset the CD-ROM Controller module. */
|
||||
cdrom_interface_reset();
|
||||
|
||||
mo_hard_reset();
|
||||
|
||||
rdisk_hard_reset();
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
32
src/config.c
32
src/config.c
@@ -1387,11 +1387,17 @@ load_floppy_and_cdrom_drives(void)
|
||||
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;
|
||||
cdrom[c].mke_channel = cdrom[c].ide_channel = cdrom[c].scsi_device_id = c & 3;
|
||||
|
||||
if (cdrom[c].bus_type == CDROM_BUS_ATAPI) {
|
||||
if (cdrom[c].bus_type == CDROM_BUS_MKE) {
|
||||
sprintf(temp, "cdrom_%02i_mke_channel", c + 1);
|
||||
cdrom[c].mke_channel = !!ini_section_get_int(cat, temp, c & 3);
|
||||
|
||||
if (cdrom[c].mke_channel > 3)
|
||||
cdrom[c].mke_channel = 3;
|
||||
} else if (cdrom[c].bus_type == CDROM_BUS_ATAPI) {
|
||||
sprintf(temp, "cdrom_%02i_ide_channel", c + 1);
|
||||
sprintf(tmp2, "%01u:%01u", (c + 2) >> 1, (c + 2) & 1);
|
||||
sprintf(tmp2, "%01u:%01u", (c & 3) >> 1, (c & 3) & 1);
|
||||
p = ini_section_get_string(cat, temp, tmp2);
|
||||
sscanf(p, "%01u:%01u", &board, &dev);
|
||||
board &= 3;
|
||||
@@ -1402,13 +1408,13 @@ load_floppy_and_cdrom_drives(void)
|
||||
cdrom[c].ide_channel = 7;
|
||||
} else if (cdrom[c].bus_type == CDROM_BUS_SCSI) {
|
||||
sprintf(temp, "cdrom_%02i_scsi_location", c + 1);
|
||||
sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c + 2);
|
||||
sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c & 3);
|
||||
p = ini_section_get_string(cat, temp, tmp2);
|
||||
sscanf(p, "%01u:%02u", &board, &dev);
|
||||
if (board >= SCSI_BUS_MAX) {
|
||||
/* Invalid bus - check legacy ID */
|
||||
sprintf(temp, "cdrom_%02i_scsi_id", c + 1);
|
||||
cdrom[c].scsi_device_id = ini_section_get_int(cat, temp, c + 2);
|
||||
cdrom[c].scsi_device_id = ini_section_get_int(cat, temp, c & 3);
|
||||
|
||||
if (cdrom[c].scsi_device_id > 15)
|
||||
cdrom[c].scsi_device_id = 15;
|
||||
@@ -1419,6 +1425,11 @@ load_floppy_and_cdrom_drives(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (cdrom[c].bus_type != CDROM_BUS_MKE) {
|
||||
sprintf(temp, "cdrom_%02i_mke_channel", c + 1);
|
||||
ini_section_delete_var(cat, temp);
|
||||
}
|
||||
|
||||
if (cdrom[c].bus_type != CDROM_BUS_ATAPI) {
|
||||
sprintf(temp, "cdrom_%02i_ide_channel", c + 1);
|
||||
ini_section_delete_var(cat, temp);
|
||||
@@ -3132,8 +3143,7 @@ save_floppy_and_cdrom_drives(void)
|
||||
|
||||
sprintf(temp, "cdrom_%02i_type", c + 1);
|
||||
char *tn = cdrom_get_internal_name(cdrom_get_type(c));
|
||||
if ((cdrom[c].bus_type == 0) || (cdrom[c].bus_type == CDROM_BUS_MITSUMI) || (cdrom[c].bus_type == CDROM_BUS_MKE) ||
|
||||
!strcmp(tn, "86cd"))
|
||||
if ((cdrom[c].bus_type == 0) || (cdrom[c].bus_type == CDROM_BUS_MITSUMI) || !strcmp(tn, "86cd"))
|
||||
ini_section_delete_var(cat, temp);
|
||||
else
|
||||
ini_section_set_string(cat, temp, tn);
|
||||
@@ -3152,6 +3162,14 @@ save_floppy_and_cdrom_drives(void)
|
||||
ini_section_set_string(cat, temp, tmp2);
|
||||
}
|
||||
|
||||
sprintf(temp, "cdrom_%02i_mke_channel", c + 1);
|
||||
if (cdrom[c].bus_type != CDROM_BUS_MKE)
|
||||
ini_section_delete_var(cat, temp);
|
||||
else {
|
||||
ini_section_set_int(cat, temp, cdrom[c].mke_channel);
|
||||
ini_section_set_string(cat, temp, tmp2);
|
||||
}
|
||||
|
||||
sprintf(temp, "cdrom_%02i_ide_channel", c + 1);
|
||||
if (cdrom[c].bus_type != CDROM_BUS_ATAPI)
|
||||
ini_section_delete_var(cat, temp);
|
||||
|
||||
@@ -94,14 +94,19 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
CDROM_BUS_DISABLED = 0,
|
||||
CDROM_BUS_ATAPI = 5,
|
||||
CDROM_BUS_SCSI = 6,
|
||||
CDROM_BUS_MITSUMI = 7,
|
||||
CDROM_BUS_MKE = 8,
|
||||
CDROM_BUS_USB = 9
|
||||
CDROM_BUS_DISABLED = 0,
|
||||
CDROM_BUS_PHILIPS = 1,
|
||||
CDROM_BUS_SONY = 2,
|
||||
CDROM_BUS_HITACHI = 3,
|
||||
CDROM_BUS_MKE = 4,
|
||||
CDROM_BUS_MITSUMI = 5,
|
||||
CDROM_BUS_LPT = 6,
|
||||
CDROM_BUS_ATAPI = 8,
|
||||
CDROM_BUS_SCSI = 9,
|
||||
CDROM_BUS_USB = 10
|
||||
};
|
||||
|
||||
#define BUS_TYPE_MKE CDROM_BUS_MKE
|
||||
#define BUS_TYPE_IDE CDROM_BUS_ATAPI
|
||||
#define BUS_TYPE_SCSI CDROM_BUS_SCSI
|
||||
#define BUS_TYPE_BOTH -2
|
||||
@@ -221,6 +226,10 @@ static const struct cdrom_drive_types_s {
|
||||
{ "TOSHIBA", "CD-ROM XM-3301TA", "0272", "toshiba_3301ta", BUS_TYPE_SCSI, 2, 2, 96, 0, 0, { -1, -1, -1, -1 } }, /* Tray. */
|
||||
{ "TOSHIBA", "CD-ROM XM-5701TA", "3136", "toshiba_5701a", BUS_TYPE_SCSI, 2, 12, 96, 0, 0, { -1, -1, -1, -1 } }, /* Tray. */
|
||||
{ "TOSHIBA", "DVD-ROM SD-M1401", "1008", "toshiba_m1401", BUS_TYPE_SCSI, 2, 40, 96, 0, 1, { -1, -1, -1, -1 } }, /* Tray. */
|
||||
{ "MATSHITA", "CR-562", "0.75", "cr562", BUS_TYPE_MKE , 0, 2, 0, 0, 0, { -1, -1, -1, -1 } },
|
||||
{ "MATSHITA", "CR-562", "0.80", "cr562_080", BUS_TYPE_MKE , 0, 2, 0, 0, 0, { -1, -1, -1, -1 } },
|
||||
{ "MATSHITA", "CR-563", "0.75", "cr563", BUS_TYPE_MKE , 0, 2, 0, 0, 0, { -1, -1, -1, -1 } },
|
||||
{ "MATSHITA", "CR-563", "0.80", "cr563_080", BUS_TYPE_MKE , 0, 2, 0, 0, 0, { -1, -1, -1, -1 } },
|
||||
{ "", "", "", "", BUS_TYPE_NONE, 0, -1, 0, 0, 0, { -1, -1, -1, -1 } }
|
||||
};
|
||||
|
||||
@@ -288,7 +297,7 @@ typedef struct cdrom {
|
||||
union {
|
||||
uint8_t res;
|
||||
uint8_t res0; /* Reserved for other ID's. */
|
||||
uint8_t res1;
|
||||
uint8_t mke_channel;
|
||||
uint8_t ide_channel;
|
||||
uint8_t scsi_device_id;
|
||||
};
|
||||
@@ -394,6 +403,7 @@ extern int cdrom_get_inquiry_len(const int type);
|
||||
extern int cdrom_has_dma(const int type);
|
||||
extern int cdrom_get_transfer_max(const int type, const int mode);
|
||||
extern int cdrom_get_type_count(void);
|
||||
extern void cdrom_generate_name_mke(const int type, char *name);
|
||||
extern void cdrom_get_identify_model(const int type, char *name, const int id);
|
||||
extern void cdrom_get_name(const int type, char *name);
|
||||
extern char *cdrom_get_internal_name(const int type);
|
||||
|
||||
@@ -67,14 +67,15 @@ enum {
|
||||
};
|
||||
#else
|
||||
enum {
|
||||
HDD_BUS_DISABLED = 0,
|
||||
HDD_BUS_MFM = 1,
|
||||
HDD_BUS_XTA = 2,
|
||||
HDD_BUS_ESDI = 3,
|
||||
HDD_BUS_IDE = 4,
|
||||
HDD_BUS_ATAPI = 5,
|
||||
HDD_BUS_SCSI = 6,
|
||||
HDD_BUS_USB = 7
|
||||
HDD_BUS_DISABLED = 0,
|
||||
HDD_BUS_MFM = 1,
|
||||
HDD_BUS_XTA = 2,
|
||||
HDD_BUS_ESDI = 3,
|
||||
HDD_BUS_LPT = 6,
|
||||
HDD_BUS_IDE = 7,
|
||||
HDD_BUS_ATAPI = 8,
|
||||
HDD_BUS_SCSI = 9,
|
||||
HDD_BUS_USB = 10
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -84,10 +84,11 @@ static const mo_drive_type_t mo_drive_types[KNOWN_MO_DRIVE_TYPES] = {
|
||||
};
|
||||
|
||||
enum {
|
||||
MO_BUS_DISABLED = 0,
|
||||
MO_BUS_ATAPI = 5,
|
||||
MO_BUS_SCSI = 6,
|
||||
MO_BUS_USB = 7
|
||||
MO_BUS_DISABLED = 0,
|
||||
MO_BUS_LPT = 6,
|
||||
MO_BUS_ATAPI = 8,
|
||||
MO_BUS_SCSI = 9,
|
||||
MO_BUS_USB = 10
|
||||
};
|
||||
|
||||
typedef struct mo_drive_t {
|
||||
|
||||
@@ -63,10 +63,12 @@ static const rdisk_drive_type_t rdisk_drive_types[KNOWN_RDISK_DRIVE_TYPES] = {
|
||||
};
|
||||
|
||||
enum {
|
||||
RDISK_BUS_DISABLED = 0,
|
||||
RDISK_BUS_ATAPI = 5,
|
||||
RDISK_BUS_SCSI = 6,
|
||||
RDISK_BUS_USB = 7
|
||||
RDISK_BUS_DISABLED = 0,
|
||||
RDISK_BUS_LPT = 6,
|
||||
RDISK_BUS_IDE = 7,
|
||||
RDISK_BUS_ATAPI = 8,
|
||||
RDISK_BUS_SCSI = 9,
|
||||
RDISK_BUS_USB = 10
|
||||
};
|
||||
|
||||
typedef struct rdisk_drive_t {
|
||||
|
||||
17
src/io.c
17
src/io.c
@@ -60,6 +60,7 @@ int initialized = 0;
|
||||
io_t *io[NPORTS];
|
||||
io_t *io_last[NPORTS];
|
||||
|
||||
// #define ENABLE_IO_LOG 1
|
||||
#ifdef ENABLE_IO_LOG
|
||||
int io_do_log = ENABLE_IO_LOG;
|
||||
|
||||
@@ -396,7 +397,9 @@ inb(uint16_t port)
|
||||
ret = 0xfe;
|
||||
#endif
|
||||
|
||||
io_log("[%04X:%08X] (%i, %i, %04i) in b(%04X) = %02X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret);
|
||||
if (!found && (CS > 0x007c) && (CS < 0xa000)) {
|
||||
io_log("[%04X:%08X] (%i, %i, %04i) in b(%04X) = %02X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -453,7 +456,9 @@ outb(uint16_t port, uint8_t val)
|
||||
#endif
|
||||
}
|
||||
|
||||
io_log("[%04X:%08X] (%i, %i, %04i) outb(%04X, %02X)\n", CS, cpu_state.pc, in_smm, found, qfound, port, val);
|
||||
if (!found && (CS > 0x007c) && (CS < 0xa000)) {
|
||||
io_log("[%04X:%08X] (%i, %i, %04i) outb(%04X, %02X)\n", CS, cpu_state.pc, in_smm, found, qfound, port, val);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -533,7 +538,7 @@ inw(uint16_t port)
|
||||
if (!found)
|
||||
cycles -= io_delay;
|
||||
|
||||
io_log("[%04X:%08X] (%i, %i, %04i) in w(%04X) = %04X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret);
|
||||
// io_log("[%04X:%08X] (%i, %i, %04i) in w(%04X) = %04X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -605,7 +610,7 @@ outw(uint16_t port, uint16_t val)
|
||||
#endif
|
||||
}
|
||||
|
||||
io_log("[%04X:%08X] (%i, %i, %04i) outw(%04X, %04X)\n", CS, cpu_state.pc, in_smm, found, qfound, port, val);
|
||||
// io_log("[%04X:%08X] (%i, %i, %04i) outw(%04X, %04X)\n", CS, cpu_state.pc, in_smm, found, qfound, port, val);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -717,7 +722,7 @@ inl(uint16_t port)
|
||||
if (!found)
|
||||
cycles -= io_delay;
|
||||
|
||||
io_log("[%04X:%08X] (%i, %i, %04i) in l(%04X) = %08X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret);
|
||||
// io_log("[%04X:%08X] (%i, %i, %04i) in l(%04X) = %08X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -807,7 +812,7 @@ outl(uint16_t port, uint32_t val)
|
||||
#endif
|
||||
}
|
||||
|
||||
io_log("[%04X:%08X] (%i, %i, %04i) outl(%04X, %08X)\n", CS, cpu_state.pc, in_smm, found, qfound, port, val);
|
||||
// io_log("[%04X:%08X] (%i, %i, %04i) outl(%04X, %08X)\n", CS, cpu_state.pc, in_smm, found, qfound, port, val);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ Harddrives::populateBuses(QAbstractItemModel *model)
|
||||
{
|
||||
model->removeRows(0, model->rowCount());
|
||||
model->insertRows(0, 6);
|
||||
|
||||
model->setData(model->index(0, 0), "MFM/RLL");
|
||||
model->setData(model->index(1, 0), "XTA");
|
||||
model->setData(model->index(2, 0), "ESDI");
|
||||
@@ -48,7 +49,7 @@ Harddrives::populateBuses(QAbstractItemModel *model)
|
||||
}
|
||||
|
||||
void
|
||||
Harddrives::populateRemovableBuses(QAbstractItemModel *model)
|
||||
Harddrives::populateCDROMBuses(QAbstractItemModel *model)
|
||||
{
|
||||
model->removeRows(0, model->rowCount());
|
||||
#ifdef USE_CDROM_MITSUMI
|
||||
@@ -56,6 +57,7 @@ Harddrives::populateRemovableBuses(QAbstractItemModel *model)
|
||||
#else
|
||||
model->insertRows(0, 4);
|
||||
#endif
|
||||
|
||||
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"));
|
||||
@@ -77,6 +79,21 @@ Harddrives::populateRemovableBuses(QAbstractItemModel *model)
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
Harddrives::populateRemovableBuses(QAbstractItemModel *model)
|
||||
{
|
||||
model->removeRows(0, model->rowCount());
|
||||
model->insertRows(0, 3);
|
||||
|
||||
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(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);
|
||||
}
|
||||
|
||||
void
|
||||
Harddrives::populateSpeeds(QAbstractItemModel *model, int bus)
|
||||
{
|
||||
@@ -144,6 +161,12 @@ Harddrives::populateBusChannels(QAbstractItemModel *model, int bus, SettingsBusT
|
||||
subChannelWidth = 2;
|
||||
busesToCheck.append(HDD_BUS_SCSI);
|
||||
break;
|
||||
case CDROM_BUS_MKE:
|
||||
shifter = 2;
|
||||
orer = 3;
|
||||
busRows = 4;
|
||||
busesToCheck.append(CDROM_BUS_MKE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -192,11 +215,11 @@ 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;
|
||||
case CDROM_BUS_MITSUMI:
|
||||
busName = QString("Mitsumi");
|
||||
break;
|
||||
case CDROM_BUS_MKE:
|
||||
busName = QString("Panasonic/MKE");
|
||||
busName = QString("Panasonic/MKE (%1:%2)").arg(channel >> 2).arg(channel & 3);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ class SettingsBusTracking;
|
||||
|
||||
namespace Harddrives {
|
||||
void populateBuses(QAbstractItemModel *model);
|
||||
void populateCDROMBuses(QAbstractItemModel *model);
|
||||
void populateRemovableBuses(QAbstractItemModel *model);
|
||||
void populateBusChannels(QAbstractItemModel *model, int bus, SettingsBusTracking *sbt = nullptr);
|
||||
void populateSpeeds(QAbstractItemModel *model, int bus);
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
SettingsBusTracking::SettingsBusTracking()
|
||||
{
|
||||
mitsumi_tracking = false;
|
||||
mke_tracking = false;
|
||||
|
||||
mke_tracking = 0x0000000000000000ULL;
|
||||
mfm_tracking = 0x0000000000000000ULL;
|
||||
esdi_tracking = 0x0000000000000000ULL;
|
||||
xta_tracking = 0x0000000000000000ULL;
|
||||
@@ -42,40 +42,76 @@ SettingsBusTracking::SettingsBusTracking()
|
||||
scsi_tracking[i] = 0x0000000000000000ULL;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
SettingsBusTracking::next_free_mke_channel()
|
||||
{
|
||||
uint64_t mask;
|
||||
uint8_t ret = CHANNEL_NONE;
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f));
|
||||
|
||||
if (!(mke_tracking & mask)) {
|
||||
ret = (uint8_t) i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
SettingsBusTracking::next_free_mfm_channel()
|
||||
{
|
||||
if ((mfm_tracking & 0xff00ULL) && !(mfm_tracking & 0x00ffULL))
|
||||
return 1;
|
||||
uint64_t mask;
|
||||
uint8_t ret = CHANNEL_NONE;
|
||||
|
||||
if (!(mfm_tracking & 0xff00ULL) && (mfm_tracking & 0x00ffULL))
|
||||
return 0;
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f));
|
||||
|
||||
return CHANNEL_NONE;
|
||||
if (!(mfm_tracking & mask)) {
|
||||
ret = (uint8_t) i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
SettingsBusTracking::next_free_esdi_channel()
|
||||
{
|
||||
if ((esdi_tracking & 0xff00ULL) && !(esdi_tracking & 0x00ffULL))
|
||||
return 1;
|
||||
uint64_t mask;
|
||||
uint8_t ret = CHANNEL_NONE;
|
||||
|
||||
if (!(esdi_tracking & 0xff00ULL) && (esdi_tracking & 0x00ffULL))
|
||||
return 0;
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f));
|
||||
|
||||
return CHANNEL_NONE;
|
||||
if (!(esdi_tracking & mask)) {
|
||||
ret = (uint8_t) i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
SettingsBusTracking::next_free_xta_channel()
|
||||
{
|
||||
if ((xta_tracking & 0xff00ULL) && !(xta_tracking & 0x00ffULL))
|
||||
return 1;
|
||||
uint64_t mask;
|
||||
uint8_t ret = CHANNEL_NONE;
|
||||
|
||||
if (!(xta_tracking & 0xff00ULL) && (xta_tracking & 0x00ffULL))
|
||||
return 0;
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f));
|
||||
|
||||
return CHANNEL_NONE;
|
||||
if (!(xta_tracking & mask)) {
|
||||
ret = (uint8_t) i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
@@ -209,29 +245,32 @@ QList<int> SettingsBusTracking::busChannelsInUse(const int bus) {
|
||||
uint64_t mask;
|
||||
switch (bus) {
|
||||
case CDROM_BUS_MKE:
|
||||
if (mke_tracking)
|
||||
channelsInUse.append(0);
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f));
|
||||
if (mke_tracking & mask)
|
||||
channelsInUse.append(i);
|
||||
}
|
||||
break;
|
||||
case CDROM_BUS_MITSUMI:
|
||||
if (mitsumi_tracking)
|
||||
channelsInUse.append(0);
|
||||
break;
|
||||
case HDD_BUS_MFM:
|
||||
for (uint8_t i = 0; i < 32; i++) {
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f));
|
||||
if (mfm_tracking & mask)
|
||||
channelsInUse.append(i);
|
||||
}
|
||||
break;
|
||||
case HDD_BUS_ESDI:
|
||||
for (uint8_t i = 0; i < 32; i++) {
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f));
|
||||
if (esdi_tracking & mask)
|
||||
channelsInUse.append(i);
|
||||
}
|
||||
break;
|
||||
case HDD_BUS_XTA:
|
||||
for (uint8_t i = 0; i < 32; i++) {
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f));
|
||||
if (xta_tracking & mask)
|
||||
channelsInUse.append(i);
|
||||
@@ -276,7 +315,12 @@ SettingsBusTracking::device_track(int set, uint8_t dev_type, int bus, int channe
|
||||
|
||||
switch (bus) {
|
||||
case CDROM_BUS_MKE:
|
||||
mke_tracking = set;
|
||||
mask = ((uint64_t) dev_type) << ((uint64_t) ((channel << 3) & 0x3f));
|
||||
|
||||
if (set)
|
||||
mke_tracking |= mask;
|
||||
else
|
||||
mke_tracking &= ~mask;
|
||||
break;
|
||||
case CDROM_BUS_MITSUMI:
|
||||
mitsumi_tracking = set;
|
||||
|
||||
@@ -31,12 +31,14 @@ public:
|
||||
QList<int> busChannelsInUse(int bus);
|
||||
|
||||
/* These return 0xff is none is free. */
|
||||
uint8_t next_free_mke_channel();
|
||||
uint8_t next_free_mfm_channel();
|
||||
uint8_t next_free_esdi_channel();
|
||||
uint8_t next_free_xta_channel();
|
||||
uint8_t next_free_ide_channel();
|
||||
uint8_t next_free_scsi_id();
|
||||
|
||||
int mke_bus_full();
|
||||
int mfm_bus_full();
|
||||
int esdi_bus_full();
|
||||
int xta_bus_full();
|
||||
@@ -49,6 +51,8 @@ public:
|
||||
void device_track(int set, uint8_t dev_type, int bus, int channel);
|
||||
|
||||
private:
|
||||
/* 1 channel, 2 devices per channel, 8 bits per device = 16 bits. */
|
||||
uint64_t mke_tracking { 0 };
|
||||
/* 1 channel, 2 devices per channel, 8 bits per device = 16 bits. */
|
||||
uint64_t mfm_tracking { 0 };
|
||||
/* 1 channel, 2 devices per channel, 8 bits per device = 16 bits. */
|
||||
@@ -63,7 +67,6 @@ private:
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
bool mitsumi_tracking;
|
||||
bool mke_tracking;
|
||||
};
|
||||
|
||||
#endif // QT_SETTINGS_BUS_TRACKING_HPP
|
||||
|
||||
@@ -105,8 +105,7 @@ 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 &&
|
||||
idx.siblingAtColumn(0).data(Qt::UserRole).toUInt() != CDROM_BUS_MKE)
|
||||
else if (idx.siblingAtColumn(0).data(Qt::UserRole).toUInt() != CDROM_BUS_MITSUMI)
|
||||
model->setData(i, CDROMName(type));
|
||||
model->setData(i, type, Qt::UserRole);
|
||||
}
|
||||
@@ -151,7 +150,7 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent)
|
||||
this, &SettingsFloppyCDROM::onFloppyRowChanged);
|
||||
ui->tableViewFloppy->setCurrentIndex(model->index(0, 0));
|
||||
|
||||
Harddrives::populateRemovableBuses(ui->comboBoxBus->model());
|
||||
Harddrives::populateCDROMBuses(ui->comboBoxBus->model());
|
||||
model = ui->comboBoxSpeed->model();
|
||||
for (int i = 0; i < 72; i++)
|
||||
Models::AddEntry(model, QString("%1x").arg(i + 1), i + 1);
|
||||
@@ -172,12 +171,13 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent)
|
||||
setCDROMSpeed(model, idx.siblingAtColumn(1), cdrom[i].speed);
|
||||
else
|
||||
setCDROMSpeed(model, idx.siblingAtColumn(1), speed);
|
||||
if (cdrom[i].bus_type == CDROM_BUS_ATAPI)
|
||||
if (cdrom[i].bus_type == CDROM_BUS_MKE)
|
||||
Harddrives::busTrackClass->device_track(1, DEV_CDROM, cdrom[i].bus_type, cdrom[i].mke_channel);
|
||||
else 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 || cdrom[i].bus_type == CDROM_BUS_MKE)
|
||||
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();
|
||||
@@ -197,9 +197,10 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent)
|
||||
int selectedTypeRow = 0;
|
||||
int eligibleRows = 0;
|
||||
while (cdrom_drive_types[j].bus_type != BUS_TYPE_NONE) {
|
||||
if (((bus_type == CDROM_BUS_ATAPI) || (bus_type == CDROM_BUS_SCSI)) &&
|
||||
if (((bus_type == CDROM_BUS_MKE) || (bus_type == CDROM_BUS_ATAPI) ||
|
||||
(bus_type == CDROM_BUS_SCSI)) &&
|
||||
((cdrom_drive_types[j].bus_type == bus_type) ||
|
||||
(cdrom_drive_types[j].bus_type == BUS_TYPE_BOTH))) {
|
||||
((cdrom_drive_types[j].bus_type == BUS_TYPE_BOTH) && (bus_type != BUS_TYPE_MKE)))) {
|
||||
QString name = CDROMName(j);
|
||||
Models::AddEntry(modelType, name, j);
|
||||
if (cdrom[cdromIdx].type == j)
|
||||
@@ -288,9 +289,10 @@ SettingsFloppyCDROM::onCDROMRowChanged(const QModelIndex ¤t)
|
||||
int selectedTypeRow = 0;
|
||||
int eligibleRows = 0;
|
||||
while (cdrom_drive_types[j].bus_type != BUS_TYPE_NONE) {
|
||||
if (((bus == CDROM_BUS_ATAPI) || (bus == CDROM_BUS_SCSI)) &&
|
||||
if (((bus == CDROM_BUS_MKE) || (bus == CDROM_BUS_ATAPI) ||
|
||||
(bus == CDROM_BUS_SCSI)) &&
|
||||
((cdrom_drive_types[j].bus_type == bus) ||
|
||||
(cdrom_drive_types[j].bus_type == BUS_TYPE_BOTH))) {
|
||||
((cdrom_drive_types[j].bus_type == BUS_TYPE_BOTH) && (bus != BUS_TYPE_MKE)))) {
|
||||
QString name = CDROMName(j);
|
||||
Models::AddEntry(modelType, name, j);
|
||||
if (type == j)
|
||||
@@ -343,9 +345,9 @@ SettingsFloppyCDROM::on_comboBoxBus_currentIndexChanged(int index)
|
||||
if (index >= 0) {
|
||||
int bus = ui->comboBoxBus->currentData().toInt();
|
||||
bool enabled = (bus != CDROM_BUS_DISABLED);
|
||||
ui->comboBoxChannel->setEnabled((bus == CDROM_BUS_MITSUMI || bus == CDROM_BUS_MKE) ? 0 : enabled);
|
||||
ui->comboBoxSpeed->setEnabled((bus == CDROM_BUS_MITSUMI || bus == CDROM_BUS_MKE) ? 0 : enabled);
|
||||
ui->comboBoxCDROMType->setEnabled((bus == CDROM_BUS_MITSUMI || bus == CDROM_BUS_MKE) ? 0 : 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, Harddrives::busTrackClass);
|
||||
}
|
||||
@@ -368,11 +370,13 @@ SettingsFloppyCDROM::on_comboBoxBus_activated(int)
|
||||
Harddrives::busTrackClass->device_track(0, DEV_CDROM, ui->tableViewCDROM->model()->data(i,
|
||||
Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i,
|
||||
Qt::UserRole + 1).toInt());
|
||||
if (bus_type == CDROM_BUS_ATAPI)
|
||||
if (bus_type == CDROM_BUS_MKE)
|
||||
ui->comboBoxChannel->setCurrentIndex(Harddrives::busTrackClass->next_free_mke_channel());
|
||||
else 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 || bus_type == CDROM_BUS_MKE)
|
||||
else if (bus_type == CDROM_BUS_MITSUMI)
|
||||
ui->comboBoxChannel->setCurrentIndex(0);
|
||||
|
||||
setCDROMBus(ui->tableViewCDROM->model(),
|
||||
@@ -390,9 +394,10 @@ SettingsFloppyCDROM::on_comboBoxBus_activated(int)
|
||||
int selectedTypeRow = 0;
|
||||
int eligibleRows = 0;
|
||||
while (cdrom_drive_types[j].bus_type != BUS_TYPE_NONE) {
|
||||
if (((bus_type == CDROM_BUS_ATAPI) || (bus_type == CDROM_BUS_SCSI)) &&
|
||||
if (((bus_type == CDROM_BUS_MKE) || (bus_type == CDROM_BUS_ATAPI) ||
|
||||
(bus_type == CDROM_BUS_SCSI)) &&
|
||||
((cdrom_drive_types[j].bus_type == bus_type) ||
|
||||
(cdrom_drive_types[j].bus_type == BUS_TYPE_BOTH))) {
|
||||
((cdrom_drive_types[j].bus_type == BUS_TYPE_BOTH) && (bus_type != BUS_TYPE_MKE)))) {
|
||||
QString name = CDROMName(j);
|
||||
Models::AddEntry(modelType, name, j);
|
||||
if (cdrom[cdromIdx].type == j)
|
||||
|
||||
@@ -140,14 +140,13 @@ SettingsInput::onCurrentMachineChanged(int machineId)
|
||||
c++;
|
||||
}
|
||||
keyboardModel->removeRows(0, removeRows);
|
||||
ui->comboBoxKeyboard->setCurrentIndex(selectedRow);
|
||||
|
||||
if ((c == 1) || has_int_kbd)
|
||||
ui->comboBoxKeyboard->setEnabled(false);
|
||||
else
|
||||
ui->comboBoxKeyboard->setEnabled(true);
|
||||
|
||||
ui->comboBoxKeyboard->setCurrentIndex(selectedRow);
|
||||
|
||||
auto *mouseModel = ui->comboBoxMouse->model();
|
||||
removeRows = mouseModel->rowCount();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user