diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 65743bead..5a50c0cd7 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -9,7 +9,7 @@ * Implementation of the CD-ROM drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)cdrom.c 1.0.33 2018/02/27 + * Version: @(#)cdrom.c 1.0.34 2018/03/06 * * Author: Miran Grca, * @@ -715,25 +715,53 @@ void cdrom_update_request_length(uint8_t id, int len, int block_len) static void cdrom_command_common(uint8_t id) { + double bytes_per_second, period; + double dusec; + cdrom[id].status = BUSY_STAT; cdrom[id].phase = 1; cdrom[id].pos = 0; if (cdrom[id].packet_status == CDROM_PHASE_COMPLETE) { - cdrom[id].callback = 20LL * CDROM_TIME; - cdrom_set_callback(id); - } else if (cdrom[id].packet_status == CDROM_PHASE_DATA_IN) { - if (cdrom[id].current_cdb[0] == 0x42) { - cdrom_log("CD-ROM %i: READ SUBCHANNEL\n", id); - cdrom[id].callback = 1000LL * CDROM_TIME; - cdrom_set_callback(id); - } else { - cdrom[id].callback = 60LL * CDROM_TIME; - cdrom_set_callback(id); - } + cdrom_phase_callback(id); + cdrom[id].callback = 0LL; } else { - cdrom[id].callback = 60LL * CDROM_TIME; - cdrom_set_callback(id); + switch(cdrom[id].current_cdb[0]) { + case 0x25: + case 0x42: + case 0x43: + case 0x44: + case 0x08: + case 0x28: + case 0x51: + case 0x52: + case 0xa8: + case 0xad: + case 0xb8: + case 0xb9: + case 0xbe: + bytes_per_second = 150.0 * 1024.0; + bytes_per_second *= (double) cdrom_drives[id].speed; + break; + default: + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { + cdrom[id].callback = -1LL; /* Speed depends on SCSI controller */ + return; + } else if (cdrom_drives[id].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA) { + if (cdrom_current_mode(id) == 2) + bytes_per_second = 66666666.666666666666666; /* 66 MB/s MDMA-2 speed */ + else + bytes_per_second = 8333333.333333333333333; /* 8.3 MB/s PIO-2 speed */ + } else + bytes_per_second = 3333333.333333333333333; /* 3.3 MB/s PIO-0 speed */ + break; + } + + period = 1000000.0 / bytes_per_second; + dusec = (double) TIMER_USEC; + dusec = dusec * period * (double) (cdrom[id].packet_len); + cdrom[id].callback = ((int64_t) dusec); } + cdrom_set_callback(id); } static void cdrom_command_complete(uint8_t id) diff --git a/src/cdrom/cdrom.h b/src/cdrom/cdrom.h index bf208267f..d82a002cb 100644 --- a/src/cdrom/cdrom.h +++ b/src/cdrom/cdrom.h @@ -9,7 +9,7 @@ * Implementation of the CD-ROM drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)cdrom.h 1.0.4 2017/11/01 + * Version: @(#)cdrom.h 1.0.5 2018/03/06 * * Author: Miran Grca, * @@ -169,6 +169,8 @@ typedef struct { unsigned int sound_on; unsigned int atapi_dma; + + uint8_t speed; } cdrom_drive_t; typedef struct { diff --git a/src/config.c b/src/config.c index dd709f765..86e002153 100644 --- a/src/config.c +++ b/src/config.c @@ -8,7 +8,7 @@ * * Configuration file handler. * - * Version: @(#)config.c 1.0.43 2018/03/06 + * Version: @(#)config.c 1.0.44 2018/03/06 * * Authors: Sarah Walker, * Miran Grca, @@ -1225,6 +1225,9 @@ load_other_removable_devices(void) sscanf("0, none", "%01u, %s", &cdrom_drives[c].sound_on, s); cdrom_drives[c].bus_type = hdd_string_to_bus(s, 1); + sprintf(temp, "cdrom_%02i_speed", c+1); + cdrom_drives[c].speed = config_get_int(cat, temp, 8); + /* Default values, needed for proper operation of the Settings dialog. */ cdrom_drives[c].ide_channel = cdrom_drives[c].scsi_device_id = c + 2; @@ -1980,6 +1983,13 @@ save_other_removable_devices(void) config_set_int(cat, temp, cdrom_drives[c].host_drive); } + sprintf(temp, "cdrom_%02i_speed", c+1); + if ((cdrom_drives[c].bus_type == 0) || (cdrom_drives[c].speed == 8)) { + config_delete_var(cat, temp); + } else { + config_set_int(cat, temp, cdrom_drives[c].speed); + } + sprintf(temp, "cdrom_%02i_parameters", c+1); if (cdrom_drives[c].bus_type == 0) { config_delete_var(cat, temp); diff --git a/src/disk/zip.c b/src/disk/zip.c index 40eaa9de8..cd20e2253 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -9,7 +9,7 @@ * Implementation of the Iomega ZIP drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)zip.c 1.0.7 2018/03/06 + * Version: @(#)zip.c 1.0.8 2018/03/07 * * Author: Miran Grca, * @@ -932,25 +932,34 @@ void zip_update_request_length(uint8_t id, int len, int block_len) static void zip_command_common(uint8_t id) { + double bytes_per_second, period; + double dusec; + zip[id].status = BUSY_STAT; zip[id].phase = 1; zip[id].pos = 0; if (zip[id].packet_status == ZIP_PHASE_COMPLETE) { - zip[id].callback = 20LL * ZIP_TIME; - zip_set_callback(id); - } else if (zip[id].packet_status == ZIP_PHASE_DATA_IN) { - if (zip[id].current_cdb[0] == 0x42) { - zip_log("ZIP %i: READ SUBCHANNEL\n"); - zip[id].callback = 1000LL * ZIP_TIME; - zip_set_callback(id); - } else { - zip[id].callback = 60LL * ZIP_TIME; - zip_set_callback(id); - } + zip_phase_callback(id); + zip[id].callback = 0LL; } else { - zip[id].callback = 60LL * ZIP_TIME; - zip_set_callback(id); + if (zip_drives[id].bus_type == ZIP_BUS_SCSI) { + zip[id].callback = -1LL; /* Speed depends on SCSI controller */ + return; + } else if (zip_drives[id].bus_type == ZIP_BUS_ATAPI_PIO_AND_DMA) { + if (zip_current_mode(id) == 2) + bytes_per_second = 66666666.666666666666666; /* 66 MB/s MDMA-2 speed */ + else + bytes_per_second = 8333333.333333333333333; /* 8.3 MB/s PIO-2 speed */ + } else + bytes_per_second = 3333333.333333333333333; /* 3.3 MB/s PIO-0 speed */ } + + period = 1000000.0 / bytes_per_second; + dusec = (double) TIMER_USEC; + dusec = dusec * period * (double) (zip[id].packet_len); + zip[id].callback = ((int64_t) dusec); + + zip_set_callback(id); } static void zip_command_complete(uint8_t id) diff --git a/src/lang/language.h b/src/lang/language.h index 92f7f4df9..e4c060da8 100644 --- a/src/lang/language.h +++ b/src/lang/language.h @@ -10,7 +10,7 @@ * * NOTE: FIXME: Strings 2176 and 2193 are same. * - * Version: @(#)language.h 1.0.6 2018/01/23 + * Version: @(#)language.h 1.0.7 2018/03/07 * * Author: Fred N. van Kempen, * @@ -151,6 +151,7 @@ #define IDS_2175 2175 // "ZIP images (*.IM?)\0*.IM..." #define IDS_2176 2176 // "ZIP images (*.IM?)\0*.IM..." #define IDS_2177 2177 // "ZIP %i (%03i): %ls" +#define IDS_2178 2178 // "Speed" #define IDS_4096 4096 // "Hard disk (%s)" #define IDS_4097 4097 // "%01i:%01i" @@ -231,7 +232,7 @@ #define IDS_LANG_ENUS IDS_7168 -#define STR_NUM_2048 130 +#define STR_NUM_2048 131 #define STR_NUM_3072 11 #define STR_NUM_4096 20 #define STR_NUM_4352 7 diff --git a/src/scsi/scsi_aha154x.c b/src/scsi/scsi_aha154x.c index 67aefc15d..efc9a5fcb 100644 --- a/src/scsi/scsi_aha154x.c +++ b/src/scsi/scsi_aha154x.c @@ -10,7 +10,7 @@ * made by Adaptec, Inc. These controllers were designed for * the ISA bus. * - * Version: @(#)scsi_aha154x.c 1.0.38 2018/02/19 + * Version: @(#)scsi_aha154x.c 1.0.39 2018/03/07 * * Authors: Fred N. van Kempen, * Original Buslogic version by SA1988 and Miran Grca. @@ -267,10 +267,7 @@ aha_fast_cmds(void *p, uint8_t cmd) x54x_t *dev = (x54x_t *)p; if (cmd == CMD_BIOS_SCSI) { - x54x_busy(1); dev->BIOSMailboxReq++; - x54x_set_wait_event(); - x54x_busy(0); return 1; } @@ -362,7 +359,6 @@ aha_cmds(void *p) case CMD_BIOS_MBINIT: /* BIOS Mailbox Initialization */ /* Sent by CF BIOS. */ - x54x_busy(1); dev->Mbx24bit = 1; mbi = (MailboxInit_t *)dev->CmdBuf; @@ -378,7 +374,6 @@ aha_cmds(void *p) dev->Status &= ~STAT_INIT; dev->DataReplyLeft = 0; - x54x_busy(0); break; case CMD_MEMORY_MAP_1: /* AHA memory mapper */ @@ -467,16 +462,12 @@ aha_do_bios_mail(x54x_t *dev) static void -aha_thread(void *p) +aha_callback(void *p) { x54x_t *dev = (x54x_t *)p; if (dev->BIOSMailboxInit && dev->BIOSMailboxReq) - { - x54x_wait_for_poll(); - aha_do_bios_mail(dev); - } } @@ -768,7 +759,7 @@ aha_init(device_t *info) dev->bit32 = 0; dev->lba_bios = 0; - dev->ven_thread = aha_thread; + dev->ven_callback = aha_callback; dev->ven_cmd_is_fast = aha_cmd_is_fast; dev->ven_fast_cmds = aha_fast_cmds; dev->get_ven_param_len = aha_param_len; @@ -797,6 +788,7 @@ aha_init(device_t *info) dev->HostID = device_get_config_int("hostid"); dev->rom_shram = 0x3F80; /* shadow RAM address base */ dev->rom_shramsz = 128; /* size of shadow RAM */ + dev->ha_bps = 5000000.0; /* normal SCSI */ break; case AHA_154xC: @@ -811,6 +803,7 @@ aha_init(device_t *info) dev->ven_get_host_id = aha_get_host_id; /* function to return host ID from EEPROM */ dev->ven_get_irq = aha_get_irq; /* function to return IRQ from EEPROM */ dev->ven_get_dma = aha_get_dma; /* function to return DMA channel from EEPROM */ + dev->ha_bps = 5000000.0; /* normal SCSI */ break; case AHA_154xCF: @@ -826,6 +819,7 @@ aha_init(device_t *info) dev->ven_get_host_id = aha_get_host_id; /* function to return host ID from EEPROM */ dev->ven_get_irq = aha_get_irq; /* function to return IRQ from EEPROM */ dev->ven_get_dma = aha_get_dma; /* function to return DMA channel from EEPROM */ + dev->ha_bps = 10000000.0; /* fast SCSI */ break; case AHA_154xCP: @@ -840,6 +834,7 @@ aha_init(device_t *info) dev->ven_get_host_id = aha_get_host_id; /* function to return host ID from EEPROM */ dev->ven_get_irq = aha_get_irq; /* function to return IRQ from EEPROM */ dev->ven_get_dma = aha_get_dma; /* function to return DMA channel from EEPROM */ + dev->ha_bps = 10000000.0; /* fast SCSI */ break; case AHA_1640: @@ -853,6 +848,7 @@ aha_init(device_t *info) dev->pos_regs[0] = 0x1F; /* MCA board ID */ dev->pos_regs[1] = 0x0F; mca_add(aha_mca_read, aha_mca_write, dev); + dev->ha_bps = 5000000.0; /* normal SCSI */ break; } diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index 8e99c81f9..cd95e823b 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -11,14 +11,14 @@ * 1 - BT-545S ISA; * 2 - BT-958D PCI * - * Version: @(#)scsi_buslogic.c 1.0.34 2018/01/06 + * Version: @(#)scsi_buslogic.c 1.0.35 2018/03/07 * * Authors: TheCollector1995, * Miran Grca, * Fred N. van Kempen, * - * Copyright 2016,2018 Miran Grca. - * Copyright 2018 Fred N. van Kempen. + * Copyright 2016-2018 Miran Grca. + * Copyright 2017,2018 Fred N. van Kempen. */ #include #include @@ -719,7 +719,6 @@ buslogic_cmds(void *p) dev->IrqEnabled = 1; return 1; case 0x81: - x54x_busy(1); dev->Mbx24bit = 0; MailboxInitE = (MailboxInitExtended_t *)dev->CmdBuf; @@ -736,7 +735,6 @@ buslogic_cmds(void *p) dev->Status &= ~STAT_INIT; dev->DataReplyLeft = 0; - x54x_busy(0); break; case 0x83: if (dev->CmdParam == 12) { @@ -1528,6 +1526,7 @@ buslogic_init(device_t *info) has_autoscsi_rom = 0; has_scam_rom = 0; dev->fw_rev = "AA335"; + dev->ha_bps = 5000000.0; /* normal SCSI */ break; case CHIP_BUSLOGIC_ISA: default: @@ -1540,6 +1539,7 @@ buslogic_init(device_t *info) autoscsi_rom_size = 0x4000; has_scam_rom = 0; dev->fw_rev = "AA421E"; + dev->ha_bps = 10000000.0; /* fast SCSI */ break; case CHIP_BUSLOGIC_MCA: strcpy(dev->name, "BT-640A"); @@ -1553,6 +1553,7 @@ buslogic_init(device_t *info) dev->pos_regs[0] = 0x08; /* MCA board ID */ dev->pos_regs[1] = 0x07; mca_add(buslogic_mca_read, buslogic_mca_write, dev); + dev->ha_bps = 5000000.0; /* normal SCSI */ break; case CHIP_BUSLOGIC_VLB: strcpy(dev->name, "BT-445S"); @@ -1565,6 +1566,7 @@ buslogic_init(device_t *info) has_scam_rom = 0; dev->fw_rev = "AA421E"; dev->bit32 = 1; + dev->ha_bps = 10000000.0; /* fast SCSI */ break; case CHIP_BUSLOGIC_PCI: strcpy(dev->name, "BT-958D"); @@ -1580,6 +1582,7 @@ buslogic_init(device_t *info) dev->fw_rev = "AA507B"; dev->cdrom_boot = 1; dev->bit32 = 1; + dev->ha_bps = 20000000.0; /* ultra SCSI */ break; } diff --git a/src/scsi/scsi_device.c b/src/scsi/scsi_device.c index 646189628..91350ec3d 100644 --- a/src/scsi/scsi_device.c +++ b/src/scsi/scsi_device.c @@ -8,7 +8,7 @@ * * The generic SCSI device command handler. * - * Version: @(#)scsi_device.c 1.0.13 2018/03/06 + * Version: @(#)scsi_device.c 1.0.14 2018/03/07 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -119,6 +119,33 @@ static void scsi_device_target_save_cdb_byte(int lun_type, uint8_t id, uint8_t c } +int64_t scsi_device_get_callback(uint8_t scsi_id, uint8_t scsi_lun) +{ + uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; + + uint8_t id = 0; + + switch (lun_type) + { + case SCSI_DISK: + id = scsi_hard_disks[scsi_id][scsi_lun]; + return shdc[id].callback; + break; + case SCSI_CDROM: + id = scsi_cdrom_drives[scsi_id][scsi_lun]; + return cdrom[id].callback; + break; + case SCSI_ZIP: + id = scsi_zip_drives[scsi_id][scsi_lun]; + return zip[id].callback; + break; + default: + return -1LL; + break; + } +} + + uint8_t *scsi_device_sense(uint8_t scsi_id, uint8_t scsi_lun) { uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; diff --git a/src/scsi/scsi_device.h b/src/scsi/scsi_device.h index f89fac3bd..9d7267528 100644 --- a/src/scsi/scsi_device.h +++ b/src/scsi/scsi_device.h @@ -8,7 +8,7 @@ * * Definitions for the generic SCSI device command handler. * - * Version: @(#)scsi_device.h 1.0.5 2018/02/17 + * Version: @(#)scsi_device.h 1.0.6 2018/03/07 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -35,6 +35,7 @@ typedef struct extern uint8_t *scsi_device_sense(uint8_t id, uint8_t lun); extern void scsi_device_type_data(uint8_t id, uint8_t lun, uint8_t *type, uint8_t *rmb); +extern int64_t scsi_device_get_callback(uint8_t scsi_id, uint8_t scsi_lun); extern void scsi_device_request_sense(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *buffer, uint8_t alloc_length); diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 0e346c255..c5c374935 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -6,11 +6,11 @@ * * Emulation of SCSI fixed and removable disks. * - * Version: @(#)scsi_disk.c 1.0.16 2018/01/25 + * Version: @(#)scsi_disk.c 1.0.17 2018/03/07 * * Author: Miran Grca, * - * Copyright 2018 Miran Grca. + * Copyright 2017,2018 Miran Grca. */ #include #include @@ -459,14 +459,11 @@ static void scsi_hd_command_common(uint8_t id) shdc[id].status = BUSY_STAT; shdc[id].phase = 1; shdc[id].pos = 0; - if (shdc[id].packet_status == CDROM_PHASE_COMPLETE) - { - shdc[id].callback = 20 * SCSI_TIME; - } - else - { - shdc[id].callback = 60 * SCSI_TIME; - } + if (shdc[id].packet_status == CDROM_PHASE_COMPLETE) { + scsi_hd_callback(id); + shdc[id].callback = 0LL; + } else + shdc[id].callback = -1LL; /* Speed depends on SCSI controller */ } diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index 2614d0ff6..97440394f 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -9,15 +9,15 @@ * Implementation of the NCR 5380 series of SCSI Host Adapters * made by NCR. These controllers were designed for the ISA bus. * - * Version: @(#)scsi_ncr5380.c 1.0.10 2018/01/26 + * Version: @(#)scsi_ncr5380.c 1.0.11 2018/03/07 * * Authors: Sarah Walker, * TheCollector1995, * Fred N. van Kempen, * - * Copyright 2017-2018 Sarah Walker. - * Copyright 2017-2018 TheCollector1995. - * Copyright 2018 Fred N. van Kempen. + * Copyright 2017,2018 Sarah Walker. + * Copyright 2017,2018 TheCollector1995. + * Copyright 2017,2018 Fred N. van Kempen. */ #include #include @@ -390,7 +390,7 @@ dma_callback(void *priv) int bytes_transferred = 0; int c; - scsi->dma_timer += POLL_TIME_US; + scsi->dma_timer += POLL_TIME_US * TIMER_USEC; switch (scsi->ncr.dma_mode) { case DMA_SEND: diff --git a/src/scsi/scsi_ncr53c810.c b/src/scsi/scsi_ncr53c810.c index bc970282d..b7b7b2b32 100644 --- a/src/scsi/scsi_ncr53c810.c +++ b/src/scsi/scsi_ncr53c810.c @@ -10,7 +10,7 @@ * NCR and later Symbios and LSI. This controller was designed * for the PCI bus. * - * Version: @(#)scsi_ncr53c810.c 1.0.6 2018/01/06 + * Version: @(#)scsi_ncr53c810.c 1.0.7 2018/03/07 * * Authors: Paul Brook (QEMU) * Artyom Tarasenko (QEMU) @@ -19,8 +19,9 @@ * * Copyright 2006-2018 Paul Brook. * Copyright 2009-2018 Artyom Tarasenko. - * Copyright 2018 Miran Grca. + * Copyright 2017,2018 Miran Grca. */ +#include #include #include #include @@ -268,6 +269,9 @@ typedef struct { uint8_t regop; uint32_t adder; + + int64_t timer_period; + int64_t timer_enabled; } ncr53c810_t; @@ -326,6 +330,8 @@ static void ncr53c810_soft_reset(ncr53c810_t *dev) { ncr53c810_log("LSI Reset\n"); + dev->timer_period = dev->timer_enabled = 0; + dev->carry = 0; dev->msg_action = 0; @@ -496,6 +502,7 @@ ncr53c810_script_scsi_interrupt(ncr53c810_t *dev, int stat0, int stat1) if ((dev->sist0 & mask0) || (dev->sist1 & mask1)) { ncr53c810_log("NCR 810: IRQ-mandated stop\n"); dev->sstop = 1; + dev->timer_period = dev->timer_enabled = 0; } ncr53c810_update_irq(dev); } @@ -509,6 +516,7 @@ ncr53c810_script_dma_interrupt(ncr53c810_t *dev, int stat) dev->dstat |= stat; ncr53c810_update_irq(dev); dev->sstop = 1; + dev->timer_period = dev->timer_enabled = 0; } @@ -526,6 +534,7 @@ ncr53c810_bad_phase(ncr53c810_t *dev, int out, int new_phase) ncr53c810_log("Phase mismatch interrupt\n"); ncr53c810_script_scsi_interrupt(dev, NCR_SIST0_MA, 0); dev->sstop = 1; + dev->timer_period = dev->timer_enabled = 0; ncr53c810_set_phase(dev, new_phase); } @@ -650,6 +659,8 @@ ncr53c810_do_command(ncr53c810_t *dev, uint8_t id) scsi_device_t *sd; uint8_t buf[12]; + double period; + memset(buf, 0, 12); DMAPageRead(dev->dnad, buf, MIN(12, dev->dbc)); if (dev->dbc > 12) { @@ -690,9 +701,19 @@ ncr53c810_do_command(ncr53c810_t *dev, uint8_t id) if ((sd->Phase == SCSI_PHASE_DATA_IN) && (sd->BufferLength > 0)) { ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: PHASE_DI\n", id, dev->current_lun, buf[0]); ncr53c810_set_phase(dev, PHASE_DI); + dev->timer_period = scsi_device_get_callback(dev->current->tag, dev->current_lun); + if (dev->timer_period <= 0LL) { + period = ((double) sd->BufferLength) * 0.2 * ((double) TIMER_USEC); /* Fast SCSI: 10000000 bytes per second */ + dev->timer_period = (int64_t) period; + } } else if ((sd->Phase == SCSI_PHASE_DATA_OUT) && (sd->BufferLength > 0)) { ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: PHASE_DO\n", id, dev->current_lun, buf[0]); ncr53c810_set_phase(dev, PHASE_DO); + dev->timer_period = scsi_device_get_callback(dev->current->tag, dev->current_lun); + if (dev->timer_period <= 0LL) { + period = ((double) sd->BufferLength) * 0.2 * ((double) TIMER_USEC); /* Fast SCSI: 10000000 bytes per second */ + dev->timer_period = (int64_t) period; + } } else ncr53c810_command_complete(dev, sd->Status); } @@ -907,7 +928,7 @@ ncr53c810_memcpy(ncr53c810_t *dev, uint32_t dest, uint32_t src, int count) static void -ncr53c810_execute_script(ncr53c810_t *dev) +ncr53c810_process_script(ncr53c810_t *dev) { uint32_t insn, addr, id, buf[2], dest; int opcode, insn_processed = 0, reg, operator, cond, jmp, n, i; @@ -936,6 +957,7 @@ again: if (dev->sist1 & NCR_SIST1_STO) { ncr53c810_log("Delayed select timeout\n"); dev->sstop = 1; + dev->timer_period = dev->timer_enabled = 0; break; } ncr53c810_log("Block Move DBC=%d\n", dev->dbc); @@ -981,7 +1003,9 @@ again: case PHASE_CMD: ncr53c810_log("Command Phase\n"); ncr53c810_do_command(dev, dev->sdid); - break; + dev->dfifo = dev->dbc & 0xff; + dev->ctest5 = (dev->ctest5 & 0xfc) | ((dev->dbc >> 8) & 3); + return; case PHASE_ST: ncr53c810_log("Status Phase\n"); ncr53c810_do_status(dev); @@ -1153,6 +1177,7 @@ again: if (dev->sist1 & NCR_SIST1_STO) { ncr53c810_log("Delayed select timeout\n"); dev->sstop = 1; + dev->timer_period = dev->timer_enabled = 0; break; } cond = jmp = (insn & (1 << 19)) != 0; @@ -1262,7 +1287,8 @@ again: ncr53c810_script_dma_interrupt(dev, NCR_DSTAT_SSI); } else { ncr53c810_log("NCR 810: SCRIPTS: Normal mode\n"); - goto again; + if (insn_processed < 100) + goto again; } } else { if (dev->sstop) @@ -1271,10 +1297,41 @@ again: ncr53c810_log("NCR 810: SCRIPTS: Waiting\n"); } + return; + ncr53c810_log("SCRIPTS execution stopped\n"); } +static void +ncr53c810_execute_script(ncr53c810_t *dev) +{ + dev->timer_period = 10LL * TIMER_USEC; + dev->timer_enabled = 1; +} + + +static void +ncr53c810_callback(void *p) +{ + ncr53c810_t *dev = (ncr53c810_t *) p; + + dev->timer_period = 0; + if (!dev->waiting) + ncr53c810_process_script(dev); + + if (dev->sstop) { + dev->timer_period = 0; + dev->timer_enabled = 0; + return; + } else + dev->timer_enabled = 1; + + if (dev->timer_period == 0) + dev->timer_period = 50LL * TIMER_USEC; +} + + static void ncr53c810_reg_writeb(ncr53c810_t *dev, uint32_t offset, uint8_t val) { @@ -1377,7 +1434,7 @@ ncr53c810_reg_writeb(ncr53c810_t *dev, uint32_t offset, uint8_t val) ncr53c810_log("Woken by SIGP\n"); dev->waiting = 0; dev->dsp = dev->dnad; - ncr53c810_execute_script(dev); + /* ncr53c810_execute_script(dev); */ } if ((val & NCR_ISTAT_SRST) && !(tmp & NCR_ISTAT_SRST)) { ncr53c810_soft_reset(dev); @@ -2076,6 +2133,8 @@ ncr53c810_init(device_t *info) ncr53c810_soft_reset(dev); + timer_add(ncr53c810_callback, &dev->timer_period, &dev->timer_enabled, dev); + return(dev); } diff --git a/src/scsi/scsi_x54x.c b/src/scsi/scsi_x54x.c index 3b58a03cd..a234e6c3f 100644 --- a/src/scsi/scsi_x54x.c +++ b/src/scsi/scsi_x54x.c @@ -11,7 +11,7 @@ * series of SCSI Host Adapters made by Mylex. * These controllers were designed for various buses. * - * Version: @(#)scsi_x54x.c 1.0.17 2018/02/25 + * Version: @(#)scsi_x54x.c 1.0.18 2018/03/07 * * Authors: TheCollector1995, * Miran Grca, @@ -20,6 +20,7 @@ * Copyright 2016-2018 Miran Grca. * Copyright 2017,2018 Fred N. van Kempen. */ +#include #include #include #include @@ -49,22 +50,7 @@ #define X54X_RESET_DURATION_US UINT64_C(50000) -static void x54x_cmd_thread(void *priv); - -static volatile -thread_t *poll_tid; -static volatile -int busy; - -static volatile -event_t *evt; -static volatile -event_t *wait_evt; - -static volatile -event_t *wake_poll_thread; -static volatile -event_t *thread_started; +static void x54x_cmd_callback(void *priv); static volatile x54x_t *x54x_dev; @@ -609,6 +595,13 @@ x54x_cmd_done(x54x_t *dev, int suppress) } +static void +x54x_add_to_period(int TransferLength) +{ + x54x_dev->temp_period += (int64_t) TransferLength; +} + + static void x54x_mbi_setup(x54x_t *dev, uint32_t CCBPointer, CCBU *CmdBlock, uint8_t HostStatus, uint8_t TargetStatus, uint8_t mbcc) @@ -636,6 +629,7 @@ x54x_ccb(x54x_t *dev) DMAPageWrite(req->CCBPointer + 0x000D, &(req->MailboxCompletionCode), 1); DMAPageWrite(req->CCBPointer + 0x000E, &(req->HostStatus), 1); DMAPageWrite(req->CCBPointer + 0x000F, &(req->TargetStatus), 1); + x54x_add_to_period(3); if (dev->MailboxOutInterrupts) dev->ToRaise = INTR_MBOA | INTR_ANY; @@ -666,6 +660,7 @@ x54x_mbi(x54x_t *dev) x54x_log("CCB statuses rewritten (pointer %08X)\n", req->CCBPointer); DMAPageWrite(req->CCBPointer + 0x000E, &(req->HostStatus), 1); DMAPageWrite(req->CCBPointer + 0x000F, &(req->TargetStatus), 1); + x54x_add_to_period(2); } else { x54x_log("Mailbox not found!\n"); } @@ -677,6 +672,7 @@ x54x_mbi(x54x_t *dev) x54x_log("Mailbox 24-bit: Status=0x%02X, CCB at 0x%04X\n", req->MailboxCompletionCode, CCBPointer); DMAPageWrite(Incoming, &(req->MailboxCompletionCode), 1); DMAPageWrite(Incoming + 1, (uint8_t *)&CCBPointer, 3); + x54x_add_to_period(4); x54x_log("%i bytes of 24-bit mailbox written to: %08X\n", sizeof(Mailbox_t), Incoming); } else { x54x_log("Mailbox 32-bit: Status=0x%02X, CCB at 0x%04X\n", req->MailboxCompletionCode, CCBPointer); @@ -684,6 +680,7 @@ x54x_mbi(x54x_t *dev) DMAPageWrite(Incoming + 4, &(req->HostStatus), 1); DMAPageWrite(Incoming + 5, &(req->TargetStatus), 1); DMAPageWrite(Incoming + 7, &(req->MailboxCompletionCode), 1); + x54x_add_to_period(7); x54x_log("%i bytes of 32-bit mailbox written to: %08X\n", sizeof(Mailbox32_t), Incoming); } @@ -704,6 +701,7 @@ x54x_rd_sge(int Is24bit, uint32_t Address, SGE32 *SG) if (Is24bit) { DMAPageRead(Address, (uint8_t *)&SGE24, sizeof(SGE)); + x54x_add_to_period(sizeof(SGE)); /* Convert the 24-bit entries into 32-bit entries. */ x54x_log("Read S/G block: %06X, %06X\n", SGE24.Segment, SGE24.SegmentPointer); @@ -711,6 +709,7 @@ x54x_rd_sge(int Is24bit, uint32_t Address, SGE32 *SG) SG->SegmentPointer = ADDR_TO_U32(SGE24.SegmentPointer); } else { DMAPageRead(Address, (uint8_t *)SG, sizeof(SGE32)); + x54x_add_to_period(sizeof(SGE32)); } } @@ -778,9 +777,11 @@ x54x_set_residue(Req_t *req, int32_t TransferLength) if (req->Is24bit) { U32_TO_ADDR(Residue24, Residue); DMAPageWrite(req->CCBPointer + 0x0004, (uint8_t *)&Residue24, 3); + x54x_add_to_period(3); x54x_log("24-bit Residual data length for reading: %d\n", Residue); } else { DMAPageWrite(req->CCBPointer + 0x0004, (uint8_t *)&Residue, 4); + x54x_add_to_period(4); x54x_log("32-bit Residual data length for reading: %d\n", Residue); } } @@ -832,9 +833,8 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir) x54x_log("Writing S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address); DMAPageWrite(Address, &(SCSIDevices[req->TargetID][req->LUN].CmdBuffer[sg_pos]), DataToTransfer); } - else { + else x54x_log("No action on S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address); - } sg_pos += SGBuffer.Segment; @@ -850,11 +850,10 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir) Address = DataPointer; if ((DataLength > 0) && (BufLen > 0) && (req->CmdBlock.common.ControlByte < 0x03)) { - if (read_from_host) { + if (read_from_host) DMAPageRead(Address, SCSIDevices[req->TargetID][req->LUN].CmdBuffer, MIN(BufLen, DataLength)); - } else if (write_to_host) { + else if (write_to_host) DMAPageWrite(Address, SCSIDevices[req->TargetID][req->LUN].CmdBuffer, MIN(BufLen, DataLength)); - } } } } @@ -938,6 +937,7 @@ SenseBufferFree(Req_t *req, int Copy) x54x_log("SenseBufferFree(): Writing %i bytes at %08X\n", SenseLength, SenseBufferAddress); DMAPageWrite(SenseBufferAddress, temp_sense, SenseLength); + x54x_add_to_period(SenseLength); x54x_log("Sense data written to buffer: %02X %02X %02X\n", temp_sense[2], temp_sense[12], temp_sense[13]); } @@ -957,6 +957,7 @@ x54x_scsi_cmd(x54x_t *dev) int32_t *BufLen; uint8_t phase; uint32_t SenseBufferAddress; + int64_t p; id = req->TargetID; lun = req->LUN; @@ -979,8 +980,10 @@ x54x_scsi_cmd(x54x_t *dev) if (req->CmdBlock.common.CdbLength <= target_cdb_len) { memcpy(temp_cdb, req->CmdBlock.common.Cdb, req->CmdBlock.common.CdbLength); + x54x_add_to_period(req->CmdBlock.common.CdbLength); } else { memcpy(temp_cdb, req->CmdBlock.common.Cdb, target_cdb_len); + x54x_add_to_period(target_cdb_len); } dev->Residue = 0; @@ -1005,8 +1008,14 @@ x54x_scsi_cmd(x54x_t *dev) if ((SCSIDevices[id][lun].Status != SCSI_STATUS_OK) && (*BufLen > 0)) { SenseBufferAddress = SenseBufferPointer(req); DMAPageWrite(SenseBufferAddress, SCSIDevices[id][lun].CmdBuffer, *BufLen); + x54x_add_to_period(*BufLen); } } else { + p = scsi_device_get_callback(id, lun); + if (p <= 0LL) + x54x_add_to_period(*BufLen); + else + dev->media_period += p; x54x_buf_alloc(id, lun, MIN(target_data_len, *BufLen)); if (phase == SCSI_PHASE_DATA_OUT) x54x_buf_dma_transfer(req, bit24, target_data_len, 1); @@ -1034,10 +1043,6 @@ x54x_scsi_cmd(x54x_t *dev) } x54x_log("SCSIDevices[%02i][%02i].Status = %02X\n", id, lun, SCSIDevices[id][lun].Status); - - if (temp_cdb[0] == 0x42) { - thread_wait_event((event_t *) evt, 10); - } } @@ -1135,6 +1140,7 @@ x54x_req_abort(x54x_t *dev, uint32_t CCBPointer) /* Fetch data from the Command Control Block. */ DMAPageRead(CCBPointer, (uint8_t *)&CmdBlock, sizeof(CCB32)); + x54x_add_to_period(sizeof(CCB32)); x54x_mbi_setup(dev, CCBPointer, &CmdBlock, 0x26, SCSI_STATUS_OK, MBI_NOT_FOUND); @@ -1163,6 +1169,7 @@ x54x_mbo(x54x_t *dev, Mailbox32_t *Mailbox32) if (dev->Mbx24bit) { Outgoing = Addr + (Cur * sizeof(Mailbox_t)); DMAPageRead(Outgoing, (uint8_t *)&MailboxOut, sizeof(Mailbox_t)); + x54x_add_to_period(sizeof(Mailbox_t)); ccbp = *(uint32_t *) &MailboxOut; Mailbox32->CCBPointer = (ccbp >> 24) | ((ccbp >> 8) & 0xff00) | ((ccbp << 8) & 0xff0000); @@ -1171,6 +1178,7 @@ x54x_mbo(x54x_t *dev, Mailbox32_t *Mailbox32) Outgoing = Addr + (Cur * sizeof(Mailbox32_t)); DMAPageRead(Outgoing, (uint8_t *)Mailbox32, sizeof(Mailbox32_t)); + x54x_add_to_period(sizeof(Mailbox32_t)); } return(Outgoing); @@ -1203,14 +1211,11 @@ x54x_mbo_process(x54x_t *dev) /* We got the mailbox, mark it as free in the guest. */ x54x_log("x54x_do_mail(): Writing %i bytes at %08X\n", sizeof(CmdStatus), Outgoing + CodeOffset); DMAPageWrite(Outgoing + CodeOffset, &CmdStatus, 1); + x54x_add_to_period(1); - if (dev->ToRaise) { + if (dev->ToRaise) raise_irq(dev, 0, dev->ToRaise); - while (dev->Interrupt) - ; - } - if (dev->MailboxIsBIOS) dev->BIOSMailboxReq--; else @@ -1264,84 +1269,29 @@ static void x54x_cmd_done(x54x_t *dev, int suppress); -void -x54x_wait_for_poll(void) -{ - if (x54x_is_busy()) { - thread_wait_event((event_t *) wake_poll_thread, -1); - } - thread_reset_event((event_t *) wake_poll_thread); -} - - static void -x54x_cmd_thread(void *priv) +x54x_cmd_callback(void *priv) { + double period; x54x_t *dev = (x54x_t *) x54x_dev; - thread_set_event((event_t *) thread_started); - - x54x_log("Polling thread started\n"); - - while (x54x_dev) { - scsi_mutex_wait(1); - - if ((dev->Status & STAT_INIT) || (!dev->MailboxInit && !dev->BIOSMailboxInit) || (!dev->MailboxReq && !dev->BIOSMailboxReq)) { - /* If we did not get anything, wait a while. */ - thread_wait_event((event_t *) wait_evt, 10); - thread_reset_event((event_t *) wait_evt); - - scsi_mutex_wait(0); - continue; - } - - if (!(x54x_dev->Status & STAT_INIT) && x54x_dev->MailboxInit && dev->MailboxReq) { - x54x_wait_for_poll(); - - x54x_do_mail(dev); - } - - if (dev->ven_thread) { - dev->ven_thread(dev); - } - - scsi_mutex_wait(0); + if ((dev->Status & STAT_INIT) || (!dev->MailboxInit && !dev->BIOSMailboxInit) || (!dev->MailboxReq && !dev->BIOSMailboxReq)) { + /* If we did not get anything, do nothing and wait 10 us. */ + dev->timer_period = 10LL * TIMER_USEC; + return; } - x54x_log("%s: Callback: polling stopped.\n", dev->name); -} + dev->temp_period = dev->media_period = 0LL; + if (!(x54x_dev->Status & STAT_INIT) && x54x_dev->MailboxInit && dev->MailboxReq) + x54x_do_mail(dev); -void -x54x_busy(uint8_t set) -{ - busy = !!set; - if (!set) - thread_set_event((event_t *) wake_poll_thread); -} + if (dev->ven_callback) + dev->ven_callback(dev); - -void -x54x_thread_start(x54x_t *dev) -{ - if (!poll_tid) { - x54x_log("Starting thread...\n"); - poll_tid = thread_create(x54x_cmd_thread, dev); - } -} - - -uint8_t -x54x_is_busy(void) -{ - return(!!busy); -} - - -void -x54x_set_wait_event(void) -{ - thread_set_event((event_t *)wait_evt); + period = (1000000.0 / x54x_dev->ha_bps) * ((double) TIMER_USEC) * ((double) dev->temp_period); + dev->timer_period = dev->media_period + ((int64_t) period) + (40LL * TIMER_USEC); + x54x_log("Temporary period: %" PRId64 " us (%" PRIi64 " periods)\n", dev->timer_period, dev->temp_period); } @@ -1518,31 +1468,24 @@ x54x_out(uint16_t port, uint8_t val, void *priv) switch (port & 3) { case 0: if ((val & CTRL_HRST) || (val & CTRL_SRST)) { - x54x_busy(1); reset = (val & CTRL_HRST); x54x_log("Reset completed = %x\n", reset); x54x_reset_ctrl(dev, reset); x54x_log("Controller reset: "); - x54x_busy(0); break; } if (val & CTRL_IRST) { - x54x_busy(1); clear_irq(dev); x54x_log("Interrupt reset: "); - x54x_busy(0); } break; case 1: /* Fast path for the mailbox execution command. */ if ((val == CMD_START_SCSI) && (dev->Command == 0xff)) { - x54x_busy(1); dev->MailboxReq++; - x54x_set_wait_event(); x54x_log("Start SCSI command: "); - x54x_busy(0); return; } if (dev->ven_fast_cmds) { @@ -1609,7 +1552,6 @@ x54x_out(uint16_t port, uint8_t val, void *priv) break; case CMD_MBINIT: /* mailbox initialization */ - x54x_busy(1); dev->Mbx24bit = 1; mbi = (MailboxInit_t *)dev->CmdBuf; @@ -1628,7 +1570,6 @@ x54x_out(uint16_t port, uint8_t val, void *priv) dev->Status &= ~STAT_INIT; dev->DataReplyLeft = 0; x54x_log("Mailbox init: "); - x54x_busy(0); break; case CMD_BIOSCMD: /* execute BIOS */ @@ -1962,22 +1903,11 @@ x54x_init(device_t *info) dev->bus = info->flags; timer_add(x54x_reset_poll, &dev->ResetCB, &dev->ResetCB, dev); + dev->timer_period = 10LL * TIMER_USEC; + timer_add(x54x_cmd_callback, &dev->timer_period, TIMER_ALWAYS_ENABLED, dev); x54x_dev = dev; - scsi_mutex(1); - - wake_poll_thread = thread_create_event(); - thread_started = thread_create_event(); - - /* Create a waitable event. */ - evt = thread_create_event(); - wait_evt = thread_create_event(); - - x54x_thread_start(dev); - thread_wait_event((event_t *) thread_started, -1); - thread_reset_event((event_t *) thread_started); - return(dev); } @@ -1990,17 +1920,8 @@ x54x_close(void *priv) if (dev) { x54x_dev = NULL; - /* Tell the thread to terminate. */ - if (poll_tid != NULL) { - x54x_busy(0); - - x54x_log("Waiting for SCSI thread to end...\n"); - /* Wait for the end event. */ - thread_wait((event_t *) poll_tid, -1); - x54x_log("SCSI thread ended\n"); - - poll_tid = NULL; - } + /* Tell the timer to terminate. */ + dev->timer_period = 0LL; dev->MailboxInit = dev->BIOSMailboxInit = 0; dev->MailboxCount = dev->BIOSMailboxCount = 0; @@ -2009,28 +1930,6 @@ x54x_close(void *priv) if (dev->ven_data) free(dev->ven_data); - if (wait_evt) { - thread_destroy_event((event_t *) evt); - evt = NULL; - } - - if (evt) { - thread_destroy_event((event_t *) evt); - evt = NULL; - } - - if (thread_started) { - thread_destroy_event((event_t *) thread_started); - thread_started = NULL; - } - - if (wake_poll_thread) { - thread_destroy_event((event_t *) wake_poll_thread); - wake_poll_thread = NULL; - } - - scsi_mutex(0); - if (dev->nvr != NULL) free(dev->nvr); diff --git a/src/scsi/scsi_x54x.h b/src/scsi/scsi_x54x.h index b4380fc89..c9b0d190e 100644 --- a/src/scsi/scsi_x54x.h +++ b/src/scsi/scsi_x54x.h @@ -11,14 +11,14 @@ * of SCSI Host Adapters made by Mylex. * These controllers were designed for various buses. * - * Version: @(#)scsi_x54x.h 1.0.4 2017/12/15 + * Version: @(#)scsi_x54x.h 1.0.5 2018/03/07 * * Authors: TheCollector1995, * Miran Grca, * Fred N. van Kempen, * - * Copyright 2016,2017 Miran Grca. - * Copyright 2017 Fred N. van Kempen. + * Copyright 2016-2018 Miran Grca. + * Copyright 2017,2018 Fred N. van Kempen. */ #ifndef SCSI_X54X_H @@ -332,6 +332,10 @@ typedef struct { char vendor[16]; /* name of device vendor */ char name[16]; /* name of device */ + int64_t timer_period, temp_period; + int64_t media_period; + double ha_bps; /* bytes per second */ + int8_t Irq; uint8_t IrqEnabled; @@ -429,8 +433,8 @@ typedef struct { /* Pointer to a structure of vendor-specific data that only the vendor-specific code can understand */ void *ven_data; - /* Pointer to a function that performs vendor-specific operation during the thread */ - void (*ven_thread)(void *p); + /* Pointer to a function that performs vendor-specific operation during the timer callback */ + void (*ven_callback)(void *p); /* Pointer to a function that executes the second parameter phase of the vendor-specific command */ void (*ven_cmd_phase1)(void *p); /* Pointer to a function that gets the host adapter ID in case it has to be read from a non-standard location */ @@ -487,10 +491,6 @@ typedef struct extern void x54x_reset_ctrl(x54x_t *dev, uint8_t Reset); -extern void x54x_busy(uint8_t set); -extern void x54x_thread_start(x54x_t *dev); -extern void x54x_set_wait_event(void); -extern uint8_t x54x_is_busy(void); extern void x54x_buf_alloc(uint8_t id, uint8_t lun, int length); extern void x54x_buf_free(uint8_t id, uint8_t lun); extern uint8_t x54x_mbo_process(x54x_t *dev); diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 8f84b85ad..21034e812 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -8,7 +8,7 @@ * * S3 emulation. * - * Version: @(#)vid_s3.c 1.0.5 2018/02/09 + * Version: @(#)vid_s3.c 1.0.6 2018/03/07 * * Authors: Sarah Walker, * Miran Grca, @@ -115,8 +115,8 @@ typedef struct s3_t struct { - uint8_t subsys_cntl; - uint8_t setup_md; + uint16_t subsys_cntl; + uint16_t setup_md; uint8_t advfunc_cntl; uint16_t cur_y; uint16_t cur_x; diff --git a/src/win/86Box.rc b/src/win/86Box.rc index 546d11ef8..7122bf0f5 100644 --- a/src/win/86Box.rc +++ b/src/win/86Box.rc @@ -8,7 +8,7 @@ * * Application resource script for Windows. * - * Version: @(#)86Box.rc 1.0.30 2018/02/11 + * Version: @(#)86Box.rc 1.0.31 2018/03/06 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -473,16 +473,16 @@ BEGIN PUSHBUTTON "&Remove",IDC_BUTTON_HDD_REMOVE,198,137,62,10 COMBOBOX IDC_COMBO_HD_BUS,33,117,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Bus:",IDT_1721,7,118,24,8 + LTEXT "Bus:",IDT_1721,7,119,24,8 COMBOBOX IDC_COMBO_HD_CHANNEL,170,117,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",IDT_1722,131,118,38,8 + LTEXT "Channel:",IDT_1722,131,119,38,8 COMBOBOX IDC_COMBO_HD_ID,170,117,22,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "ID:",IDT_1723,131,118,38,8 + LTEXT "ID:",IDT_1723,131,119,38,8 COMBOBOX IDC_COMBO_HD_LUN,239,117,22,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "LUN:",IDT_1724,200,118,38,8 + LTEXT "LUN:",IDT_1724,200,119,38,8 COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,170,117,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -510,16 +510,16 @@ BEGIN LTEXT "File name:",IDT_1731,7,7,204,9 COMBOBOX IDC_COMBO_HD_BUS,33,71,58,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Bus:",IDT_1721,7,72,24,8 + LTEXT "Bus:",IDT_1721,7,73,24,8 COMBOBOX IDC_COMBO_HD_CHANNEL,134,71,77,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",IDT_1722,99,72,34,8 + LTEXT "Channel:",IDT_1722,99,73,34,8 COMBOBOX IDC_COMBO_HD_ID,133,71,26,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "ID:",IDT_1723,117,72,15,8 + LTEXT "ID:",IDT_1723,117,73,15,8 COMBOBOX IDC_COMBO_HD_LUN,185,71,26,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "LUN:",IDT_1724,168,72,15,8 + LTEXT "LUN:",IDT_1724,168,73,15,8 COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,134,71,77,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Progress:",IDT_1752,7,7,204,9 @@ -537,7 +537,7 @@ BEGIN LTEXT "Floppy drives:",IDT_1737,7,7,43,8 COMBOBOX IDC_COMBO_FD_TYPE,33,85,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Type:",IDT_1738,7,86,24,8 + LTEXT "Type:",IDT_1738,7,87,24,8 CONTROL "Turbo timings",IDC_CHECKTURBO,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,131,86,64,10 CONTROL "Check BPB",IDC_CHECKBPB,"Button", @@ -554,34 +554,37 @@ BEGIN LTEXT "CD-ROM drives:",IDT_1739,7,7,50,8 COMBOBOX IDC_COMBO_CD_BUS,33,85,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Bus:",IDT_1740,7,86,24,8 + LTEXT "Bus:",IDT_1740,7,87,24,8 COMBOBOX IDC_COMBO_CD_ID,170,85,22,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "ID:",IDT_1741,131,86,38,8 + LTEXT "ID:",IDT_1741,131,87,38,8 COMBOBOX IDC_COMBO_CD_LUN,239,85,22,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "LUN:",IDT_1742,200,86,38,8 + LTEXT "LUN:",IDT_1742,200,87,38,8 COMBOBOX IDC_COMBO_CD_CHANNEL_IDE,170,85,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",IDT_1743,131,86,38,8 + LTEXT "Channel:",IDT_1743,131,87,38,8 + COMBOBOX IDC_COMBO_CD_SPEED,33,105,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Speed:",IDT_1758,7,107,24,8 CONTROL "List1",IDC_LIST_ZIP_DRIVES,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER | - WS_TABSTOP,7,117,253,60 - LTEXT "ZIP drives:",IDT_1739,7,107,50,8 - COMBOBOX IDC_COMBO_ZIP_BUS,33,184,90,12,CBS_DROPDOWNLIST | + WS_TABSTOP,7,137,253,60 + LTEXT "ZIP drives:",IDT_1739,7,127,50,8 + COMBOBOX IDC_COMBO_ZIP_BUS,73,204,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Bus:",IDT_1753,7,185,24,8 - COMBOBOX IDC_COMBO_ZIP_ID,170,184,22,12,CBS_DROPDOWNLIST | + LTEXT "Bus:",IDT_1753,57,206,14,8 + COMBOBOX IDC_COMBO_ZIP_ID,190,204,22,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "ID:",IDT_1754,131,185,38,8 - COMBOBOX IDC_COMBO_ZIP_LUN,239,184,22,12,CBS_DROPDOWNLIST | + LTEXT "ID:",IDT_1754,171,206,18,8 + COMBOBOX IDC_COMBO_ZIP_LUN,239,204,22,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "LUN:",IDT_1755,200,185,38,8 - COMBOBOX IDC_COMBO_ZIP_CHANNEL_IDE,170,184,90,12,CBS_DROPDOWNLIST | + LTEXT "LUN:",IDT_1755,220,206,18,8 + COMBOBOX IDC_COMBO_ZIP_CHANNEL_IDE,200,204,60,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",IDT_1756,131,185,38,8 + LTEXT "Channel:",IDT_1756,171,206,28,8 CONTROL "ZIP 250",IDC_CHECK250,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,204,64,10 + BS_AUTOCHECKBOX | WS_TABSTOP,7,204,44,10 END @@ -955,6 +958,7 @@ BEGIN IDS_2175 "ZIP images (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0All files (*.*)\0*.*\0" IDS_2176 "ZIP images (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" IDS_2177 "ZIP %i (%03i): %ls" + IDS_2178 "Speed" IDS_4096 "Hard disk (%s)" IDS_4097 "%01i:%01i" diff --git a/src/win/resource.h b/src/win/resource.h index 3112d462a..af9d94b77 100644 --- a/src/win/resource.h +++ b/src/win/resource.h @@ -8,7 +8,7 @@ * * Windows resource defines. * - * Version: @(#)resource.h 1.0.21 2018/02/11 + * Version: @(#)resource.h 1.0.22 2018/03/06 * * Authors: Sarah Walker, * Miran Grca, @@ -90,6 +90,7 @@ #define IDT_1755 1755 /* LUN: */ #define IDT_1756 1756 /* Channel: */ #define IDT_1757 1757 /* Progress: */ +#define IDT_1758 1758 /* Speed: */ /* @@ -195,6 +196,7 @@ #define IDC_COMBO_ZIP_LUN 1163 #define IDC_COMBO_ZIP_CHANNEL_IDE 1164 #define IDC_CHECK250 1165 +#define IDC_COMBO_CD_SPEED 1166 #define IDC_SLIDER_GAIN 1180 /* sound gain dialog */ diff --git a/src/win/win_settings.c b/src/win/win_settings.c index fd5c222f2..6a746ae53 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.40 2018/03/06 + * Version: @(#)win_settings.c 1.0.41 2018/03/07 * * Author: Miran Grca, * @@ -3961,6 +3961,7 @@ static BOOL win_settings_cdrom_drives_recalc_list(HWND hwndList) { fsid = combo_id_to_format_string_id(temp_cdrom_drives[i].bus_type); + lvI.iSubItem = 0; switch (temp_cdrom_drives[i].bus_type) { case CDROM_BUS_DISABLED: @@ -3989,6 +3990,21 @@ static BOOL win_settings_cdrom_drives_recalc_list(HWND hwndList) if (ListView_InsertItem(hwndList, &lvI) == -1) return FALSE; + + lvI.iSubItem = 1; + if (temp_cdrom_drives[i].bus_type == CDROM_BUS_DISABLED) + lvI.pszText = plat_get_string(IDS_2152); + else { + wsprintf(szText, L"%ix", temp_cdrom_drives[i].speed); + lvI.pszText = szText; + } + lvI.iItem = i; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return FALSE; + } } return TRUE; @@ -4102,7 +4118,7 @@ static BOOL win_settings_cdrom_drives_init_columns(HWND hwndList) lvc.iSubItem = 0; lvc.pszText = plat_get_string(IDS_2082); - lvc.cx = 392; + lvc.cx = 342; lvc.fmt = LVCFMT_LEFT; if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) @@ -4110,6 +4126,17 @@ static BOOL win_settings_cdrom_drives_init_columns(HWND hwndList) return FALSE; } + lvc.iSubItem = 1; + lvc.pszText = plat_get_string(IDS_2178); + + lvc.cx = 50; + lvc.fmt = LVCFMT_LEFT; + + if (ListView_InsertColumn(hwndList, 1, &lvc) == -1) + { + return FALSE; + } + return TRUE; } @@ -4130,7 +4157,6 @@ static BOOL win_settings_zip_drives_init_columns(HWND hwndList) return FALSE; } - lvc.iSubItem = 1; lvc.pszText = plat_get_string(IDS_2143); @@ -4294,6 +4320,21 @@ static void win_settings_cdrom_drives_update_item(HWND hwndList, int i) { return; } + + lvI.iSubItem = 1; + if (temp_cdrom_drives[i].bus_type == CDROM_BUS_DISABLED) + lvI.pszText = plat_get_string(IDS_2152); + else { + wsprintf(szText, L"%ix", temp_cdrom_drives[i].speed); + lvI.pszText = szText; + } + lvI.iItem = i; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return; + } } static void win_settings_zip_drives_update_item(HWND hwndList, int i) @@ -4367,6 +4408,13 @@ static void cdrom_add_locations(HWND hdlg) } } + h = GetDlgItem(hdlg, IDC_COMBO_CD_SPEED); + for (i = 1; i <= 52; i++) + { + wsprintf(lptsTemp, L"%ix", i); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); for (i = 0; i < 16; i++) { @@ -4390,6 +4438,7 @@ static void cdrom_add_locations(HWND hdlg) free(lptsTemp); } + static void cdrom_recalc_location_controls(HWND hdlg, int assign_id) { int i = 0; @@ -4416,6 +4465,16 @@ static void cdrom_recalc_location_controls(HWND hdlg, int assign_id) EnableWindow(h, FALSE); ShowWindow(h, SW_HIDE); + h = GetDlgItem(hdlg, IDC_COMBO_CD_SPEED); + if (bus == CDROM_BUS_DISABLED) { + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + } else { + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].speed - 1, 0); + } + switch(bus) { case CDROM_BUS_ATAPI_PIO_ONLY: /* ATAPI (PIO-only) */ @@ -4496,6 +4555,7 @@ static void zip_add_locations(HWND hdlg) free(lptsTemp); } + static void zip_recalc_location_controls(HWND hdlg, int assign_id) { int i = 0; @@ -4969,6 +5029,8 @@ win_settings_other_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam } cdrom_untrack(cdlv_current_sel); assign = (temp_cdrom_drives[cdlv_current_sel].bus_type == b2) ? 0 : 1; + if (temp_cdrom_drives[cdlv_current_sel].bus_type == CDROM_BUS_DISABLED) + temp_cdrom_drives[cdlv_current_sel].speed = 8; 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)) @@ -5030,6 +5092,20 @@ cdrom_bus_skip: rd_ignore_change = 0; return FALSE; + case IDC_COMBO_CD_SPEED: + if (rd_ignore_change) + { + return FALSE; + } + + rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_CD_SPEED); + temp_cdrom_drives[cdlv_current_sel].speed = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; + h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); + win_settings_cdrom_drives_update_item(h, cdlv_current_sel); + rd_ignore_change = 0; + return FALSE; + case IDC_COMBO_ZIP_BUS: if (rd_ignore_change) {