diff --git a/CMakeLists.txt b/CMakeLists.txt index 561e1eeda..f3d7ae4f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,7 +40,7 @@ if(MUNT_EXTERNAL) endif() project(86Box - VERSION 3.6 + VERSION 3.7 DESCRIPTION "Emulator of x86-based systems" HOMEPAGE_URL "https://86box.net" LANGUAGES C CXX) diff --git a/src/86box.c b/src/86box.c index 8569ae53f..deded3382 100644 --- a/src/86box.c +++ b/src/86box.c @@ -183,6 +183,7 @@ int confirm_save = 1; /* (C) enable save confirmation */ int enable_discord = 0; /* (C) enable Discord integration */ int pit_mode = -1; /* (C) force setting PIT mode */ int fm_driver = 0; /* (C) select FM sound driver */ +int open_dir_usr_path = 0; /* default file open dialog directory of usr_path */ /* Statistics. */ extern int mmuflush; diff --git a/src/config.c b/src/config.c index 8d488936e..d22d25b1d 100644 --- a/src/config.c +++ b/src/config.c @@ -611,6 +611,8 @@ load_general(void) enable_discord = !!config_get_int(cat, "enable_discord", 0); + open_dir_usr_path = config_get_int(cat, "open_dir_usr_path", 0); + video_framerate = config_get_int(cat, "video_gl_framerate", -1); video_vsync = config_get_int(cat, "video_gl_vsync", 0); strncpy(video_shader, config_get_string(cat, "video_gl_shader", ""), sizeof(video_shader)); @@ -2380,6 +2382,11 @@ save_general(void) else config_delete_var(cat, "enable_discord"); + if (open_dir_usr_path) + config_set_int(cat, "open_dir_usr_path", open_dir_usr_path); + else + config_delete_var(cat, "open_dir_usr_path"); + if (video_framerate != -1) config_set_int(cat, "video_gl_framerate", video_framerate); else @@ -2767,7 +2774,7 @@ save_storage_controllers(void) delete_section_if_empty(cat); - if (cassette_enable == 1) + if (cassette_enable == 0) config_delete_var(cat, "cassette_enabled"); else config_set_int(cat, "cassette_enabled", cassette_enable); diff --git a/src/device.c b/src/device.c index 331305f2d..c69acaad0 100644 --- a/src/device.c +++ b/src/device.c @@ -331,17 +331,14 @@ device_get_priv(const device_t *d) int device_available(const device_t *d) { - device_config_t *config; - device_config_bios_t *bios; + device_config_t *config = NULL; + device_config_bios_t *bios = NULL; int bf, roms_present = 0; int i = 0; -#ifdef RELEASE_BUILD - if (d->flags & DEVICE_NOT_WORKING) return(0); -#endif if (d != NULL) { config = (device_config_t *) d->config; - if (config != NULL) { + if (config != NULL) { while (config->type != -1) { if (config->type == CONFIG_BIOS) { bios = (device_config_bios_t *) config->bios; @@ -362,9 +359,9 @@ device_available(const device_t *d) } } - /* No CONFIG_BIOS field present, use the classic available(). */ + /* No CONFIG_BIOS field present, use the classic available(). */ if (d->available != NULL) - return(d->available()); + return(d->available()); else return(1); } diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 8bb436a0c..24b0775c4 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -1398,7 +1398,7 @@ write64_ami(void *priv, uint8_t val) else add_data(dev, 'H'); } else - add_data(dev, 'F'); + add_data(dev, 'H'); return 0; case 0xa2: /* clear keyboard controller lines P22/P23 */ diff --git a/src/disk/hdc_esdi_mca.c b/src/disk/hdc_esdi_mca.c index e0859697f..72db74359 100644 --- a/src/disk/hdc_esdi_mca.c +++ b/src/disk/hdc_esdi_mca.c @@ -60,12 +60,14 @@ * Copyright 2008-2018 Sarah Walker. * Copyright 2017,2018 Fred N. van Kempen. */ + #include #include #include #include #include #include +#include #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/device.h> @@ -80,19 +82,16 @@ #include <86box/hdc.h> #include <86box/hdd.h> - /* These are hardwired. */ -#define ESDI_IOADDR_PRI 0x3510 -#define ESDI_IOADDR_SEC 0x3518 -#define ESDI_IRQCHAN 14 +#define ESDI_IOADDR_PRI 0x3510 +#define ESDI_IOADDR_SEC 0x3518 +#define ESDI_IRQCHAN 14 -#define BIOS_FILE_L "roms/hdd/esdi/90x8969.bin" -#define BIOS_FILE_H "roms/hdd/esdi/90x8970.bin" - - -#define ESDI_TIME 512 -#define CMD_ADAPTER 0 +#define BIOS_FILE_L "roms/hdd/esdi/90x8969.bin" +#define BIOS_FILE_H "roms/hdd/esdi/90x8970.bin" +#define ESDI_TIME 512.0 +#define CMD_ADAPTER 0 typedef struct esdi_drive_t { int spt, hpc; @@ -103,128 +102,123 @@ typedef struct esdi_drive_t { } drive_t; typedef struct esdi_t { - int8_t dma; + int8_t dma; - uint32_t bios; - rom_t bios_rom; + uint32_t bios; + rom_t bios_rom; - uint8_t basic_ctrl; - uint8_t status; - uint8_t irq_status; - int irq_in_progress; - int cmd_req_in_progress; - int cmd_pos; - uint16_t cmd_data[4]; - int cmd_dev; + uint8_t basic_ctrl; + uint8_t status; + uint8_t irq_status; + int irq_in_progress; + int cmd_req_in_progress; + int cmd_pos; + uint16_t cmd_data[4]; + int cmd_dev; - int status_pos, - status_len; + int status_pos, + status_len; - uint16_t status_data[256]; + uint16_t status_data[256]; - int data_pos; - uint16_t data[256]; + int data_pos; + uint16_t data[256]; - uint16_t sector_buffer[256][256]; + uint16_t sector_buffer[256][256]; - int sector_pos; - int sector_count; + int sector_pos; + int sector_count; - int command; - int cmd_state; + int command; + int cmd_state; - int in_reset; - uint64_t callback; - pc_timer_t timer; + int in_reset; + pc_timer_t timer; - uint32_t rba; + uint32_t rba; struct { int req_in_progress; - } cmds[3]; + } cmds[3]; - drive_t drives[2]; + drive_t drives[2]; - uint8_t pos_regs[8]; + uint8_t pos_regs[8]; } esdi_t; -#define STATUS_DMA_ENA (1 << 7) -#define STATUS_IRQ_PENDING (1 << 6) -#define STATUS_CMD_IN_PROGRESS (1 << 5) -#define STATUS_BUSY (1 << 4) -#define STATUS_STATUS_OUT_FULL (1 << 3) -#define STATUS_CMD_IR_FULL (1 << 2) -#define STATUS_TRANSFER_REQ (1 << 1) -#define STATUS_IRQ (1 << 0) +#define STATUS_DMA_ENA (1 << 7) +#define STATUS_IRQ_PENDING (1 << 6) +#define STATUS_CMD_IN_PROGRESS (1 << 5) +#define STATUS_BUSY (1 << 4) +#define STATUS_STATUS_OUT_FULL (1 << 3) +#define STATUS_CMD_IR_FULL (1 << 2) +#define STATUS_TRANSFER_REQ (1 << 1) +#define STATUS_IRQ (1 << 0) -#define CTRL_RESET (1 << 7) -#define CTRL_DMA_ENA (1 << 1) -#define CTRL_IRQ_ENA (1 << 0) +#define CTRL_RESET (1 << 7) +#define CTRL_DMA_ENA (1 << 1) +#define CTRL_IRQ_ENA (1 << 0) -#define IRQ_HOST_ADAPTER (7 << 5) -#define IRQ_DEVICE_0 (0 << 5) -#define IRQ_CMD_COMPLETE_SUCCESS 0x1 -#define IRQ_RESET_COMPLETE 0xa -#define IRQ_DATA_TRANSFER_READY 0xb -#define IRQ_CMD_COMPLETE_FAILURE 0xc +#define IRQ_HOST_ADAPTER (7 << 5) +#define IRQ_DEVICE_0 (0 << 5) +#define IRQ_CMD_COMPLETE_SUCCESS 0x1 +#define IRQ_RESET_COMPLETE 0xa +#define IRQ_DATA_TRANSFER_READY 0xb +#define IRQ_CMD_COMPLETE_FAILURE 0xc -#define ATTN_DEVICE_SEL (7 << 5) -#define ATTN_HOST_ADAPTER (7 << 5) -#define ATTN_DEVICE_0 (0 << 5) -#define ATTN_DEVICE_1 (1 << 5) -#define ATTN_REQ_MASK 0x0f -#define ATTN_CMD_REQ 1 -#define ATTN_EOI 2 -#define ATTN_RESET 4 +#define ATTN_DEVICE_SEL (7 << 5) +#define ATTN_HOST_ADAPTER (7 << 5) +#define ATTN_DEVICE_0 (0 << 5) +#define ATTN_DEVICE_1 (1 << 5) +#define ATTN_REQ_MASK 0x0f +#define ATTN_CMD_REQ 1 +#define ATTN_EOI 2 +#define ATTN_RESET 4 -#define CMD_SIZE_4 (1 << 14) +#define CMD_SIZE_4 (1 << 14) -#define CMD_DEVICE_SEL (7 << 5) -#define CMD_MASK 0x1f -#define CMD_READ 0x01 -#define CMD_WRITE 0x02 -#define CMD_READ_VERIFY 0x03 -#define CMD_WRITE_VERIFY 0x04 -#define CMD_SEEK 0x05 -#define CMD_GET_DEV_STATUS 0x08 -#define CMD_GET_DEV_CONFIG 0x09 -#define CMD_GET_POS_INFO 0x0a -#define CMD_FORMAT_UNIT 0x16 -#define CMD_FORMAT_PREPARE 0x17 +#define CMD_DEVICE_SEL (7 << 5) +#define CMD_MASK 0x1f +#define CMD_READ 0x01 +#define CMD_WRITE 0x02 +#define CMD_READ_VERIFY 0x03 +#define CMD_WRITE_VERIFY 0x04 +#define CMD_SEEK 0x05 +#define CMD_GET_DEV_STATUS 0x08 +#define CMD_GET_DEV_CONFIG 0x09 +#define CMD_GET_POS_INFO 0x0a +#define CMD_FORMAT_UNIT 0x16 +#define CMD_FORMAT_PREPARE 0x17 -#define STATUS_LEN(x) ((x) << 8) -#define STATUS_DEVICE(x) ((x) << 5) +#define STATUS_LEN(x) ((x) << 8) +#define STATUS_DEVICE(x) ((x) << 5) #define STATUS_DEVICE_HOST_ADAPTER (7 << 5) - #ifdef ENABLE_ESDI_MCA_LOG int esdi_mca_do_log = ENABLE_ESDI_MCA_LOG; - static void esdi_mca_log(const char *fmt, ...) { va_list ap; if (esdi_mca_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define esdi_mca_log(fmt, ...) +# define esdi_mca_log(fmt, ...) #endif - static __inline void set_irq(esdi_t *dev) { if (dev->basic_ctrl & CTRL_IRQ_ENA) - picint(1 << 14); + picint(1 << 14); } - static __inline void clear_irq(esdi_t *dev) { @@ -232,26 +226,30 @@ clear_irq(esdi_t *dev) } static void -esdi_mca_set_callback(esdi_t *dev, uint64_t callback) +esdi_mca_set_callback(esdi_t *dev, double callback) { if (!dev) { - return; + return; } if (callback) { - dev->callback = callback; - timer_on_auto(&dev->timer, dev->callback); - } else { - dev->callback = 0; - timer_stop(&dev->timer); - } + timer_on_auto(&dev->timer, callback); + } else { + timer_stop(&dev->timer); + } } +static double +esdi_mca_get_xfer_time(esdi_t *esdi, int size) +{ + /* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */ + return (3125.0 / 8.0) * (double)size; +} static void cmd_unsupported(esdi_t *dev) { - dev->status_len = 9; + dev->status_len = 9; dev->status_data[0] = dev->command | STATUS_LEN(9) | dev->cmd_dev; dev->status_data[1] = 0x0f03; /*Attention error, command not supported*/ dev->status_data[2] = 0x0002; /*Interface fault*/ @@ -262,17 +260,17 @@ cmd_unsupported(esdi_t *dev) dev->status_data[7] = 0; dev->status_data[8] = 0; - dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_FAILURE; + dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_FAILURE; dev->irq_in_progress = 1; set_irq(dev); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); } - static void device_not_present(esdi_t *dev) { - dev->status_len = 9; + dev->status_len = 9; dev->status_data[0] = dev->command | STATUS_LEN(9) | dev->cmd_dev; dev->status_data[1] = 0x0c11; /*Command failed, internal hardware error*/ dev->status_data[2] = 0x000b; /*Selection error*/ @@ -283,17 +281,17 @@ device_not_present(esdi_t *dev) dev->status_data[7] = 0; dev->status_data[8] = 0; - dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_FAILURE; + dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_FAILURE; dev->irq_in_progress = 1; set_irq(dev); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); } - static void rba_out_of_range(esdi_t *dev) { - dev->status_len = 9; + dev->status_len = 9; dev->status_data[0] = dev->command | STATUS_LEN(9) | dev->cmd_dev; dev->status_data[1] = 0x0e01; /*Command block error, invalid parameter*/ dev->status_data[2] = 0x0007; /*RBA out of range*/ @@ -304,834 +302,863 @@ rba_out_of_range(esdi_t *dev) dev->status_data[7] = 0; dev->status_data[8] = 0; - dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_FAILURE; + dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_FAILURE; dev->irq_in_progress = 1; set_irq(dev); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); } - static void complete_command_status(esdi_t *dev) { dev->status_len = 7; if (dev->cmd_dev == ATTN_DEVICE_0) - dev->status_data[0] = CMD_READ | STATUS_LEN(7) | STATUS_DEVICE(0); + dev->status_data[0] = CMD_READ | STATUS_LEN(7) | STATUS_DEVICE(0); else - dev->status_data[0] = CMD_READ | STATUS_LEN(7) | STATUS_DEVICE(1); - dev->status_data[1] = 0x0000; /*Error bits*/ - dev->status_data[2] = 0x1900; /*Device status*/ - dev->status_data[3] = 0; /*Number of blocks left to do*/ - dev->status_data[4] = (dev->rba-1) & 0xffff; /*Last RBA processed*/ - dev->status_data[5] = (dev->rba-1) >> 8; + dev->status_data[0] = CMD_READ | STATUS_LEN(7) | STATUS_DEVICE(1); + dev->status_data[1] = 0x0000; /*Error bits*/ + dev->status_data[2] = 0x1900; /*Device status*/ + dev->status_data[3] = 0; /*Number of blocks left to do*/ + dev->status_data[4] = (dev->rba - 1) & 0xffff; /*Last RBA processed*/ + dev->status_data[5] = (dev->rba - 1) >> 8; dev->status_data[6] = 0; /*Number of blocks requiring error recovery*/ + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); } -#define ESDI_ADAPTER_ONLY() do \ - { \ - if (dev->cmd_dev != ATTN_HOST_ADAPTER) \ - { \ - cmd_unsupported(dev); \ - return; \ - } \ - } while (0) - -#define ESDI_DRIVE_ONLY() do \ - { \ - if (dev->cmd_dev != ATTN_DEVICE_0 && dev->cmd_dev != ATTN_DEVICE_1) \ - { \ - cmd_unsupported(dev); \ - return; \ - } \ - if (dev->cmd_dev == ATTN_DEVICE_0) \ - drive = &dev->drives[0]; \ - else \ - drive = &dev->drives[1]; \ - } while (0) +#define ESDI_ADAPTER_ONLY() \ + do { \ + if (dev->cmd_dev != ATTN_HOST_ADAPTER) { \ + cmd_unsupported(dev); \ + return; \ + } \ + } while (0) +#define ESDI_DRIVE_ONLY() \ + do { \ + if (dev->cmd_dev != ATTN_DEVICE_0 && dev->cmd_dev != ATTN_DEVICE_1) { \ + cmd_unsupported(dev); \ + return; \ + } \ + if (dev->cmd_dev == ATTN_DEVICE_0) \ + drive = &dev->drives[0]; \ + else \ + drive = &dev->drives[1]; \ + } while (0) static void esdi_callback(void *priv) { - esdi_t *dev = (esdi_t *)priv; + esdi_t *dev = (esdi_t *) priv; drive_t *drive; - int val; + int val; + double cmd_time = 0.0; esdi_mca_set_callback(dev, 0); /* If we are returning from a RESET, handle this first. */ if (dev->in_reset) { - dev->in_reset = 0; - dev->status = STATUS_IRQ; - dev->irq_status = IRQ_HOST_ADAPTER | IRQ_RESET_COMPLETE; + dev->in_reset = 0; + dev->status = STATUS_IRQ; + dev->irq_status = IRQ_HOST_ADAPTER | IRQ_RESET_COMPLETE; - return; + return; } switch (dev->command) { - case CMD_READ: - ESDI_DRIVE_ONLY(); + case CMD_READ: + ESDI_DRIVE_ONLY(); - if (! drive->present) { - device_not_present(dev); + if (!drive->present) { + device_not_present(dev); + return; + } + + switch (dev->cmd_state) { + case 0: + dev->rba = (dev->cmd_data[2] | (dev->cmd_data[3] << 16)) & 0x0fffffff; + + dev->sector_pos = 0; + dev->sector_count = dev->cmd_data[1]; + + if ((dev->rba + dev->sector_count) > hdd_image_get_last_sector(drive->hdd_num)) { + rba_out_of_range(dev); return; - } + } - switch (dev->cmd_state) { - case 0: - dev->rba = (dev->cmd_data[2] | (dev->cmd_data[3] << 16)) & 0x0fffffff; + dev->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; + dev->irq_status = dev->cmd_dev | IRQ_DATA_TRANSFER_READY; + dev->irq_in_progress = 1; + set_irq(dev); - dev->sector_pos = 0; - dev->sector_count = dev->cmd_data[1]; + dev->cmd_state = 1; + esdi_mca_set_callback(dev, ESDI_TIME); + dev->data_pos = 0; + break; - if ((dev->rba + dev->sector_count) > hdd_image_get_last_sector(drive->hdd_num)) { - rba_out_of_range(dev); - return; - } - - dev->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; - dev->irq_status = dev->cmd_dev | IRQ_DATA_TRANSFER_READY; - dev->irq_in_progress = 1; - set_irq(dev); - - dev->cmd_state = 1; - esdi_mca_set_callback(dev, ESDI_TIME); - dev->data_pos = 0; - break; - - case 1: - if (!(dev->basic_ctrl & CTRL_DMA_ENA)) { - esdi_mca_set_callback(dev, ESDI_TIME); - return; - } - - while (dev->sector_pos < dev->sector_count) { - if (! dev->data_pos) { - if (dev->rba >= drive->sectors) - fatal("Read past end of drive\n"); - hdd_image_read(drive->hdd_num, dev->rba, 1, (uint8_t *)dev->data); - ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1); - } - - while (dev->data_pos < 256) { - val = dma_channel_write(dev->dma, dev->data[dev->data_pos]); - - if (val == DMA_NODATA) { - esdi_mca_set_callback(dev, ESDI_TIME); - return; - } - - dev->data_pos++; - } - - dev->data_pos = 0; - dev->sector_pos++; - dev->rba++; - } - - dev->status = STATUS_CMD_IN_PROGRESS; - dev->cmd_state = 2; - esdi_mca_set_callback(dev, ESDI_TIME); - break; - - case 2: - complete_command_status(dev); - dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; - dev->irq_in_progress = 1; - set_irq(dev); - break; - } - break; - - case CMD_WRITE: - case CMD_WRITE_VERIFY: - ESDI_DRIVE_ONLY(); - if (! drive->present) { - device_not_present(dev); + case 1: + if (!(dev->basic_ctrl & CTRL_DMA_ENA)) { + esdi_mca_set_callback(dev, ESDI_TIME); return; - } + } - switch (dev->cmd_state) { - case 0: - dev->rba = (dev->cmd_data[2] | (dev->cmd_data[3] << 16)) & 0x0fffffff; + while (dev->sector_pos < dev->sector_count) { + if (!dev->data_pos) { + if (dev->rba >= drive->sectors) + fatal("Read past end of drive\n"); + hdd_image_read(drive->hdd_num, dev->rba, 1, (uint8_t *) dev->data); + cmd_time += hdd_timing_read(&hdd[drive->hdd_num], dev->rba, 1); + cmd_time += esdi_mca_get_xfer_time(dev, 1); + } - dev->sector_pos = 0; - dev->sector_count = dev->cmd_data[1]; + while (dev->data_pos < 256) { + val = dma_channel_write(dev->dma, dev->data[dev->data_pos]); - if ((dev->rba + dev->sector_count) > hdd_image_get_last_sector(drive->hdd_num)) { - rba_out_of_range(dev); - return; - } - - dev->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; - dev->irq_status = dev->cmd_dev | IRQ_DATA_TRANSFER_READY; - dev->irq_in_progress = 1; - set_irq(dev); - - dev->cmd_state = 1; - esdi_mca_set_callback(dev, ESDI_TIME); - dev->data_pos = 0; - break; - - case 1: - if (! (dev->basic_ctrl & CTRL_DMA_ENA)) { - esdi_mca_set_callback(dev, ESDI_TIME); - return; - } - - while (dev->sector_pos < dev->sector_count) { - while (dev->data_pos < 256) { - val = dma_channel_read(dev->dma); - - if (val == DMA_NODATA) { - esdi_mca_set_callback(dev, ESDI_TIME); - return; - } - - dev->data[dev->data_pos++] = val & 0xffff; - } - - if (dev->rba >= drive->sectors) - fatal("Write past end of drive\n"); - hdd_image_write(drive->hdd_num, dev->rba, 1, (uint8_t *)dev->data); - dev->rba++; - dev->sector_pos++; - ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, - dev->cmd_dev == ATTN_DEVICE_0 ? 0 : 1); - - dev->data_pos = 0; - } - - dev->status = STATUS_CMD_IN_PROGRESS; - dev->cmd_state = 2; - esdi_mca_set_callback(dev, ESDI_TIME); - break; - - case 2: - complete_command_status(dev); - dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; - dev->irq_in_progress = 1; - set_irq(dev); - break; - } - break; - - case CMD_READ_VERIFY: - ESDI_DRIVE_ONLY(); - - if (! drive->present) { - device_not_present(dev); - return; - } - - if ((dev->rba + dev->sector_count) > hdd_image_get_last_sector(drive->hdd_num)) { - rba_out_of_range(dev); - return; - } - - dev->rba += dev->sector_count; - complete_command_status(dev); - dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; - dev->irq_in_progress = 1; - set_irq(dev); - break; - - case CMD_SEEK: - ESDI_DRIVE_ONLY(); - - if (! drive->present) { - device_not_present(dev); - return; - } - - complete_command_status(dev); - dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; - dev->irq_in_progress = 1; - set_irq(dev); - break; - - case CMD_GET_DEV_STATUS: - ESDI_DRIVE_ONLY(); - - if (! drive->present) { - device_not_present(dev); - return; - } - - if ((dev->status & STATUS_IRQ) || dev->irq_in_progress) - fatal("IRQ in progress %02x %i\n", dev->status, dev->irq_in_progress); - - dev->status_len = 9; - dev->status_data[0] = CMD_GET_DEV_STATUS | STATUS_LEN(9) | STATUS_DEVICE_HOST_ADAPTER; - dev->status_data[1] = 0x0000; /*Error bits*/ - dev->status_data[2] = 0x1900; /*Device status*/ - dev->status_data[3] = 0; /*ESDI Standard Status*/ - dev->status_data[4] = 0; /*ESDI Vendor Unique Status*/ - dev->status_data[5] = 0; - dev->status_data[6] = 0; - dev->status_data[7] = 0; - dev->status_data[8] = 0; - - dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; - dev->irq_in_progress = 1; - set_irq(dev); - break; - - case CMD_GET_DEV_CONFIG: - ESDI_DRIVE_ONLY(); - - if (! drive->present) { - device_not_present(dev); - return; - } - - if ((dev->status & STATUS_IRQ) || dev->irq_in_progress) - fatal("IRQ in progress %02x %i\n", dev->status, dev->irq_in_progress); - - dev->status_len = 6; - dev->status_data[0] = CMD_GET_DEV_CONFIG | STATUS_LEN(6) | STATUS_DEVICE_HOST_ADAPTER; - dev->status_data[1] = 0x10; /*Zero defect*/ - dev->status_data[2] = drive->sectors & 0xffff; - dev->status_data[3] = drive->sectors >> 16; - dev->status_data[4] = drive->tracks; - dev->status_data[5] = drive->hpc | (drive->spt << 16); - - esdi_mca_log("CMD_GET_DEV_CONFIG %i %04x %04x %04x %04x %04x %04x\n", - drive->sectors, - dev->status_data[0], dev->status_data[1], - dev->status_data[2], dev->status_data[3], - dev->status_data[4], dev->status_data[5]); - - dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; - dev->irq_in_progress = 1; - set_irq(dev); - break; - - case CMD_GET_POS_INFO: - ESDI_ADAPTER_ONLY(); - - if ((dev->status & STATUS_IRQ) || dev->irq_in_progress) - fatal("IRQ in progress %02x %i\n", dev->status, dev->irq_in_progress); - - dev->status_len = 5; - dev->status_data[0] = CMD_GET_POS_INFO | STATUS_LEN(5) | STATUS_DEVICE_HOST_ADAPTER; - dev->status_data[1] = 0xffdd; /*MCA ID*/ - dev->status_data[2] = dev->pos_regs[3] | - (dev->pos_regs[2] << 8); - dev->status_data[3] = 0xff; - dev->status_data[4] = 0xff; - - dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - dev->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS; - dev->irq_in_progress = 1; - set_irq(dev); - break; - - case 0x10: - ESDI_ADAPTER_ONLY(); - switch (dev->cmd_state) { - case 0: - dev->sector_pos = 0; - dev->sector_count = dev->cmd_data[1]; - if (dev->sector_count > 256) - fatal("Write sector buffer count %04x\n", dev->cmd_data[1]); - - dev->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; - dev->irq_status = IRQ_HOST_ADAPTER | IRQ_DATA_TRANSFER_READY; - dev->irq_in_progress = 1; - set_irq(dev); - - dev->cmd_state = 1; - esdi_mca_set_callback(dev, ESDI_TIME); - dev->data_pos = 0; - break; - - case 1: - if (! (dev->basic_ctrl & CTRL_DMA_ENA)) { - esdi_mca_set_callback(dev, ESDI_TIME); - return; - } - while (dev->sector_pos < dev->sector_count) { - while (dev->data_pos < 256) { - val = dma_channel_read(dev->dma); - - if (val == DMA_NODATA) { - esdi_mca_set_callback(dev, ESDI_TIME); - return; - } - - dev->data[dev->data_pos++] = val & 0xffff;; - } - - memcpy(dev->sector_buffer[dev->sector_pos++], dev->data, 512); - dev->data_pos = 0; - } - - dev->status = STATUS_CMD_IN_PROGRESS; - dev->cmd_state = 2; - esdi_mca_set_callback(dev, ESDI_TIME); - break; - - case 2: - dev->status = STATUS_IRQ; - dev->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS; - dev->irq_in_progress = 1; - set_irq(dev); - break; - } - break; - - case 0x11: - ESDI_ADAPTER_ONLY(); - switch (dev->cmd_state) { - case 0: - dev->sector_pos = 0; - dev->sector_count = dev->cmd_data[1]; - if (dev->sector_count > 256) - fatal("Read sector buffer count %04x\n", dev->cmd_data[1]); - - dev->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; - dev->irq_status = IRQ_HOST_ADAPTER | IRQ_DATA_TRANSFER_READY; - dev->irq_in_progress = 1; - set_irq(dev); - - dev->cmd_state = 1; - esdi_mca_set_callback(dev, ESDI_TIME); - dev->data_pos = 0; - break; - - case 1: - if (! (dev->basic_ctrl & CTRL_DMA_ENA)) { - esdi_mca_set_callback(dev, ESDI_TIME); - return; - } - - while (dev->sector_pos < dev->sector_count) { - if (! dev->data_pos) - memcpy(dev->data, dev->sector_buffer[dev->sector_pos++], 512); - while (dev->data_pos < 256) { - val = dma_channel_write(dev->dma, dev->data[dev->data_pos]); - - if (val == DMA_NODATA) { - esdi_mca_set_callback(dev, ESDI_TIME); - return; - } - - dev->data_pos++; - } - - dev->data_pos = 0; - } - - dev->status = STATUS_CMD_IN_PROGRESS; - dev->cmd_state = 2; - esdi_mca_set_callback(dev, ESDI_TIME); - break; - - case 2: - dev->status = STATUS_IRQ; - dev->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS; - dev->irq_in_progress = 1; - set_irq(dev); - break; - } - break; - - case 0x12: - ESDI_ADAPTER_ONLY(); - if ((dev->status & STATUS_IRQ) || dev->irq_in_progress) - fatal("IRQ in progress %02x %i\n", dev->status, dev->irq_in_progress); - - dev->status_len = 2; - dev->status_data[0] = 0x12 | STATUS_LEN(5) | STATUS_DEVICE_HOST_ADAPTER; - dev->status_data[1] = 0; - - dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - dev->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS; - dev->irq_in_progress = 1; - set_irq(dev); - break; - - case CMD_FORMAT_UNIT: - case CMD_FORMAT_PREPARE: - ESDI_DRIVE_ONLY(); - - if (! drive->present) { - device_not_present(dev); - return; - } - - switch (dev->cmd_state) { - case 0: - dev->rba = (dev->cmd_data[2] | (dev->cmd_data[3] << 16)) & 0x0fffffff; - - dev->sector_count = dev->cmd_data[1]; - - if ((dev->rba + dev->sector_count) > hdd_image_get_last_sector(drive->hdd_num)) { - rba_out_of_range(dev); - return; + if (val == DMA_NODATA) { + esdi_mca_set_callback(dev, ESDI_TIME + cmd_time); + return; } - dev->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; - dev->irq_status = dev->cmd_dev | IRQ_DATA_TRANSFER_READY; - dev->irq_in_progress = 1; - set_irq(dev); + dev->data_pos++; + } - dev->cmd_state = 1; - esdi_mca_set_callback(dev, ESDI_TIME); - break; + dev->data_pos = 0; + dev->sector_pos++; + dev->rba++; + } - case 1: - if (!(dev->basic_ctrl & CTRL_DMA_ENA)) { - esdi_mca_set_callback(dev, ESDI_TIME); - return; + dev->status = STATUS_CMD_IN_PROGRESS; + dev->cmd_state = 2; + esdi_mca_set_callback(dev, cmd_time); + break; + + case 2: + complete_command_status(dev); + dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; + dev->irq_in_progress = 1; + set_irq(dev); + break; + } + break; + + case CMD_WRITE: + case CMD_WRITE_VERIFY: + ESDI_DRIVE_ONLY(); + if (!drive->present) { + device_not_present(dev); + return; + } + + switch (dev->cmd_state) { + case 0: + dev->rba = (dev->cmd_data[2] | (dev->cmd_data[3] << 16)) & 0x0fffffff; + + dev->sector_pos = 0; + dev->sector_count = dev->cmd_data[1]; + + if ((dev->rba + dev->sector_count) > hdd_image_get_last_sector(drive->hdd_num)) { + rba_out_of_range(dev); + return; + } + + dev->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; + dev->irq_status = dev->cmd_dev | IRQ_DATA_TRANSFER_READY; + dev->irq_in_progress = 1; + set_irq(dev); + + dev->cmd_state = 1; + esdi_mca_set_callback(dev, ESDI_TIME); + dev->data_pos = 0; + break; + + case 1: + if (!(dev->basic_ctrl & CTRL_DMA_ENA)) { + esdi_mca_set_callback(dev, ESDI_TIME); + return; + } + + while (dev->sector_pos < dev->sector_count) { + while (dev->data_pos < 256) { + val = dma_channel_read(dev->dma); + + if (val == DMA_NODATA) { + esdi_mca_set_callback(dev, ESDI_TIME + cmd_time); + return; } - hdd_image_zero(drive->hdd_num, dev->rba, dev->sector_count); - ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1); + dev->data[dev->data_pos++] = val & 0xffff; + } - dev->status = STATUS_CMD_IN_PROGRESS; - dev->cmd_state = 2; - esdi_mca_set_callback(dev, ESDI_TIME); - break; + if (dev->rba >= drive->sectors) + fatal("Write past end of drive\n"); + hdd_image_write(drive->hdd_num, dev->rba, 1, (uint8_t *) dev->data); + cmd_time += hdd_timing_write(&hdd[drive->hdd_num], dev->rba, 1); + cmd_time += esdi_mca_get_xfer_time(dev, 1); + dev->rba++; + dev->sector_pos++; + dev->data_pos = 0; + } - case 2: - complete_command_status(dev); - dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; - dev->irq_in_progress = 1; - set_irq(dev); - break; - } - break; + dev->status = STATUS_CMD_IN_PROGRESS; + dev->cmd_state = 2; + esdi_mca_set_callback(dev, cmd_time); + break; - default: - fatal("BAD COMMAND %02x %i\n", dev->command, dev->cmd_dev); + case 2: + complete_command_status(dev); + dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; + dev->irq_in_progress = 1; + set_irq(dev); + break; + } + break; + + case CMD_READ_VERIFY: + ESDI_DRIVE_ONLY(); + + if (!drive->present) { + device_not_present(dev); + return; + } + + switch (dev->cmd_state) { + case 0: + dev->rba = (dev->cmd_data[2] | (dev->cmd_data[3] << 16)) & 0x0fffffff; + dev->sector_count = dev->cmd_data[1]; + + if ((dev->rba + dev->sector_count) > hdd_image_get_last_sector(drive->hdd_num)) { + rba_out_of_range(dev); + return; + } + + cmd_time = hdd_timing_read(&hdd[drive->hdd_num], dev->rba, dev->sector_count); + esdi_mca_set_callback(dev, ESDI_TIME + cmd_time); + dev->cmd_state = 1; + break; + + case 1: + complete_command_status(dev); + dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; + dev->irq_in_progress = 1; + set_irq(dev); + break; + } + break; + + case CMD_SEEK: + ESDI_DRIVE_ONLY(); + + if (!drive->present) { + device_not_present(dev); + return; + } + + if ((dev->rba + dev->sector_count) > hdd_image_get_last_sector(drive->hdd_num)) { + rba_out_of_range(dev); + return; + } + + switch (dev->cmd_state) { + case 0: + dev->rba = (dev->cmd_data[2] | (dev->cmd_data[3] << 16)) & 0x0fffffff; + cmd_time = hdd_seek_get_time(&hdd[drive->hdd_num], dev->rba, HDD_OP_SEEK, 0, 0.0); + esdi_mca_set_callback(dev, ESDI_TIME + cmd_time); + dev->cmd_state = 1; + break; + + case 1: + complete_command_status(dev); + dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; + dev->irq_in_progress = 1; + set_irq(dev); + break; + } + break; + + case CMD_GET_DEV_STATUS: + ESDI_DRIVE_ONLY(); + + if (!drive->present) { + device_not_present(dev); + return; + } + + if ((dev->status & STATUS_IRQ) || dev->irq_in_progress) + fatal("IRQ in progress %02x %i\n", dev->status, dev->irq_in_progress); + + dev->status_len = 9; + dev->status_data[0] = CMD_GET_DEV_STATUS | STATUS_LEN(9) | STATUS_DEVICE_HOST_ADAPTER; + dev->status_data[1] = 0x0000; /*Error bits*/ + dev->status_data[2] = 0x1900; /*Device status*/ + dev->status_data[3] = 0; /*ESDI Standard Status*/ + dev->status_data[4] = 0; /*ESDI Vendor Unique Status*/ + dev->status_data[5] = 0; + dev->status_data[6] = 0; + dev->status_data[7] = 0; + dev->status_data[8] = 0; + + dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; + dev->irq_in_progress = 1; + set_irq(dev); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); + break; + + case CMD_GET_DEV_CONFIG: + ESDI_DRIVE_ONLY(); + + if (!drive->present) { + device_not_present(dev); + return; + } + + if ((dev->status & STATUS_IRQ) || dev->irq_in_progress) + fatal("IRQ in progress %02x %i\n", dev->status, dev->irq_in_progress); + + dev->status_len = 6; + dev->status_data[0] = CMD_GET_DEV_CONFIG | STATUS_LEN(6) | STATUS_DEVICE_HOST_ADAPTER; + dev->status_data[1] = 0x10; /*Zero defect*/ + dev->status_data[2] = drive->sectors & 0xffff; + dev->status_data[3] = drive->sectors >> 16; + dev->status_data[4] = drive->tracks; + dev->status_data[5] = drive->hpc | (drive->spt << 16); + + esdi_mca_log("CMD_GET_DEV_CONFIG %i %04x %04x %04x %04x %04x %04x\n", + drive->sectors, + dev->status_data[0], dev->status_data[1], + dev->status_data[2], dev->status_data[3], + dev->status_data[4], dev->status_data[5]); + + dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; + dev->irq_in_progress = 1; + set_irq(dev); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); + break; + + case CMD_GET_POS_INFO: + ESDI_ADAPTER_ONLY(); + + if ((dev->status & STATUS_IRQ) || dev->irq_in_progress) + fatal("IRQ in progress %02x %i\n", dev->status, dev->irq_in_progress); + + dev->status_len = 5; + dev->status_data[0] = CMD_GET_POS_INFO | STATUS_LEN(5) | STATUS_DEVICE_HOST_ADAPTER; + dev->status_data[1] = 0xffdd; /*MCA ID*/ + dev->status_data[2] = dev->pos_regs[3] | (dev->pos_regs[2] << 8); + dev->status_data[3] = 0xff; + dev->status_data[4] = 0xff; + + dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + dev->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS; + dev->irq_in_progress = 1; + set_irq(dev); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); + break; + + case 0x10: + ESDI_ADAPTER_ONLY(); + switch (dev->cmd_state) { + case 0: + dev->sector_pos = 0; + dev->sector_count = dev->cmd_data[1]; + if (dev->sector_count > 256) + fatal("Write sector buffer count %04x\n", dev->cmd_data[1]); + + dev->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; + dev->irq_status = IRQ_HOST_ADAPTER | IRQ_DATA_TRANSFER_READY; + dev->irq_in_progress = 1; + set_irq(dev); + + dev->cmd_state = 1; + esdi_mca_set_callback(dev, ESDI_TIME); + dev->data_pos = 0; + break; + + case 1: + if (!(dev->basic_ctrl & CTRL_DMA_ENA)) { + esdi_mca_set_callback(dev, ESDI_TIME); + return; + } + while (dev->sector_pos < dev->sector_count) { + while (dev->data_pos < 256) { + val = dma_channel_read(dev->dma); + + if (val == DMA_NODATA) { + esdi_mca_set_callback(dev, ESDI_TIME); + return; + } + + dev->data[dev->data_pos++] = val & 0xffff; + ; + } + + memcpy(dev->sector_buffer[dev->sector_pos++], dev->data, 512); + dev->data_pos = 0; + } + + dev->status = STATUS_CMD_IN_PROGRESS; + dev->cmd_state = 2; + esdi_mca_set_callback(dev, ESDI_TIME); + break; + + case 2: + dev->status = STATUS_IRQ; + dev->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS; + dev->irq_in_progress = 1; + set_irq(dev); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); + break; + } + break; + + case 0x11: + ESDI_ADAPTER_ONLY(); + switch (dev->cmd_state) { + case 0: + dev->sector_pos = 0; + dev->sector_count = dev->cmd_data[1]; + if (dev->sector_count > 256) + fatal("Read sector buffer count %04x\n", dev->cmd_data[1]); + + dev->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; + dev->irq_status = IRQ_HOST_ADAPTER | IRQ_DATA_TRANSFER_READY; + dev->irq_in_progress = 1; + set_irq(dev); + + dev->cmd_state = 1; + esdi_mca_set_callback(dev, ESDI_TIME); + dev->data_pos = 0; + break; + + case 1: + if (!(dev->basic_ctrl & CTRL_DMA_ENA)) { + esdi_mca_set_callback(dev, ESDI_TIME); + return; + } + + while (dev->sector_pos < dev->sector_count) { + if (!dev->data_pos) + memcpy(dev->data, dev->sector_buffer[dev->sector_pos++], 512); + while (dev->data_pos < 256) { + val = dma_channel_write(dev->dma, dev->data[dev->data_pos]); + + if (val == DMA_NODATA) { + esdi_mca_set_callback(dev, ESDI_TIME); + return; + } + + dev->data_pos++; + } + + dev->data_pos = 0; + } + + dev->status = STATUS_CMD_IN_PROGRESS; + dev->cmd_state = 2; + esdi_mca_set_callback(dev, ESDI_TIME); + break; + + case 2: + dev->status = STATUS_IRQ; + dev->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS; + dev->irq_in_progress = 1; + set_irq(dev); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); + break; + } + break; + + case 0x12: + ESDI_ADAPTER_ONLY(); + if ((dev->status & STATUS_IRQ) || dev->irq_in_progress) + fatal("IRQ in progress %02x %i\n", dev->status, dev->irq_in_progress); + + dev->status_len = 2; + dev->status_data[0] = 0x12 | STATUS_LEN(5) | STATUS_DEVICE_HOST_ADAPTER; + dev->status_data[1] = 0; + + dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + dev->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS; + dev->irq_in_progress = 1; + set_irq(dev); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); + break; + + case CMD_FORMAT_UNIT: + case CMD_FORMAT_PREPARE: + ESDI_DRIVE_ONLY(); + + if (!drive->present) { + device_not_present(dev); + return; + } + + switch (dev->cmd_state) { + case 0: + dev->rba = (dev->cmd_data[2] | (dev->cmd_data[3] << 16)) & 0x0fffffff; + + dev->sector_count = dev->cmd_data[1]; + + if ((dev->rba + dev->sector_count) > hdd_image_get_last_sector(drive->hdd_num)) { + rba_out_of_range(dev); + return; + } + + dev->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; + dev->irq_status = dev->cmd_dev | IRQ_DATA_TRANSFER_READY; + dev->irq_in_progress = 1; + set_irq(dev); + + dev->cmd_state = 1; + esdi_mca_set_callback(dev, ESDI_TIME); + break; + + case 1: + if (!(dev->basic_ctrl & CTRL_DMA_ENA)) { + esdi_mca_set_callback(dev, ESDI_TIME); + return; + } + + hdd_image_zero(drive->hdd_num, dev->rba, dev->sector_count); + + dev->status = STATUS_CMD_IN_PROGRESS; + dev->cmd_state = 2; + esdi_mca_set_callback(dev, ESDI_TIME); + break; + + case 2: + complete_command_status(dev); + dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; + dev->irq_in_progress = 1; + set_irq(dev); + break; + } + break; + + default: + fatal("BAD COMMAND %02x %i\n", dev->command, dev->cmd_dev); } } - static uint8_t esdi_read(uint16_t port, void *priv) { - esdi_t *dev = (esdi_t *)priv; + esdi_t *dev = (esdi_t *) priv; uint8_t ret = 0xff; switch (port & 7) { - case 2: /*Basic status register*/ - ret = dev->status; - break; + case 2: /*Basic status register*/ + ret = dev->status; + break; - case 3: /*IRQ status*/ - dev->status &= ~STATUS_IRQ; - ret = dev->irq_status; - break; + case 3: /*IRQ status*/ + dev->status &= ~STATUS_IRQ; + ret = dev->irq_status; + break; - default: - fatal("esdi_read port=%04x\n", port); + default: + fatal("esdi_read port=%04x\n", port); } - return(ret); + return (ret); } - static void esdi_write(uint16_t port, uint8_t val, void *priv) { - esdi_t *dev = (esdi_t *)priv; + esdi_t *dev = (esdi_t *) priv; esdi_mca_log("ESDI: wr(%04x, %02x)\n", port & 7, val); switch (port & 7) { - case 2: /*Basic control register*/ - if ((dev->basic_ctrl & CTRL_RESET) && !(val & CTRL_RESET)) { - dev->in_reset = 1; - esdi_mca_set_callback(dev, ESDI_TIME * 50); - dev->status = STATUS_BUSY; - } - dev->basic_ctrl = val; + case 2: /*Basic control register*/ + if ((dev->basic_ctrl & CTRL_RESET) && !(val & CTRL_RESET)) { + dev->in_reset = 1; + esdi_mca_set_callback(dev, ESDI_TIME * 50); + dev->status = STATUS_BUSY; + } + dev->basic_ctrl = val; - if (! (dev->basic_ctrl & CTRL_IRQ_ENA)) - picintc(1 << 14); - break; + if (!(dev->basic_ctrl & CTRL_IRQ_ENA)) + picintc(1 << 14); + break; - case 3: /*Attention register*/ - switch (val & ATTN_DEVICE_SEL) { - case ATTN_HOST_ADAPTER: - switch (val & ATTN_REQ_MASK) { - case ATTN_CMD_REQ: - if (dev->cmd_req_in_progress) - fatal("Try to start command on in_progress adapter\n"); - dev->cmd_req_in_progress = 1; - dev->cmd_dev = ATTN_HOST_ADAPTER; - dev->status |= STATUS_BUSY; - dev->cmd_pos = 0; - dev->status_pos = 0; - break; + case 3: /*Attention register*/ + switch (val & ATTN_DEVICE_SEL) { + case ATTN_HOST_ADAPTER: + switch (val & ATTN_REQ_MASK) { + case ATTN_CMD_REQ: + if (dev->cmd_req_in_progress) + fatal("Try to start command on in_progress adapter\n"); + dev->cmd_req_in_progress = 1; + dev->cmd_dev = ATTN_HOST_ADAPTER; + dev->status |= STATUS_BUSY; + dev->cmd_pos = 0; + dev->status_pos = 0; + break; - case ATTN_EOI: - dev->irq_in_progress = 0; - dev->status &= ~STATUS_IRQ; - clear_irq(dev); - break; + case ATTN_EOI: + dev->irq_in_progress = 0; + dev->status &= ~STATUS_IRQ; + clear_irq(dev); + break; - case ATTN_RESET: - dev->in_reset = 1; - esdi_mca_set_callback(dev, ESDI_TIME * 50); - dev->status = STATUS_BUSY; - break; + case ATTN_RESET: + dev->in_reset = 1; + esdi_mca_set_callback(dev, ESDI_TIME * 50); + dev->status = STATUS_BUSY; + break; - default: - fatal("Bad attention request %02x\n", val); - } - break; + default: + fatal("Bad attention request %02x\n", val); + } + break; - case ATTN_DEVICE_0: - switch (val & ATTN_REQ_MASK) { - case ATTN_CMD_REQ: - if (dev->cmd_req_in_progress) - fatal("Try to start command on in_progress device0\n"); - dev->cmd_req_in_progress = 1; - dev->cmd_dev = ATTN_DEVICE_0; - dev->status |= STATUS_BUSY; - dev->cmd_pos = 0; - dev->status_pos = 0; - break; + case ATTN_DEVICE_0: + switch (val & ATTN_REQ_MASK) { + case ATTN_CMD_REQ: + if (dev->cmd_req_in_progress) + fatal("Try to start command on in_progress device0\n"); + dev->cmd_req_in_progress = 1; + dev->cmd_dev = ATTN_DEVICE_0; + dev->status |= STATUS_BUSY; + dev->cmd_pos = 0; + dev->status_pos = 0; + break; - case ATTN_EOI: - dev->irq_in_progress = 0; - dev->status &= ~STATUS_IRQ; - clear_irq(dev); - break; + case ATTN_EOI: + dev->irq_in_progress = 0; + dev->status &= ~STATUS_IRQ; + clear_irq(dev); + break; - default: - fatal("Bad attention request %02x\n", val); - } - break; + default: + fatal("Bad attention request %02x\n", val); + } + break; - case ATTN_DEVICE_1: - switch (val & ATTN_REQ_MASK) { - case ATTN_CMD_REQ: - if (dev->cmd_req_in_progress) - fatal("Try to start command on in_progress device0\n"); - dev->cmd_req_in_progress = 1; - dev->cmd_dev = ATTN_DEVICE_1; - dev->status |= STATUS_BUSY; - dev->cmd_pos = 0; - dev->status_pos = 0; - break; + case ATTN_DEVICE_1: + switch (val & ATTN_REQ_MASK) { + case ATTN_CMD_REQ: + if (dev->cmd_req_in_progress) + fatal("Try to start command on in_progress device0\n"); + dev->cmd_req_in_progress = 1; + dev->cmd_dev = ATTN_DEVICE_1; + dev->status |= STATUS_BUSY; + dev->cmd_pos = 0; + dev->status_pos = 0; + break; - case ATTN_EOI: - dev->irq_in_progress = 0; - dev->status &= ~STATUS_IRQ; - clear_irq(dev); - break; + case ATTN_EOI: + dev->irq_in_progress = 0; + dev->status &= ~STATUS_IRQ; + clear_irq(dev); + break; - default: - fatal("Bad attention request %02x\n", val); - } - break; + default: + fatal("Bad attention request %02x\n", val); + } + break; - default: - fatal("Attention to unknown device %02x\n", val); - } - break; + default: + fatal("Attention to unknown device %02x\n", val); + } + break; - default: - fatal("esdi_write port=%04x val=%02x\n", port, val); + default: + fatal("esdi_write port=%04x val=%02x\n", port, val); } } - static uint16_t esdi_readw(uint16_t port, void *priv) { - esdi_t *dev = (esdi_t *)priv; + esdi_t *dev = (esdi_t *) priv; uint16_t ret = 0xffff; switch (port & 7) { - case 0: /*Status Interface Register*/ - if (dev->status_pos >= dev->status_len) - return(0); - ret = dev->status_data[dev->status_pos++]; if (dev->status_pos >= dev->status_len) { - dev->status &= ~STATUS_STATUS_OUT_FULL; - dev->status_pos = dev->status_len = 0; - } - break; + case 0: /*Status Interface Register*/ + if (dev->status_pos >= dev->status_len) + return (0); + ret = dev->status_data[dev->status_pos++]; + if (dev->status_pos >= dev->status_len) { + dev->status &= ~STATUS_STATUS_OUT_FULL; + dev->status_pos = dev->status_len = 0; + } + break; - default: - fatal("esdi_readw port=%04x\n", port); + default: + fatal("esdi_readw port=%04x\n", port); } - return(ret); + return (ret); } - static void esdi_writew(uint16_t port, uint16_t val, void *priv) { - esdi_t *dev = (esdi_t *)priv; + esdi_t *dev = (esdi_t *) priv; esdi_mca_log("ESDI: wrw(%04x, %04x)\n", port & 7, val); switch (port & 7) { - case 0: /*Command Interface Register*/ - if (dev->cmd_pos >= 4) - fatal("CIR pos 4\n"); - dev->cmd_data[dev->cmd_pos++] = val; - if (((dev->cmd_data[0] & CMD_SIZE_4) && dev->cmd_pos == 4) || - (!(dev->cmd_data[0] & CMD_SIZE_4) && dev->cmd_pos == 2)) { - dev->cmd_pos = 0; - dev->cmd_req_in_progress = 0; - dev->cmd_state = 0; + case 0: /*Command Interface Register*/ + if (dev->cmd_pos >= 4) + fatal("CIR pos 4\n"); + dev->cmd_data[dev->cmd_pos++] = val; + if (((dev->cmd_data[0] & CMD_SIZE_4) && dev->cmd_pos == 4) || (!(dev->cmd_data[0] & CMD_SIZE_4) && dev->cmd_pos == 2)) { + dev->cmd_pos = 0; + dev->cmd_req_in_progress = 0; + dev->cmd_state = 0; - if ((dev->cmd_data[0] & CMD_DEVICE_SEL) != dev->cmd_dev) - fatal("Command device mismatch with attn\n"); - dev->command = dev->cmd_data[0] & CMD_MASK; - esdi_mca_set_callback(dev, ESDI_TIME); - dev->status = STATUS_BUSY; - dev->data_pos = 0; - } - break; + if ((dev->cmd_data[0] & CMD_DEVICE_SEL) != dev->cmd_dev) + fatal("Command device mismatch with attn\n"); + dev->command = dev->cmd_data[0] & CMD_MASK; + esdi_mca_set_callback(dev, ESDI_TIME); + dev->status = STATUS_BUSY; + dev->data_pos = 0; + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1); + } + break; - default: - fatal("esdi_writew port=%04x val=%04x\n", port, val); + default: + fatal("esdi_writew port=%04x val=%04x\n", port, val); } } - static uint8_t esdi_mca_read(int port, void *priv) { - esdi_t *dev = (esdi_t *)priv; + esdi_t *dev = (esdi_t *) priv; esdi_mca_log("ESDI: mcard(%04x)\n", port); - return(dev->pos_regs[port & 7]); + return (dev->pos_regs[port & 7]); } - static void esdi_mca_write(int port, uint8_t val, void *priv) { - esdi_t *dev = (esdi_t *)priv; + esdi_t *dev = (esdi_t *) priv; esdi_mca_log("ESDI: mcawr(%04x, %02x) pos[2]=%02x pos[3]=%02x\n", - port, val, dev->pos_regs[2], dev->pos_regs[3]); + port, val, dev->pos_regs[2], dev->pos_regs[3]); if (port < 0x102) - return; + return; /* Save the new value. */ dev->pos_regs[port & 7] = val; io_removehandler(ESDI_IOADDR_PRI, 8, - esdi_read, esdi_readw, NULL, - esdi_write, esdi_writew, NULL, dev); + esdi_read, esdi_readw, NULL, + esdi_write, esdi_writew, NULL, dev); mem_mapping_disable(&dev->bios_rom.mapping); - switch(dev->pos_regs[2] & 0x3c) { - case 0x14: - dev->dma = 5; - break; - case 0x18: - dev->dma = 6; - break; - case 0x1c: - dev->dma = 7; - break; - case 0x00: - dev->dma = 0; - break; - case 0x04: - dev->dma = 1; - break; - case 0x0c: - dev->dma = 3; - break; - case 0x10: - dev->dma = 4; - break; + switch (dev->pos_regs[2] & 0x3c) { + case 0x14: + dev->dma = 5; + break; + case 0x18: + dev->dma = 6; + break; + case 0x1c: + dev->dma = 7; + break; + case 0x00: + dev->dma = 0; + break; + case 0x04: + dev->dma = 1; + break; + case 0x0c: + dev->dma = 3; + break; + case 0x10: + dev->dma = 4; + break; } if (dev->pos_regs[2] & 1) { - io_sethandler(ESDI_IOADDR_PRI, 8, - esdi_read, esdi_readw, NULL, - esdi_write, esdi_writew, NULL, dev); + io_sethandler(ESDI_IOADDR_PRI, 8, + esdi_read, esdi_readw, NULL, + esdi_write, esdi_writew, NULL, dev); - if (!(dev->pos_regs[3] & 8)) { - mem_mapping_enable(&dev->bios_rom.mapping); - mem_mapping_set_addr(&dev->bios_rom.mapping, - ((dev->pos_regs[3] & 7) * 0x4000) + 0xc0000, 0x4000); - } + if (!(dev->pos_regs[3] & 8)) { + mem_mapping_enable(&dev->bios_rom.mapping); + mem_mapping_set_addr(&dev->bios_rom.mapping, + ((dev->pos_regs[3] & 7) * 0x4000) + 0xc0000, 0x4000); + } - /* Say hello. */ - esdi_mca_log("ESDI: I/O=3510, IRQ=14, DMA=%d, BIOS @%05X\n", - dev->dma, dev->bios); + /* Say hello. */ + esdi_mca_log("ESDI: I/O=3510, IRQ=14, DMA=%d, BIOS @%05X\n", + dev->dma, dev->bios); } } - static uint8_t esdi_mca_feedb(void *priv) { - esdi_t *dev = (esdi_t *)priv; + esdi_t *dev = (esdi_t *) priv; return (dev->pos_regs[2] & 1); } - static void * esdi_init(const device_t *info) { drive_t *drive; - esdi_t *dev; - int c, i; + esdi_t *dev; + int c, i; dev = malloc(sizeof(esdi_t)); - if (dev == NULL) return(NULL); + if (dev == NULL) + return (NULL); memset(dev, 0x00, sizeof(esdi_t)); /* Mark as unconfigured. */ dev->irq_status = 0xff; rom_init_interleaved(&dev->bios_rom, - BIOS_FILE_H, BIOS_FILE_L, - 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + BIOS_FILE_H, BIOS_FILE_L, + 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); mem_mapping_disable(&dev->bios_rom.mapping); dev->drives[0].present = dev->drives[1].present = 0; - for (c=0,i=0; idrives[hdd[i].esdi_channel]; + for (c = 0, i = 0; i < HDD_NUM; i++) { + if ((hdd[i].bus == HDD_BUS_ESDI) && (hdd[i].esdi_channel < ESDI_NUM)) { + /* This is an ESDI drive. */ + drive = &dev->drives[hdd[i].esdi_channel]; - /* Try to load an image for the drive. */ - if (! hdd_image_load(i)) { - /* Nope. */ - drive->present = 0; - continue; - } + /* Try to load an image for the drive. */ + if (!hdd_image_load(i)) { + /* Nope. */ + drive->present = 0; + continue; + } - /* OK, so fill in geometry info. */ - drive->spt = hdd[i].spt; - drive->hpc = hdd[i].hpc; - drive->tracks = hdd[i].tracks; - drive->sectors = hdd_image_get_last_sector(i) + 1; - drive->hdd_num = i; + hdd_preset_apply(i); - /* Mark drive as present. */ - drive->present = 1; - } + /* OK, so fill in geometry info. */ + drive->spt = hdd[i].spt; + drive->hpc = hdd[i].hpc; + drive->tracks = hdd[i].tracks; + drive->sectors = hdd_image_get_last_sector(i) + 1; + drive->hdd_num = i; - if (++c >= ESDI_NUM) break; + /* Mark drive as present. */ + drive->present = 1; + } + + if (++c >= ESDI_NUM) + break; } /* Set the MCA ID for this controller, 0xFFDD. */ @@ -1147,47 +1174,45 @@ esdi_init(const device_t *info) dev->status = STATUS_BUSY; /* Set the reply timer. */ - timer_add(&dev->timer, esdi_callback, dev, 0); + timer_add(&dev->timer, esdi_callback, dev, 0); - return(dev); + return (dev); } - static void esdi_close(void *priv) { - esdi_t *dev = (esdi_t *)priv; + esdi_t *dev = (esdi_t *) priv; drive_t *drive; - int d; + int d; dev->drives[0].present = dev->drives[1].present = 0; - for (d=0; d<2; d++) { - drive = &dev->drives[d]; + for (d = 0; d < 2; d++) { + drive = &dev->drives[d]; - hdd_image_close(drive->hdd_num); + hdd_image_close(drive->hdd_num); } free(dev); } - static int esdi_available(void) { - return(rom_present(BIOS_FILE_L) && rom_present(BIOS_FILE_H)); + return (rom_present(BIOS_FILE_L) && rom_present(BIOS_FILE_H)); } const device_t esdi_ps2_device = { - .name = "IBM PS/2 ESDI Fixed Disk Adapter (MCA)", + .name = "IBM PS/2 ESDI Fixed Disk Adapter (MCA)", .internal_name = "esdi_mca", - .flags = DEVICE_MCA, - .local = 0, - .init = esdi_init, - .close = esdi_close, - .reset = NULL, + .flags = DEVICE_MCA, + .local = 0, + .init = esdi_init, + .close = esdi_close, + .reset = NULL, { .available = esdi_available }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index 93a9fa0a1..ca7fbb99c 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -137,6 +137,7 @@ extern int fm_driver; /* (C) select FM sound driver */ extern char exe_path[2048]; /* path (dir) of executable */ extern char usr_path[1024]; /* path (dir) of user data */ extern char cfg_path[1024]; /* full path of config file */ +extern int open_dir_usr_path; /* default file open dialog directory of usr_path */ #ifndef USE_NEW_DYNAREC extern FILE *stdlog; /* file to log output to */ #endif diff --git a/src/include/86box/device.h b/src/include/86box/device.h index 47f9b2448..948c4b03b 100644 --- a/src/include/86box/device.h +++ b/src/include/86box/device.h @@ -54,7 +54,6 @@ #define CONFIG_BIOS 11 enum { - DEVICE_NOT_WORKING = 1, /* does not currently work correctly and will be disabled in a release build */ DEVICE_PCJR = 2, /* requires an IBM PCjr */ DEVICE_AT = 4, /* requires an AT-compatible system */ DEVICE_PS2 = 8, /* requires a PS/1 or PS/2 system */ @@ -70,6 +69,17 @@ enum { DEVICE_LPT = 0x2000 /* requires a parallel port */ }; + +#define BIOS_NORMAL 0 +#define BIOS_INTERLEAVED 1 +#define BIOS_INTERLEAVED_SINGLEFILE 2 +#define BIOS_INTERLEAVED_QUAD 3 +#define BIOS_INTERLEAVED_QUAD_SINGLEFILE 4 +#define BIOS_INTEL_AMI 5 +#define BIOS_INTERLEAVED_INVERT 8 +#define BIOS_HIGH_BIT_INVERT 16 + + typedef struct { const char *description; int value; @@ -80,6 +90,8 @@ typedef struct { const char *internal_name; int bios_type; int files_no; + uint32_t local, size; + void *dev1, *dev2; const char **files; } device_config_bios_t; diff --git a/src/include_make/86box/version.h b/src/include_make/86box/version.h index 63e675c1e..4c7bca1bd 100644 --- a/src/include_make/86box/version.h +++ b/src/include_make/86box/version.h @@ -20,11 +20,11 @@ #define EMU_NAME "86Box" #define EMU_NAME_W LSTR(EMU_NAME) -#define EMU_VERSION "3.6" +#define EMU_VERSION "3.7" #define EMU_VERSION_W LSTR(EMU_VERSION) #define EMU_VERSION_EX "3.50" /* frozen due to IDE re-detection behavior on Windows */ #define EMU_VERSION_MAJ 3 -#define EMU_VERSION_MIN 6 +#define EMU_VERSION_MIN 7 #define EMU_VERSION_PATCH 0 #define EMU_BUILD_NUM 0 @@ -40,7 +40,7 @@ #define EMU_ROMS_URL "https://github.com/86Box/roms/releases/latest" #define EMU_ROMS_URL_W LSTR(EMU_ROMS_URL) #ifdef RELEASE_BUILD -# define EMU_DOCS_URL "https://86box.readthedocs.io/en/v3.6/" +# define EMU_DOCS_URL "https://86box.readthedocs.io/en/v3.7/" #else # define EMU_DOCS_URL "https://86box.readthedocs.io" #endif diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 6a2624fec..07034c805 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -440,6 +440,40 @@ const machine_t machines[] = { .device = NULL, .vid_device = NULL }, + { + .name = "[8088] Bondwell BW230", + .internal_name = "bw230", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_bw230_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_8088, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 64, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .kbc = KBC_IBM_PC_XT, + .kbc_p1 = 0xff00, + .gpio = 0xffffffff, + .device = NULL, + .vid_device = NULL + }, { .name = "[8088] Columbia Data Products MPC-1600", .internal_name = "mpc1600", @@ -610,6 +644,108 @@ const machine_t machines[] = { .device = NULL, .vid_device = NULL }, + { + .name = "[8088] Hyosung Topstar 88T", + .internal_name = "top88", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_top88_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_8088, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 128, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .kbc = KBC_IBM_PC_XT, + .kbc_p1 = 0xff00, + .gpio = 0xffffffff, + .device = NULL, + .vid_device = NULL + }, + { + .name = "[8088] Hyundai SUPER-16T", + .internal_name = "super16t", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_super16t_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_8088, + .block = CPU_BLOCK_NONE, + .min_bus = 4772728, + .max_bus = 7159092, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 128, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .kbc = KBC_IBM_PC_XT, + .kbc_p1 = 0xff00, + .gpio = 0xffffffff, + .device = NULL, + .vid_device = NULL + }, + { + .name = "[8088] Hyundai SUPER-16TE", + .internal_name = "super16te", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_super16te_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_8088, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 10000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 128, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .kbc = KBC_IBM_PC_XT, + .kbc_p1 = 0xff00, + .gpio = 0xffffffff, + .device = NULL, + .vid_device = NULL + }, { .name = "[8088] Juko ST", .internal_name = "jukopc", @@ -916,6 +1052,40 @@ const machine_t machines[] = { .device = NULL, .vid_device = NULL }, + { + .name = "[8088] Sanyo SX-16", + .internal_name = "sansx16", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_sansx16_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_8088, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + MACHINE_FLAGS_NONE, + .ram = { + .min = 256, + .max = 640, + .step = 256 + }, + .nvrmask = 0, + .kbc = KBC_IBM_PC_XT, + .kbc_p1 = 0xff00, + .gpio = 0xffffffff, + .device = NULL, + .vid_device = NULL + }, { .name = "[8088] Schneider EuroPC", .internal_name = "europc", diff --git a/src/nvr_at.c b/src/nvr_at.c index fc5ae4bde..bb4c38b85 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -1050,7 +1050,9 @@ nvr_at_init(const device_t *info) if (info->local == 12) { local->def = 0x00; local->flags |= FLAG_AMI_1992_HACK; - } else + } else if (info->local == 20) + local->def = 0x00; + else local->def = 0xff; nvr->irq = 8; local->cent = RTC_CENTURY_AT; @@ -1297,3 +1299,17 @@ const device_t p6rp4_nvr_device = { .force_redraw = NULL, .config = NULL }; + +const device_t amstrad_megapc_nvr_device = { + .name = "Amstrad MegapC NVRAM", + .internal_name = "amstrad_megapc_nvr", + .flags = DEVICE_ISA | DEVICE_AT, + .local = 20, + .init = nvr_at_init, + .close = nvr_at_close, + .reset = nvr_at_reset, + { .available = NULL }, + .speed_changed = nvr_at_speed_changed, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/pic.c b/src/pic.c index fe6b29fc8..12fd80264 100644 --- a/src/pic.c +++ b/src/pic.c @@ -436,6 +436,7 @@ pic_read(uint16_t addr, void *priv) dev->data_bus = dev->irr; #endif if (dev->ocw3 & 0x04) { + dev->interrupt &= ~0x20; /* Freeze the interrupt until the poll is over. */ if (dev->int_pending) { dev->data_bus = 0x80 | (dev->interrupt & 7); pic_acknowledge(dev); @@ -516,6 +517,8 @@ pic_write(uint16_t addr, uint8_t val, void *priv) update_pending(); } else if (val & 0x08) { dev->ocw3 = val; + if (dev->ocw3 & 0x04) + dev->interrupt |= 0x20; /* Freeze the interrupt until the poll is over. */ if (dev->ocw3 & 0x40) dev->special_mask_mode = !!(dev->ocw3 & 0x20); } else { @@ -721,10 +724,25 @@ pic_irq_ack(void) { int ret; + /* Needed for Xi8088. */ + if ((pic.ack_bytes == 0) && pic.int_pending && pic_slave_on(&pic, pic.interrupt)) { + if (!pic.slaves[pic.interrupt]->int_pending) { + /* If we are on AT, IRQ 2 is pending, and we cannot find a pending IRQ on PIC 2, fatal out. */ + fatal("IRQ %i pending on AT without a pending IRQ on PIC %i (normal)\n", pic.interrupt, pic.interrupt); + exit(-1); + return -1; + } + + pic.interrupt |= 0x40; /* Mark slave pending. */ + } + ret = pic_irq_ack_read(&pic, pic.ack_bytes); pic.ack_bytes = (pic.ack_bytes + 1) % (pic_i86_mode(&pic) ? 2 : 3); if (pic.ack_bytes == 0) { + /* Needed for Xi8088. */ + if (pic.interrupt & 0x40) + pic2.interrupt = 0x17; pic.interrupt = 0x17; update_pending(); } diff --git a/src/qt/qt_d3d9renderer.cpp b/src/qt/qt_d3d9renderer.cpp index cb2d0a25a..e7ef16f77 100644 --- a/src/qt/qt_d3d9renderer.cpp +++ b/src/qt/qt_d3d9renderer.cpp @@ -1,3 +1,4 @@ +#include "qt_mainwindow.hpp" #include "qt_d3d9renderer.hpp" #include #include @@ -139,7 +140,7 @@ void D3D9Renderer::resizeEvent(QResizeEvent *event) void D3D9Renderer::blit(int x, int y, int w, int h) { - if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || surfaceInUse) { + if (blitDummied || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || surfaceInUse) { video_blit_complete_monitor(m_monitor_index); return; } diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index c30304eb8..a74958511 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -289,6 +289,7 @@ int main(int argc, char* argv[]) { cpu_thread_run = 0; main_thread->join(); pc_close(nullptr); + endblit(); socket.close(); return ret; diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 7da72e569..ebccbe0cb 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -123,6 +123,8 @@ filter_result keyb_filter(BMessage *message, BHandler **target, BMessageFilter * static BMessageFilter* filter; #endif +std::atomic blitDummied{false}; + extern void qt_mouse_capture(int); extern "C" void qt_blit(int x, int y, int w, int h, int monitor_index); @@ -648,6 +650,11 @@ MainWindow::~MainWindow() { void MainWindow::showEvent(QShowEvent *event) { if (shownonce) return; shownonce = true; + if (window_remember) { + if (window_w == 0) window_w = 320; + if (window_h == 0) window_h = 200; + } + if (window_remember && !QApplication::platformName().contains("wayland")) { setGeometry(window_x, window_y, window_w, window_h + menuBar()->height() + (hide_status_bar ? 0 : statusBar()->height()) + (hide_tool_bar ? 0 : ui->toolBar->height())); } @@ -1474,7 +1481,7 @@ void MainWindow::on_actionFullscreen_triggered() { questionbox.exec(); config_save(); - /* (re-capture mouse after dialog. */ + /* (re-capture mouse after dialog). */ if (wasCaptured) emit setMouseCapture(true); } @@ -1594,7 +1601,7 @@ void MainWindow::keyPressEvent(QKeyEvent* event) void MainWindow::blitToWidget(int x, int y, int w, int h, int monitor_index) { if (monitor_index >= 1) { - if (renderers[monitor_index]) renderers[monitor_index]->blit(x, y, w, h); + if (!blitDummied && renderers[monitor_index] && renderers[monitor_index]->isVisible()) renderers[monitor_index]->blit(x, y, w, h); else video_blit_complete_monitor(monitor_index); } else ui->stackedWidget->blit(x, y, w, h); @@ -1915,6 +1922,8 @@ void MainWindow::on_actionHiDPI_scaling_triggered() void MainWindow::on_actionHide_status_bar_triggered() { + auto w = ui->stackedWidget->width(); + auto h = ui->stackedWidget->height(); hide_status_bar ^= 1; ui->actionHide_status_bar->setChecked(hide_status_bar); statusBar()->setVisible(!hide_status_bar); @@ -1926,13 +1935,16 @@ void MainWindow::on_actionHide_status_bar_triggered() } else { int vid_resize_orig = vid_resize; vid_resize = 0; - emit resizeContents(monitors[0].mon_scrnsz_x, monitors[0].mon_scrnsz_y); + emit resizeContents(w, h); vid_resize = vid_resize_orig; + if (vid_resize == 1) setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); } } void MainWindow::on_actionHide_tool_bar_triggered() { + auto w = ui->stackedWidget->width(); + auto h = ui->stackedWidget->height(); hide_tool_bar ^= 1; ui->actionHide_tool_bar->setChecked(hide_tool_bar); ui->toolBar->setVisible(!hide_tool_bar); @@ -1944,8 +1956,9 @@ void MainWindow::on_actionHide_tool_bar_triggered() } else { int vid_resize_orig = vid_resize; vid_resize = 0; - emit resizeContents(monitors[0].mon_scrnsz_x, monitors[0].mon_scrnsz_y); + emit resizeContents(w, h); vid_resize = vid_resize_orig; + if (vid_resize == 1) setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); } } @@ -2047,6 +2060,8 @@ void MainWindow::on_actionShow_non_primary_monitors_triggered() { show_second_monitors ^= 1; + blitDummied = true; + if (show_second_monitors) { for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) { auto& secondaryRenderer = renderers[monitor_index]; @@ -2073,5 +2088,7 @@ void MainWindow::on_actionShow_non_primary_monitors_triggered() } } } + + blitDummied = false; } diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 49300e72b..a7d029bff 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -12,6 +12,8 @@ class MediaMenu; class RendererStack; +extern std::atomic blitDummied; + namespace Ui { class MainWindow; } diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index ebfe68bef..96fba3808 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -28,6 +28,7 @@ #include extern "C" { +#include <86box/86box.h> #include <86box/config.h> #include <86box/device.h> #include <86box/timer.h> @@ -173,7 +174,7 @@ void MediaMenu::cassetteNewImage() { void MediaMenu::cassetteSelectImage(bool wp) { auto filename = QFileDialog::getOpenFileName(parentWidget, QString(), - QString(), + getMediaOpenDirectory(), tr("Cassette images") % util::DlgFilter({ "pcm","raw","wav","cas" }) % tr("All files") % @@ -247,7 +248,7 @@ void MediaMenu::cartridgeSelectImage(int i) { auto filename = QFileDialog::getOpenFileName( parentWidget, QString(), - QString(), + getMediaOpenDirectory(), tr("Cartridge images") % util::DlgFilter({ "a","b","jrc" }) % tr("All files") % @@ -291,7 +292,7 @@ void MediaMenu::floppySelectImage(int i, bool wp) { auto filename = QFileDialog::getOpenFileName( parentWidget, QString(), - QString(), + getMediaOpenDirectory(), tr("All images") % util::DlgFilter({ "0??","1??","??0","86f","bin","cq?","d??","flp","hdm","im?","json","td0","*fd?","mfm","xdf" }) % tr("Advanced sector images") % @@ -400,7 +401,7 @@ void MediaMenu::cdromMount(int i) { auto filename = QFileDialog::getOpenFileName( parentWidget, QString(), - QString(), + getMediaOpenDirectory(), tr("CD-ROM images") % util::DlgFilter({ "iso","cue" }) % tr("All files") % @@ -571,7 +572,7 @@ void MediaMenu::moSelectImage(int i, bool wp) { auto filename = QFileDialog::getOpenFileName( parentWidget, QString(), - QString(), + getMediaOpenDirectory(), tr("MO images") % util::DlgFilter({ "im?", "mdi" }) % tr("All files") % @@ -656,6 +657,13 @@ void MediaMenu::moUpdateMenu(int i) { menu->setTitle(QString::asprintf(tr("MO %i (%ls): %ls").toUtf8().constData(), i + 1, busName.toStdU16String().data(), name.isEmpty() ? tr("(empty)").toStdU16String().data() : name.toStdU16String().data())); } +QString MediaMenu::getMediaOpenDirectory() { + QString openDirectory; + if (open_dir_usr_path > 0) { + openDirectory = QString::fromUtf8(usr_path); + } + return openDirectory; +} // callbacks from 86box C code extern "C" { diff --git a/src/qt/qt_mediamenu.hpp b/src/qt/qt_mediamenu.hpp index 3c45b2414..94f547d3f 100644 --- a/src/qt/qt_mediamenu.hpp +++ b/src/qt/qt_mediamenu.hpp @@ -66,6 +66,8 @@ private: QMap zipMenus; QMap moMenus; + QString getMediaOpenDirectory(); + int cassetteRecordPos; int cassettePlayPos; int cassetteRewindPos; diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index 7c7cd55fa..3a5f58846 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -26,6 +26,14 @@ #include "qt_opengloptionsdialog.hpp" #include "qt_openglrenderer.hpp" +#ifndef GL_MAP_PERSISTENT_BIT +#define GL_MAP_PERSISTENT_BIT 0x0040 +#endif + +#ifndef GL_MAP_COHERENT_BIT +#define GL_MAP_COHERENT_BIT 0x0080 +#endif + OpenGLRenderer::OpenGLRenderer(QWidget *parent) : QWindow(parent->windowHandle()) , renderTimer(new QTimer(this)) @@ -239,10 +247,12 @@ void OpenGLRenderer::initializeExtensions() { #ifndef NO_BUFFER_STORAGE - if (context->hasExtension("GL_ARB_buffer_storage")) { + if (context->hasExtension("GL_ARB_buffer_storage") || context->hasExtension("GL_EXT_buffer_storage")) { hasBufferStorage = true; - glBufferStorage = (PFNGLBUFFERSTORAGEPROC) context->getProcAddress("glBufferStorage"); + glBufferStorage = (PFNGLBUFFERSTORAGEEXTPROC_LOCAL) context->getProcAddress(context->hasExtension("GL_EXT_buffer_storage") ? "glBufferStorageEXT" : "glBufferStorage"); + if (!glBufferStorage) + glBufferStorage = glBufferStorage = (PFNGLBUFFERSTORAGEEXTPROC_LOCAL) context->getProcAddress("glBufferStorage"); } #endif } diff --git a/src/qt/qt_openglrenderer.hpp b/src/qt/qt_openglrenderer.hpp index a27e0fe21..da64ea79b 100644 --- a/src/qt/qt_openglrenderer.hpp +++ b/src/qt/qt_openglrenderer.hpp @@ -39,6 +39,8 @@ #include "qt_opengloptions.hpp" #include "qt_renderercommon.hpp" +typedef void (QOPENGLF_APIENTRYP PFNGLBUFFERSTORAGEEXTPROC_LOCAL) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); + class OpenGLRenderer : public QWindow, protected QOpenGLExtraFunctions, public RendererCommon { Q_OBJECT @@ -103,7 +105,7 @@ private: /* GL_ARB_buffer_storage */ bool hasBufferStorage = false; #ifndef NO_BUFFER_STORAGE - PFNGLBUFFERSTORAGEPROC glBufferStorage = nullptr; + PFNGLBUFFERSTORAGEEXTPROC_LOCAL glBufferStorage = nullptr; #endif private slots: diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index d1f5318ba..527b4e2ab 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -54,7 +54,6 @@ QElapsedTimer elapsed_timer; static std::atomic_int blitmx_contention = 0; static std::recursive_mutex blitmx; -static thread_local std::unique_lock blit_lock { blitmx, std::defer_lock }; class CharPointer { public: @@ -469,17 +468,17 @@ void dynld_close(void *handle) void startblit() { blitmx_contention++; - if (blit_lock.try_lock()) { + if (blitmx.try_lock()) { return; } - blit_lock.lock(); + blitmx.lock(); } void endblit() { blitmx_contention--; - blit_lock.unlock(); + blitmx.unlock(); if (blitmx_contention > 0) { // a deadlock has been observed on linux when toggling via video_toggle_option // because the mutex is typically unfair on linux diff --git a/src/qt/qt_progsettings.cpp b/src/qt/qt_progsettings.cpp index b11466c08..0b4f0e955 100644 --- a/src/qt/qt_progsettings.cpp +++ b/src/qt/qt_progsettings.cpp @@ -113,12 +113,14 @@ ProgSettings::ProgSettings(QWidget *parent) : mouseSensitivity = mouse_sensitivity; ui->horizontalSlider->setValue(mouseSensitivity * 100.); + ui->openDirUsrPath->setChecked(open_dir_usr_path > 0); } void ProgSettings::accept() { strcpy(icon_set, ui->comboBox->currentData().toString().toUtf8().data()); lang_id = ui->comboBoxLanguage->currentData().toUInt(); + open_dir_usr_path = ui->openDirUsrPath->isChecked() ? 1 : 0; loadTranslators(QCoreApplication::instance()); reloadStrings(); diff --git a/src/qt/qt_progsettings.ui b/src/qt/qt_progsettings.ui index 11bb39b74..05775489f 100644 --- a/src/qt/qt_progsettings.ui +++ b/src/qt/qt_progsettings.ui @@ -7,7 +7,7 @@ 0 0 458 - 303 + 374 @@ -29,24 +29,14 @@ QLayout::SetFixedSize - - - - Qt::Horizontal + + + + false - - - 40 - 20 - - - - - - - (System Default) + (Default) @@ -58,30 +48,6 @@ - - - - Default - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - Default - - - @@ -89,8 +55,8 @@ - - + + Default @@ -109,25 +75,15 @@ - - - - Language: - - - - - + + Qt::Horizontal - - - 40 - 20 - + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok - + @@ -151,18 +107,72 @@ - - - - false - + + - (Default) + (System Default) + + + + Language: + + + + + + + Default + + + + + + + Default + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + <html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html> + + + Select media images from program working directory + + + diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index ef415a82c..7a802e898 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -257,7 +257,7 @@ RendererStack::switchRenderer(Renderer renderer) createRenderer(renderer); disconnect(this, &RendererStack::blit, this, &RendererStack::blitDummy); blitDummied = false; - QTimer::singleShot(1000, this, [this]() { this->blitDummied = false; } ); + QTimer::singleShot(1000, this, [this]() { blitDummied = false; } ); }); rendererWindow->hasBlitFunc() ? current.reset() : current.release()->deleteLater(); @@ -435,7 +435,7 @@ RendererStack::blitRenderer(int x, int y, int w, int h) void RendererStack::blitCommon(int x, int y, int w, int h) { - if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || imagebufs.empty() || std::get(imagebufs[currentBuf])->test_and_set() || blitDummied) { + if (blitDummied || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || imagebufs.empty() || std::get(imagebufs[currentBuf])->test_and_set()) { video_blit_complete_monitor(m_monitor_index); return; } diff --git a/src/qt/qt_rendererstack.hpp b/src/qt/qt_rendererstack.hpp index 6ee1a0433..75cabec49 100644 --- a/src/qt/qt_rendererstack.hpp +++ b/src/qt/qt_rendererstack.hpp @@ -103,7 +103,7 @@ private: RendererCommon *rendererWindow { nullptr }; std::unique_ptr current; - std::atomic directBlitting{false}, blitDummied{false}; + std::atomic directBlitting{false}; }; #endif // QT_RENDERERCONTAINER_HPP diff --git a/src/qt/qt_settingsstoragecontrollers.cpp b/src/qt/qt_settingsstoragecontrollers.cpp index 114654340..7664fdd5f 100644 --- a/src/qt/qt_settingsstoragecontrollers.cpp +++ b/src/qt/qt_settingsstoragecontrollers.cpp @@ -161,6 +161,8 @@ void SettingsStorageControllers::onCurrentMachineChanged(int machineId) { int is_at = IS_AT(machineId); ui->checkBoxTertiaryIDE->setEnabled(is_at > 0); ui->checkBoxQuaternaryIDE->setEnabled(is_at > 0); + ui->checkBoxTertiaryIDE->setChecked(ui->checkBoxTertiaryIDE->isEnabled() && ide_ter_enabled); + ui->checkBoxQuaternaryIDE->setChecked(ui->checkBoxQuaternaryIDE->isEnabled() && ide_qua_enabled); } void SettingsStorageControllers::on_comboBoxHD_currentIndexChanged(int index) { diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 1662598c9..0dd35c049 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -745,7 +745,7 @@ pas16_close(void *p) const device_t pas16_device = { .name = "Pro Audio Spectrum 16", .internal_name = "pas16", - .flags = DEVICE_ISA | DEVICE_NOT_WORKING, + .flags = DEVICE_ISA, .local = 0, .init = pas16_init, .close = pas16_close, diff --git a/src/unix/assets/86Box.spec b/src/unix/assets/86Box.spec index 55df4b7d9..f0b15a45a 100644 --- a/src/unix/assets/86Box.spec +++ b/src/unix/assets/86Box.spec @@ -12,10 +12,10 @@ # After a successful build, you can install the RPMs as follows: # sudo dnf install RPMS/$(uname -m)/86Box-3* RPMS/noarch/86Box-roms* -%global romver 20220701 +%global romver 20220730 Name: 86Box -Version: 3.6 +Version: 3.7 Release: 1%{?dist} Summary: Classic PC emulator License: GPLv2+ @@ -100,9 +100,6 @@ appstream-util validate-relax --nonet %{buildroot}%{_metainfodir}/net.86box.86Bo pushd roms-%{romver} mkdir -p %{buildroot}%{_datadir}/%{name}/roms cp -a * %{buildroot}%{_datadir}/%{name}/roms/ - # hack to create symlink in /usr/bin - cd %{buildroot}%{_bindir} - ln -s ../share/%{name}/roms roms popd # files part of the main package @@ -117,8 +114,7 @@ popd %files roms %license roms-%{romver}/LICENSE %{_datadir}/%{name}/roms -%{_bindir}/roms %changelog -* Fri Jul 01 2022 Robert de Rooy 3.6-1 +* Sat Jul 30 2022 Robert de Rooy 3.7-1 - Bump release diff --git a/src/unix/assets/net.86box.86Box.metainfo.xml b/src/unix/assets/net.86box.86Box.metainfo.xml index 982ae9b4d..d024b0a1e 100644 --- a/src/unix/assets/net.86box.86Box.metainfo.xml +++ b/src/unix/assets/net.86box.86Box.metainfo.xml @@ -10,7 +10,7 @@ net.86box.86Box.desktop - + diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 7cded795e..cea6ee807 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -51,7 +51,8 @@ #define BIOS_GD5428_ISA_PATH "roms/video/cirruslogic/5428.bin" #define BIOS_GD5428_MCA_PATH "roms/video/cirruslogic/SVGA141.ROM" #define BIOS_GD5428_PATH "roms/video/cirruslogic/vlbusjapan.BIN" -#define BIOS_GD5428_BOCA_ISA_PATH "roms/video/cirruslogic/boca_gd5428_1.30b.bin" +#define BIOS_GD5428_BOCA_ISA_PATH_1 "roms/video/cirruslogic/boca_gd5428_1.30b_1.bin" +#define BIOS_GD5428_BOCA_ISA_PATH_2 "roms/video/cirruslogic/boca_gd5428_1.30b_2.bin" #define BIOS_GD5429_PATH "roms/video/cirruslogic/5429.vbi" #define BIOS_GD5430_DIAMOND_A8_VLB_PATH "roms/video/cirruslogic/diamondvlbus.bin" #define BIOS_GD5430_ORCHID_VLB_PATH "roms/video/cirruslogic/orchidvlbus.bin" @@ -3863,6 +3864,7 @@ static void int id = info->local & 0xff; int vram; char *romfn = NULL; + char *romfn1 = NULL, *romfn2 = NULL; memset(gd54xx, 0, sizeof(gd54xx_t)); gd54xx->pci = !!(info->flags & DEVICE_PCI); @@ -3917,8 +3919,10 @@ static void if (info->local & 0x100) if (gd54xx->vlb) romfn = BIOS_GD5428_DIAMOND_B1_VLB_PATH; - else - romfn = BIOS_GD5428_BOCA_ISA_PATH; + else { + romfn1 = BIOS_GD5428_BOCA_ISA_PATH_1; + romfn2 = BIOS_GD5428_BOCA_ISA_PATH_2; + } else { if (gd54xx->vlb) romfn = BIOS_GD5428_PATH; @@ -4016,7 +4020,10 @@ static void gd54xx->vram_mask = gd54xx->vram_size - 1; if (romfn) - rom_init(&gd54xx->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&gd54xx->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + else if (romfn1 && romfn2) + rom_init_interleaved(&gd54xx->bios_rom, BIOS_GD5428_BOCA_ISA_PATH_1, BIOS_GD5428_BOCA_ISA_PATH_2, 0xc0000, + 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (info->flags & DEVICE_ISA) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_gd54xx_isa); @@ -4193,7 +4200,7 @@ gd5428_diamond_b1_available(void) static int gd5428_boca_isa_available(void) { - return rom_present(BIOS_GD5428_BOCA_ISA_PATH); + return rom_present(BIOS_GD5428_BOCA_ISA_PATH_1) && rom_present(BIOS_GD5428_BOCA_ISA_PATH_2); } static int diff --git a/src/video/vid_voodoo_fifo.c b/src/video/vid_voodoo_fifo.c index 013c21db3..87260ce54 100644 --- a/src/video/vid_voodoo_fifo.c +++ b/src/video/vid_voodoo_fifo.c @@ -494,6 +494,7 @@ void voodoo_fifo_thread(void *param) switch (header >> 30) { case 0: /*Linear framebuffer (Banshee)*/ + case 1: /*Planar YUV*/ if (voodoo->texture_present[0][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) { // voodoo_fifo_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); diff --git a/vcpkg.json b/vcpkg.json index f3b639078..2f70e4456 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,6 +1,6 @@ { "name": "86box", - "version-string": "3.6", + "version-string": "3.7", "homepage": "https://86box.net/", "documentation": "http://86box.readthedocs.io/", "license": "GPL-2.0-or-later",