From 2dce0de74914d1031f4d65e25e273d70bec57a1e Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 24 Jan 2018 18:38:43 +0100 Subject: [PATCH] Fixed bugs in the Settings dialog regarding channel/ID/LUN tracking; Fixed the MODE SELECT (6) command for CD-ROM and SCSI disk; Implemented REQUEST SENSE with DESC bit set for SCSI disk; Implemented the SCSI RESERVE, SCSI RELEASE, and SEND DIAGNOSTIC commands for SCSI disk. --- src/cdrom/cdrom.c | 34 ++++++-- src/cdrom/cdrom_image.cc | 2 +- src/scsi/scsi.h | 173 ++++++++++++++++++++------------------- src/scsi/scsi_disk.c | 56 +++++++++---- src/win/win_settings.c | 25 ++++-- 5 files changed, 175 insertions(+), 115 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index dd61fdbde..a4c5b31f7 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -9,11 +9,11 @@ * Implementation of the CD-ROM drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)cdrom.c 1.0.28 2018/01/17 + * Version: @(#)cdrom.c 1.0.29 2018/01/24 * * Author: Miran Grca, * - * Copyright 2016,2018 Miran Grca. + * Copyright 2016-2018 Miran Grca. */ #include #include @@ -1695,6 +1695,7 @@ cdrom_readtoc_fallback: case GPCMD_READ_12: cdrom[id].sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); cdrom[id].sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + cdrom_log("CD-ROM %i: Length: %i, LBA: %i\n", id, cdrom[id].sector_len, cdrom[id].sector_pos); msf = 0; break; case GPCMD_READ_CD_MSF: @@ -2534,18 +2535,30 @@ uint8_t cdrom_phase_data_out(uint8_t id) uint8_t hdr_len, val, old_val, ch; + FILE *f; + switch(cdrom[id].current_cdb[0]) { case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: + f = nvr_fopen(L"modeselect.bin", L"wb"); + fwrite(cdbufferb, 1, cdrom[id].total_length, f); + fclose(f); + if (cdrom[id].current_cdb[0] == GPCMD_MODE_SELECT_10) hdr_len = 8; else hdr_len = 4; if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { - block_desc_len = cdbufferb[6]; - block_desc_len <<= 8; - block_desc_len |= cdbufferb[7]; + if (cdrom[id].current_cdb[0] == GPCMD_MODE_SELECT_6) { + block_desc_len = cdbufferb[2]; + block_desc_len <<= 8; + block_desc_len |= cdbufferb[3]; + } else { + block_desc_len = cdbufferb[6]; + block_desc_len <<= 8; + block_desc_len |= cdbufferb[7]; + } } else block_desc_len = 0; @@ -2557,9 +2570,10 @@ uint8_t cdrom_phase_data_out(uint8_t id) pos += 2; - if (!(cdrom_mode_sense_page_flags & (1LL << ((uint64_t) page)))) + if (!(cdrom_mode_sense_page_flags & (1LL << ((uint64_t) page)))) { + cdrom_log("Unimplemented page %02X\n", page); error |= 1; - else { + } else { for (i = 0; i < page_len; i++) { ch = cdrom_mode_sense_pages_changeable.pages[page][i + 2]; val = cdbufferb[pos + i]; @@ -2567,8 +2581,10 @@ uint8_t cdrom_phase_data_out(uint8_t id) if (val != old_val) { if (ch) cdrom_mode_sense_pages_saved[id].pages[page][i + 2] = val; - else + else { + cdrom_log("Unchangeable value on position %02X on page %02X\n", i + 2, page); error |= 1; + } } } } @@ -3039,7 +3055,7 @@ cdrom_global_reset(void) if (cdrom_drives[c].bus_type) SCSIReset(cdrom_drives[c].scsi_device_id, cdrom_drives[c].scsi_device_lun); -pclog("CDROM global_reset drive=%d host=%02x\n", c, cdrom_drives[c].host_drive); +cdrom_log("CDROM global_reset drive=%d host=%02x\n", c, cdrom_drives[c].host_drive); if (cdrom_drives[c].host_drive == 200) image_open(c, cdrom_image[c].image_path); else if ((cdrom_drives[c].host_drive>='A') && (cdrom_drives[c].host_drive <= 'Z')) diff --git a/src/cdrom/cdrom_image.cc b/src/cdrom/cdrom_image.cc index d18ea5d4f..89fef440d 100644 --- a/src/cdrom/cdrom_image.cc +++ b/src/cdrom/cdrom_image.cc @@ -71,7 +71,7 @@ void image_audio_callback(uint8_t id, int16_t *output, int len) { if (!cdrom_drives[id].sound_on || (cdrom_image[id].cd_state != CD_PLAYING) || cdrom_image[id].image_is_iso) { - pclog("image_audio_callback(i): Not playing\n", id); + cdrom_image_log("image_audio_callback(i): Not playing\n", id); if (cdrom_ioctl[id].cd_state == CD_PLAYING) { cdrom[id].seek_pos += (len >> 11); diff --git a/src/scsi/scsi.h b/src/scsi/scsi.h index 890f3ef7a..b35a623ce 100644 --- a/src/scsi/scsi.h +++ b/src/scsi/scsi.h @@ -8,15 +8,15 @@ * * SCSI controller handler header. * - * Version: @(#)scsi_h 1.0.10 2018/01/13 + * Version: @(#)scsi_h 1.0.11 2018/01/24 * * Authors: TheCollector1995, * Miran Grca, * Fred N. van Kempen, * - * Copyright 2016,2018 TheCollector1995. - * Copyright 2016,2018 Miran Grca. - * Copyright 2018 Fred N. van Kempen. + * Copyright 2016-2018 TheCollector1995. + * Copyright 2016-2018 Miran Grca. + * Copyright 2017,2018 Fred N. van Kempen. */ #ifndef EMU_SCSI_H #define EMU_SCSI_H @@ -35,69 +35,76 @@ /* SCSI commands. */ -#define GPCMD_TEST_UNIT_READY 0x00 -#define GPCMD_REZERO_UNIT 0x01 -#define GPCMD_REQUEST_SENSE 0x03 -#define GPCMD_FORMAT_UNIT 0x04 -#define GPCMD_READ_6 0x08 -#define GPCMD_WRITE_6 0x0a -#define GPCMD_SEEK_6 0x0b -#define GPCMD_INQUIRY 0x12 -#define GPCMD_VERIFY_6 0x13 -#define GPCMD_MODE_SELECT_6 0x15 -#define GPCMD_MODE_SENSE_6 0x1a -#define GPCMD_START_STOP_UNIT 0x1b -#define GPCMD_PREVENT_REMOVAL 0x1e -#define GPCMD_READ_CDROM_CAPACITY 0x25 -#define GPCMD_READ_10 0x28 -#define GPCMD_WRITE_10 0x2a -#define GPCMD_SEEK_10 0x2b -#define GPCMD_WRITE_AND_VERIFY_10 0x2e -#define GPCMD_VERIFY_10 0x2f -#define GPCMD_WRITE_SAME_10 0x41 -#define GPCMD_READ_SUBCHANNEL 0x42 -#define GPCMD_READ_TOC_PMA_ATIP 0x43 -#define GPCMD_READ_HEADER 0x44 -#define GPCMD_PLAY_AUDIO_10 0x45 -#define GPCMD_GET_CONFIGURATION 0x46 -#define GPCMD_PLAY_AUDIO_MSF 0x47 -#define GPCMD_PLAY_AUDIO_TRACK_INDEX 0x48 -#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a -#define GPCMD_PAUSE_RESUME 0x4b -#define GPCMD_STOP_PLAY_SCAN 0x4e -#define GPCMD_READ_DISC_INFORMATION 0x51 -#define GPCMD_READ_TRACK_INFORMATION 0x52 -#define GPCMD_MODE_SELECT_10 0x55 -#define GPCMD_MODE_SENSE_10 0x5a -#define GPCMD_PLAY_AUDIO_12 0xa5 -#define GPCMD_READ_12 0xa8 -#define GPCMD_WRITE_12 0xaa -#define GPCMD_READ_DVD_STRUCTURE 0xad /* For reading. */ -#define GPCMD_WRITE_AND_VERIFY_12 0xae -#define GPCMD_VERIFY_12 0xaf -#define GPCMD_PLAY_CD_OLD 0xb4 -#define GPCMD_READ_CD_OLD 0xb8 -#define GPCMD_READ_CD_MSF 0xb9 -#define GPCMD_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 PCem. */ -#define GPCMD_PAUSE_RESUME_ALT 0xc2 -#define GPCMD_SCAN_ALT 0xcd /* Should be equivalent to 0xba */ -#define GPCMD_SET_SPEED_ALT 0xda /* Should be equivalent to 0xbb */ +#define GPCMD_TEST_UNIT_READY 0x00 +#define GPCMD_REZERO_UNIT 0x01 +#define GPCMD_REQUEST_SENSE 0x03 +#define GPCMD_FORMAT_UNIT 0x04 +#define GPCMD_IOMEGA_SENSE 0x06 +#define GPCMD_READ_6 0x08 +#define GPCMD_WRITE_6 0x0a +#define GPCMD_SEEK_6 0x0b +#define GPCMD_IOMEGA_SET_PROTECTION_MODE 0x0c +#define GPCMD_IOMEGA_EJECT 0x0d /* ATAPI only? */ +#define GPCMD_INQUIRY 0x12 +#define GPCMD_VERIFY_6 0x13 +#define GPCMD_MODE_SELECT_6 0x15 +#define GPCMD_SCSI_RESERVE 0x16 +#define GPCMD_SCSI_RELEASE 0x17 +#define GPCMD_MODE_SENSE_6 0x1a +#define GPCMD_START_STOP_UNIT 0x1b +#define GPCMD_SEND_DIAGNOSTIC 0x1d +#define GPCMD_PREVENT_REMOVAL 0x1e +#define GPCMD_READ_CDROM_CAPACITY 0x25 +#define GPCMD_READ_10 0x28 +#define GPCMD_WRITE_10 0x2a +#define GPCMD_SEEK_10 0x2b +#define GPCMD_WRITE_AND_VERIFY_10 0x2e +#define GPCMD_VERIFY_10 0x2f +#define GPCMD_READ_BUFFER 0x3c +#define GPCMD_WRITE_SAME_10 0x41 +#define GPCMD_READ_SUBCHANNEL 0x42 +#define GPCMD_READ_TOC_PMA_ATIP 0x43 +#define GPCMD_READ_HEADER 0x44 +#define GPCMD_PLAY_AUDIO_10 0x45 +#define GPCMD_GET_CONFIGURATION 0x46 +#define GPCMD_PLAY_AUDIO_MSF 0x47 +#define GPCMD_PLAY_AUDIO_TRACK_INDEX 0x48 +#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a +#define GPCMD_PAUSE_RESUME 0x4b +#define GPCMD_STOP_PLAY_SCAN 0x4e +#define GPCMD_READ_DISC_INFORMATION 0x51 +#define GPCMD_READ_TRACK_INFORMATION 0x52 +#define GPCMD_MODE_SELECT_10 0x55 +#define GPCMD_MODE_SENSE_10 0x5a +#define GPCMD_PLAY_AUDIO_12 0xa5 +#define GPCMD_READ_12 0xa8 +#define GPCMD_WRITE_12 0xaa +#define GPCMD_READ_DVD_STRUCTURE 0xad /* For reading. */ +#define GPCMD_WRITE_AND_VERIFY_12 0xae +#define GPCMD_VERIFY_12 0xaf +#define GPCMD_PLAY_CD_OLD 0xb4 +#define GPCMD_READ_CD_OLD 0xb8 +#define GPCMD_READ_CD_MSF 0xb9 +#define GPCMD_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 PCem. */ +#define GPCMD_PAUSE_RESUME_ALT 0xc2 +#define GPCMD_SCAN_ALT 0xcd /* Should be equivalent to 0xba */ +#define GPCMD_SET_SPEED_ALT 0xda /* Should be equivalent to 0xbb */ /* Mode page codes for mode sense/set */ -#define GPMODE_R_W_ERROR_PAGE 0x01 -#define GPMODE_CDROM_PAGE 0x0d -#define GPMODE_CDROM_AUDIO_PAGE 0x0e -#define GPMODE_CAPABILITIES_PAGE 0x2a -#define GPMODE_ALL_PAGES 0x3f +#define GPMODE_R_W_ERROR_PAGE 0x01 +#define GPMODE_CDROM_PAGE 0x0d +#define GPMODE_CDROM_AUDIO_PAGE 0x0e +#define GPMODE_CAPABILITIES_PAGE 0x2a +#define GPMODE_ALL_PAGES 0x3f /* SCSI Status Codes */ -#define SCSI_STATUS_OK 0 -#define SCSI_STATUS_CHECK_CONDITION 2 +#define SCSI_STATUS_OK 0 +#define SCSI_STATUS_CHECK_CONDITION 2 /* SCSI Sense Keys */ #define SENSE_NONE 0 @@ -132,6 +139,10 @@ Not that it means anything */ #define CDROM_SPEED 706 /* 0x2C2 */ +#define BUFFER_SIZE (256*1024) + +#define RW_DELAY (TIMER_USEC * 500) + /* Some generally useful CD-ROM information */ #define CD_MINS 75 /* max. minutes per CD */ #define CD_SECS 60 /* seconds per minute */ @@ -215,8 +226,6 @@ extern uint8_t page_current; #define PAGE_CHANGEABLE 1 #define PAGE_CHANGED 2 -extern uint8_t scsi_cdrom_id; - struct _scsisense_ { uint8_t SenseBuffer[18]; uint8_t SenseLength; @@ -229,24 +238,26 @@ struct _scsisense_ { extern int cd_status; extern int prev_status; -#define SCSI_NONE 0 -#define SCSI_DISK 1 -#define SCSI_CDROM 2 +enum { + SCSI_NONE = 0, + SCSI_DISK, + SCSI_CDROM +}; #define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) #define MSG_COMMAND_COMPLETE 0x00 -#define BUS_DBP 0x01 -#define BUS_SEL 0x02 -#define BUS_IO 0x04 -#define BUS_CD 0x08 -#define BUS_MSG 0x10 -#define BUS_REQ 0x20 -#define BUS_BSY 0x40 -#define BUS_RST 0x80 -#define BUS_ACK 0x200 -#define BUS_ATN 0x200 +#define BUS_DBP 0x01 +#define BUS_SEL 0x02 +#define BUS_IO 0x04 +#define BUS_CD 0x08 +#define BUS_MSG 0x10 +#define BUS_REQ 0x20 +#define BUS_BSY 0x40 +#define BUS_RST 0x80 +#define BUS_ACK 0x200 +#define BUS_ATN 0x200 #define BUS_ARB 0x8000 #define BUS_SETDATA(val) ((uint32_t)val << 16) #define BUS_GETDATA(val) ((val >> 16) & 0xff) @@ -274,12 +285,6 @@ extern scsi_device_t SCSIDevices[SCSI_ID_MAX][SCSI_LUN_MAX]; extern void SCSIReset(uint8_t id, uint8_t lun); -extern uint32_t SCSICDROMModeSense(uint8_t *buf, uint32_t pos, uint8_t type); -extern uint8_t SCSICDROMSetProfile(uint8_t *buf, uint8_t *index, uint16_t profile); -extern int SCSICDROMReadDVDStructure(int format, const uint8_t *packet, uint8_t *buf); -extern uint32_t SCSICDROMEventStatus(uint8_t *buffer); -extern void SCSICDROM_Insert(void); - extern int cdrom_add_error_and_subchannel(uint8_t *b, int real_sector_type); extern int cdrom_LBAtoMSF_accurate(void); diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 14ca68146..1438d32eb 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -6,7 +6,7 @@ * * Emulation of SCSI fixed and removable disks. * - * Version: @(#)scsi_disk.c 1.0.13 2018/01/13 + * Version: @(#)scsi_disk.c 1.0.14 2018/01/21 * * Author: Miran Grca, * @@ -93,10 +93,13 @@ uint8_t scsi_hd_command_flags[0x100] = { IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ 0, IMPLEMENTED, /* 0x15 */ - 0, 0, 0, 0, + IMPLEMENTED | SCSI_ONLY, /* 0x16 */ + IMPLEMENTED | SCSI_ONLY, /* 0x17 */ + 0, 0, IMPLEMENTED, IMPLEMENTED | CHECK_READY, /* 0x1B */ - 0, 0, + 0, + IMPLEMENTED, /* 0x1D */ IMPLEMENTED | CHECK_READY, /* 0x1E */ 0, 0, 0, 0, 0, 0, IMPLEMENTED | CHECK_READY, /* 0x25 */ @@ -777,13 +780,19 @@ void scsi_hd_reset(uint8_t id) } -void scsi_hd_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) +void scsi_hd_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length, int desc) { /*Will return 18 bytes of 0*/ if (alloc_length != 0) { memset(buffer, 0, alloc_length); - memcpy(buffer, shdc[id].sense, alloc_length); + if (!desc) + memcpy(buffer, shdc[id].sense, alloc_length); + else { + buffer[1] = scsi_hd_sense_key; + buffer[2] = scsi_hd_asc; + buffer[3] = scsi_hd_scq; + } } else { @@ -794,14 +803,14 @@ void scsi_hd_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) if (shdc[id].unit_attention && (scsi_hd_sense_key == 0)) { - buffer[2]=SENSE_UNIT_ATTENTION; - buffer[12]=ASC_MEDIUM_MAY_HAVE_CHANGED; - buffer[13]=0x00; + buffer[desc ? 1 : 2]=SENSE_UNIT_ATTENTION; + buffer[desc ? 2 : 12]=ASC_MEDIUM_MAY_HAVE_CHANGED; + buffer[desc ? 3 : 13]=0x00; } scsi_hd_log("SCSI HD %i: Reporting sense: %02X %02X %02X\n", id, buffer[2], buffer[12], buffer[13]); - if (buffer[2] == SENSE_UNIT_ATTENTION) + if (buffer[desc ? 1: 2] == SENSE_UNIT_ATTENTION) { /* If the last remaining sense is unit attention, clear that condition. */ @@ -845,7 +854,7 @@ void scsi_hd_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_l /* Do *NOT* advance the unit attention phase. */ - scsi_hd_request_sense(id, buffer, alloc_length); + scsi_hd_request_sense(id, buffer, alloc_length, 0); } @@ -921,6 +930,13 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) switch (cdb[0]) { + case GPCMD_SEND_DIAGNOSTIC: + if (!(cdb[1] & (1 << 2))) { + scsi_hd_invalid_field(id); + return; + } + case GPCMD_SCSI_RESERVE: + case GPCMD_SCSI_RELEASE: case GPCMD_TEST_UNIT_READY: case GPCMD_FORMAT_UNIT: scsi_hd_set_phase(id, SCSI_PHASE_STATUS); @@ -945,9 +961,11 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) { cdb[4] = *BufLen; } - + + len = (cdb[1] & 1) ? 8 : 18; + scsi_hd_set_phase(id, SCSI_PHASE_DATA_IN); - scsi_hd_data_command_finish(id, 18, 18, cdb[4], 0); + scsi_hd_data_command_finish(id, len, len, cdb[4], 0); break; case GPCMD_MECHANISM_STATUS: @@ -1492,7 +1510,7 @@ void scsi_hd_phase_data_in(uint8_t id) { case GPCMD_REQUEST_SENSE: scsi_hd_log("SCSI HDD %i: %08X, %08X\n", id, hdbufferb, *BufLen); - scsi_hd_request_sense(id, hdbufferb, *BufLen); + scsi_hd_request_sense(id, hdbufferb, *BufLen, shdc[id].current_cdb[1] & 1); break; case GPCMD_MECHANISM_STATUS: memset(hdbufferb, 0, *BufLen); @@ -1621,9 +1639,15 @@ void scsi_hd_phase_data_out(uint8_t id) else hdr_len = 4; - block_desc_len = hdbufferb[6]; - block_desc_len <<= 8; - block_desc_len |= hdbufferb[7]; + if (shdc[id].current_cdb[0] == GPCMD_MODE_SELECT_6) { + block_desc_len = hdbufferb[2]; + block_desc_len <<= 8; + block_desc_len |= hdbufferb[3]; + } else { + block_desc_len = hdbufferb[6]; + block_desc_len <<= 8; + block_desc_len |= hdbufferb[7]; + } pos = hdr_len + block_desc_len; diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 14478d20b..0eca3f706 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -8,7 +8,7 @@ * * Windows 86Box Settings dialog handler. * - * Version: @(#)win_settings.c 1.0.31 2018/01/21 + * Version: @(#)win_settings.c 1.0.32 2018/01/24 * * Author: Miran Grca, * @@ -3478,6 +3478,7 @@ win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPar HWND h; int old_sel = 0; int b = 0, i = 0; + int assign = 0; switch (message) { @@ -3558,9 +3559,15 @@ win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPar { goto hd_bus_skip; } - temp_hdd[hdlv_current_sel].bus = b; hard_disk_untrack(hdlv_current_sel); - recalc_location_controls(hdlg, 0, 1); + assign = (temp_hdd[hdlv_current_sel].bus == b) ? 0 : 1; + if ((b == HDD_BUS_IDE_PIO_ONLY) && (temp_hdd[hdlv_current_sel].bus == HDD_BUS_IDE_PIO_AND_DMA)) + assign = 0; + else if ((b == HDD_BUS_IDE_PIO_AND_DMA) && (temp_hdd[hdlv_current_sel].bus == HDD_BUS_IDE_PIO_ONLY)) + assign = 0; + temp_hdd[hdlv_current_sel].bus = b; + recalc_location_controls(hdlg, 0, assign); + hard_disk_track(hdlv_current_sel); h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); hd_bus_skip: @@ -3686,7 +3693,7 @@ hd_bus_skip: { hdlv_current_sel = -1; } - recalc_location_controls(hdlg, 0, 1); + recalc_location_controls(hdlg, 0, 0); ignore_change = 0; return FALSE; } @@ -4188,6 +4195,7 @@ win_settings_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam, LPAR int b = 0; int b2 = 0; WCHAR szText[256]; + int assign = 0; switch (message) { @@ -4407,8 +4415,13 @@ win_settings_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam, LPAR goto cdrom_bus_skip; } cdrom_untrack(cdlv_current_sel); + assign = (temp_cdrom_drives[cdlv_current_sel].bus_type == b2) ? 0 : 1; + if ((b2 == CDROM_BUS_ATAPI_PIO_ONLY) && (temp_cdrom_drives[cdlv_current_sel].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA)) + assign = 0; + else if ((b2 == CDROM_BUS_ATAPI_PIO_AND_DMA) && (temp_cdrom_drives[cdlv_current_sel].bus_type == CDROM_BUS_ATAPI_PIO_ONLY)) + assign = 0; temp_cdrom_drives[cdlv_current_sel].bus_type = b2; - cdrom_recalc_location_controls(hdlg, 1); + cdrom_recalc_location_controls(hdlg, assign); cdrom_track(cdlv_current_sel); h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); win_settings_cdrom_drives_update_item(h, cdlv_current_sel); @@ -4424,7 +4437,9 @@ cdrom_bus_skip: rd_ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); + cdrom_untrack(cdlv_current_sel); temp_cdrom_drives[cdlv_current_sel].scsi_device_id = SendMessage(h, CB_GETCURSEL, 0, 0); + cdrom_track(cdlv_current_sel); h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); win_settings_cdrom_drives_update_item(h, cdlv_current_sel); rd_ignore_change = 0;