From 94c84b299d6b9c58b01bfd07b2d9f6a2be4f04d6 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 30 Jul 2022 14:38:02 +0600 Subject: [PATCH 01/34] qt: Fix hide toggles on resizable main window --- src/qt/qt_mainwindow.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 7da72e569..017e19ee3 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -1474,7 +1474,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); } @@ -1915,6 +1915,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 +1928,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 +1949,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); } } From 313b2ab8523beabea87229505ec1abab61c04dbe Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 30 Jul 2022 14:38:44 +0600 Subject: [PATCH 02/34] qt: Properly display tertiary/quarternary IDE toggle in Settings --- src/qt/qt_settingsstoragecontrollers.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/qt/qt_settingsstoragecontrollers.cpp b/src/qt/qt_settingsstoragecontrollers.cpp index 114654340..54016ad24 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_ter_enabled); } void SettingsStorageControllers::on_comboBoxHD_currentIndexChanged(int index) { From e6cfdf4f6991d4d36d3d2e29ae4cdbb9173cc7d6 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 30 Jul 2022 14:42:23 +0600 Subject: [PATCH 03/34] config: Save and load cassette toggle properly --- src/config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.c b/src/config.c index 8d488936e..84645fa4f 100644 --- a/src/config.c +++ b/src/config.c @@ -2767,7 +2767,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); From 180682aa363f536e9f2f332ce046868640784268 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 30 Jul 2022 15:46:44 +0600 Subject: [PATCH 04/34] Fix mislabled variable reference Co-authored-by: Alexander Babikov <2708460+lemondrops@users.noreply.github.com> --- src/qt/qt_settingsstoragecontrollers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_settingsstoragecontrollers.cpp b/src/qt/qt_settingsstoragecontrollers.cpp index 54016ad24..7664fdd5f 100644 --- a/src/qt/qt_settingsstoragecontrollers.cpp +++ b/src/qt/qt_settingsstoragecontrollers.cpp @@ -162,7 +162,7 @@ void SettingsStorageControllers::onCurrentMachineChanged(int 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_ter_enabled); + ui->checkBoxQuaternaryIDE->setChecked(ui->checkBoxQuaternaryIDE->isEnabled() && ide_qua_enabled); } void SettingsStorageControllers::on_comboBoxHD_currentIndexChanged(int index) { From 7aec47583d12246f140371c30cb8f4f9c34737ac Mon Sep 17 00:00:00 2001 From: Adrien Moulin Date: Sat, 30 Jul 2022 17:14:03 +0200 Subject: [PATCH 05/34] ESDI MCA: implement HDD timings and fix status icon updating (#2538) * esdi_mca: clang-format * esdi_mca: implement hdd timings * esdi_mca: fix drive status icon updating --- src/disk/hdc_esdi_mca.c | 1597 ++++++++++++++++++++------------------- 1 file changed, 811 insertions(+), 786 deletions(-) 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 }; From ef213a80dd9e38cd8eddf3e447f17c0a81353bde Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 30 Jul 2022 14:09:38 -0400 Subject: [PATCH 06/34] Re-add other machines which went missing from the machine table --- src/machine/machine_table.c | 170 ++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) 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", From 2dab754b4cea00e2987b90e3b119fd452e8fc138 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 30 Jul 2022 14:54:16 -0400 Subject: [PATCH 07/34] Possibly fix some issues in Voodoo --- src/video/vid_voodoo_fifo.c | 1 + 1 file changed, 1 insertion(+) 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); From 9f15ffd4e9845a295a67898929a4c37644139fce Mon Sep 17 00:00:00 2001 From: cold-brewed Date: Sat, 30 Jul 2022 14:56:44 -0400 Subject: [PATCH 08/34] qt: Adds a global option in preferences to use usr_path as the default open directory for image file selection. --- src/86box.c | 1 + src/config.c | 7 ++ src/include/86box/86box.h | 1 + src/qt/qt_mediamenu.cpp | 18 +++-- src/qt/qt_mediamenu.hpp | 2 + src/qt/qt_progsettings.cpp | 2 + src/qt/qt_progsettings.ui | 136 ++++++++++++++++++++----------------- 7 files changed, 99 insertions(+), 68 deletions(-) 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..f518b35bc 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 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/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_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 + + + From 28dd2d386f706a4ad2aade2c97df5e821594b386 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 30 Jul 2022 16:47:19 -0300 Subject: [PATCH 09/34] Bump version to 3.7 --- CMakeLists.txt | 2 +- src/include_make/86box/version.h | 6 +++--- src/unix/assets/86Box.spec | 6 +++--- src/unix/assets/net.86box.86Box.metainfo.xml | 2 +- vcpkg.json | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) 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/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/unix/assets/86Box.spec b/src/unix/assets/86Box.spec index 55df4b7d9..a48acdee7 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+ @@ -120,5 +120,5 @@ popd %{_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/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", From fc48e5a284ce0e3befdfc56dced2d3b424dbf331 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 30 Jul 2022 21:55:41 +0200 Subject: [PATCH 10/34] Fixed the rom loading of the boca cirrus 5428 bios. --- src/video/vid_cl54xx.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) 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 From a5a419a8caaf459b2c07450c0087231aea1a98db Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 30 Jul 2022 23:36:12 +0200 Subject: [PATCH 11/34] The device config struct now has a local variable for local flags and points for up to two devices (neeeded for graphics cards and their RAMDAC's and clock chips). --- src/include/86box/device.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/include/86box/device.h b/src/include/86box/device.h index 47f9b2448..e1342eb74 100644 --- a/src/include/86box/device.h +++ b/src/include/86box/device.h @@ -80,6 +80,8 @@ typedef struct { const char *internal_name; int bios_type; int files_no; + uint32_t local; + const device_t *dev1, *dev2; const char **files; } device_config_bios_t; From 338fd9acdf3a5978371a8d6d66e28b740e243c3e Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 30 Jul 2022 23:42:41 +0200 Subject: [PATCH 12/34] BIOS type defines and size variable. --- src/include/86box/device.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/include/86box/device.h b/src/include/86box/device.h index e1342eb74..4b88442ae 100644 --- a/src/include/86box/device.h +++ b/src/include/86box/device.h @@ -70,6 +70,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,7 +91,7 @@ typedef struct { const char *internal_name; int bios_type; int files_no; - uint32_t local; + uint32_t local, size; const device_t *dev1, *dev2; const char **files; } device_config_bios_t; From f199ddcbcc14a0432b98181404fce45c9871d2b5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 30 Jul 2022 23:56:33 +0200 Subject: [PATCH 13/34] Changed the pointers to void pointers. --- src/include/86box/device.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/86box/device.h b/src/include/86box/device.h index 4b88442ae..25cf5c3f2 100644 --- a/src/include/86box/device.h +++ b/src/include/86box/device.h @@ -92,7 +92,7 @@ typedef struct { int bios_type; int files_no; uint32_t local, size; - const device_t *dev1, *dev2; + void *dev1, *dev2; const char **files; } device_config_bios_t; From 64c67f3cdee38c45f2e49430c43a25e6db48417d Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 31 Jul 2022 02:01:20 +0200 Subject: [PATCH 14/34] Fixed device_available(). --- src/device.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/device.c b/src/device.c index 331305f2d..1a4b1ca13 100644 --- a/src/device.c +++ b/src/device.c @@ -331,17 +331,19 @@ 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) { +#ifdef RELEASE_BUILD + if (d->flags & DEVICE_NOT_WORKING) + return(0); +#endif + 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 +364,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); } From 37bf41ec1713e121aca8848248c21cdbe0018e8c Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 31 Jul 2022 02:23:58 +0200 Subject: [PATCH 15/34] MegaPC NVR device. --- src/nvr_at.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) 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 +}; From acf66baaad8ab5e07938998206aebe4331307ddc Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 30 Jul 2022 21:12:01 -0400 Subject: [PATCH 16/34] Remove unnecessary DEVICE_NOT_WORKING --- src/device.c | 5 ----- src/include/86box/device.h | 1 - src/sound/snd_pas16.c | 2 +- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/device.c b/src/device.c index 1a4b1ca13..c69acaad0 100644 --- a/src/device.c +++ b/src/device.c @@ -337,11 +337,6 @@ device_available(const device_t *d) int i = 0; if (d != NULL) { -#ifdef RELEASE_BUILD - if (d->flags & DEVICE_NOT_WORKING) - return(0); -#endif - config = (device_config_t *) d->config; if (config != NULL) { while (config->type != -1) { diff --git a/src/include/86box/device.h b/src/include/86box/device.h index 25cf5c3f2..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 */ 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, From 69379b68b02e1074983dea371684ff3419778788 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 31 Jul 2022 04:45:26 +0200 Subject: [PATCH 17/34] Implemented PIC IRQ freeze on poll mode start. --- src/pic.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pic.c b/src/pic.c index fe6b29fc8..857f45cfc 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 { From d04f9b602f555e0ee3918e7cd661331854620a12 Mon Sep 17 00:00:00 2001 From: Robert de Rooy Date: Sun, 31 Jul 2022 15:07:27 +0200 Subject: [PATCH 18/34] Remove obsolete symlink hack --- src/unix/assets/86Box.spec | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/unix/assets/86Box.spec b/src/unix/assets/86Box.spec index a48acdee7..f0b15a45a 100644 --- a/src/unix/assets/86Box.spec +++ b/src/unix/assets/86Box.spec @@ -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,7 +114,6 @@ popd %files roms %license roms-%{romver}/LICENSE %{_datadir}/%{name}/roms -%{_bindir}/roms %changelog * Sat Jul 30 2022 Robert de Rooy 3.7-1 From 831835b884445e05e7643ed9fde401388e7e2251 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 1 Aug 2022 02:39:50 +0600 Subject: [PATCH 19/34] qt: fix hard freeze on hidden second windows --- src/qt/qt_mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 017e19ee3..745b62ec0 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -1594,7 +1594,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 (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); From 34d80ce170dd0cca96a247f7c3b6535cde00c624 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 1 Aug 2022 02:42:51 +0600 Subject: [PATCH 20/34] It's '->' --- src/qt/qt_mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 745b62ec0..efe1e8682 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -1594,7 +1594,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].isVisible()) renderers[monitor_index]->blit(x, y, w, h); + if (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); From 16f7460c737433f7cc3348af133295115abce76e Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 31 Jul 2022 23:31:59 +0200 Subject: [PATCH 21/34] Attempt at some QT fixes. --- src/qt/qt_d3d9renderer.cpp | 2 +- src/qt/qt_mainwindow.cpp | 8 ++++++++ src/qt/qt_rendererstack.cpp | 2 +- src/qt/qt_ui.cpp | 3 +++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_d3d9renderer.cpp b/src/qt/qt_d3d9renderer.cpp index cb2d0a25a..14357c12d 100644 --- a/src/qt/qt_d3d9renderer.cpp +++ b/src/qt/qt_d3d9renderer.cpp @@ -139,7 +139,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_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index efe1e8682..d4bb122c3 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -1594,7 +1594,11 @@ void MainWindow::keyPressEvent(QKeyEvent* event) void MainWindow::blitToWidget(int x, int y, int w, int h, int monitor_index) { if (monitor_index >= 1) { +#ifdef STRICTER_CHECK if (renderers[monitor_index] && renderers[monitor_index]->isVisible()) renderers[monitor_index]->blit(x, y, w, h); +#else + if (renderers[monitor_index]) renderers[monitor_index]->blit(x, y, w, h); +#endif else video_blit_complete_monitor(monitor_index); } else ui->stackedWidget->blit(x, y, w, h); @@ -2053,6 +2057,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]; @@ -2079,5 +2085,7 @@ void MainWindow::on_actionShow_non_primary_monitors_triggered() } } } + + blitDummied = false; } diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index ef415a82c..a5955dbe9 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -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_ui.cpp b/src/qt/qt_ui.cpp index 7400a4f7a..b7f2cffaf 100644 --- a/src/qt/qt_ui.cpp +++ b/src/qt/qt_ui.cpp @@ -73,6 +73,9 @@ wchar_t* ui_window_title(wchar_t* str) extern "C" void qt_blit(int x, int y, int w, int h, int monitor_index) { + if (blitDummied) + return; + main_window->blitToWidget(x, y, w, h, monitor_index); } From f3db64317cdc063b5b867ff298bf7efdb3c5ccad Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 31 Jul 2022 23:37:24 +0200 Subject: [PATCH 22/34] Attempted fix of the fix. --- src/qt/qt_mainwindow.cpp | 2 ++ src/qt/qt_mainwindow.hpp | 2 ++ src/qt/qt_rendererstack.hpp | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index d4bb122c3..a9d3ee216 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -103,6 +103,8 @@ namespace IOKit { extern MainWindow* main_window; +std::atomic blitDummied{false}; + filter_result keyb_filter(BMessage *message, BHandler **target, BMessageFilter *filter) { if (message->what == B_KEY_DOWN || message->what == B_KEY_UP diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 49300e72b..eeccc8fe2 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{false}; + namespace Ui { class MainWindow; } 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 From 14fa83402ed03c0ed53950961bbede59f61bdd78 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 31 Jul 2022 23:38:43 +0200 Subject: [PATCH 23/34] One last fix. --- src/qt/qt_rendererstack.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index a5955dbe9..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(); From 68992c0020012ddb1ff73110f37db895ad32d7f0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 31 Jul 2022 23:48:58 +0200 Subject: [PATCH 24/34] And another fix. --- src/qt/qt_d3d9renderer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qt/qt_d3d9renderer.cpp b/src/qt/qt_d3d9renderer.cpp index 14357c12d..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 From 1280cbd4a5bf361efa2719a23ac184a87f8c0628 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 31 Jul 2022 23:53:24 +0200 Subject: [PATCH 25/34] Attempted fix for the extern. --- src/qt/qt_mainwindow.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index eeccc8fe2..a7d029bff 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -12,7 +12,7 @@ class MediaMenu; class RendererStack; -extern std::atomic blitDummied{false}; +extern std::atomic blitDummied; namespace Ui { class MainWindow; From 42fade36d0cc766a9848c113f6713137928e4701 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 1 Aug 2022 00:02:28 +0200 Subject: [PATCH 26/34] Another fix attempt. --- src/qt/qt_mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index a9d3ee216..9e8d23912 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -103,7 +103,7 @@ namespace IOKit { extern MainWindow* main_window; -std::atomic blitDummied{false}; +std::atomic blitDummied = false; filter_result keyb_filter(BMessage *message, BHandler **target, BMessageFilter *filter) { From b69565d0ae072ac523f69f84dd9b4e22d22c5995 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 1 Aug 2022 00:28:15 +0200 Subject: [PATCH 27/34] And actually fixed compile now. --- src/qt/qt_mainwindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 9e8d23912..a7142463e 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -103,8 +103,6 @@ namespace IOKit { extern MainWindow* main_window; -std::atomic blitDummied = false; - filter_result keyb_filter(BMessage *message, BHandler **target, BMessageFilter *filter) { if (message->what == B_KEY_DOWN || message->what == B_KEY_UP @@ -125,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); From 93404cf291309fa47d0ed6dbccb2d8d84afd5a90 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 1 Aug 2022 00:40:31 +0200 Subject: [PATCH 28/34] Actually fixed the hang. --- src/qt/qt_mainwindow.cpp | 6 +----- src/qt/qt_ui.cpp | 3 --- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index a7142463e..144c55d2d 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -1596,11 +1596,7 @@ void MainWindow::keyPressEvent(QKeyEvent* event) void MainWindow::blitToWidget(int x, int y, int w, int h, int monitor_index) { if (monitor_index >= 1) { -#ifdef STRICTER_CHECK - if (renderers[monitor_index] && renderers[monitor_index]->isVisible()) renderers[monitor_index]->blit(x, y, w, h); -#else - if (renderers[monitor_index]) renderers[monitor_index]->blit(x, y, w, h); -#endif + 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); diff --git a/src/qt/qt_ui.cpp b/src/qt/qt_ui.cpp index b7f2cffaf..7400a4f7a 100644 --- a/src/qt/qt_ui.cpp +++ b/src/qt/qt_ui.cpp @@ -73,9 +73,6 @@ wchar_t* ui_window_title(wchar_t* str) extern "C" void qt_blit(int x, int y, int w, int h, int monitor_index) { - if (blitDummied) - return; - main_window->blitToWidget(x, y, w, h, monitor_index); } From dc38b7d950d71425c89eff81799de26724798d2a Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 1 Aug 2022 03:16:44 +0200 Subject: [PATCH 29/34] The PIC now correctly processes slave interrupts in XT mode as well, fixes PS/2 mouse on the Xi8088, fixes #2045. --- src/pic.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/pic.c b/src/pic.c index 857f45cfc..12fd80264 100644 --- a/src/pic.c +++ b/src/pic.c @@ -724,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(); } From 039b9e766259338c5070539f16d34ca8be2dc2db Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 1 Aug 2022 03:28:34 +0200 Subject: [PATCH 30/34] Non-PS/2 AMI keyboard controller again identifies as 'H' instead of 'F', fixes #2545 as the AOpen Vi15G absolutely demands a 'H' keyboard controller. --- src/device/keyboard_at.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 */ From 63513949189b501500961721b5186c90c9672df3 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 1 Aug 2022 12:45:38 +0600 Subject: [PATCH 31/34] qt: Fix compile on ARM64 with GLES2 headers --- src/qt/qt_openglrenderer.cpp | 14 ++++++++++++-- src/qt/qt_openglrenderer.hpp | 4 +++- 2 files changed, 15 insertions(+), 3 deletions(-) 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: From ac12ad224391cadb868c6402fd84e9321d8c4223 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 1 Aug 2022 13:26:07 +0600 Subject: [PATCH 32/34] Revert "Fix crash at exit due to a unreleased mutex." This reverts commit 80e547000673b1f8f9804a3cacbe5dc934077493. std::unique_lock is incapable of recursively locking a mutex, which is needed for multi-monitor setups. As a result it will crash/show undefined behaviour when switching renderers. Switch to instead calling endblit() after pc_close to avoid crashes; at this point the CPU thread is now terminated so the mutex no longer remains held by it. --- src/qt/qt_main.cpp | 1 + src/qt/qt_platform.cpp | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) 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_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 From 8b99f9f3604242555c071ad4fbb4834a6084dd5c Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 1 Aug 2022 17:36:46 +0600 Subject: [PATCH 33/34] qt: avoid zero-sized main window --- src/qt/qt_mainwindow.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 144c55d2d..63e876944 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -650,6 +650,11 @@ MainWindow::~MainWindow() { void MainWindow::showEvent(QShowEvent *event) { if (shownonce) return; shownonce = true; + if (window_remember) { + if (window_w < 320) window_w = 320; + if (window_h < 200) 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())); } From af316716199207c786e032eaafc67e5242da2908 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 1 Aug 2022 18:06:45 +0600 Subject: [PATCH 34/34] Update qt_mainwindow.cpp --- src/qt/qt_mainwindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 63e876944..ebccbe0cb 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -651,8 +651,8 @@ void MainWindow::showEvent(QShowEvent *event) { if (shownonce) return; shownonce = true; if (window_remember) { - if (window_w < 320) window_w = 320; - if (window_h < 200) window_h = 200; + if (window_w == 0) window_w = 320; + if (window_h == 0) window_h = 200; } if (window_remember && !QApplication::platformName().contains("wayland")) {