diff --git a/.ci/build.sh b/.ci/build.sh index 6d4d9697d..1b1e5825e 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -579,6 +579,7 @@ else arm32) arch_deb="armhf";; *) arch_deb="$arch";; esac + grep -q " bullseye " /etc/apt/sources.list || echo [!] WARNING: System not running the expected Debian version # Establish general dependencies. pkgs="cmake ninja-build pkg-config git wget p7zip-full extra-cmake-modules wayland-protocols tar gzip file appstream" diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index ae3f96de2..bde200b6b 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -313,6 +313,9 @@ jobs: new: on slug: -NDR ui: + - name: SDL GUI + qt: off + static: on - name: Qt GUI qt: on slug: -Qt @@ -406,6 +409,11 @@ jobs: new: on slug: -NDR ui: + - name: SDL GUI + qt: off + static: on + src-packages: >- + libsndfile - name: Qt GUI qt: on slug: -Qt diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 86467d657..5c23961d5 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -26,6 +26,7 @@ on: jobs: analyze-msys2: + name: "Analyze Windows MSYS2 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }})" runs-on: windows-2022 @@ -171,6 +172,8 @@ jobs: new: on slug: -NDR ui: + - name: SDL GUI + qt: off - name: Qt GUI qt: on slug: -Qt @@ -224,6 +227,7 @@ jobs: category: "/language:${{matrix.language}}" analyze-macos11: + name: "Analyze macOS 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)" runs-on: macos-11 @@ -254,6 +258,8 @@ jobs: new: on slug: -NDR ui: + - name: SDL GUI + qt: off - name: Qt GUI qt: on slug: -Qt diff --git a/cmake/flags-gcc-armv7.cmake b/cmake/flags-gcc-armv7.cmake index 828fb1a21..070e5e52a 100644 --- a/cmake/flags-gcc-armv7.cmake +++ b/cmake/flags-gcc-armv7.cmake @@ -14,7 +14,7 @@ # Copyright 2021 David Hrdlička. # -string(APPEND CMAKE_C_FLAGS_INIT " -march=armv7-a -mfloat-abi=hard") -string(APPEND CMAKE_CXX_FLAGS_INIT " -march=armv7-a -mfloat-abi=hard") +string(APPEND CMAKE_C_FLAGS_INIT " -march=armv7-a+fp -mfloat-abi=hard") +string(APPEND CMAKE_CXX_FLAGS_INIT " -march=armv7-a+fp -mfloat-abi=hard") include(${CMAKE_CURRENT_LIST_DIR}/flags-gcc.cmake) diff --git a/src/86box.c b/src/86box.c index ab1dc8881..b42a15656 100644 --- a/src/86box.c +++ b/src/86box.c @@ -1388,7 +1388,7 @@ pc_run(void) } if (title_update) { - mouse_msg_idx = ((mouse_type == MOUSE_TYPE_NONE) || (mouse_mode >= 1)) ? 2 : !!mouse_capture; + mouse_msg_idx = ((mouse_type == MOUSE_TYPE_NONE) || (mouse_input_mode >= 1)) ? 2 : !!mouse_capture; swprintf(temp, sizeof_w(temp), mouse_msg[mouse_msg_idx], fps); #ifdef __APPLE__ /* Needed due to modifying the UI on the non-main thread is a big no-no. */ diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 2a9ede6b0..ff8ca0b30 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -145,10 +145,8 @@ cdrom_interface_reset(void) cdrom_interface_current); /* If we have a valid controller, add its device. */ - if (!controllers[cdrom_interface_current].device) - return; - - device_add(controllers[cdrom_interface_current].device); + if ((cdrom_interface_current > 0) && controllers[cdrom_interface_current].device) + device_add(controllers[cdrom_interface_current].device); } const char * diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index ccdaf0c46..4d8dea3ce 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -197,8 +197,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) case 0x44: /* Set IRQ Line for Primary IDE if it's on native mode */ dev->pci_conf[addr] = val & 0xdf; soft_reset_pci = !!(val & 0x80); - sff_set_irq_level(dev->ide_controller[0], 0, !(val & 0x10)); - sff_set_irq_level(dev->ide_controller[1], 0, !(val & 0x10)); + pci_set_mirq_level(PCI_MIRQ2, !(val & 0x10)); ali1543_log("INTAJ = IRQ %i\n", ali1533_irq_routing[val & 0x0f]); pci_set_mirq_routing(PCI_MIRQ0, ali1533_irq_routing[val & 0x0f]); pci_set_mirq_routing(PCI_MIRQ2, ali1533_irq_routing[val & 0x0f]); @@ -418,8 +417,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) case 0x75: /* Set IRQ Line for Secondary IDE if it's on native mode */ dev->pci_conf[addr] = val & 0x1f; - sff_set_irq_level(dev->ide_controller[0], 1, !(val & 0x10)); - sff_set_irq_level(dev->ide_controller[1], 1, !(val & 0x10)); + pci_set_mirq_level(PCI_MIRQ3, !(val & 0x10)); ali1543_log("INTBJ = IRQ %i\n", ali1533_irq_routing[val & 0x0f]); pci_set_mirq_routing(PCI_MIRQ1, ali1533_irq_routing[val & 0x0f]); pci_set_mirq_routing(PCI_MIRQ3, ali1533_irq_routing[val & 0x0f]); @@ -503,34 +501,29 @@ ali5229_ide_irq_handler(ali1543_t *dev) if (dev->ide_conf[0x09] & (1 ^ bit)) { /* Primary IDE is native. */ ali1543_log("Primary IDE IRQ mode: Native, Native\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 4); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 4); + sff_set_irq_mode(dev->ide_controller[ctl], IRQ_MODE_ALI_ALADDIN); } else { /* Primary IDE is legacy. */ switch (dev->pci_conf[0x58] & 0x03) { case 0x00: /* SIRQI, SIRQII */ ali1543_log("Primary IDE IRQ mode: SIRQI, SIRQII\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 2); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 5); + sff_set_irq_mode(dev->ide_controller[ctl], ctl ? IRQ_MODE_MIRQ_1 : IRQ_MODE_MIRQ_0); break; case 0x01: /* IRQ14, IRQ15 */ ali1543_log("Primary IDE IRQ mode: IRQ14, IRQ15\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 0); + sff_set_irq_mode(dev->ide_controller[ctl], IRQ_MODE_LEGACY); break; case 0x02: /* IRQ14, SIRQII */ ali1543_log("Primary IDE IRQ mode: IRQ14, SIRQII\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 5); + sff_set_irq_mode(dev->ide_controller[ctl], ctl ? IRQ_MODE_MIRQ_1 : IRQ_MODE_LEGACY); break; case 0x03: /* IRQ14, SIRQI */ ali1543_log("Primary IDE IRQ mode: IRQ14, SIRQI\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 2); + sff_set_irq_mode(dev->ide_controller[ctl], ctl ? IRQ_MODE_MIRQ_0 : IRQ_MODE_LEGACY); break; default: @@ -543,34 +536,29 @@ ali5229_ide_irq_handler(ali1543_t *dev) if (dev->ide_conf[0x09] & (4 ^ bit)) { /* Secondary IDE is native. */ ali1543_log("Secondary IDE IRQ mode: Native, Native\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 4); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 4); + sff_set_irq_mode(dev->ide_controller[ctl], IRQ_MODE_ALI_ALADDIN); } else { /* Secondary IDE is legacy. */ switch (dev->pci_conf[0x58] & 0x03) { case 0x00: /* SIRQI, SIRQII */ ali1543_log("Secondary IDE IRQ mode: SIRQI, SIRQII\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 2); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 5); + sff_set_irq_mode(dev->ide_controller[ctl], ctl ? IRQ_MODE_MIRQ_1 : IRQ_MODE_MIRQ_0); break; case 0x01: /* IRQ14, IRQ15 */ ali1543_log("Secondary IDE IRQ mode: IRQ14, IRQ15\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 0); + sff_set_irq_mode(dev->ide_controller[ctl], IRQ_MODE_LEGACY); break; case 0x02: /* IRQ14, SIRQII */ ali1543_log("Secondary IDE IRQ mode: IRQ14, SIRQII\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 5); + sff_set_irq_mode(dev->ide_controller[ctl], ctl ? IRQ_MODE_MIRQ_1 : IRQ_MODE_LEGACY); break; case 0x03: /* IRQ14, SIRQI */ ali1543_log("Secondary IDE IRQ mode: IRQ14, SIRQI\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 2); + sff_set_irq_mode(dev->ide_controller[ctl], ctl ? IRQ_MODE_MIRQ_0 : IRQ_MODE_LEGACY); break; default: @@ -636,7 +624,6 @@ ali5229_ide_handler(ali1543_t *dev) ali1543_log("ali5229_ide_handler(): Enabling primary IDE...\n"); ide_pri_enable(); - sff_bus_master_handler(dev->ide_controller[0], dev->ide_conf[0x04] & 0x01, ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + (0 ^ ch)); ali1543_log("M5229 PRI: BASE %04x SIDE %04x\n", current_pri_base, current_pri_side); } @@ -650,13 +637,14 @@ ali5229_ide_handler(ali1543_t *dev) ali1543_log("ali5229_ide_handler(): Enabling secondary IDE...\n"); ide_sec_enable(); - sff_bus_master_handler(dev->ide_controller[1], dev->ide_conf[0x04] & 0x01, ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + (8 ^ ch)); ali1543_log("M5229 SEC: BASE %04x SIDE %04x\n", current_sec_base, current_sec_side); } - } else { - sff_bus_master_handler(dev->ide_controller[0], dev->ide_conf[0x04] & 0x01, (dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)); - sff_bus_master_handler(dev->ide_controller[1], dev->ide_conf[0x04] & 0x01, ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + 8); } + + sff_bus_master_handler(dev->ide_controller[0], dev->ide_conf[0x04] & 0x01, + ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + (0 ^ ch)); + sff_bus_master_handler(dev->ide_controller[1], dev->ide_conf[0x04] & 0x01, + ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + (8 ^ ch)); } static void @@ -722,8 +710,8 @@ ali5229_chip_reset(ali1543_t *dev) sff_set_slot(dev->ide_controller[0], dev->ide_slot); sff_set_slot(dev->ide_controller[1], dev->ide_slot); - sff_bus_master_reset(dev->ide_controller[0], (dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)); - sff_bus_master_reset(dev->ide_controller[1], ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + 8); + sff_bus_master_reset(dev->ide_controller[0]); + sff_bus_master_reset(dev->ide_controller[1]); ali5229_ide_handler(dev); } @@ -844,8 +832,8 @@ ali5229_write(int func, int addr, uint8_t val, void *priv) if (val & 0x80) ali5229_chip_reset(dev); else if (val & 0x40) { - sff_bus_master_reset(dev->ide_controller[0], (dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)); - sff_bus_master_reset(dev->ide_controller[1], ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + 8); + sff_bus_master_reset(dev->ide_controller[0]); + sff_bus_master_reset(dev->ide_controller[1]); } break; diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index eebe95f58..1e4158b94 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -1672,11 +1672,12 @@ i4x0_init(const device_t *info) regs[0x52] = 0xea; /* 512 kB burst cache, set to 0xaa for 256 kB */ regs[0x57] = 0x31; regs[0x59] = 0x0f; - regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; - dev->max_drb = 7; - dev->drb_unit = 1; - dev->drb_default = 0x02; - dev->write_drbs = spd_write_drbs_with_ext; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = + regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; + dev->max_drb = 7; + dev->drb_unit = 1; + dev->drb_default = 0x02; + dev->write_drbs = spd_write_drbs_with_ext; break; case INTEL_430FX: regs[0x02] = 0x2d; @@ -1705,11 +1706,12 @@ i4x0_init(const device_t *info) regs[0x57] |= 0x02; else if ((cpu_busspeed > 60000000) && (cpu_busspeed <= 66666667)) regs[0x57] |= 0x03; - regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; - regs[0x72] = 0x02; - dev->max_drb = 7; - dev->drb_unit = 4; - dev->drb_default = 0x02; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = + regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; + regs[0x72] = 0x02; + dev->max_drb = 7; + dev->drb_unit = 4; + dev->drb_default = 0x02; break; case INTEL_430VX: regs[0x02] = 0x30; @@ -1764,12 +1766,13 @@ i4x0_init(const device_t *info) regs[0x53] = 0x80; regs[0x57] = 0x01; regs[0x58] = 0x10; - regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; - regs[0x71] = 0x10; - regs[0x72] = 0x02; - dev->max_drb = 7; - dev->drb_unit = 8; - dev->drb_default = 0x02; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = + regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; + regs[0x71] = 0x10; + regs[0x72] = 0x02; + dev->max_drb = 7; + dev->drb_unit = 8; + dev->drb_default = 0x02; break; case INTEL_440LX: regs[0x02] = 0x80; @@ -1784,7 +1787,8 @@ i4x0_init(const device_t *info) regs[0x51] |= 0x00; regs[0x53] = 0x83; regs[0x57] = 0x01; - regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = + regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; regs[0x6c] = regs[0x6d] = regs[0x6e] = regs[0x6f] = 0x55; regs[0x72] = 0x02; regs[0xa0] = 0x02; @@ -1806,7 +1810,8 @@ i4x0_init(const device_t *info) regs[0x51] = 0x80; regs[0x53] = 0x83; regs[0x57] = 0x01; - regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = + regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; regs[0x6c] = regs[0x6d] = regs[0x6e] = regs[0x6f] = 0x55; regs[0x72] = 0x02; regs[0xa0] = 0x02; @@ -1834,19 +1839,20 @@ i4x0_init(const device_t *info) regs[0x51] |= 0x00; regs[0x57] = 0x28; /* 4 DIMMs, SDRAM */ regs[0x58] = 0x03; - regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; - regs[0x72] = 0x02; - regs[0x73] = 0x38; - regs[0x7b] = 0x38; - regs[0x90] = 0x80; - regs[0xa0] = (regs[0x7a] & 0x02) ? 0x00 : 0x02; - regs[0xa2] = (regs[0x7a] & 0x02) ? 0x00 : 0x10; - regs[0xa4] = 0x03; - regs[0xa5] = 0x02; - regs[0xa7] = 0x1f; - dev->max_drb = 7; - dev->drb_unit = 8; - dev->drb_default = 0x01; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = + regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; + regs[0x72] = 0x02; + regs[0x73] = 0x38; + regs[0x7b] = 0x38; + regs[0x90] = 0x80; + regs[0xa0] = (regs[0x7a] & 0x02) ? 0x00 : 0x02; + regs[0xa2] = (regs[0x7a] & 0x02) ? 0x00 : 0x10; + regs[0xa4] = 0x03; + regs[0xa5] = 0x02; + regs[0xa7] = 0x1f; + dev->max_drb = 7; + dev->drb_unit = 8; + dev->drb_default = 0x01; break; case INTEL_440GX: regs[0x7a] = (info->local >> 8) & 0xff; @@ -1857,19 +1863,20 @@ i4x0_init(const device_t *info) regs[0x10] = 0x08; regs[0x34] = (regs[0x7a] & 0x02) ? 0x00 : 0xa0; regs[0x57] = 0x28; - regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; - regs[0x72] = 0x02; - regs[0x73] = 0x38; - regs[0x7b] = 0x38; - regs[0x90] = 0x80; - regs[0xa0] = (regs[0x7a] & 0x02) ? 0x00 : 0x02; - regs[0xa2] = (regs[0x7a] & 0x02) ? 0x00 : 0x10; - regs[0xa4] = 0x03; - regs[0xa5] = 0x02; - regs[0xa7] = 0x1f; - dev->max_drb = 7; - dev->drb_unit = 8; - dev->drb_default = 0x01; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = + regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; + regs[0x72] = 0x02; + regs[0x73] = 0x38; + regs[0x7b] = 0x38; + regs[0x90] = 0x80; + regs[0xa0] = (regs[0x7a] & 0x02) ? 0x00 : 0x02; + regs[0xa2] = (regs[0x7a] & 0x02) ? 0x00 : 0x10; + regs[0xa4] = 0x03; + regs[0xa5] = 0x02; + regs[0xa7] = 0x1f; + dev->max_drb = 7; + dev->drb_unit = 8; + dev->drb_default = 0x01; break; default: break; @@ -1918,7 +1925,7 @@ i4x0_init(const device_t *info) if ((dev->type >= INTEL_440BX) && !(regs[0x7a] & 0x02)) { device_add((dev->type == INTEL_440GX) ? &i440gx_agp_device : &i440bx_agp_device); dev->agpgart = device_add(&agpgart_device); - } else if (dev->type >= INTEL_440LX) { + } else if ((dev->type == INTEL_440LX) || (dev->type == INTEL_440EX)) { device_add(&i440lx_agp_device); dev->agpgart = device_add(&agpgart_device); } @@ -2109,7 +2116,7 @@ const device_t i440bx_device = { }; const device_t i440bx_no_agp_device = { - .name = "Intel 82443BX", + .name = "Intel 82443BX (No AGP)", .internal_name = "i440bx_no_agp", .flags = DEVICE_PCI, .local = 0x8200 | INTEL_440BX, diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index f588910f5..53ed617d2 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -106,13 +106,13 @@ static void smsc_ide_irqs(piix_t *dev) { int irq_line = 3; - uint8_t irq_mode[2] = { 0, 0 }; + uint8_t irq_mode[2] = { IRQ_MODE_LEGACY, IRQ_MODE_LEGACY }; if (dev->regs[1][0x09] & 0x01) - irq_mode[0] = (dev->regs[0][0xe1] & 0x01) ? 3 : 1; + irq_mode[0] = (dev->regs[0][0xe1] & 0x01) ? IRQ_MODE_PCI_IRQ_LINE : IRQ_MODE_PCI_IRQ_PIN; if (dev->regs[1][0x09] & 0x04) - irq_mode[1] = (dev->regs[0][0xe1] & 0x01) ? 3 : 1; + irq_mode[1] = (dev->regs[0][0xe1] & 0x01) ? IRQ_MODE_PCI_IRQ_LINE : IRQ_MODE_PCI_IRQ_PIN; switch ((dev->regs[0][0xe1] >> 1) & 0x07) { case 0x00: @@ -144,12 +144,10 @@ smsc_ide_irqs(piix_t *dev) } sff_set_irq_line(dev->bm[0], irq_line); - sff_set_irq_mode(dev->bm[0], 0, irq_mode[0]); - sff_set_irq_mode(dev->bm[0], 1, irq_mode[1]); + sff_set_irq_mode(dev->bm[0], irq_mode[0]); sff_set_irq_line(dev->bm[1], irq_line); - sff_set_irq_mode(dev->bm[1], 0, irq_mode[0]); - sff_set_irq_mode(dev->bm[1], 1, irq_mode[1]); + sff_set_irq_mode(dev->bm[1], irq_mode[1]); } static void @@ -1213,23 +1211,19 @@ piix_reset_hard(piix_t *dev) { uint8_t *fregs; - uint16_t old_base = (dev->regs[1][0x20] & 0xf0) | (dev->regs[1][0x21] << 8); - - sff_bus_master_reset(dev->bm[0], old_base); - sff_bus_master_reset(dev->bm[1], old_base + 8); + sff_bus_master_reset(dev->bm[0]); + sff_bus_master_reset(dev->bm[1]); if (dev->type >= 4) { sff_set_slot(dev->bm[0], dev->pci_slot); sff_set_irq_pin(dev->bm[0], PCI_INTA); sff_set_irq_line(dev->bm[0], 14); - sff_set_irq_mode(dev->bm[0], 0, 0); - sff_set_irq_mode(dev->bm[0], 1, 0); + sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); sff_set_slot(dev->bm[1], dev->pci_slot); sff_set_irq_pin(dev->bm[1], PCI_INTA); sff_set_irq_line(dev->bm[1], 14); - sff_set_irq_mode(dev->bm[1], 0, 0); - sff_set_irq_mode(dev->bm[1], 1, 0); + sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); } #ifdef ENABLE_PIIX_LOG @@ -1504,16 +1498,12 @@ piix_reset(void *priv) piix_write(3, 0xd2, 0x00, priv); } - sff_set_irq_mode(dev->bm[0], 0, 0); - sff_set_irq_mode(dev->bm[1], 0, 0); + sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); - if (dev->no_mirq0 || (dev->type >= 4)) { - sff_set_irq_mode(dev->bm[0], 1, 0); - sff_set_irq_mode(dev->bm[1], 1, 0); - } else { - sff_set_irq_mode(dev->bm[0], 1, 2); - sff_set_irq_mode(dev->bm[1], 1, 2); - } + if (dev->no_mirq0 || (dev->type >= 4)) + sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); + else + sff_set_irq_mode(dev->bm[1], IRQ_MODE_MIRQ_0); } static void @@ -1567,16 +1557,12 @@ piix_init(const device_t *info) ide_board_set_force_ata3(1, 1); } - sff_set_irq_mode(dev->bm[0], 0, 0); - sff_set_irq_mode(dev->bm[1], 0, 0); + sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); - if (dev->no_mirq0 || (dev->type >= 4)) { - sff_set_irq_mode(dev->bm[0], 1, 0); - sff_set_irq_mode(dev->bm[1], 1, 0); - } else { - sff_set_irq_mode(dev->bm[0], 1, 2); - sff_set_irq_mode(dev->bm[1], 1, 2); - } + if (dev->no_mirq0 || (dev->type >= 4)) + sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); + else + sff_set_irq_mode(dev->bm[1], IRQ_MODE_MIRQ_0); if (dev->type >= 3) dev->usb = device_add(&usb_device); diff --git a/src/chipset/sis_5511.c b/src/chipset/sis_5511.c index d30ef39ca..f2ee01ebb 100644 --- a/src/chipset/sis_5511.c +++ b/src/chipset/sis_5511.c @@ -8,11 +8,11 @@ * * Implementation of the SiS 5511/5512/5513 Pentium PCI/ISA Chipset. * + * Authors: Miran Grca, + * Tiseno100, * - * - * Authors: Tiseno100, - * - * Copyright 2021 Tiseno100. + * Copyright 2021-2023 Miran Grca. + * Copyright 2021-2023 Tiseno100. */ #include #include @@ -27,26 +27,23 @@ #include <86box/timer.h> #include <86box/mem.h> +#include <86box/nvr.h> #include <86box/hdd.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/hdc_ide_sff8038i.h> #include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> #include <86box/plat_unused.h> #include <86box/port_92.h> #include <86box/smram.h> +#include <86box/spd.h> #include <86box/chipset.h> -/* IDE Flags (1 Native / 0 Compatibility)*/ -#define PRIMARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 1) -#define SECONDARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 4) -#define PRIMARY_NATIVE_BASE (dev->pci_conf_sb[1][0x11] << 8) | (dev->pci_conf_sb[1][0x10] & 0xf8) -#define PRIMARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x15] << 8) | (dev->pci_conf_sb[1][0x14] & 0xfc)) + 2) -#define SECONDARY_NATIVE_BASE (dev->pci_conf_sb[1][0x19] << 8) | (dev->pci_conf_sb[1][0x18] & 0xf8) -#define SECONDARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x1d] << 8) | (dev->pci_conf_sb[1][0x1c] & 0xfc)) + 2) -#define BUS_MASTER_BASE ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) - #ifdef ENABLE_SIS_5511_LOG int sis_5511_do_log = ENABLE_SIS_5511_LOG; @@ -72,14 +69,22 @@ typedef struct sis_5511_t { uint8_t pad; uint8_t regs[16]; + uint8_t states[7]; + + uint8_t slic_regs[4096]; uint8_t pci_conf[256]; uint8_t pci_conf_sb[2][256]; - sff8038i_t *ide_drive[2]; + mem_mapping_t slic_mapping; + + sff8038i_t *bm[2]; smram_t *smram; port_92_t *port_92; + void *pit; + nvr_t *nvr; + uint8_t (*pit_read_reg)(void *priv, uint8_t reg); } sis_5511_t; static void @@ -90,23 +95,31 @@ sis_5511_shadow_recalc(sis_5511_t *dev) for (uint8_t i = 0x80; i <= 0x86; i++) { if (i == 0x86) { - state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; - mem_set_mem_state_both(0xf0000, 0x10000, state); - pclog("000F0000-000FFFFF\n"); + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(0xf0000, 0x10000, state); + sis_5511_log("000F0000-000FFFFF\n"); + } } else { base = ((i & 0x07) << 15) + 0xc0000; - state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; - mem_set_mem_state_both(base, 0x4000, state); - pclog("%08X-%08X\n", base, base + 0x3fff); + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base, 0x4000, state); + sis_5511_log("%08X-%08X\n", base, base + 0x3fff); + } - state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; - mem_set_mem_state_both(base + 0x4000, 0x4000, state); - pclog("%08X-%08X\n", base + 0x4000, base + 0x7fff); + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) { + state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base + 0x4000, 0x4000, state); + sis_5511_log("%08X-%08X\n", base + 0x4000, base + 0x7fff); + } } + + dev->states[i & 0x0f] = dev->pci_conf[i]; } flushmmucache_nopc(); @@ -135,38 +148,14 @@ sis_5511_smram_recalc(sis_5511_t *dev) flushmmucache(); } -void -sis_5513_ide_handler(sis_5511_t *dev) -{ - ide_pri_disable(); - ide_sec_disable(); - if (dev->pci_conf_sb[1][4] & 1) { - if (dev->pci_conf_sb[1][0x4a] & 4) { - ide_set_base(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_BASE : 0x1f0); - ide_set_side(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_SIDE : 0x3f6); - ide_pri_enable(); - } - if (dev->pci_conf_sb[1][0x4a] & 2) { - ide_set_base(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_BASE : 0x170); - ide_set_side(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_SIDE : 0x376); - ide_sec_enable(); - } - } -} - -void -sis_5513_bm_handler(sis_5511_t *dev) -{ - sff_bus_master_handler(dev->ide_drive[0], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE); - sff_bus_master_handler(dev->ide_drive[1], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE + 8); -} - static void sis_5511_write(UNUSED(int func), int addr, uint8_t val, void *priv) { sis_5511_t *dev = (sis_5511_t *) priv; - switch (addr) { + sis_5511_log("SiS 5511: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + if (func == 0x00) switch (addr) { case 0x07: /* Status - High Byte */ dev->pci_conf[addr] &= 0xb0; break; @@ -266,106 +255,120 @@ sis_5511_write(UNUSED(int func), int addr, uint8_t val, void *priv) break; case 0x70: /* DRAM Bank Register 0-0 */ - case 0x71: /* DRAM Bank Register 0-0 */ case 0x72: /* DRAM Bank Register 0-1 */ - dev->pci_conf[addr] = val; - break; - - case 0x73: /* DRAM Bank Register 0-1 */ - dev->pci_conf[addr] = val & 0x83; - break; - case 0x74: /* DRAM Bank Register 1-0 */ + case 0x76: /* DRAM Bank Register 1-1 */ + case 0x78: /* DRAM Bank Register 2-0 */ + case 0x7a: /* DRAM Bank Register 2-1 */ + case 0x7c: /* DRAM Bank Register 3-0 */ + case 0x7e: /* DRAM Bank Register 3-1 */ + spd_write_drbs(dev->regs, 0x70, 0x7e, 0x82); + break; + + case 0x71: /* DRAM Bank Register 0-0 */ dev->pci_conf[addr] = val; break; case 0x75: /* DRAM Bank Register 1-0 */ - dev->pci_conf[addr] = val & 0x7f; - break; - - case 0x76: /* DRAM Bank Register 1-1 */ - dev->pci_conf[addr] = val; - break; - - case 0x77: /* DRAM Bank Register 1-1 */ - dev->pci_conf[addr] = val & 0x83; - break; - - case 0x78: /* DRAM Bank Register 2-0 */ - dev->pci_conf[addr] = val; - break; - case 0x79: /* DRAM Bank Register 2-0 */ - dev->pci_conf[addr] = val & 0x7f; - break; - - case 0x7a: /* DRAM Bank Register 2-1 */ - dev->pci_conf[addr] = val; - break; - - case 0x7b: /* DRAM Bank Register 2-1 */ - dev->pci_conf[addr] = val & 0x83; - break; - - case 0x7c: /* DRAM Bank Register 3-0 */ - dev->pci_conf[addr] = val; - break; - case 0x7d: /* DRAM Bank Register 3-0 */ dev->pci_conf[addr] = val & 0x7f; break; - case 0x7e: /* DRAM Bank Register 3-1 */ - dev->pci_conf[addr] = val; - break; - + case 0x73: /* DRAM Bank Register 0-1 */ + case 0x77: /* DRAM Bank Register 1-1 */ + case 0x7b: /* DRAM Bank Register 2-1 */ case 0x7f: /* DRAM Bank Register 3-1 */ dev->pci_conf[addr] = val & 0x83; break; - case 0x80: - case 0x81: - case 0x82: - case 0x83: - case 0x84: - case 0x85: + case 0x80 ... 0x85: + dev->pci_conf[addr] = val & 0xee; + sis_5511_shadow_recalc(dev); + break; case 0x86: - dev->pci_conf[addr] = val & ((addr == 0x86) ? 0xe8 : 0xee); + dev->pci_conf[addr] = val & 0xe8; sis_5511_shadow_recalc(dev); break; - case 0x90: /* 5512 General Purpose Register Index */ - case 0x91: /* 5512 General Purpose Register Index */ - case 0x92: /* 5512 General Purpose Register Index */ - case 0x93: /* 5512 General Purpose Register Index */ + case 0x90 ... 0x93: /* 5512 General Purpose Register Index */ dev->pci_conf[addr] = val; break; default: break; } - sis_5511_log("SiS 5511: dev->pci_conf[%02x] = %02x POST: %02x\n", addr, dev->pci_conf[addr], inb(0x80)); +} + +static void +sis_5511_slic_write(uint32_t addr, uint8_t val, void *priv) +{ + sis_5511_t *dev = (sis_5511_t *) priv; + + addr &= 0x00000fff; + + switch (addr) { + case 0x00000000: + case 0x00000008: /* 0x00000008 is a SiS 5512 register. */ + dev->slic_regs[addr] = val; + break; + case 0x00000010: + case 0x00000018: + case 0x00000028: + case 0x00000038: + dev->slic_regs[addr] = val & 0x01; + break; + case 0x00000030: + dev->slic_regs[addr] = val & 0x0f; + mem_mapping_set_addr(&dev->slic_mapping, + (((uint32_t) (val & 0x0f)) << 28) | 0x0fc00000, 0x00001000); + break; + } } static uint8_t sis_5511_read(UNUSED(int func), int addr, void *priv) { const sis_5511_t *dev = (sis_5511_t *) priv; + uint8_t ret = 0xff; - sis_5511_log("SiS 5511: dev->pci_conf[%02x] (%02x) POST %02x\n", addr, dev->pci_conf[addr], inb(0x80)); - return dev->pci_conf[addr]; + if (func == 0x00) + ret = dev->pci_conf[addr]; + + sis_5511_log("SiS 5511: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static uint8_t +sis_5511_slic_read(uint32_t addr, void *priv) +{ + sis_5511_t *dev = (sis_5511_t *) priv; + uint8_t ret = 0xff; + + addr &= 0x00000fff; + + switch (addr) { + case 0x00000008: /* 0x00000008 is a SiS 5512 register. */ + ret = dev->slic_regs[addr]; + break; + } + + return ret; } void sis_5513_pci_to_isa_write(int addr, uint8_t val, sis_5511_t *dev) { + sis_5511_log("SiS 5513 P2I: [W] dev->pci_conf_sb[0][%02X] = %02X\n", addr, val); + switch (addr) { case 0x04: /* Command */ - dev->pci_conf_sb[0][addr] = val & 7; + dev->pci_conf_sb[0][addr] = val & 0x0f; break; case 0x07: /* Status */ - dev->pci_conf_sb[0][addr] &= val & 0x36; + dev->pci_conf_sb[0][addr] = (dev->pci_conf_sb[0][addr] & 0x06) & ~(val & 0x30); break; case 0x40: /* BIOS Control Register */ @@ -377,40 +380,24 @@ sis_5513_pci_to_isa_write(int addr, uint8_t val, sis_5511_t *dev) case 0x43: /* INTC# Remapping Control Register */ case 0x44: /* INTD# Remapping Control Register */ dev->pci_conf_sb[0][addr] = val & 0x8f; - pci_set_irq_routing(addr & 7, (val & 0x80) ? (val & 0x80) : PCI_IRQ_DISABLED); + pci_set_irq_routing(addr & 0x07, (val & 0x80) ? PCI_IRQ_DISABLED : (val & 0x0f)); break; case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ - case 0x4c: - case 0x4d: - case 0x4e: - case 0x4f: - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - case 0x58: - case 0x59: - case 0x5a: - case 0x5b: - case 0x5c: - case 0x5d: - case 0x5e: - case 0x5f: dev->pci_conf_sb[0][addr] = val; break; case 0x60: /* MIRQ0 Remapping Control Register */ case 0x61: /* MIRQ1 Remapping Control Register */ + sis_5511_log("Set MIRQ routing: MIRQ%i -> %02X\n", addr & 0x01, val); dev->pci_conf_sb[0][addr] = val & 0xcf; - pci_set_mirq_routing(addr & 1, (val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), val & 0xf); break; case 0x62: /* On-board Device DMA Control Register */ @@ -418,11 +405,12 @@ sis_5513_pci_to_isa_write(int addr, uint8_t val, sis_5511_t *dev) break; case 0x63: /* IDEIRQ Remapping Control Register */ + sis_5511_log("Set MIRQ routing: IDEIRQ -> %02X\n", val); dev->pci_conf_sb[0][addr] = val & 0x8f; - if (val & 0x80) { - sff_set_irq_line(dev->ide_drive[0], (val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); - sff_set_irq_line(dev->ide_drive[1], (val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); - } + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ2, val & 0xf); break; case 0x64: /* GPIO0 Control Register */ @@ -439,7 +427,8 @@ sis_5513_pci_to_isa_write(int addr, uint8_t val, sis_5511_t *dev) break; case 0x6a: /* GPIO Status Register */ - dev->pci_conf_sb[0][addr] &= val & 0x15; + dev->pci_conf_sb[0][addr] |= (val & 0x10); + dev->pci_conf_sb[0][addr] &= ~(val & 0x01); break; default: @@ -447,52 +436,139 @@ sis_5513_pci_to_isa_write(int addr, uint8_t val, sis_5511_t *dev) } } +static void +sis_5513_ide_irq_handler(sis_5511_t *dev) +{ + if (dev->pci_conf_sb[1][0x09] & 0x01) { + /* Primary IDE is native. */ + sis_5511_log("Primary IDE IRQ mode: Native, Native\n"); + sff_set_irq_mode(dev->bm[0], IRQ_MODE_SIS_551X); + } else { + /* Primary IDE is legacy. */ + sis_5511_log("Primary IDE IRQ mode: IRQ14, IRQ15\n"); + sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); + } + + if (dev->pci_conf_sb[1][0x09] & 0x04) { + /* Secondary IDE is native. */ + sis_5511_log("Secondary IDE IRQ mode: Native, Native\n"); + sff_set_irq_mode(dev->bm[1], IRQ_MODE_SIS_551X); + } else { + /* Secondary IDE is legacy. */ + sis_5511_log("Secondary IDE IRQ mode: IRQ14, IRQ15\n"); + sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); + } +} + +static void +sis_5513_ide_handler(sis_5511_t *dev) +{ + uint8_t ide_io_on = dev->pci_conf_sb[1][0x04] & 0x01; + + uint16_t native_base_pri_addr = (dev->pci_conf_sb[1][0x11] | dev->pci_conf_sb[1][0x10] << 8) & 0xfffe; + uint16_t native_side_pri_addr = (dev->pci_conf_sb[1][0x15] | dev->pci_conf_sb[1][0x14] << 8) & 0xfffe; + uint16_t native_base_sec_addr = (dev->pci_conf_sb[1][0x19] | dev->pci_conf_sb[1][0x18] << 8) & 0xfffe; + uint16_t native_side_sec_addr = (dev->pci_conf_sb[1][0x1c] | dev->pci_conf_sb[1][0x1b] << 8) & 0xfffe; + + uint16_t current_pri_base; + uint16_t current_pri_side; + uint16_t current_sec_base; + uint16_t current_sec_side; + + /* Primary Channel Programming */ + current_pri_base = (!(dev->pci_conf_sb[1][0x09] & 1)) ? 0x01f0 : native_base_pri_addr; + current_pri_side = (!(dev->pci_conf_sb[1][0x09] & 1)) ? 0x03f6 : native_side_pri_addr; + + /* Secondary Channel Programming */ + current_sec_base = (!(dev->pci_conf_sb[1][0x09] & 4)) ? 0x0170 : native_base_sec_addr; + current_sec_side = (!(dev->pci_conf_sb[1][0x09] & 4)) ? 0x0376 : native_side_sec_addr; + + sis_5511_log("sis_5513_ide_handler(): Disabling primary IDE...\n"); + ide_pri_disable(); + sis_5511_log("sis_5513_ide_handler(): Disabling secondary IDE...\n"); + ide_sec_disable(); + + if (ide_io_on) { + /* Primary Channel Setup */ + if (dev->pci_conf_sb[1][0x4a] & 0x02) { + sis_5511_log("sis_5513_ide_handler(): Primary IDE base now %04X...\n", current_pri_base); + ide_set_base(0, current_pri_base); + sis_5511_log("sis_5513_ide_handler(): Primary IDE side now %04X...\n", current_pri_side); + ide_set_side(0, current_pri_side); + + sis_5511_log("sis_5513_ide_handler(): Enabling primary IDE...\n"); + ide_pri_enable(); + + sis_5511_log("SiS 5513 PRI: BASE %04x SIDE %04x\n", current_pri_base, current_pri_side); + } + + /* Secondary Channel Setup */ + if (dev->pci_conf_sb[1][0x4a] & 0x04) { + sis_5511_log("sis_5513_ide_handler(): Secondary IDE base now %04X...\n", current_sec_base); + ide_set_base(1, current_sec_base); + sis_5511_log("sis_5513_ide_handler(): Secondary IDE side now %04X...\n", current_sec_side); + ide_set_side(1, current_sec_side); + + sis_5511_log("sis_5513_ide_handler(): Enabling secondary IDE...\n"); + ide_sec_enable(); + + sis_5511_log("SiS 5513: BASE %04x SIDE %04x\n", current_sec_base, current_sec_side); + } + } + + sff_bus_master_handler(dev->bm[0], ide_io_on, + ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + 0); + sff_bus_master_handler(dev->bm[1], ide_io_on, + ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + 8); +} + void sis_5513_ide_write(int addr, uint8_t val, sis_5511_t *dev) { + sis_5511_log("SiS 5513 IDE: [W] dev->pci_conf_sb[1][%02X] = %02X\n", addr, val); + switch (addr) { case 0x04: /* Command low byte */ - dev->pci_conf_sb[1][addr] = val & 5; + dev->pci_conf_sb[1][addr] = val & 0x05; sis_5513_ide_handler(dev); - sis_5513_bm_handler(dev); + break; + case 0x06: /* Status low byte */ + dev->pci_conf_sb[1][addr] = val & 0x20; break; case 0x07: /* Status high byte */ - dev->pci_conf_sb[1][addr] &= val & 0x3f; + dev->pci_conf_sb[1][addr] = (dev->pci_conf_sb[1][addr] & 0x06) & ~(val & 0x38); break; case 0x09: /* Programming Interface Byte */ - dev->pci_conf_sb[1][addr] = val; + dev->pci_conf_sb[1][addr] = (dev->pci_conf_sb[1][addr] & 0x8a) | (val & 0x05); + sis_5513_ide_irq_handler(dev); sis_5513_ide_handler(dev); break; case 0x0d: /* Latency Timer */ dev->pci_conf_sb[1][addr] = val; break; - case 0x10: /* Primary Channel Base Address Register */ - case 0x11: /* Primary Channel Base Address Register */ - case 0x12: /* Primary Channel Base Address Register */ - case 0x13: /* Primary Channel Base Address Register */ - case 0x14: /* Primary Channel Base Address Register */ - case 0x15: /* Primary Channel Base Address Register */ - case 0x16: /* Primary Channel Base Address Register */ - case 0x17: /* Primary Channel Base Address Register */ - case 0x18: /* Secondary Channel Base Address Register */ - case 0x19: /* Secondary Channel Base Address Register */ - case 0x1a: /* Secondary Channel Base Address Register */ - case 0x1b: /* Secondary Channel Base Address Register */ - case 0x1c: /* Secondary Channel Base Address Register */ - case 0x1d: /* Secondary Channel Base Address Register */ - case 0x1e: /* Secondary Channel Base Address Register */ - case 0x1f: /* Secondary Channel Base Address Register */ - dev->pci_conf_sb[1][addr] = val; - sis_5513_ide_handler(dev); - break; + /* Primary Base Address */ + case 0x10: + case 0x11: + case 0x14: + case 0x15: + fallthrough; - case 0x20: /* Bus Master IDE Control Register Base Address */ - case 0x21: /* Bus Master IDE Control Register Base Address */ - case 0x22: /* Bus Master IDE Control Register Base Address */ - case 0x23: /* Bus Master IDE Control Register Base Address */ - dev->pci_conf_sb[1][addr] = val; - sis_5513_bm_handler(dev); + /* Secondary Base Address */ + case 0x18: + case 0x19: + case 0x1c: + case 0x1d: + fallthrough; + + /* Bus Mastering Base Address */ + case 0x20: + case 0x21: + if (addr == 0x20) + dev->pci_conf_sb[1][addr] = (val & 0xe0) | 0x01; + else + dev->pci_conf_sb[1][addr] = val; + sis_5513_ide_handler(dev); break; case 0x30: /* Expansion ROM Base Address */ @@ -516,7 +592,7 @@ sis_5513_ide_write(int addr, uint8_t val, sis_5511_t *dev) break; case 0x4a: /* IDE General Control Register 0 */ - dev->pci_conf_sb[1][addr] = val & 0x9f; + dev->pci_conf_sb[1][addr] = val & 0x9e; sis_5513_ide_handler(dev); break; @@ -540,30 +616,55 @@ static void sis_5513_write(int func, int addr, uint8_t val, void *priv) { sis_5511_t *dev = (sis_5511_t *) priv; + switch (func) { + default: + break; case 0: sis_5513_pci_to_isa_write(addr, val, dev); break; case 1: sis_5513_ide_write(addr, val, dev); break; - - default: - break; } - sis_5511_log("SiS 5513: dev->pci_conf[%02x][%02x] = %02x POST: %02x\n", func, addr, dev->pci_conf_sb[func][addr], inb(0x80)); } static uint8_t sis_5513_read(int func, int addr, void *priv) { const sis_5511_t *dev = (sis_5511_t *) priv; + uint8_t ret = 0xff; - sis_5511_log("SiS 5513: dev->pci_conf[%02x][%02x] = %02x POST %02x\n", func, addr, dev->pci_conf_sb[func][addr], inb(0x80)); - if ((func >= 0) && (func <= 1)) - return dev->pci_conf_sb[func][addr]; - else - return 0xff; + if (func == 0x00) { + switch (addr) { + default: + ret = dev->pci_conf_sb[func][addr]; + break; + case 0x4c ... 0x4f: + ret = pic_read_icw(0, addr & 0x03); + break; + case 0x50 ... 0x53: + ret = pic_read_icw(1, addr & 0x03); + break; + case 0x54 ... 0x55: + ret = pic_read_ocw(0, addr & 0x01); + break; + case 0x56 ... 0x57: + ret = pic_read_ocw(1, addr & 0x01); + break; + case 0x58 ... 0x5f: + ret = dev->pit_read_reg(dev->pit, addr & 0x07); + break; + } + + sis_5511_log("SiS 5513 P2I: [R] dev->pci_conf_sb[0][%02X] = %02X\n", addr, ret); + } else if (func == 0x01) { + ret = dev->pci_conf_sb[func][addr]; + + sis_5511_log("SiS 5513 IDE: [R] dev->pci_conf_sb[1][%02X] = %02X\n", addr, ret); + } + + return ret; } static void @@ -576,6 +677,8 @@ sis_5513_isa_write(uint16_t addr, uint8_t val, void *priv) dev->index = val - 0x50; break; case 0x23: + sis_5511_log("SiS 5513 ISA: [W] dev->regs[%02X] = %02X\n", dev->index + 0x50, val); + switch (dev->index) { case 0x00: dev->regs[dev->index] = val & 0xed; @@ -593,6 +696,7 @@ sis_5513_isa_write(uint16_t addr, uint8_t val, void *priv) default: break; } + nvr_bank_set(0, !!(val & 0x08), dev->nvr); break; case 0x01: dev->regs[dev->index] = val & 0xf4; @@ -604,7 +708,8 @@ sis_5513_isa_write(uint16_t addr, uint8_t val, void *priv) dev->regs[dev->index] = val; break; case 0x05: - dev->regs[dev->index] = inb(0x70); + dev->regs[dev->index] = val; + outb(0x70, val); break; case 0x08: case 0x09: @@ -616,7 +721,6 @@ sis_5513_isa_write(uint16_t addr, uint8_t val, void *priv) default: break; } - sis_5511_log("SiS 5513-ISA: dev->regs[%02x] = %02x POST: %02x\n", dev->index + 0x50, dev->regs[dev->index], inb(0x80)); break; default: @@ -628,12 +732,18 @@ static uint8_t sis_5513_isa_read(uint16_t addr, void *priv) { const sis_5511_t *dev = (sis_5511_t *) priv; + uint8_t ret = 0xff; if (addr == 0x23) { - sis_5511_log("SiS 5513-ISA: dev->regs[%02x] (%02x) POST: %02x\n", dev->index + 0x50, dev->regs[dev->index], inb(0x80)); - return dev->regs[dev->index]; - } else - return 0xff; + if (dev->index == 0x05) + ret = inb(0x70); + else + ret = dev->regs[dev->index]; + + sis_5511_log("SiS 5513 ISA: [R] dev->regs[%02X] = %02X\n", dev->index + 0x50, ret); + } + + return ret; } static void @@ -667,58 +777,108 @@ sis_5511_reset(void *priv) dev->pci_conf[0x66] = 0x00; dev->pci_conf[0x67] = 0xff; dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00; - dev->pci_conf[0x6a] = dev->pci_conf[0x6b] = 0x00; - dev->pci_conf[0x6c] = dev->pci_conf[0x6d] = 0x00; - dev->pci_conf[0x6e] = dev->pci_conf[0x6f] = 0x00; + dev->pci_conf[0x6a] = 0x00; + dev->pci_conf[0x6b] = dev->pci_conf[0x6c] = 0xff; + dev->pci_conf[0x6d] = dev->pci_conf[0x6e] = 0xff; + dev->pci_conf[0x6f] = 0x00; + dev->pci_conf[0x70] = dev->pci_conf[0x72] = 0x04; + dev->pci_conf[0x74] = dev->pci_conf[0x76] = 0x04; + dev->pci_conf[0x78] = dev->pci_conf[0x7a] = 0x04; + dev->pci_conf[0x7c] = dev->pci_conf[0x7e] = 0x04; + dev->pci_conf[0x73] = dev->pci_conf[0x77] = 0x80; + dev->pci_conf[0x7b] = dev->pci_conf[0x7f] = 0x80; + dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00; + dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00; + dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0x00; + dev->pci_conf[0x86] = 0x00; cpu_cache_ext_enabled = 0; cpu_update_waitstates(); - dev->pci_conf[0x6b] = 0xff; - dev->pci_conf[0x6c] = 0xff; - dev->pci_conf[0x70] = 4; - dev->pci_conf[0x72] = 4; - dev->pci_conf[0x73] = 0x80; - dev->pci_conf[0x74] = 4; - dev->pci_conf[0x76] = 4; - dev->pci_conf[0x77] = 0x80; - dev->pci_conf[0x78] = 4; - dev->pci_conf[0x7a] = 4; - dev->pci_conf[0x7b] = 0x80; - dev->pci_conf[0x7c] = 4; - dev->pci_conf[0x7e] = 4; - dev->pci_conf[0x7f] = 0x80; - dev->pci_conf[0x80] = 0x00; - dev->pci_conf[0x81] = 0x00; - dev->pci_conf[0x82] = 0x00; - dev->pci_conf[0x83] = 0x00; - dev->pci_conf[0x84] = 0x00; - dev->pci_conf[0x85] = 0x00; - dev->pci_conf[0x86] = 0x00; sis_5511_smram_recalc(dev); sis_5511_shadow_recalc(dev); + flushmmucache(); + + memset(dev->slic_regs, 0x00, 4096 * sizeof(uint8_t)); + dev->slic_regs[0x18] = 0x0f; + + mem_mapping_set_addr(&dev->slic_mapping, 0xffc00000, 0x00001000); + /* SiS 5513 */ dev->pci_conf_sb[0][0x00] = 0x39; dev->pci_conf_sb[0][0x01] = 0x10; - dev->pci_conf_sb[0][0x02] = 8; - dev->pci_conf_sb[0][0x04] = 7; - dev->pci_conf_sb[0][0x0a] = 1; - dev->pci_conf_sb[0][0x0b] = 6; + dev->pci_conf_sb[0][0x02] = 0x08; + dev->pci_conf_sb[0][0x03] = 0x00; + dev->pci_conf_sb[0][0x04] = 0x07; + dev->pci_conf_sb[0][0x05] = dev->pci_conf_sb[0][0x06] = 0x00; + dev->pci_conf_sb[0][0x07] = 0x02; + dev->pci_conf_sb[0][0x08] = dev->pci_conf_sb[0][0x09] = 0x00; + dev->pci_conf_sb[0][0x0a] = 0x01; + dev->pci_conf_sb[0][0x0b] = 0x06; dev->pci_conf_sb[0][0x0e] = 0x80; + dev->pci_conf_sb[0][0x40] = 0x00; + dev->pci_conf_sb[0][0x41] = dev->pci_conf_sb[0][0x42] = 0x80; + dev->pci_conf_sb[0][0x43] = dev->pci_conf_sb[0][0x44] = 0x80; + dev->pci_conf_sb[0][0x48] = dev->pci_conf_sb[0][0x49] = 0x80; + dev->pci_conf_sb[0][0x4a] = dev->pci_conf_sb[0][0x4b] = 0x80; + dev->pci_conf_sb[0][0x60] = dev->pci_conf_sb[0][0x51] = 0x80; + dev->pci_conf_sb[0][0x62] = 0x00; + dev->pci_conf_sb[0][0x63] = 0x80; + dev->pci_conf_sb[0][0x64] = 0x00; + dev->pci_conf_sb[0][0x65] = 0x80; + dev->pci_conf_sb[0][0x66] = dev->pci_conf_sb[0][0x67] = 0x00; + dev->pci_conf_sb[0][0x68] = dev->pci_conf_sb[0][0x69] = 0x00; + dev->pci_conf_sb[0][0x6a] = 0x04; + + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + + pci_set_mirq_routing(PCI_MIRQ0, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); + + dev->regs[0x00] = dev->regs[0x01] = 0x00; + dev->regs[0x03] = dev->regs[0x04] = 0x00; + dev->regs[0x05] = 0x00; + dev->regs[0x08] = dev->regs[0x09] = 0x00; + dev->regs[0x0a] = dev->regs[0x0b] = 0x00; + + cpu_set_isa_speed(7159091); + nvr_bank_set(0, 0, dev->nvr); /* SiS 5513 IDE Controller */ dev->pci_conf_sb[1][0x00] = 0x39; dev->pci_conf_sb[1][0x01] = 0x10; dev->pci_conf_sb[1][0x02] = 0x13; dev->pci_conf_sb[1][0x03] = 0x55; - dev->pci_conf_sb[1][0x0a] = 1; - dev->pci_conf_sb[1][0x0b] = 1; + dev->pci_conf_sb[1][0x04] = dev->pci_conf_sb[1][0x05] = 0x00; + dev->pci_conf_sb[1][0x06] = dev->pci_conf_sb[1][0x07] = 0x00; + dev->pci_conf_sb[1][0x08] = 0x00; + dev->pci_conf_sb[1][0x09] = 0x8a; + dev->pci_conf_sb[1][0x0a] = dev->pci_conf_sb[1][0x0b] = 0x01; + dev->pci_conf_sb[1][0x0c] = dev->pci_conf_sb[1][0x0d] = 0x00; dev->pci_conf_sb[1][0x0e] = 0x80; - sff_set_slot(dev->ide_drive[0], dev->sb_slot); - sff_set_slot(dev->ide_drive[1], dev->sb_slot); - sff_bus_master_reset(dev->ide_drive[0], BUS_MASTER_BASE); - sff_bus_master_reset(dev->ide_drive[1], BUS_MASTER_BASE + 8); + dev->pci_conf_sb[1][0x0f] = 0x00; + dev->pci_conf_sb[1][0x10] = 0xf1; + dev->pci_conf_sb[1][0x11] = 0x01; + dev->pci_conf_sb[1][0x14] = 0xf5; + dev->pci_conf_sb[1][0x15] = 0x03; + dev->pci_conf_sb[1][0x18] = 0x71; + dev->pci_conf_sb[1][0x19] = 0x01; + dev->pci_conf_sb[1][0x1c] = 0x75; + dev->pci_conf_sb[1][0x1d] = 0x03; + dev->pci_conf_sb[1][0x20] = 0x01; + dev->pci_conf_sb[1][0x21] = 0xf0; + dev->pci_conf_sb[1][0x22] = dev->pci_conf_sb[1][0x23] = 0x00; + + sis_5513_ide_irq_handler(dev); + sis_5513_ide_handler(dev); + + sff_bus_master_reset(dev->bm[0]); + sff_bus_master_reset(dev->bm[1]); } static void @@ -733,27 +893,55 @@ sis_5511_close(void *priv) static void * sis_5511_init(UNUSED(const device_t *info)) { - sis_5511_t *dev = (sis_5511_t *) malloc(sizeof(sis_5511_t)); + sis_5511_t *dev = (sis_5511_t *) calloc(1, sizeof(sis_5511_t)); + uint8_t pit_is_fast = (((pit_mode == -1) && is486) || (pit_mode == 1)); + memset(dev, 0, sizeof(sis_5511_t)); - pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5511_read, sis_5511_write, dev, &dev->nb_slot); /* Device 0: SiS 5511 */ - pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5513_read, sis_5513_write, dev, &dev->sb_slot); /* Device 1: SiS 5513 */ - io_sethandler(0x0022, 0x0002, sis_5513_isa_read, NULL, NULL, sis_5513_isa_write, NULL, NULL, dev); /* Ports 22h-23h: SiS 5513 ISA */ + /* Device 0: SiS 5511 */ + pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5511_read, sis_5511_write, dev, &dev->nb_slot); + /* Device 1: SiS 5513 */ + pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5513_read, sis_5513_write, dev, &dev->sb_slot); + + /* SLiC Memory Mapped Registers */ + mem_mapping_add(&dev->slic_mapping, + 0xffc00000, 0x00001000, + sis_5511_slic_read, + NULL, + NULL, + sis_5511_slic_write, + NULL, + NULL, + NULL, MEM_MAPPING_EXTERNAL, + dev); + + /* Ports 22h-23h: SiS 5513 ISA */ + io_sethandler(0x0022, 0x0002, sis_5513_isa_read, NULL, NULL, sis_5513_isa_write, NULL, NULL, dev); /* MIRQ */ pci_enable_mirq(0); pci_enable_mirq(1); + /* IDEIRQ */ + pci_enable_mirq(2); + /* Port 92h */ dev->port_92 = device_add(&port_92_device); /* SFF IDE */ - dev->ide_drive[0] = device_add_inst(&sff8038i_device, 1); - dev->ide_drive[1] = device_add_inst(&sff8038i_device, 2); + dev->bm[0] = device_add_inst(&sff8038i_device, 1); + dev->bm[1] = device_add_inst(&sff8038i_device, 2); /* SMRAM */ dev->smram = smram_add(); + /* PIT */ + dev->pit = device_find_first_priv(DEVICE_PIT); + dev->pit_read_reg = pit_is_fast ? pitf_read_reg : pit_read_reg; + + /* NVR */ + dev->nvr = device_add(&at_mb_nvr_device); + sis_5511_reset(dev); return dev; diff --git a/src/chipset/sis_5571.c b/src/chipset/sis_5571.c index 0761e4865..f130ecd8a 100644 --- a/src/chipset/sis_5571.c +++ b/src/chipset/sis_5571.c @@ -703,8 +703,8 @@ sis_5571_reset(void *priv) dev->pci_conf_sb[1][0x4a] = 0x06; sff_set_slot(dev->ide_drive[0], dev->sb_slot); sff_set_slot(dev->ide_drive[1], dev->sb_slot); - sff_bus_master_reset(dev->ide_drive[0], BUS_MASTER_BASE); - sff_bus_master_reset(dev->ide_drive[1], BUS_MASTER_BASE + 8); + sff_bus_master_reset(dev->ide_drive[0]); + sff_bus_master_reset(dev->ide_drive[1]); /* USB Controller */ dev->pci_conf_sb[2][0x00] = 0x39; diff --git a/src/chipset/stpc.c b/src/chipset/stpc.c index aa5e1fb8b..dbe39ec5c 100644 --- a/src/chipset/stpc.c +++ b/src/chipset/stpc.c @@ -929,11 +929,9 @@ stpc_init(const device_t *info) dev->bm[0] = device_add_inst(&sff8038i_device, 1); dev->bm[1] = device_add_inst(&sff8038i_device, 2); - sff_set_irq_mode(dev->bm[0], 0, 0); - sff_set_irq_mode(dev->bm[0], 1, 0); + sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); - sff_set_irq_mode(dev->bm[1], 0, 0); - sff_set_irq_mode(dev->bm[1], 1, 0); + sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); stpc_setup(dev); stpc_reset(dev); diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index a8e0f9ff2..1f153092b 100644 --- a/src/chipset/via_pipc.c +++ b/src/chipset/via_pipc.c @@ -210,10 +210,9 @@ pipc_reset_hard(void *priv) pipc_log("PIPC: reset_hard()\n"); pipc_t *dev = (pipc_t *) priv; - uint16_t old_base = (dev->ide_regs[0x20] & 0xf0) | (dev->ide_regs[0x21] << 8); - sff_bus_master_reset(dev->bm[0], old_base); - sff_bus_master_reset(dev->bm[1], old_base + 8); + sff_bus_master_reset(dev->bm[0]); + sff_bus_master_reset(dev->bm[1]); memset(dev->pci_isa_regs, 0, 256); memset(dev->ide_regs, 0, 256); @@ -237,7 +236,8 @@ pipc_reset_hard(void *priv) dev->pci_isa_regs[0x4a] = 0x04; dev->pci_isa_regs[0x4f] = 0x03; - dev->pci_isa_regs[0x50] = (dev->local >= VIA_PIPC_686A) ? 0x0e : 0x24; /* 686A/B default value does not line up with default bits */ + /* 686A/B default value does not line up with default bits */ + dev->pci_isa_regs[0x50] = (dev->local >= VIA_PIPC_686A) ? 0x0e : 0x24; dev->pci_isa_regs[0x59] = 0x04; if (dev->local >= VIA_PIPC_686A) dev->pci_isa_regs[0x5a] = dev->pci_isa_regs[0x5f] = 0x04; @@ -566,19 +566,17 @@ pipc_ide_handlers(pipc_t *dev) static void pipc_ide_irqs(pipc_t *dev) { - int irq_mode[2] = { 0, 0 }; + int irq_mode[2] = { IRQ_MODE_LEGACY, IRQ_MODE_LEGACY }; if (dev->ide_regs[0x09] & 0x01) - irq_mode[0] = (dev->ide_regs[0x3d] & 0x01); + irq_mode[0] = (dev->ide_regs[0x3d] & 0x01) ? IRQ_MODE_PCI_IRQ_PIN : IRQ_MODE_LEGACY; if (dev->ide_regs[0x09] & 0x04) - irq_mode[1] = (dev->ide_regs[0x3d] & 0x01); + irq_mode[1] = (dev->ide_regs[0x3d] & 0x01) ? IRQ_MODE_PCI_IRQ_PIN : IRQ_MODE_LEGACY; - sff_set_irq_mode(dev->bm[0], 0, irq_mode[0]); - sff_set_irq_mode(dev->bm[0], 1, irq_mode[1]); + sff_set_irq_mode(dev->bm[0], irq_mode[0]); - sff_set_irq_mode(dev->bm[1], 0, irq_mode[0]); - sff_set_irq_mode(dev->bm[1], 1, irq_mode[1]); + sff_set_irq_mode(dev->bm[1], irq_mode[1]); } static void @@ -1638,22 +1636,20 @@ pipc_init(const device_t *info) pci_add_card(PCI_ADD_SOUTHBRIDGE, pipc_read, pipc_write, dev, &dev->pci_slot); dev->bm[0] = device_add_inst(&sff8038i_device, 1); - sff_set_irq_mode(dev->bm[0], 0, 0); - sff_set_irq_mode(dev->bm[0], 1, 0); + sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); sff_set_irq_pin(dev->bm[0], PCI_INTA); dev->bm[1] = device_add_inst(&sff8038i_device, 2); - sff_set_irq_mode(dev->bm[1], 0, 0); - sff_set_irq_mode(dev->bm[1], 1, 0); + sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); sff_set_irq_pin(dev->bm[1], PCI_INTA); - dev->nvr = device_add(&via_nvr_device); - if (dev->local == VIA_PIPC_686B) dev->smbus = device_add(&via_smbus_device); else if (dev->local >= VIA_PIPC_596A) dev->smbus = device_add(&piix4_smbus_device); + dev->nvr = device_add(&via_nvr_device); + if (dev->local >= VIA_PIPC_596A) { dev->acpi = device_add(&acpi_via_596b_device); acpi_set_trap_update(dev->acpi, pipc_trap_update_596, dev); diff --git a/src/device.c b/src/device.c index 814122e1d..c517f98e9 100644 --- a/src/device.c +++ b/src/device.c @@ -39,6 +39,7 @@ * Boston, MA 02111-1307 * USA. */ +#include #include #include #include @@ -158,6 +159,8 @@ device_add_common(const device_t *dev, const device_t *cd, void *p, void *params /* Do this so that a chained device_add will not identify the same ID its master device is already trying to assign. */ devices[c] = (device_t *) dev; + if (!strcmp(dev->name, "None") || !strcmp(dev->name, "Internal")) + fatal("Attempting to add dummy device of type: %s\n", dev->name); if (p == NULL) { memcpy(&device_prev, &device_current, sizeof(device_context_t)); @@ -327,6 +330,23 @@ device_reset_all(uint32_t match_flags) } } +void * +device_find_first_priv(uint32_t match_flags) +{ + void *ret = NULL; + + for (uint16_t c = 0; c < DEVICE_MAX; c++) { + if (devices[c] != NULL) { + if ((device_priv[c] != NULL) && (devices[c]->flags & match_flags)) { + ret = device_priv[c]; + break; + } + } + } + + return ret; +} + void * device_get_priv(const device_t *dev) { @@ -550,6 +570,8 @@ device_speed_changed(void) { for (uint16_t c = 0; c < DEVICE_MAX; c++) { if (devices[c] != NULL) { + device_log("DEVICE: device '%s' speed changed\n", devices[c]->name); + if (devices[c]->speed_changed != NULL) devices[c]->speed_changed(device_priv[c]); } diff --git a/src/device/keyboard_xt.c b/src/device/keyboard_xt.c index 0f573ea5a..028c58493 100644 --- a/src/device/keyboard_xt.c +++ b/src/device/keyboard_xt.c @@ -546,8 +546,8 @@ kbd_write(uint16_t port, uint8_t val, void *priv) timer_process(); - if (((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ)) && - (cassette != NULL)) + if (((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || + (kbd->type == KBD_TYPE_PRAVETZ)) && (cassette != NULL)) pc_cas_set_motor(cassette, (kbd->pb & 0x08) == 0); speaker_update(); @@ -599,12 +599,19 @@ kbd_read(uint16_t port, void *priv) switch (port) { case 0x60: /* Keyboard Data Register (aka Port A) */ - if ((kbd->pb & 0x80) && ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ) || (kbd->type == KBD_TYPE_XT82) || - (kbd->type == KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) || (kbd->type == KBD_TYPE_ZENITH))) { - if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) || (kbd->type == KBD_TYPE_PRAVETZ)) + if ((kbd->pb & 0x80) && ((kbd->type == KBD_TYPE_PC81) || + (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ) || + (kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_XT86) || + (kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) || + (kbd->type == KBD_TYPE_ZENITH))) { + if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || + (kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) || + (kbd->type == KBD_TYPE_PRAVETZ)) ret = (kbd->pd & ~0x02) | (hasfpu ? 0x02 : 0x00); else if ((kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_XT86)) - ret = 0xff; /* According to Ruud on the PCem forum, this is supposed to return 0xFF on the XT. */ + /* According to Ruud on the PCem forum, this is supposed to + return 0xFF on the XT. */ + ret = 0xff; else if (kbd->type == KBD_TYPE_ZENITH) { /* Zenith Data Systems Z-151 * SW1 switch settings: @@ -633,7 +640,8 @@ kbd_read(uint16_t port, void *priv) break; case 0x62: /* Switch Register (aka Port C) */ - if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ)) { + if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || + (kbd->type == KBD_TYPE_PRAVETZ)) { if (kbd->pb & 0x04) /* PB2 */ switch (mem_size + isa_mem_size) { case 64: @@ -648,8 +656,8 @@ kbd_read(uint16_t port, void *priv) } else ret = (((mem_size + isa_mem_size) - 64) / 32) >> 4; - } else if (kbd->type == KBD_TYPE_OLIVETTI - || kbd->type == KBD_TYPE_ZENITH) { + } else if ((kbd->type == KBD_TYPE_OLIVETTI) || + (kbd->type == KBD_TYPE_ZENITH)) { /* Olivetti M19 or Zenith Data Systems Z-151 */ if (kbd->pb & 0x04) /* PB2 */ ret = kbd->pd & 0xbf; @@ -673,7 +681,8 @@ kbd_read(uint16_t port, void *priv) /* This is needed to avoid error 131 (cassette error). This is serial read: bit 5 = clock, bit 4 = data, cassette header is 256 x 0xff. */ - if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ)) { + if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || + (kbd->type == KBD_TYPE_PRAVETZ)) { if (cassette == NULL) ret |= (ppispeakon ? 0x10 : 0); else @@ -754,7 +763,6 @@ kbd_init(const device_t *info) (kbd->type <= KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) || (kbd->type == KBD_TYPE_TOSHIBA) || (kbd->type == KBD_TYPE_OLIVETTI)) { - /* DIP switch readout: bit set = OFF, clear = ON. */ if (kbd->type == KBD_TYPE_OLIVETTI) /* Olivetti M19 diff --git a/src/device/mouse.c b/src/device/mouse.c index 62e023691..193149bc8 100644 --- a/src/device/mouse.c +++ b/src/device/mouse.c @@ -41,7 +41,7 @@ typedef struct mouse_t { } mouse_t; int mouse_type = 0; -int mouse_mode; +int mouse_input_mode; int mouse_timed = 1; int mouse_tablet_in_proximity = 0; int tablet_tool_type = 1; /* 0 = Puck/Cursor, 1 = Pen */ @@ -530,9 +530,9 @@ mouse_process(void) if (mouse_curr == NULL) return; - if ((mouse_mode >= 1) && mouse_poll_ex) + if ((mouse_input_mode >= 1) && mouse_poll_ex) mouse_poll_ex(); - else if ((mouse_mode == 0) && ((mouse_dev_poll != NULL) || (mouse_curr->poll != NULL))) { + else if ((mouse_input_mode == 0) && ((mouse_dev_poll != NULL) || (mouse_curr->poll != NULL))) { if (mouse_curr->poll != NULL) mouse_curr->poll(mouse_priv); else @@ -628,7 +628,7 @@ mouse_reset(void) /* Clear local data. */ mouse_clear_coords(); mouse_clear_buttons(); - mouse_mode = 0; + mouse_input_mode = 0; mouse_timed = 1; /* If no mouse configured, we're done. */ @@ -643,7 +643,7 @@ mouse_reset(void) mouse_curr = mouse_devices[mouse_type].device; - if (mouse_curr != NULL) + if ((mouse_type > 1) && (mouse_curr != NULL)) mouse_priv = device_add(mouse_curr); } diff --git a/src/device/mouse_wacom_tablet.c b/src/device/mouse_wacom_tablet.c index 667b020f1..d299d8bab 100644 --- a/src/device/mouse_wacom_tablet.c +++ b/src/device/mouse_wacom_tablet.c @@ -215,7 +215,7 @@ wacom_process_settings_dword(mouse_wacom_t *wacom, uint32_t dword) break; } - mouse_mode = !wacom->settings_bits.coord_sys; + mouse_input_mode = !wacom->settings_bits.coord_sys; wacom->x_res = wacom->y_res = wacom_resolution_values[wacom->settings_bits.resolution]; } @@ -235,7 +235,7 @@ wacom_reset(mouse_wacom_t *wacom) wacom->settings_bits.remote_mode = wacom->remote_req = 0; wacom->settings_bits.out_of_range_data = 0; - mouse_mode = 1; + mouse_input_mode = 1; wacom_process_settings_dword(wacom, 0xA21BC800); } @@ -257,7 +257,7 @@ wacom_reset_artpad(mouse_wacom_t *wacom) wacom->settings_bits.out_of_range_data = 0; wacom_process_settings_dword(wacom, 0xE203C000); - mouse_mode = 1; + mouse_input_mode = 1; } static void @@ -364,8 +364,8 @@ wacom_write(UNUSED(struct serial_s *serial), void *priv, uint8_t data) } else if (!memcmp(wacom->data_rec, "IT", 2)) { sscanf((const char *) wacom->data_rec, "IT%d", &wacom->interval); } else if (!memcmp(wacom->data_rec, "DE", 2) && wacom->settings_bits.cmd_set == WACOM_CMDSET_IIS) { - sscanf((const char *) wacom->data_rec, "DE%d", &mouse_mode); - mouse_mode = !mouse_mode; + sscanf((const char *) wacom->data_rec, "DE%d", &mouse_input_mode); + mouse_input_mode = !mouse_input_mode; plat_mouse_capture(0); } else if (!memcmp(wacom->data_rec, "SU", 2)) { sscanf((const char *) wacom->data_rec, "SU%d", &wacom->suppressed_increment); @@ -520,7 +520,7 @@ wacom_transmit_prepare(mouse_wacom_t *wacom, int x, int y) data[1] = ((x & 0x3F80) >> 7) & 0x7F; data[0] |= (((x & 0xC000) >> 14) & 3); - if (mouse_mode == 0 && wacom->settings_bits.cmd_set == WACOM_CMDSET_IIS) { + if (mouse_input_mode == 0 && wacom->settings_bits.cmd_set == WACOM_CMDSET_IIS) { data[0] |= (!!(x < 0)) << 2; data[3] |= (!!(y < 0)) << 2; } @@ -563,7 +563,7 @@ wacom_report_timer(void *priv) { mouse_wacom_t *wacom = (mouse_wacom_t *) priv; double milisecond_diff = ((double) (tsc - wacom->old_tsc)) / cpuclock * 1000.0; - int relative_mode = (mouse_mode == 0); + int relative_mode = (mouse_input_mode == 0); int x = (relative_mode ? wacom->rel_x : wacom->abs_x); int y = (relative_mode ? wacom->rel_y : wacom->abs_y); int x_diff = abs(relative_mode ? wacom->rel_x : (wacom->abs_x - wacom->last_abs_x)); diff --git a/src/device/pci_bridge.c b/src/device/pci_bridge.c index ad44fc9e7..8183f8afa 100644 --- a/src/device/pci_bridge.c +++ b/src/device/pci_bridge.c @@ -501,7 +501,9 @@ pci_bridge_init(const device_t *info) for (uint8_t i = 0; i < interrupt_count; i++) interrupts[i] = pci_get_int(dev->slot, PCI_INTA + i); } - pci_bridge_log("PCI Bridge %d: upstream bus %02X slot %02X interrupts %02X %02X %02X %02X\n", dev->bus_index, (dev->slot >> 5) & 0xff, dev->slot & 31, interrupts[0], interrupts[1], interrupts[2], interrupts[3]); + pci_bridge_log("PCI Bridge %d: upstream bus %02X slot %02X interrupts %02X %02X %02X %02X\n", + dev->bus_index, (dev->slot >> 5) & 0xff, dev->slot & 31, interrupts[0], + interrupts[1], interrupts[2], interrupts[3]); if (info->local == PCI_BRIDGE_DEC_21150) slot_count = 9; /* 9 bus masters */ @@ -510,7 +512,10 @@ pci_bridge_init(const device_t *info) for (uint8_t i = 0; i < slot_count; i++) { /* Interrupts for bridge slots are assigned in round-robin: ABCD, BCDA, CDAB and so on. */ - pci_bridge_log("PCI Bridge %d: downstream slot %02X interrupts %02X %02X %02X %02X\n", dev->bus_index, i, interrupts[i & interrupt_mask], interrupts[(i + 1) & interrupt_mask], interrupts[(i + 2) & interrupt_mask], interrupts[(i + 3) & interrupt_mask]); + pci_bridge_log("PCI Bridge %d: downstream slot %02X interrupts %02X %02X %02X %02X\n", + dev->bus_index, i, interrupts[i & interrupt_mask], + interrupts[(i + 1) & interrupt_mask], interrupts[(i + 2) & interrupt_mask], + interrupts[(i + 3) & interrupt_mask]); pci_register_bus_slot(dev->bus_index, i, AGP_BRIDGE(dev->local) ? PCI_CARD_AGP : PCI_CARD_NORMAL, interrupts[i & interrupt_mask], interrupts[(i + 1) & interrupt_mask], diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 0abd4df89..8cd0d9885 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -124,8 +124,8 @@ typedef struct ide_board_t { } ide_board_t; typedef struct ide_bm_t { - int (*dma)(int channel, uint8_t *data, int transfer_length, int out, void *priv); - void (*set_irq)(int channel, void *priv); + int (*dma)(uint8_t *data, int transfer_length, int out, void *priv); + void (*set_irq)(uint8_t status, void *priv); void *priv; } ide_bm_t; @@ -342,7 +342,7 @@ ide_irq_raise(ide_t *ide) if (!(ide->fdisk & 2) && ide->selected) { if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->set_irq) - ide_bm[ide->board]->set_irq(ide->board | 0x40, ide_bm[ide->board]->priv); + ide_bm[ide->board]->set_irq(0x04, ide_bm[ide->board]->priv); else if (ide_boards[ide->board]->irq != -1) picint(1 << ide_boards[ide->board]->irq); } @@ -363,7 +363,7 @@ ide_irq_lower(ide_t *ide) if (ide->irqstat && ide->selected) { if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->set_irq) - ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv); + ide_bm[ide->board]->set_irq(0x00, ide_bm[ide->board]->priv); else if (ide_boards[ide->board]->irq != -1) picintc(1 << ide_boards[ide->board]->irq); } @@ -382,8 +382,8 @@ ide_irq_update(ide_t *ide) if (!(ide->fdisk & 2) && ide->irqstat) { ide_log("IDE %i: IRQ update raise\n", ide->board); if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->set_irq) { - ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv); - ide_bm[ide->board]->set_irq(ide->board | 0x40, ide_bm[ide->board]->priv); + ide_bm[ide->board]->set_irq(0x00, ide_bm[ide->board]->priv); + ide_bm[ide->board]->set_irq(0x04, ide_bm[ide->board]->priv); } else if (ide_boards[ide->board]->irq != -1) { picintc(1 << ide_boards[ide->board]->irq); picint(1 << ide_boards[ide->board]->irq); @@ -391,7 +391,7 @@ ide_irq_update(ide_t *ide) } else if ((ide->fdisk & 2) || !ide->irqstat) { ide_log("IDE %i: IRQ update lower\n", ide->board); if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->set_irq) - ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv); + ide_bm[ide->board]->set_irq(0x00, ide_bm[ide->board]->priv); else if (ide_boards[ide->board]->irq != -1) picintc(1 << ide_boards[ide->board]->irq); } @@ -1022,9 +1022,9 @@ ide_atapi_callback(ide_t *ide) #endif out = (ide->sc->packet_status & 0x01); - if (!ide->sc->pad0 && !ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->dma) { - ret = ide_bm[ide->board]->dma(ide->board, - ide->sc->temp_buffer, ide->sc->packet_len, + if (!ide->sc->pad0 && !ide_boards[ide->board]->force_ata3 && + ide_bm[ide->board] && ide_bm[ide->board]->dma) { + ret = ide_bm[ide->board]->dma(ide->sc->temp_buffer, ide->sc->packet_len, out, ide_bm[ide->board]->priv); } else { /* DMA command without a bus master. */ @@ -1069,7 +1069,7 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out) { scsi_common_t *dev = ide->sc; - ide_irq_lower(ide_drives[ide->board]); + ide_irq_lower(ide); dev->status = BSY_STAT; @@ -2333,8 +2333,7 @@ ide_callback(void *priv) if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->dma) { /* We should not abort - we should simply wait for the host to start DMA. */ - ret = ide_bm[ide->board]->dma(ide->board, - ide->sector_buffer, ide->sector_pos * 512, + ret = ide_bm[ide->board]->dma(ide->sector_buffer, ide->sector_pos * 512, 0, ide_bm[ide->board]->priv); if (ret == 2) { /* Bus master DMA disabled, simply wait for the host to enable DMA. */ @@ -2431,8 +2430,7 @@ ide_callback(void *priv) else ide->sector_pos = 256; - ret = ide_bm[ide->board]->dma(ide->board, - ide->sector_buffer, ide->sector_pos * 512, + ret = ide_bm[ide->board]->dma(ide->sector_buffer, ide->sector_pos * 512, 1, ide_bm[ide->board]->priv); if (ret == 2) { @@ -2917,7 +2915,9 @@ ide_board_init(int board, int irq, int base_main, int side_main, int type) ide_log("IDE: Initializing board %i...\n", board); - ide_boards[board] = (ide_board_t *) malloc(sizeof(ide_board_t)); + if (ide_boards[board] == NULL) + ide_boards[board] = (ide_board_t *) malloc(sizeof(ide_board_t)); + memset(ide_boards[board], 0, sizeof(ide_board_t)); ide_boards[board]->irq = irq; ide_boards[board]->cur_dev = board << 1; @@ -3039,8 +3039,8 @@ ide_xtide_close(void) void ide_set_bus_master(int board, - int (*dma)(int channel, uint8_t *data, int transfer_length, int out, void *priv), - void (*set_irq)(int channel, void *priv), void *priv) + int (*dma)(uint8_t *data, int transfer_length, int out, void *priv), + void (*set_irq)(uint8_t status, void *priv), void *priv) { if (ide_bm[board] == NULL) ide_bm[board] = (ide_bm_t *) malloc(sizeof(ide_bm_t)); @@ -3072,7 +3072,8 @@ ide_init(const device_t *info) break; } - return ide_drives; + // return ide_drives; + return (void *) (intptr_t) -1; } static void diff --git a/src/disk/hdc_ide_cmd640.c b/src/disk/hdc_ide_cmd640.c index 2d203f3f8..3e77730a2 100644 --- a/src/disk/hdc_ide_cmd640.c +++ b/src/disk/hdc_ide_cmd640.c @@ -74,38 +74,52 @@ cmd640_log(const char *fmt, ...) #endif void -cmd640_set_irq(int channel, void *priv) +cmd640_set_irq_0(uint8_t status, void *priv) { cmd640_t *dev = (cmd640_t *) priv; - int irq = !!(channel & 0x40); + int irq = !!(status & 0x04); - if (channel & 0x01) { - if (!(dev->regs[0x57] & 0x10) || (channel & 0x40)) { - dev->regs[0x57] &= ~0x10; - dev->regs[0x57] |= (channel >> 2); - } - } else { - if (!(dev->regs[0x50] & 0x04) || (channel & 0x40)) { - dev->regs[0x50] &= ~0x04; - dev->regs[0x50] |= (channel >> 4); - } - } + if (!(dev->regs[0x50] & 0x04) || (status & 0x04)) + dev->regs[0x50] = (dev->regs[0x50] & ~0x04) | status; - channel &= 0x01; - - if (!(dev->channels & (1 << channel))) + if (!(dev->channels & 1)) return; if (irq) { - if (dev->irq_mode[channel] == 1) + if (dev->irq_mode[0] == 1) pci_set_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state); else - picint(1 << (14 + channel)); + picint(1 << 14); } else { - if (dev->irq_mode[channel] == 1) + if (dev->irq_mode[0] == 1) pci_clear_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state); else - picintc(1 << (14 + channel)); + picintc(1 << 14); + } +} + +void +cmd640_set_irq_1(uint8_t status, void *priv) +{ + cmd640_t *dev = (cmd640_t *) priv; + int irq = !!(status & 0x04); + + if (!(dev->regs[0x57] & 0x10) || (status & 0x04)) + dev->regs[0x57] = (dev->regs[0x57] & ~0x10) | (status << 2); + + if (!(dev->channels & 2)) + return; + + if (irq) { + if (dev->irq_mode[1] == 1) + pci_set_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state); + else + picint(1 << 15); + } else { + if (dev->irq_mode[1] == 1) + pci_clear_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state); + else + picintc(1 << 15); } } @@ -415,10 +429,10 @@ cmd640_reset(void *priv) } if (dev->channels & 0x01) - cmd640_set_irq(0x00, priv); + cmd640_set_irq_0(0x00, priv); if (dev->channels & 0x02) - cmd640_set_irq(0x01, priv); + cmd640_set_irq_1(0x00, priv); memset(dev->regs, 0x00, sizeof(dev->regs)); @@ -509,10 +523,10 @@ cmd640_init(const device_t *info) pci_add_card(PCI_ADD_IDE, cmd640_pci_read, cmd640_pci_write, dev, &dev->pci_slot); if (dev->channels & 0x01) - ide_set_bus_master(0, NULL, cmd640_set_irq, dev); + ide_set_bus_master(0, NULL, cmd640_set_irq_0, dev); if (dev->channels & 0x02) - ide_set_bus_master(1, NULL, cmd640_set_irq, dev); + ide_set_bus_master(1, NULL, cmd640_set_irq_1, dev); /* The CMD PCI-0640B IDE controller has no DMA capability, so set our devices IDE devices to force ATA-3 (no DMA). */ diff --git a/src/disk/hdc_ide_cmd646.c b/src/disk/hdc_ide_cmd646.c index 397329010..8367b9a41 100644 --- a/src/disk/hdc_ide_cmd646.c +++ b/src/disk/hdc_ide_cmd646.c @@ -73,31 +73,41 @@ cmd646_log(const char *fmt, ...) #endif static void -cmd646_set_irq(int channel, void *priv) +cmd646_set_irq_0(uint8_t status, void *priv) { cmd646_t *dev = (cmd646_t *) priv; - if (channel & 0x01) { - if (!(dev->regs[0x57] & 0x10) || (channel & 0x40)) { - dev->regs[0x57] &= ~0x10; - dev->regs[0x57] |= (channel >> 2); - } - } else { - if (!(dev->regs[0x50] & 0x04) || (channel & 0x40)) { - dev->regs[0x50] &= ~0x04; - dev->regs[0x50] |= (channel >> 4); - } - } + if (!(dev->regs[0x50] & 0x04) || (status & 0x04)) + dev->regs[0x50] = (dev->regs[0x50] & ~0x04) | status; - sff_bus_master_set_irq(channel, dev->bm[channel & 0x01]); + sff_bus_master_set_irq(status, dev->bm[0]); +} + +static void +cmd646_set_irq_1(uint8_t status, void *priv) +{ + cmd646_t *dev = (cmd646_t *) priv; + + if (!(dev->regs[0x57] & 0x10) || (status & 0x04)) + dev->regs[0x57] = (dev->regs[0x57] & ~0x10) | (status << 2); + + sff_bus_master_set_irq(status, dev->bm[1]); } static int -cmd646_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv) +cmd646_bus_master_dma_0(uint8_t *data, int transfer_length, int out, void *priv) { const cmd646_t *dev = (cmd646_t *) priv; - return sff_bus_master_dma(channel, data, transfer_length, out, dev->bm[channel & 0x01]); + return sff_bus_master_dma(data, transfer_length, out, dev->bm[0]); +} + +static int +cmd646_bus_master_dma_1(uint8_t *data, int transfer_length, int out, void *priv) +{ + const cmd646_t *dev = (cmd646_t *) priv; + + return sff_bus_master_dma(data, transfer_length, out, dev->bm[1]); } static void @@ -105,7 +115,7 @@ cmd646_ide_handlers(cmd646_t *dev) { uint16_t main; uint16_t side; - int irq_mode[2] = { 0, 0 }; + int irq_mode[2] = { IRQ_MODE_LEGACY, IRQ_MODE_LEGACY }; sff_set_slot(dev->bm[0], dev->pci_slot); sff_set_slot(dev->bm[1], dev->pci_slot); @@ -124,10 +134,9 @@ cmd646_ide_handlers(cmd646_t *dev) ide_set_side(0, side); if (dev->regs[0x09] & 0x01) - irq_mode[0] = 1; + irq_mode[0] = IRQ_MODE_PCI_IRQ_PIN; - sff_set_irq_mode(dev->bm[0], 0, irq_mode[0]); - sff_set_irq_mode(dev->bm[0], 1, irq_mode[1]); + sff_set_irq_mode(dev->bm[0], irq_mode[0]); if (dev->regs[0x04] & 0x01) ide_pri_enable(); @@ -151,8 +160,7 @@ cmd646_ide_handlers(cmd646_t *dev) if (dev->regs[0x09] & 0x04) irq_mode[1] = 1; - sff_set_irq_mode(dev->bm[1], 0, irq_mode[0]); - sff_set_irq_mode(dev->bm[1], 1, irq_mode[1]); + sff_set_irq_mode(dev->bm[1], irq_mode[1]); if ((dev->regs[0x04] & 0x01) && (dev->regs[0x51] & 0x08)) ide_sec_enable(); @@ -321,8 +329,8 @@ cmd646_reset(void *priv) mo_reset((scsi_common_t *) mo_drives[i].priv); } - cmd646_set_irq(0x00, priv); - cmd646_set_irq(0x01, priv); + cmd646_set_irq_0(0x00, priv); + cmd646_set_irq_1(0x00, priv); memset(dev->regs, 0x00, sizeof(dev->regs)); @@ -401,17 +409,14 @@ cmd646_init(const device_t *info) if (!dev->single_channel) dev->bm[1] = device_add_inst(&sff8038i_device, 2); - ide_set_bus_master(0, cmd646_bus_master_dma, cmd646_set_irq, dev); + ide_set_bus_master(0, cmd646_bus_master_dma_0, cmd646_set_irq_0, dev); if (!dev->single_channel) - ide_set_bus_master(1, cmd646_bus_master_dma, cmd646_set_irq, dev); + ide_set_bus_master(1, cmd646_bus_master_dma_1, cmd646_set_irq_1, dev); - sff_set_irq_mode(dev->bm[0], 0, 0); - sff_set_irq_mode(dev->bm[0], 1, 0); + sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); - if (!dev->single_channel) { - sff_set_irq_mode(dev->bm[1], 0, 0); - sff_set_irq_mode(dev->bm[1], 1, 0); - } + if (!dev->single_channel) + sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); cmd646_reset(dev); diff --git a/src/disk/hdc_ide_sff8038i.c b/src/disk/hdc_ide_sff8038i.c index fd6bee29d..40cca95a9 100644 --- a/src/disk/hdc_ide_sff8038i.c +++ b/src/disk/hdc_ide_sff8038i.c @@ -74,7 +74,7 @@ sff_log(const char *fmt, ...) void sff_bus_master_handler(sff8038i_t *dev, int enabled, uint16_t base) { - if (dev->base != 0x0000) { + if (dev->enabled && (dev->base != 0x0000)) { io_removehandler(dev->base, 0x08, sff_bus_master_read, sff_bus_master_readw, sff_bus_master_readl, sff_bus_master_write, sff_bus_master_writew, sff_bus_master_writel, @@ -314,7 +314,7 @@ sff_bus_master_readl(uint16_t port, void *priv) } int -sff_bus_master_dma(UNUSED(int channel), uint8_t *data, int transfer_length, int out, void *priv) +sff_bus_master_dma(uint8_t *data, int transfer_length, int out, void *priv) { sff8038i_t *dev = (sff8038i_t *) priv; #ifdef ENABLE_SFF_LOG @@ -385,64 +385,72 @@ sff_bus_master_dma(UNUSED(int channel), uint8_t *data, int transfer_length, int } void -sff_bus_master_set_irq(int channel, void *priv) +sff_bus_master_set_irq(uint8_t status, void *priv) { sff8038i_t *dev = (sff8038i_t *) priv; - uint8_t irq = !!(channel & 0x40); + uint8_t irq = !!(status & 0x04); + int irq_shift = 0; - if (!(dev->status & 0x04) || (channel & 0x40)) { - dev->status &= ~0x04; - dev->status |= (channel >> 4); - } + if (!(dev->status & 0x04) || (status & 0x04)) + dev->status = (dev->status & ~0x04) | status; - channel &= 0x01; - - switch (dev->irq_mode[channel]) { + switch (dev->irq_mode) { default: - case 0: + case IRQ_MODE_LEGACY: /* Legacy IRQ mode. */ if (irq) - picint(1 << (14 + channel)); + picint(1 << dev->irq_line); else - picintc(1 << (14 + channel)); + picintc(1 << dev->irq_line); break; - case 1: + case IRQ_MODE_PCI_IRQ_PIN: /* Native PCI IRQ mode with interrupt pin. */ if (irq) pci_set_irq(dev->slot, dev->irq_pin, &dev->irq_state); else pci_clear_irq(dev->slot, dev->irq_pin, &dev->irq_state); break; - case 2: - case 5: + case IRQ_MODE_MIRQ_0: + case IRQ_MODE_MIRQ_1: /* MIRQ 0 or 1. */ + case IRQ_MODE_MIRQ_2: + case IRQ_MODE_MIRQ_3: + /* MIRQ 2 or 3. */ if (irq) - pci_set_mirq((dev->irq_mode[channel] & 1), 0, &dev->irq_state); + pci_set_mirq((dev->irq_mode & 3) + irq_shift, 0, &dev->irq_state); else - pci_clear_mirq((dev->irq_mode[channel] & 1), 0, &dev->irq_state); + pci_clear_mirq((dev->irq_mode & 3) + irq_shift, 0, &dev->irq_state); break; - case 3: + /* TODO: Redo this as a MIRQ. */ + case IRQ_MODE_PCI_IRQ_LINE: /* Native PCI IRQ mode with specified interrupt line. */ if (irq) - picintlevel(1 << dev->irq_line, &dev->irq_state); + pci_set_dirq(dev->pci_irq_line, &dev->irq_state); else - picintclevel(1 << dev->irq_line, &dev->irq_state); + pci_clear_dirq(dev->pci_irq_line, &dev->irq_state); break; - case 4: + case IRQ_MODE_ALI_ALADDIN: /* ALi Aladdin Native PCI INTAJ mode. */ if (irq) - pci_set_mirq((channel + 2), dev->irq_level[channel], &dev->irq_state); + pci_set_mirq((dev->channel + 2), pci_get_mirq_level(dev->channel + 2), &dev->irq_state); else - pci_clear_mirq((channel + 2), dev->irq_level[channel], &dev->irq_state); + pci_clear_mirq((dev->channel + 2), pci_get_mirq_level(dev->channel + 2), &dev->irq_state); + break; + case IRQ_MODE_SIS_551X: + /* SiS 551x mode. */ + if (irq) + pci_set_mirq(2, 1, &dev->irq_state); + else + pci_clear_mirq(2, 1, &dev->irq_state); break; } } void -sff_bus_master_reset(sff8038i_t *dev, uint16_t old_base) +sff_bus_master_reset(sff8038i_t *dev) { - if (dev->enabled) { - io_removehandler(old_base, 0x08, + if (dev->enabled && (dev->base != 0x0000)) { + io_removehandler(dev->base, 0x08, sff_bus_master_read, sff_bus_master_readw, sff_bus_master_readl, sff_bus_master_write, sff_bus_master_writew, sff_bus_master_writel, dev); @@ -493,44 +501,54 @@ sff_set_slot(sff8038i_t *dev, int slot) } void -sff_set_irq_line(sff8038i_t *dev, int irq_line) +sff_set_irq_line(sff8038i_t *dev, int pci_irq_line) { - dev->irq_line = irq_line; + dev->pci_irq_line = pci_irq_line; +} + +/* TODO: Why does this always set the level to 0, regardless of the parameter?! */ +void +sff_set_irq_level(sff8038i_t *dev, UNUSED(int irq_level)) +{ + dev->irq_level = 0; } void -sff_set_irq_level(sff8038i_t *dev, int channel, UNUSED(int irq_level)) +sff_set_irq_mode(sff8038i_t *dev, int irq_mode) { - dev->irq_level[channel] = 0; -} + dev->irq_mode = irq_mode; -void -sff_set_irq_mode(sff8038i_t *dev, int channel, int irq_mode) -{ - dev->irq_mode[channel] = irq_mode; - - switch (dev->irq_mode[channel]) { + switch (dev->irq_mode) { default: - case 0: + case IRQ_MODE_LEGACY: /* Legacy IRQ mode. */ - sff_log("[%08X] Setting channel %i to legacy IRQ %i\n", dev, channel, 14 + channel); + sff_log("[%08X] Setting IRQ mode to legacy IRQ %i\n", dev, 14 + channel); break; - case 1: + case IRQ_MODE_PCI_IRQ_PIN: /* Native PCI IRQ mode with interrupt pin. */ - sff_log("[%08X] Setting channel %i to native PCI INT%c\n", dev, channel, '@' + dev->irq_pin); + sff_log("[%08X] Setting IRQ mode to native PCI INT%c\n", dev, 0x40 + dev->irq_pin); break; - case 2: - case 5: + case IRQ_MODE_MIRQ_0: + case IRQ_MODE_MIRQ_1: /* MIRQ 0 or 1. */ - sff_log("[%08X] Setting channel %i to PCI MIRQ%i\n", dev, channel, irq_mode & 1); + sff_log("[%08X] Setting IRQ mode to PCI MIRQ%i\n", dev, irq_mode & 1); break; - case 3: + case IRQ_MODE_MIRQ_2: + case IRQ_MODE_MIRQ_3: + /* MIRQ 0 or 1. */ + sff_log("[%08X] Setting IRQ mode to PCI MIRQ%i\n", dev, (irq_mode & 1) + 1); + break; + case IRQ_MODE_PCI_IRQ_LINE: /* Native PCI IRQ mode with specified interrupt line. */ - sff_log("[%08X] Setting channel %i to native PCI IRQ %i\n", dev, channel, dev->irq_line); + sff_log("[%08X] Setting IRQ mode to native PCI IRQ %i\n", dev, dev->pci_irq_line); break; - case 4: + case IRQ_MODE_ALI_ALADDIN: /* ALi Aladdin Native PCI INTAJ mode. */ - sff_log("[%08X] Setting channel %i to INT%cJ\n", dev, channel, 'A' + channel); + sff_log("[%08X] Setting IRQ mode to INT%cJ\n", dev, 'A' + dev->channel); + break; + case IRQ_MODE_SIS_551X: + /* SiS 551x mode. */ + sff_log("[%08X] Setting IRQ mode to PCI MIRQ2\n", dev); break; } } @@ -566,13 +584,15 @@ sff_init(UNUSED(const device_t *info)) ide_set_bus_master(next_id, sff_bus_master_dma, sff_bus_master_set_irq, dev); dev->slot = 7; - dev->irq_mode[0] = 0; /* Channel 0 goes to IRQ 14. */ - dev->irq_mode[1] = 2; /* Channel 1 goes to MIRQ0. */ + /* Channel 0 goes to IRQ 14, channel 1 goes to MIRQ0. */ + dev->irq_mode = next_id ? IRQ_MODE_MIRQ_0 : IRQ_MODE_LEGACY; dev->irq_pin = PCI_INTA; - dev->irq_line = 14; - dev->irq_level[0] = dev->irq_level[1] = 0; + dev->irq_line = 14 + next_id; + dev->pci_irq_line = 14; + dev->irq_level = 0; dev->irq_state = 0; + dev->channel = next_id; next_id++; return dev; diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index 9735b42b5..88948aed9 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -191,10 +191,8 @@ fdc_card_get_from_internal_name(char *s) void fdc_card_init(void) { - if (!fdc_cards[fdc_type].device) - return; - - device_add(fdc_cards[fdc_type].device); + if ((fdc_type > 0) && fdc_cards[fdc_type].device) + device_add(fdc_cards[fdc_type].device); } uint8_t diff --git a/src/include/86box/device.h b/src/include/86box/device.h index 57cf7c849..b2d7a05ed 100644 --- a/src/include/86box/device.h +++ b/src/include/86box/device.h @@ -41,20 +41,23 @@ #ifndef EMU_DEVICE_H #define EMU_DEVICE_H -#define CONFIG_END -1 -#define CONFIG_STRING 0 -#define CONFIG_INT 1 -#define CONFIG_BINARY 2 -#define CONFIG_SELECTION 3 -#define CONFIG_MIDI_OUT 4 -#define CONFIG_FNAME 5 -#define CONFIG_SPINNER 6 -#define CONFIG_HEX16 7 -#define CONFIG_HEX20 8 -#define CONFIG_MAC 9 -#define CONFIG_MIDI_IN 10 -#define CONFIG_BIOS 11 -#define CONFIG_SERPORT 12 +#define CONFIG_END -1 +#define CONFIG_STRING 0 +#define CONFIG_INT 1 +#define CONFIG_BINARY 2 +#define CONFIG_SELECTION 3 +#define CONFIG_MIDI_OUT 4 +#define CONFIG_FNAME 5 +#define CONFIG_SPINNER 6 +#define CONFIG_HEX16 7 +#define CONFIG_HEX20 8 +#define CONFIG_MAC 9 +#define CONFIG_MIDI_IN 10 +#define CONFIG_BIOS 11 +#define CONFIG_SERPORT 12 + +#define CONFIG_ONBOARD 256 /* only avaialble on the on-board variant */ +#define CONFIG_STANDALONE 257 /* not available on the on-board variant */ enum { DEVICE_PCJR = 2, /* requires an IBM PCjr */ @@ -68,19 +71,23 @@ enum { DEVICE_MCA = 0x200, /* requires the MCA bus */ DEVICE_HIL = 0x400, /* requires the HP HIL bus */ DEVICE_EISA = 0x800, /* requires the EISA bus */ - DEVICE_OLB = 0x1000, /* requires the OPTi local bus */ - DEVICE_VLB = 0x2000, /* requires the VLB bus */ - DEVICE_PCI = 0x4000, /* requires the PCI bus */ - DEVICE_CARDBUS = 0x8000, /* requires the CardBus bus */ - DEVICE_USB = 0x10000, /* requires the USB bus */ - DEVICE_AGP = 0x20000, /* requires the AGP bus */ - DEVICE_AC97 = 0x40000, /* requires the AC'97 bus */ - DEVICE_COM = 0x80000, /* requires a serial port */ - DEVICE_LPT = 0x100000, /* requires a parallel port */ - DEVICE_KBC = 0x200000, /* is a keyboard controller */ + DEVICE_AT32 = 0x1000, /* requires the Mylex AT/32 local bus */ + DEVICE_OLB = 0x2000, /* requires the OPTi local bus */ + DEVICE_VLB = 0x4000, /* requires the VLB bus */ + DEVICE_PCI = 0x8000, /* requires the PCI bus */ + DEVICE_CARDBUS = 0x10000, /* requires the CardBus bus */ + DEVICE_USB = 0x20000, /* requires the USB bus */ + DEVICE_AGP = 0x40000, /* requires the AGP bus */ + DEVICE_AC97 = 0x80000, /* requires the AC'97 bus */ + DEVICE_COM = 0x100000, /* requires a serial port */ + DEVICE_LPT = 0x200000, /* requires a parallel port */ + DEVICE_KBC = 0x400000, /* is a keyboard controller */ + DEVICE_ONBOARD = 0x20000000, /* is on-board */ DEVICE_EXTPARAMS = 0x40000000, /* accepts extended parameters */ + DEVICE_PIT = 0x80000000, /* device is a PIT */ + DEVICE_ALL = 0xffffffff /* match all devices */ }; @@ -183,6 +190,7 @@ extern void device_cadd_inst_ex(const device_t *dev, const device_t *cd, void * extern void device_cadd_inst_ex_parameters(const device_t *dev, const device_t *cd, void *priv, int inst, void *params); extern void device_close_all(void); extern void device_reset_all(uint32_t match_flags); +extern void *device_find_first_priv(uint32_t match_flags); extern void *device_get_priv(const device_t *dev); extern int device_available(const device_t *dev); extern int device_poll(const device_t *dev); diff --git a/src/include/86box/filters.h b/src/include/86box/filters.h index f93695433..dfe19c654 100644 --- a/src/include/86box/filters.h +++ b/src/include/86box/filters.h @@ -197,8 +197,8 @@ low_iir(int c, int i, double NewSample) 0.93726236021404663000 }; - static double y[2][2][NCoef + 1]; /* output samples */ - static double x[2][2][NCoef + 1]; /* input samples */ + static double y[3][2][NCoef + 1]; /* output samples */ + static double x[3][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -232,8 +232,8 @@ low_cut_iir(int c, int i, double NewSample) 0.93726236021916731000 }; - static double y[2][2][NCoef + 1]; /* output samples */ - static double x[2][2][NCoef + 1]; /* input samples */ + static double y[3][2][NCoef + 1]; /* output samples */ + static double x[3][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -266,8 +266,8 @@ high_iir(int c, int i, double NewSample) -1.36640781670578510000, 0.52352474706139873000 }; - static double y[2][2][NCoef + 1]; /* output samples */ - static double x[2][2][NCoef + 1]; /* input samples */ + static double y[3][2][NCoef + 1]; /* output samples */ + static double x[3][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -300,8 +300,8 @@ high_cut_iir(int c, int i, double NewSample) -1.36640781666419950000, 0.52352474703279628000 }; - static double y[2][2][NCoef + 1]; /* output samples */ - static double x[2][2][NCoef + 1]; /* input samples */ + static double y[3][2][NCoef + 1]; /* output samples */ + static double x[3][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -334,8 +334,8 @@ deemph_iir(int i, double NewSample) -1.05429146278569141337, 0.26412280202756849290 }; - static double y[2][NCoef + 1]; /* output samples */ - static double x[2][NCoef + 1]; /* input samples */ + static double y[3][NCoef + 1]; /* output samples */ + static double x[3][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -372,8 +372,8 @@ sb_iir(int c, int i, double NewSample) 0.55326988968868285000 }; - static double y[2][2][NCoef + 1]; /* output samples */ - static double x[2][2][NCoef + 1]; /* input samples */ + static double y[3][2][NCoef + 1]; /* output samples */ + static double x[3][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -395,13 +395,13 @@ sb_iir(int c, int i, double NewSample) #define NCoef 1 #define SB16_NCoef 51 -extern double low_fir_sb16_coef[2][SB16_NCoef]; +extern double low_fir_sb16_coef[3][SB16_NCoef]; static inline double low_fir_sb16(int c, int i, double NewSample) { - static double x[2][2][SB16_NCoef + 1]; // input samples - static int pos[2] = { 0, 0 }; + static double x[3][2][SB16_NCoef + 1]; // input samples + static int pos[3] = { 0, 0 }; double out = 0.0; int n; diff --git a/src/include/86box/hdc_ide.h b/src/include/86box/hdc_ide.h index 7ecb188e6..37b11da85 100644 --- a/src/include/86box/hdc_ide.h +++ b/src/include/86box/hdc_ide.h @@ -149,8 +149,8 @@ extern uint8_t ide_read_alt_status(uint16_t addr, void *priv); extern uint16_t ide_readw(uint16_t addr, void *priv); extern void ide_set_bus_master(int board, - int (*dma)(int channel, uint8_t *data, int transfer_length, int out, void *priv), - void (*set_irq)(int channel, void *priv), void *priv); + int (*dma)(uint8_t *data, int transfer_length, int out, void *priv), + void (*set_irq)(uint8_t status, void *priv), void *priv); extern void win_cdrom_eject(uint8_t id); extern void win_cdrom_reload(uint8_t id); @@ -180,10 +180,6 @@ extern void ide_set_board_callback(uint8_t board, double callback); extern void ide_padstr(char *str, const char *src, int len); extern void ide_padstr8(uint8_t *buf, int buf_size, const char *src); -extern int (*ide_bus_master_dma)(int channel, uint8_t *data, int transfer_length, int out, void *priv); -extern void (*ide_bus_master_set_irq)(int channel, void *priv); -extern void *ide_bus_master_priv[2]; - extern uint8_t ide_read_ali_75(void); extern uint8_t ide_read_ali_76(void); diff --git a/src/include/86box/hdc_ide_sff8038i.h b/src/include/86box/hdc_ide_sff8038i.h index f9c40e29a..2283497bb 100644 --- a/src/include/86box/hdc_ide_sff8038i.h +++ b/src/include/86box/hdc_ide_sff8038i.h @@ -20,52 +20,62 @@ #ifndef EMU_HDC_IDE_SFF8038I_H #define EMU_HDC_IDE_SFF8038I_H -typedef struct sff8038i_t { +enum +{ + IRQ_MODE_LEGACY = 0, + IRQ_MODE_PCI_IRQ_PIN, + IRQ_MODE_PCI_IRQ_LINE, + IRQ_MODE_ALI_ALADDIN, + IRQ_MODE_MIRQ_0, + IRQ_MODE_MIRQ_1, + IRQ_MODE_MIRQ_2, + IRQ_MODE_MIRQ_3, + IRQ_MODE_SIS_551X +}; + +typedef struct sff8038i_t +{ uint8_t command; uint8_t status; uint8_t ptr0; uint8_t enabled; uint8_t dma_mode; uint8_t irq_state; - uint8_t pad; - uint8_t pad0; + uint8_t channel; + uint8_t irq_line; uint16_t base; - uint16_t pad1; + uint16_t pad; uint32_t ptr; uint32_t ptr_cur; uint32_t addr; int count; int eot; int slot; - int irq_mode[2]; - int irq_level[2]; + int irq_mode; + int irq_level; int irq_pin; - int irq_line; + int pci_irq_line; } sff8038i_t; extern const device_t sff8038i_device; extern void sff_bus_master_handler(sff8038i_t *dev, int enabled, uint16_t base); -extern int sff_bus_master_dma_read(int channel, uint8_t *data, int transfer_length, void *priv); -extern int sff_bus_master_dma_write(int channel, uint8_t *data, int transfer_length, void *priv); - -extern void sff_bus_master_set_irq(int channel, void *priv); - -extern int sff_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv); +extern void sff_bus_master_set_irq(uint8_t status, void *priv); +extern int sff_bus_master_dma(uint8_t *data, int transfer_length, int out, void *priv); extern void sff_bus_master_write(uint16_t port, uint8_t val, void *priv); extern uint8_t sff_bus_master_read(uint16_t port, void *priv); -extern void sff_bus_master_reset(sff8038i_t *dev, uint16_t old_base); +extern void sff_bus_master_reset(sff8038i_t *dev); extern void sff_set_slot(sff8038i_t *dev, int slot); extern void sff_set_irq_line(sff8038i_t *dev, int irq_line); -extern void sff_set_irq_mode(sff8038i_t *dev, int channel, int irq_mode); +extern void sff_set_irq_mode(sff8038i_t *dev, int irq_mode); extern void sff_set_irq_pin(sff8038i_t *dev, int irq_pin); -extern void sff_set_irq_level(sff8038i_t *dev, int channel, int irq_level); +extern void sff_set_irq_level(sff8038i_t *dev, int irq_level); #endif /*EMU_HDC_IDE_SFF8038I_H*/ diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 27735b4dd..bc0443011 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -39,14 +39,15 @@ #define MACHINE_BUS_PS2 (MACHINE_BUS_PS2_LATCH | MACHINE_BUS_PS2_PORTS) #define MACHINE_BUS_HIL 0x00000400 /* system has HP HIL keyboard and mouse ports */ #define MACHINE_BUS_EISA 0x00000800 /* sys has EISA bus */ -#define MACHINE_BUS_OLB 0x00001000 /* sys has OPTi local bus */ -#define MACHINE_BUS_VLB 0x00002000 /* sys has VL bus */ -#define MACHINE_BUS_MCA 0x00004000 /* sys has MCA bus */ -#define MACHINE_BUS_PCI 0x00008000 /* sys has PCI bus */ -#define MACHINE_BUS_CARDBUS 0x00010000 /* sys has CardBus bus */ -#define MACHINE_BUS_USB 0x00020000 /* sys has USB bus */ -#define MACHINE_BUS_AGP 0x00040000 /* sys has AGP bus */ -#define MACHINE_BUS_AC97 0x00080000 /* sys has AC97 bus (ACR/AMR/CNR slot) */ +#define MACHINE_BUS_AT32 0x00001000 /* sys has Mylex AT/32 local bus */ +#define MACHINE_BUS_OLB 0x00002000 /* sys has OPTi local bus */ +#define MACHINE_BUS_VLB 0x00004000 /* sys has VL bus */ +#define MACHINE_BUS_MCA 0x00008000 /* sys has MCA bus */ +#define MACHINE_BUS_PCI 0x00010000 /* sys has PCI bus */ +#define MACHINE_BUS_CARDBUS 0x00020000 /* sys has CardBus bus */ +#define MACHINE_BUS_USB 0x00040000 /* sys has USB bus */ +#define MACHINE_BUS_AGP 0x00080000 /* sys has AGP bus */ +#define MACHINE_BUS_AC97 0x00100000 /* sys has AC97 bus (ACR/AMR/CNR slot) */ /* Aliases. */ #define MACHINE_CASSETTE (MACHINE_BUS_CASSETTE) /* sys has cassette port */ #define MACHINE_CARTRIDGE (MACHINE_BUS_CARTRIDGE) /* sys has two cartridge bays */ diff --git a/src/include/86box/mouse.h b/src/include/86box/mouse.h index 93c9a744d..3ed6b2126 100644 --- a/src/include/86box/mouse.h +++ b/src/include/86box/mouse.h @@ -50,7 +50,7 @@ extern "C" { #endif extern int mouse_type; -extern int mouse_mode; /* 1 = Absolute, 0 = Relative */ +extern int mouse_input_mode; /* 1 = Absolute, 0 = Relative */ extern int mouse_timed; /* 1 = Timed, 0 = Constant */ extern int mouse_tablet_in_proximity; extern double mouse_x_abs; diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index c5ddfe4df..17f9f6687 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -147,10 +147,14 @@ #define pci_set_mirq(mirq, level, irq_state) \ pci_irq(PCI_MIRQ_BASE | (mirq), 0, level, 1, irq_state) +#define pci_set_dirq(irq, irq_state) \ + pci_irq(PCI_DIRQ_BASE | (irq), 0, 1, 1, irq_state) #define pci_set_irq(slot, pci_int, irq_state) \ pci_irq(slot, pci_int, 0, 1, irq_state) #define pci_clear_mirq(mirq, level, irq_state) \ pci_irq(PCI_MIRQ_BASE | (mirq), 0, level, 0, irq_state) +#define pci_clear_dirq(dirq, irq_state) \ + pci_irq(PCI_DIRQ_BASE | (irq), 0, 1, 0, irq_state) #define pci_clear_irq(slot, pci_int, irq_state) \ pci_irq(slot, pci_int, 0, 0, irq_state) @@ -216,7 +220,9 @@ extern uint32_t pci_size; extern void pci_set_irq_routing(int pci_int, int irq); extern void pci_set_irq_level(int pci_int, int level); extern void pci_enable_mirq(int mirq); -extern void pci_set_mirq_routing(int mirq, int irq); +extern void pci_set_mirq_routing(int mirq, uint8_t irq); +extern uint8_t pci_get_mirq_level(int mirq); +extern void pci_set_mirq_level(int mirq, uint8_t irq); /* PCI raise IRQ: the first parameter is slot if < PCI_MIRQ_BASE, MIRQ if >= PCI_MIRQ_BASE and < PCI_DIRQ_BASE, and direct IRQ line if >= PCI_DIRQ_BASE (RichardG's diff --git a/src/include/86box/pic.h b/src/include/86box/pic.h index a66e511b8..798cc3357 100644 --- a/src/include/86box/pic.h +++ b/src/include/86box/pic.h @@ -81,9 +81,11 @@ extern void pic_init_pcjr(void); extern void pic2_init(void); extern void pic_reset(void); -extern int picint_is_level(int irq); -extern void picint_common(uint16_t num, int level, int set, uint8_t *irq_state); -extern int picinterrupt(void); +extern uint8_t pic_read_icw(uint8_t pic_id, uint8_t icw); +extern uint8_t pic_read_ocw(uint8_t pic_id, uint8_t ocw); +extern int picint_is_level(int irq); +extern void picint_common(uint16_t num, int level, int set, uint8_t *irq_state); +extern int picinterrupt(void); #define PIC_IRQ_EDGE 0 #define PIC_IRQ_LEVEL 1 diff --git a/src/include/86box/pit.h b/src/include/86box/pit.h index af9142625..d288b7e6c 100644 --- a/src/include/86box/pit.h +++ b/src/include/86box/pit.h @@ -131,6 +131,8 @@ extern void pit_nmi_timer_ps2(int new_out, int old_out); extern void pit_set_clock(uint32_t clock); extern void pit_handler(int set, uint16_t base, int size, void *priv); +extern uint8_t pit_read_reg(void *priv, uint8_t reg); + #ifdef EMU_DEVICE_H extern const device_t i8253_device; extern const device_t i8254_device; diff --git a/src/include/86box/pit_fast.h b/src/include/86box/pit_fast.h index a7caeabe7..2485a360c 100644 --- a/src/include/86box/pit_fast.h +++ b/src/include/86box/pit_fast.h @@ -69,6 +69,8 @@ typedef struct pitf_t { uint8_t ctrl; } pitf_t; +extern uint8_t pitf_read_reg(void *priv, uint8_t reg); + extern const pit_intf_t pit_fast_intf; #ifdef EMU_DEVICE_H diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index 8b95b55b5..2736a4eb5 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -72,6 +72,7 @@ extern const device_t sio_detect_device; #endif extern const device_t um8669f_device; extern const device_t via_vt82c686_sio_device; +extern const device_t w83787f_88h_device; extern const device_t w83787f_device; extern const device_t w83787f_ide_device; extern const device_t w83787f_ide_en_device; diff --git a/src/include/86box/snd_sb.h b/src/include/86box/snd_sb.h index f83a31eb8..f433dd107 100644 --- a/src/include/86box/snd_sb.h +++ b/src/include/86box/snd_sb.h @@ -25,15 +25,18 @@ #include <86box/snd_opl.h> #include <86box/snd_sb_dsp.h> -#define SADLIB 1 /* No DSP */ -#define SB1 2 /* DSP v1.05 */ -#define SB15 3 /* DSP v2.00 */ -#define SB2 4 /* DSP v2.01 - needed for high-speed DMA */ -#define SBPRO 5 /* DSP v3.00 */ -#define SBPRO2 6 /* DSP v3.02 + OPL3 */ -#define SB16 7 /* DSP v4.05 + OPL3 */ -#define SBAWE32 8 /* DSP v4.13 + OPL3 */ -#define SBAWE64 9 /* DSP v4.16 + OPL3 */ +enum { + SADLIB = 1, /* No DSP */ + SB1, /* DSP v1.05 */ + SB15, /* DSP v2.00 */ + SB2, /* DSP v2.01 - needed for high-speed DMA */ + SBPRO, /* DSP v3.00 */ + SBPRO2, /* DSP v3.02 + OPL3 */ + SB16, /* DSP v4.05 + OPL3 */ + SBAWE32, /* DSP v4.12 + OPL3 */ + SBAWE32PNP, /* DSP v4.13 + OPL3 */ + SBAWE64 /* DSP v4.16 + OPL3 */ +}; /* SB 2.0 CD version */ typedef struct sb_ct1335_mixer_t { @@ -141,6 +144,7 @@ typedef struct sb_t { void *gameport; int pos; + int pnp; uint8_t pos_regs[8]; uint8_t pnp_rom[512]; diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index f106942ff..ecabe426d 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -33,6 +33,10 @@ typedef struct sb_dsp_t { int sb_16_autolen; int sb_16_output; int sb_16_dmanum; + int sb_16_8_dmanum; + int sb_16_dma_enabled; + int sb_16_dma_supported; + int sb_16_dma_translate; int sb_pausetime; int (*dma_readb)(void *priv); int (*dma_readw)(void *priv); @@ -132,35 +136,39 @@ typedef struct sb_dsp_t { mpu_t *mpu; } sb_dsp_t; -void sb_dsp_input_msg(void *priv, uint8_t *msg, uint32_t len); +extern void sb_dsp_input_msg(void *priv, uint8_t *msg, uint32_t len); -int sb_dsp_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort); +extern int sb_dsp_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort); -void sb_dsp_set_mpu(sb_dsp_t *dsp, mpu_t *src_mpu); +extern void sb_dsp_set_mpu(sb_dsp_t *dsp, mpu_t *src_mpu); -void sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent); -void sb_dsp_close(sb_dsp_t *dsp); +extern void sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent); +extern void sb_dsp_close(sb_dsp_t *dsp); -void sb_dsp_setirq(sb_dsp_t *dsp, int irq); -void sb_dsp_setdma8(sb_dsp_t *dsp, int dma); -void sb_dsp_setdma16(sb_dsp_t *dsp, int dma); -void sb_dsp_setaddr(sb_dsp_t *dsp, uint16_t addr); +extern void sb_dsp_setirq(sb_dsp_t *dsp, int irq); +extern void sb_dsp_setdma8(sb_dsp_t *dsp, int dma); +extern void sb_dsp_setdma16(sb_dsp_t *dsp, int dma); +extern void sb_dsp_setdma16_8(sb_dsp_t *dsp, int dma); +extern void sb_dsp_setdma16_enabled(sb_dsp_t *dsp, int enabled); +extern void sb_dsp_setdma16_supported(sb_dsp_t *dsp, int supported); +extern void sb_dsp_setdma16_translate(sb_dsp_t *dsp, int translate); +extern void sb_dsp_setaddr(sb_dsp_t *dsp, uint16_t addr); -void sb_dsp_speed_changed(sb_dsp_t *dsp); +extern void sb_dsp_speed_changed(sb_dsp_t *dsp); -void sb_dsp_poll(sb_dsp_t *dsp, int16_t *l, int16_t *r); +extern void sb_dsp_poll(sb_dsp_t *dsp, int16_t *l, int16_t *r); -void sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo); +extern void sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo); -void sb_dsp_update(sb_dsp_t *dsp); -void sb_update_mask(sb_dsp_t *dsp, int irqm8, int irqm16, int irqm401); +extern void sb_dsp_update(sb_dsp_t *dsp); +extern void sb_update_mask(sb_dsp_t *dsp, int irqm8, int irqm16, int irqm401); -void sb_dsp_irq_attach(sb_dsp_t *dsp, void (*irq_update)(void *priv, int set), void *priv); -void sb_dsp_dma_attach(sb_dsp_t *dsp, - int (*dma_readb)(void *priv), - int (*dma_readw)(void *priv), - int (*dma_writeb)(void *priv, uint8_t val), - int (*dma_writew)(void *priv, uint16_t val), - void *priv); +extern void sb_dsp_irq_attach(sb_dsp_t *dsp, void (*irq_update)(void *priv, int set), void *priv); +extern void sb_dsp_dma_attach(sb_dsp_t *dsp, + int (*dma_readb)(void *priv), + int (*dma_readw)(void *priv), + int (*dma_writeb)(void *priv, uint8_t val), + int (*dma_writew)(void *priv, uint16_t val), + void *priv); #endif /* SOUND_SND_SB_DSP_H */ diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index 28dda0c02..60628ece8 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -52,9 +52,16 @@ extern int sound_card_current[SOUND_CARD_MAX]; extern void sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *priv), void *priv); + extern void sound_set_cd_audio_filter(void (*filter)(int channel, double *buffer, void *priv), void *priv); +extern void sound_set_pc_speaker_filter(void (*filter)(int channel, + double *buffer, void *priv), + void *priv); + +extern void (*filter_pc_speaker)(int channel, double *buffer, void *priv); +extern void *filter_pc_speaker_p; extern int sound_card_available(int card); #ifdef EMU_DEVICE_H diff --git a/src/include/86box/video.h b/src/include/86box/video.h index a28faf335..1858fc246 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -187,6 +187,8 @@ extern int video_fullscreen_scale; extern int video_fullscreen_first; extern uint8_t fontdat[2048][8]; extern uint8_t fontdatm[2048][16]; +extern uint8_t fontdat2[2048][8]; +extern uint8_t fontdatm2[2048][16]; extern uint8_t fontdatw[512][32]; extern uint8_t fontdat8x12[256][16]; extern uint8_t fontdat12x18[256][36]; diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index 1d208dea2..86656b181 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -280,7 +280,7 @@ compaq_plasma_poll(void *priv) uint32_t fg = (self->cga.cgacol & 0x0f) ? amber : black; uint32_t bg = black; uint32_t cols[2]; - uint8_t dat2; + uint8_t dat; uint8_t pattern; uint32_t ink0 = 0; uint32_t ink1 = 0; @@ -315,25 +315,25 @@ compaq_plasma_poll(void *priv) addr = ((self->cga.displine >> 1) & 1) * 0x2000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1); } for (uint8_t x = 0; x < 80; x++) { - dat2 = self->cga.vram[addr & 0x7FFF]; + dat = self->cga.vram[addr & 0x7FFF]; addr++; for (uint8_t c = 0; c < 8; c++) { - ink = (dat2 & 0x80) ? fg : bg; + ink = (dat & 0x80) ? fg : bg; if (!(self->cga.cgamode & 8)) ink = black; (buffer32->line[self->cga.displine])[x * 8 + c] = ink; - dat2 <<= 1; + dat <<= 1; } } } else { addr = ((self->cga.displine >> 1) & 1) * 0x2000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1); for (uint8_t x = 0; x < 80; x++) { - dat2 = self->cga.vram[addr & 0x7fff]; + dat = self->cga.vram[addr & 0x7fff]; addr++; for (uint8_t c = 0; c < 4; c++) { - pattern = (dat2 & 0xC0) >> 6; + pattern = (dat & 0xC0) >> 6; if (!(self->cga.cgamode & 8)) pattern = 0; @@ -368,7 +368,7 @@ compaq_plasma_poll(void *priv) } buffer32->line[self->cga.displine][x * 8 + 2 * c] = ink0; buffer32->line[self->cga.displine][x * 8 + 2 * c + 1] = ink1; - dat2 <<= 2; + dat <<= 2; } } } @@ -386,34 +386,25 @@ compaq_plasma_poll(void *priv) /* for each text column */ for (uint8_t x = 0; x < 80; x++) { /* video output enabled */ - if (self->cga.cgamode & 8) { - chr = self->cga.vram[(addr + 2 * x) & 0x7fff]; - attr = self->cga.vram[(addr + 2 * x + 1) & 0x7fff]; - } else - chr = attr = 0; - /* check if cursor has to be drawn */ - drawcursor = ((ma == ca) && cursorline && self->cga.cursoron); + chr = self->cga.vram[(addr + 2 * x) & 0x7FFF]; + attr = self->cga.vram[(addr + 2 * x + 1) & 0x7FFF]; + drawcursor = ((ma == ca) && cursorline && (self->cga.cgamode & 8) && (self->cga.cgablink & 16)); + + blink = ((self->cga.cgablink & 16) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); underline = ((self->port_23c6 & 0x40) && (attr & 0x1) && !(attr & 0x6)); - if (underline) { - /* set forecolor to white */ - attr |= 7; - } - blink = 0; /* blink active */ if (self->cga.cgamode & 0x20) { cols[1] = blinkcols[attr][1]; cols[0] = blinkcols[attr][0]; /* attribute 7 active and not cursor */ - if ((self->cga.cgablink & 8) && (attr & 0x80) && !self->cga.drawcursor) { + if (blink) { /* set blinking */ cols[1] = cols[0]; - blink = 1; } } else { /* Set intensity bit */ cols[1] = normcols[attr][1]; cols[0] = normcols[attr][0]; - blink = (attr & 0x80) * 8 + 7 + 16; } /* character underline active and 7th row of pixels in character height being drawn */ if (underline && (sc == 7)) { @@ -422,10 +413,10 @@ compaq_plasma_poll(void *priv) buffer32->line[self->cga.displine][(x << 3) + c] = mdaattr[attr][blink][1]; } else if (drawcursor) { for (uint8_t c = 0; c < 8; c++) - buffer32->line[self->cga.displine][(x << 3) + c] = cols[(fontdatm[chr + self->cga.fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); + buffer32->line[self->cga.displine][(x << 3) + c] = cols[(fontdatm2[chr + self->cga.fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); } else { for (uint8_t c = 0; c < 8; c++) - buffer32->line[self->cga.displine][(x << 3) + c] = cols[(fontdatm[chr + self->cga.fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0]; + buffer32->line[self->cga.displine][(x << 3) + c] = cols[(fontdatm2[chr + self->cga.fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0]; } ++ma; @@ -441,34 +432,25 @@ compaq_plasma_poll(void *priv) cursorline = ((self->cga.crtc[0x0a] & 0x0f) * 2 <= sc) && ((self->cga.crtc[0x0b] & 0x0F) * 2 >= sc); for (uint8_t x = 0; x < 40; x++) { - if (self->cga.cgamode & 8) { - chr = self->cga.vram[(addr + 2 * x) & 0x7fff]; - attr = self->cga.vram[(addr + 2 * x + 1) & 0x7fff]; - } else { - chr = attr = 0; - } - drawcursor = ((ma == ca) && cursorline && self->cga.cursoron); + chr = self->cga.vram[(addr + 2 * x) & 0x7FFF]; + attr = self->cga.vram[(addr + 2 * x + 1) & 0x7FFF]; + drawcursor = ((ma == ca) && cursorline && (self->cga.cgamode & 8) && (self->cga.cgablink & 16)); + + blink = ((self->cga.cgablink & 16) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); underline = ((self->port_23c6 & 0x40) && (attr & 0x1) && !(attr & 0x6)); - if (underline) { - /* set forecolor to white */ - attr |= 7; - } - blink = 0; /* blink active */ if (self->cga.cgamode & 0x20) { cols[1] = blinkcols[attr][1]; cols[0] = blinkcols[attr][0]; /* attribute 7 active and not cursor */ - if ((self->cga.cgablink & 8) && (attr & 0x80) && !self->cga.drawcursor) { + if (blink) { /* set blinking */ cols[1] = cols[0]; - blink = 1; } } else { /* Set intensity bit */ cols[1] = normcols[attr][1]; cols[0] = normcols[attr][0]; - blink = (attr & 0x80) * 8 + 7 + 16; } /* character underline active and 7th row of pixels in character height being drawn */ if (underline && (sc == 7)) { @@ -476,13 +458,11 @@ compaq_plasma_poll(void *priv) for (uint8_t c = 0; c < 8; c++) buffer32->line[self->cga.displine][(x << 4) + (c * 2)] = buffer32->line[self->cga.displine][(x << 4) + (c * 2) + 1] = mdaattr[attr][blink][1]; } else if (drawcursor) { - for (uint8_t c = 0; c < 8; c++) { - buffer32->line[self->cga.displine][(x << 4) + c * 2] = buffer32->line[self->cga.displine][(x << 4) + c * 2 + 1] = cols[(fontdatm[chr][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); - } + for (uint8_t c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 4) + c * 2] = buffer32->line[self->cga.displine][(x << 4) + c * 2 + 1] = cols[(fontdatm2[chr][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); } else { - for (uint8_t c = 0; c < 8; c++) { - buffer32->line[self->cga.displine][(x << 4) + c * 2] = buffer32->line[self->cga.displine][(x << 4) + c * 2 + 1] = cols[(fontdatm[chr][sc] & (1 << (c ^ 7))) ? 1 : 0]; - } + for (uint8_t c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 4) + c * 2] = buffer32->line[self->cga.displine][(x << 4) + c * 2 + 1] = cols[(fontdatm2[chr][sc] & (1 << (c ^ 7))) ? 1 : 0]; } ++ma; } @@ -653,7 +633,7 @@ compaq_plasma_init(UNUSED(const device_t *info)) memset(self, 0, sizeof(compaq_plasma_t)); video_inform(VIDEO_FLAG_TYPE_CGA, &timing_compaq_plasma); - loadfont_ex("roms/machines/portableiii/K Combined.bin", 1, 0x4bb2); + loadfont_ex("roms/machines/portableiii/K Combined.bin", 11, 0x4bb2); self->cga.composite = 0; self->cga.revision = 0; diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index 06974a96d..de87ec90d 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -716,18 +716,18 @@ machine_at_ap5s_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 2, 1); - pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 3, 2, 1); + pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&sis_5511_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&keyboard_ps2_ami_device); device_add(&fdc37c665_device); device_add(&sst_flash_29ee010_device); @@ -745,19 +745,19 @@ machine_at_ms5124_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0xFE, 0xFF, 0, 0); - pci_register_slot(0x10, PCI_CARD_NORMAL, 0x41, 0x42, 0x43, 0x44); - pci_register_slot(0x11, PCI_CARD_NORMAL, 0x44, 0x41, 0x42, 0x43); - pci_register_slot(0x12, PCI_CARD_NORMAL, 0x43, 0x44, 0x41, 0x42); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 0x42, 0x43, 0x44, 0x41); + pci_register_slot(0x10, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); device_add(&sis_5511_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&w83787f_device); + device_add(&keyboard_ps2_ami_device); + device_add(&w83787f_88h_device); device_add(&sst_flash_29ee010_device); return ret; diff --git a/src/machine/m_xt_olivetti.c b/src/machine/m_xt_olivetti.c index 58134dfc9..0b5a3eab0 100644 --- a/src/machine/m_xt_olivetti.c +++ b/src/machine/m_xt_olivetti.c @@ -130,7 +130,7 @@ typedef struct m24_kbd_t { uint8_t scan[7]; /* Mouse stuff. */ - int mouse_mode; + int mouse_input_mode; int b; pc_timer_t send_delay_timer; @@ -550,7 +550,7 @@ m24_kbd_write(uint16_t port, uint8_t val, void *priv) if (m24_kbd->param == m24_kbd->param_total) { switch (m24_kbd->command) { case 0x11: - m24_kbd->mouse_mode = 0; + m24_kbd->mouse_input_mode = 0; m24_kbd->scan[0] = m24_kbd->params[0]; m24_kbd->scan[1] = m24_kbd->params[1]; m24_kbd->scan[2] = m24_kbd->params[2]; @@ -561,7 +561,7 @@ m24_kbd_write(uint16_t port, uint8_t val, void *priv) break; case 0x12: - m24_kbd->mouse_mode = 1; + m24_kbd->mouse_input_mode = 1; m24_kbd->scan[0] = m24_kbd->params[0]; m24_kbd->scan[1] = m24_kbd->params[1]; m24_kbd->scan[2] = m24_kbd->params[2]; @@ -720,7 +720,7 @@ m24_kbd_reset(void *priv) m24_kbd->wantirq = 0; keyboard_scan = 1; m24_kbd->param = m24_kbd->param_total = 0; - m24_kbd->mouse_mode = 0; + m24_kbd->mouse_input_mode = 0; m24_kbd->scan[0] = 0x1c; m24_kbd->scan[1] = 0x53; m24_kbd->scan[2] = 0x01; @@ -767,7 +767,7 @@ ms_poll(void *priv) m24_kbd_adddata(m24_kbd->scan[1] | 0x80); m24_kbd->b = (m24_kbd->b & ~4) | (b & 4); - if (m24_kbd->mouse_mode) { + if (m24_kbd->mouse_input_mode) { if (((key_queue_end - key_queue_start) & 0xf) > 12) return 0xff; diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index bb64ebab5..f52df1d07 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -1045,7 +1045,7 @@ const machine_t machines[] = { .ram = { .min = 256, .max = 640, - .step = 256 + .step = 128 }, .nvrmask = 0, .kbc_device = &keyboard_xtclone_device, @@ -1472,7 +1472,7 @@ const machine_t machines[] = { .bus_flags = MACHINE_PC, .flags = MACHINE_VIDEO_FIXED, .ram = { - .min = 256, + .min = 384, .max = 640, .step = 128 }, diff --git a/src/mem/spd.c b/src/mem/spd.c index cbc9ac2b7..b2d0f7f16 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -349,9 +349,12 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit uint8_t dimm; uint8_t drb; uint8_t apollo = 0; + uint8_t two_step = !!(drb_unit & 0x80); uint16_t size; uint16_t rows[SPD_MAX_SLOTS]; + drb_unit &= 0x7f; + /* Special case for VIA Apollo Pro family, which jumps from 5F to 56. */ if (reg_max < reg_min) { apollo = reg_max; @@ -384,7 +387,10 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit } /* Determine the DRB register to write. */ - drb = reg_min + row; + if (two_step) + drb = reg_min + row; + else + drb = reg_min + (row << 1); if (apollo && ((drb & 0xf) < 0xa)) drb = apollo + (drb & 0xf); diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index 4981fb9a3..e1747580b 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -122,15 +122,15 @@ struct pcap_if { }; struct pcap_send_queue { - u_int maxlen; /* Maximum size of the queue, in bytes. This + unsigned int maxlen; /* Maximum size of the queue, in bytes. This variable contains the size of the buffer field. */ - u_int len; /* Current size of the queue, in bytes. */ + unsigned int len; /* Current size of the queue, in bytes. */ char *buffer; /* Buffer containing the packets to be sent. */ }; typedef struct pcap_send_queue pcap_send_queue; -typedef void (*pcap_handler)(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes); +typedef void (*pcap_handler)(unsigned char *user, const struct pcap_pkthdr *h, const unsigned char *bytes); #endif typedef struct { @@ -169,15 +169,15 @@ static int (*f_pcap_setnonblock)(void *, int, char *); static int (*f_pcap_set_immediate_mode)(void *, int); static int (*f_pcap_set_promisc)(void *, int); static int (*f_pcap_set_snaplen)(void *, int); -static int (*f_pcap_dispatch)(void *, int, pcap_handler callback, u_char *user); +static int (*f_pcap_dispatch)(void *, int, pcap_handler callback, unsigned char *user); static void *(*f_pcap_create)(const char *, char *); static int (*f_pcap_activate)(void *); static void *(*f_pcap_geterr)(void *); #ifdef _WIN32 static HANDLE (*f_pcap_getevent)(void *); static int (*f_pcap_sendqueue_queue)(void *, void *, void *); -static u_int (*f_pcap_sendqueue_transmit)(void *, void *, int sync); -static void *(*f_pcap_sendqueue_alloc)(u_int memsize); +static unsigned int (*f_pcap_sendqueue_transmit)(void *, void *, int sync); +static void *(*f_pcap_sendqueue_alloc)(unsigned int memsize); static void (*f_pcap_sendqueue_destroy)(void *); #else static int (*f_pcap_get_selectable_fd)(void *); @@ -294,7 +294,7 @@ net_pcap_thread(void *priv) break; case NET_EVENT_RX: - f_pcap_dispatch(pcap->pcap, PCAP_PKT_BATCH, net_pcap_rx_handler, (u_char *) pcap); + f_pcap_dispatch(pcap->pcap, PCAP_PKT_BATCH, net_pcap_rx_handler, (unsigned char *) pcap); break; default: @@ -341,7 +341,7 @@ net_pcap_thread(void *priv) } if (pfd[NET_EVENT_RX].revents & POLLIN) { - f_pcap_dispatch(pcap->pcap, PCAP_PKT_BATCH, net_pcap_rx_handler, (u_char *) pcap); + f_pcap_dispatch(pcap->pcap, PCAP_PKT_BATCH, net_pcap_rx_handler, (unsigned char *) pcap); } } diff --git a/src/network/network.c b/src/network/network.c index 2488f4058..8d814c1c4 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -584,7 +584,8 @@ network_reset(void) } net_card_current = i; - device_add_inst(net_cards[net_cards_conf[i].device_num], i + 1); + if (net_cards_conf[i].device_num > NET_INTERNAL) + device_add_inst(net_cards[net_cards_conf[i].device_num], i + 1); } } @@ -689,7 +690,8 @@ network_dev_available(int id) { int available = (net_cards_conf[id].device_num > 0); - if (net_cards_conf[id].net_type == NET_TYPE_PCAP && (network_dev_to_id(net_cards_conf[id].host_dev_name) <= 0)) + if ((net_cards_conf[id].net_type == NET_TYPE_PCAP) && + (network_dev_to_id(net_cards_conf[id].host_dev_name) <= 0)) available = 0; // TODO: Handle VDE device diff --git a/src/nvr_at.c b/src/nvr_at.c index 581eccf71..c66799579 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -580,7 +580,8 @@ nvr_reg_common_write(uint16_t reg, uint8_t val, nvr_t *nvr, local_t *local) return; if (nvr->regs[reg] != val) { nvr->regs[reg] = val; - nvr_dosave = 1; + if ((reg >= 0x0d) && ((local->cent == 0xff) || (reg != local->cent))) + nvr_dosave = 1; } } @@ -643,7 +644,7 @@ nvr_reg_write(uint16_t reg, uint8_t val, void *priv) /* Update internal clock. */ time_get(nvr, &tm); nvr_time_set(&tm); - nvr_dosave = 1; + // nvr_dosave = 1; } } } diff --git a/src/pci.c b/src/pci.c index 6c0a904bb..7c61545b2 100644 --- a/src/pci.c +++ b/src/pci.c @@ -56,6 +56,8 @@ typedef struct pci_card_desc_t { typedef struct pci_mirq_t { uint8_t enabled; uint8_t irq_line; + uint8_t irq_level; + uint8_t pad; } pci_mirq_t; int pci_burst_time; @@ -131,11 +133,23 @@ pci_enable_mirq(int mirq) } void -pci_set_mirq_routing(int mirq, int irq) +pci_set_mirq_routing(int mirq, uint8_t irq) { pci_mirqs[mirq].irq_line = irq; } +uint8_t +pci_get_mirq_level(int mirq) +{ + return pci_mirqs[mirq].irq_level; +} + +void +pci_set_mirq_level(int mirq, uint8_t level) +{ + pci_mirqs[mirq].irq_level = level; +} + /* PCI raise IRQ: the first parameter is slot if < PCI_MIRQ_BASE, MIRQ if >= PCI_MIRQ_BASE and < PCI_DIRQ_BASE, and direct IRQ line if >= PCI_DIRQ_BASE (RichardG's hack that may no longer be needed). */ @@ -817,10 +831,12 @@ pci_add_bridge(uint8_t agp, uint8_t (*read)(int func, int addr, void *priv), voi pci_card_t *card; uint8_t bridge_slot = agp ? pci_find_slot(PCI_ADD_AGPBRIDGE, 0xff) : last_normal_pci_card_id; - card = &pci_cards[bridge_slot]; - card->read = read; - card->write = write; - card->priv = priv; + if (bridge_slot != PCI_CARD_INVALID) { + card = &pci_cards[bridge_slot]; + card->read = read; + card->write = write; + card->priv = priv; + } *slot = bridge_slot; } diff --git a/src/pic.c b/src/pic.c index 2e59dda10..82905261a 100644 --- a/src/pic.c +++ b/src/pic.c @@ -408,6 +408,48 @@ pic_latch_read(UNUSED(uint16_t addr), UNUSED(void *priv)) return ret; } +uint8_t +pic_read_icw(uint8_t pic_id, uint8_t icw) +{ + pic_t *dev = pic_id ? &pic2 : &pic; + uint8_t ret = 0xff; + + switch (icw) { + case 0x00: + ret = dev->icw1; + break; + case 0x01: + ret = dev->icw2; + break; + case 0x02: + ret = dev->icw3; + break; + case 0x03: + ret = dev->icw4; + break; + } + + return ret; +} + +uint8_t +pic_read_ocw(uint8_t pic_id, uint8_t ocw) +{ + pic_t *dev = pic_id ? &pic2 : &pic; + uint8_t ret = 0xff; + + switch (ocw) { + case 0x00: + ret = dev->ocw2; + break; + case 0x01: + ret = dev->ocw3; + break; + } + + return ret; +} + uint8_t pic_read(uint16_t addr, void *priv) { diff --git a/src/pit.c b/src/pit.c index fc65839a3..f5816aaf5 100644 --- a/src/pit.c +++ b/src/pit.c @@ -637,6 +637,41 @@ pit_write(uint16_t addr, uint8_t val, void *priv) extern uint8_t *ram; +uint8_t +pit_read_reg(void *priv, uint8_t reg) +{ + pit_t *dev = (pit_t *) priv; + uint8_t ret = 0xff; + + switch (reg) { + case 0x00: + case 0x02: + case 0x04: + ret = dev->counters[reg >> 1].l & 0xff; + break; + case 0x01: + case 0x03: + case 0x05: + ret = (dev->counters[reg >> 1].l >> 8) & 0xff; + break; + case 0x06: + ret = dev->ctrl; + break; + case 0x07: + /* The SiS 551x datasheet is unclear about how exactly + this register is structured. */ + ret = (dev->counters[0].rm & 0x80) ? 0x01 : 0x00; + ret = (dev->counters[0].wm & 0x80) ? 0x02 : 0x00; + ret = (dev->counters[1].rm & 0x80) ? 0x04 : 0x00; + ret = (dev->counters[1].wm & 0x80) ? 0x08 : 0x00; + ret = (dev->counters[2].rm & 0x80) ? 0x10 : 0x00; + ret = (dev->counters[2].wm & 0x80) ? 0x20 : 0x00; + break; + } + + return ret; +} + static uint8_t pit_read(uint16_t addr, void *priv) { @@ -852,7 +887,7 @@ pit_init(const device_t *info) const device_t i8253_device = { .name = "Intel 8253/8253-5 Programmable Interval Timer", .internal_name = "i8253", - .flags = DEVICE_ISA, + .flags = DEVICE_ISA | DEVICE_PIT, .local = PIT_8253, .init = pit_init, .close = pit_close, @@ -866,7 +901,7 @@ const device_t i8253_device = { const device_t i8254_device = { .name = "Intel 8254 Programmable Interval Timer", .internal_name = "i8254", - .flags = DEVICE_ISA, + .flags = DEVICE_ISA | DEVICE_PIT, .local = PIT_8254, .init = pit_init, .close = pit_close, @@ -1126,4 +1161,4 @@ const pit_intf_t pit_classic_intf = { &pit_ctr_set_load_func, &ctr_clock, NULL, -}; \ No newline at end of file +}; diff --git a/src/pit_fast.c b/src/pit_fast.c index 80e359eee..20633de80 100644 --- a/src/pit_fast.c +++ b/src/pit_fast.c @@ -498,6 +498,41 @@ pitf_write(uint16_t addr, uint8_t val, void *priv) } } +uint8_t +pitf_read_reg(void *priv, uint8_t reg) +{ + pitf_t *dev = (pitf_t *) priv; + uint8_t ret = 0xff; + + switch (reg) { + case 0x00: + case 0x02: + case 0x04: + ret = dev->counters[reg >> 1].l & 0xff; + break; + case 0x01: + case 0x03: + case 0x05: + ret = (dev->counters[reg >> 1].l >> 8) & 0xff; + break; + case 0x06: + ret = dev->ctrl; + break; + case 0x07: + /* The SiS 551x datasheet is unclear about how exactly + this register is structured. */ + ret = (dev->counters[0].rm & 0x80) ? 0x01 : 0x00; + ret = (dev->counters[0].wm & 0x80) ? 0x02 : 0x00; + ret = (dev->counters[1].rm & 0x80) ? 0x04 : 0x00; + ret = (dev->counters[1].wm & 0x80) ? 0x08 : 0x00; + ret = (dev->counters[2].rm & 0x80) ? 0x10 : 0x00; + ret = (dev->counters[2].wm & 0x80) ? 0x20 : 0x00; + break; + } + + return ret; +} + static uint8_t pitf_read(uint16_t addr, void *priv) { @@ -654,7 +689,7 @@ pitf_init(const device_t *info) const device_t i8253_fast_device = { .name = "Intel 8253/8253-5 Programmable Interval Timer", .internal_name = "i8253_fast", - .flags = DEVICE_ISA, + .flags = DEVICE_ISA | DEVICE_PIT, .local = PIT_8253, .init = pitf_init, .close = pitf_close, @@ -668,7 +703,7 @@ const device_t i8253_fast_device = { const device_t i8254_fast_device = { .name = "Intel 8254 Programmable Interval Timer", .internal_name = "i8254_fast", - .flags = DEVICE_ISA, + .flags = DEVICE_ISA | DEVICE_PIT, .local = PIT_8254, .init = pitf_init, .close = pitf_close, @@ -731,4 +766,4 @@ const pit_intf_t pit_fast_intf = { &pitf_ctr_set_load_func, &pitf_ctr_clock, NULL, -}; \ No newline at end of file +}; diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index 613496fd9..7ea47bc1a 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -1223,4 +1223,4 @@ msgid "Fast" msgstr "速い" msgid "&Auto-pause on focus loss" -msgstr "フォーカスが外れると自動ポーズ(&A)" +msgstr "フォーカスが奪われると自動停止(&A)" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index 0c12fa76a..fe099265b 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -1223,5 +1223,5 @@ msgid "Fast" msgstr "快" msgid "&Auto-pause on focus loss" -msgstr "&失焦自动暂停" +msgstr "失去焦点时自动暂停(&A)" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index c840230bd..2d2ea473e 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -1223,4 +1223,4 @@ msgid "Fast" msgstr "快" msgid "&Auto-pause on focus loss" -msgstr "&失去焦點時自動暫停" +msgstr "失去焦點時自動暫停(&A)" diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 427b47598..2aebc39ef 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -212,7 +212,7 @@ MainWindow::MainWindow(QWidget *parent) ui->actionMCA_devices->setVisible(machine_has_bus(machine, MACHINE_BUS_MCA)); QApplication::setOverrideCursor(Qt::ArrowCursor); #ifdef USE_WACOM - ui->menuTablet_tool->menuAction()->setVisible(mouse_mode >= 1); + ui->menuTablet_tool->menuAction()->setVisible(mouse_input_mode >= 1); #else ui->menuTablet_tool->menuAction()->setVisible(false); #endif @@ -555,6 +555,7 @@ MainWindow::MainWindow(QWidget *parent) actGroup->addAction(ui->actionFullScreen_43); actGroup->addAction(ui->actionFullScreen_keepRatio); actGroup->addAction(ui->actionFullScreen_int); + actGroup->addAction(ui->actionFullScreen_int43); switch (video_grayscale) { case 0: ui->actionRGB_Color->setChecked(true); @@ -1534,10 +1535,11 @@ MainWindow::on_actionLinear_triggered() static void update_fullscreen_scale_checkboxes(Ui::MainWindow *ui, QAction *selected) { - ui->actionFullScreen_stretch->setChecked(ui->actionFullScreen_stretch == selected); - ui->actionFullScreen_43->setChecked(ui->actionFullScreen_43 == selected); - ui->actionFullScreen_keepRatio->setChecked(ui->actionFullScreen_keepRatio == selected); - ui->actionFullScreen_int->setChecked(ui->actionFullScreen_int == selected); + ui->actionFullScreen_stretch->setChecked(selected == ui->actionFullScreen_stretch); + ui->actionFullScreen_43->setChecked(selected == ui->actionFullScreen_43); + ui->actionFullScreen_keepRatio->setChecked(selected == ui->actionFullScreen_keepRatio); + ui->actionFullScreen_int->setChecked(selected == ui->actionFullScreen_int); + ui->actionFullScreen_int43->setChecked(selected == ui->actionFullScreen_int43); { auto widget = ui->stackedWidget->currentWidget(); @@ -1546,7 +1548,8 @@ update_fullscreen_scale_checkboxes(Ui::MainWindow *ui, QAction *selected) for (int i = 1; i < MONITORS_NUM; i++) { if (main_window->renderers[i]) - main_window->renderers[i]->onResize(main_window->renderers[i]->width(), main_window->renderers[i]->height()); + main_window->renderers[i]->onResize(main_window->renderers[i]->width(), + main_window->renderers[i]->height()); } device_force_redraw(); diff --git a/src/qt/qt_renderercommon.cpp b/src/qt/qt_renderercommon.cpp index 1eef4863c..cebda184c 100644 --- a/src/qt/qt_renderercommon.cpp +++ b/src/qt/qt_renderercommon.cpp @@ -73,14 +73,19 @@ RendererCommon::onResize(int width, int height) double gw = source.width(); double gh = source.height(); double hsr = hw / hh; + double r43 = 4.0 / 3.0; switch (video_fullscreen_scale) { case FULLSCR_SCALE_INT: case FULLSCR_SCALE_INT43: - if (video_fullscreen_scale == FULLSCR_SCALE_INT43) - gsr = 4.0 / 3.0; - else - gsr = gw / gh; + gsr = gw / gh; + + if (video_fullscreen_scale == FULLSCR_SCALE_INT43) { + gh = gw / r43; + gw = gw; + + gsr = r43; + } if (gsr <= hsr) { dw = hh * gsr; @@ -89,8 +94,10 @@ RendererCommon::onResize(int width, int height) dw = hw; dh = hw / gsr; } + integer_scale(&dw, &gw); integer_scale(&dh, &gh); + dx = (hw - dw) / 2.0; dy = (hh - dh) / 2.0; destination.setRect((int) dx, (int) dy, (int) dw, (int) dh); @@ -98,7 +105,7 @@ RendererCommon::onResize(int width, int height) case FULLSCR_SCALE_43: case FULLSCR_SCALE_KEEPRATIO: if (video_fullscreen_scale == FULLSCR_SCALE_43) - gsr = 4.0 / 3.0; + gsr = r43; else gsr = gw / gh; diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 6b0f98885..469dc04de 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -144,7 +144,7 @@ int ignoreNextMouseEvent = 1; void RendererStack::mouseReleaseEvent(QMouseEvent *event) { - if (this->geometry().contains(event->pos()) && (event->button() == Qt::LeftButton) && !mouse_capture && (isMouseDown & 1) && (kbd_req_capture || (mouse_get_buttons() != 0)) && (mouse_mode == 0)) { + if (this->geometry().contains(event->pos()) && (event->button() == Qt::LeftButton) && !mouse_capture && (isMouseDown & 1) && (kbd_req_capture || (mouse_get_buttons() != 0)) && (mouse_input_mode == 0)) { plat_mouse_capture(1); this->setCursor(Qt::BlankCursor); if (!ignoreNextMouseEvent) @@ -158,16 +158,16 @@ RendererStack::mouseReleaseEvent(QMouseEvent *event) isMouseDown &= ~1; return; } - if (mouse_capture || (mouse_mode >= 1)) { + if (mouse_capture || (mouse_input_mode >= 1)) { #ifdef Q_OS_WINDOWS - if (((m_monitor_index >= 1) && (mouse_mode >= 1) && mousedata.mouse_tablet_in_proximity) || - ((m_monitor_index < 1) && (mouse_mode >= 1))) + if (((m_monitor_index >= 1) && (mouse_input_mode >= 1) && mousedata.mouse_tablet_in_proximity) || + ((m_monitor_index < 1) && (mouse_input_mode >= 1))) #else #ifndef __APPLE__ - if (((m_monitor_index >= 1) && (mouse_mode >= 1) && mousedata.mouse_tablet_in_proximity) || + if (((m_monitor_index >= 1) && (mouse_input_mode >= 1) && mousedata.mouse_tablet_in_proximity) || (m_monitor_index < 1)) #else - if ((m_monitor_index >= 1) && (mouse_mode >= 1) && mousedata.mouse_tablet_in_proximity) + if ((m_monitor_index >= 1) && (mouse_input_mode >= 1) && mousedata.mouse_tablet_in_proximity) #endif #endif mouse_set_buttons_ex(mouse_get_buttons_ex() & ~event->button()); @@ -179,16 +179,16 @@ void RendererStack::mousePressEvent(QMouseEvent *event) { isMouseDown |= 1; - if (mouse_capture || (mouse_mode >= 1)) { + if (mouse_capture || (mouse_input_mode >= 1)) { #ifdef Q_OS_WINDOWS - if (((m_monitor_index >= 1) && (mouse_mode >= 1) && mousedata.mouse_tablet_in_proximity) || - ((m_monitor_index < 1) && (mouse_mode >= 1))) + if (((m_monitor_index >= 1) && (mouse_input_mode >= 1) && mousedata.mouse_tablet_in_proximity) || + ((m_monitor_index < 1) && (mouse_input_mode >= 1))) #else #ifndef __APPLE__ - if (((m_monitor_index >= 1) && (mouse_mode >= 1) && mousedata.mouse_tablet_in_proximity) || + if (((m_monitor_index >= 1) && (mouse_input_mode >= 1) && mousedata.mouse_tablet_in_proximity) || (m_monitor_index < 1)) #else - if ((m_monitor_index >= 1) && (mouse_mode >= 1) && mousedata.mouse_tablet_in_proximity) + if ((m_monitor_index >= 1) && (mouse_input_mode >= 1) && mousedata.mouse_tablet_in_proximity) #endif #endif mouse_set_buttons_ex(mouse_get_buttons_ex() | event->button()); @@ -249,7 +249,7 @@ RendererStack::enterEvent(QEvent *event) { mousedata.mouse_tablet_in_proximity = 1; - if (mouse_mode == 1) + if (mouse_input_mode == 1) QApplication::setOverrideCursor(Qt::BlankCursor); } @@ -258,7 +258,7 @@ RendererStack::leaveEvent(QEvent *event) { mousedata.mouse_tablet_in_proximity = 0; - if (mouse_mode == 1 && QApplication::overrideCursor()) + if (mouse_input_mode == 1 && QApplication::overrideCursor()) QApplication::restoreOverrideCursor(); if (QApplication::platformName().contains("wayland")) { event->accept(); @@ -528,7 +528,7 @@ RendererStack::event(QEvent* event) QMouseEvent* mouse_event = (QMouseEvent*)event; if (m_monitor_index >= 1) { - if (mouse_mode >= 1) { + if (mouse_input_mode >= 1) { mouse_x_abs = (mouse_event->localPos().x()) / (long double)width(); mouse_y_abs = (mouse_event->localPos().y()) / (long double)height(); if (!mouse_tablet_in_proximity) @@ -538,7 +538,7 @@ RendererStack::event(QEvent* event) } #ifdef Q_OS_WINDOWS - if (mouse_mode == 0) { + if (mouse_input_mode == 0) { mouse_x_abs = (mouse_event->localPos().x()) / (long double)width(); mouse_y_abs = (mouse_event->localPos().y()) / (long double)height(); return QStackedWidget::event(event); diff --git a/src/qt/qt_winrawinputfilter.cpp b/src/qt/qt_winrawinputfilter.cpp index 1beddba51..b8e7d1038 100644 --- a/src/qt/qt_winrawinputfilter.cpp +++ b/src/qt/qt_winrawinputfilter.cpp @@ -174,9 +174,6 @@ void WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) { USHORT scancode; - static int recv_lalt = 0; - static int recv_ralt = 0; - static int recv_tab = 0; RAWKEYBOARD rawKB = raw->data.keyboard; scancode = rawKB.MakeCode; @@ -185,7 +182,18 @@ WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) return; /* If it's not a scan code that starts with 0xE1 */ - if (!(rawKB.Flags & RI_KEY_E1)) { + if ((rawKB.Flags & RI_KEY_E1)) { + if (rawKB.MakeCode == 0x1D) { + scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would + otherwise be E0 00 but that is invalid + anyway). + Also, take a potential mapping into + account. */ + } else + scancode = 0xFFFF; + if (scancode != 0xFFFF) + keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode); + } else { if (rawKB.Flags & RI_KEY_E0) scancode |= 0x100; @@ -198,70 +206,22 @@ WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) scancode = scancode_map[scancode]; /* If it's not 0xFFFF, send it to the emulated - keyboard. - We use scan code 0xFFFF to mean a mapping that - has a prefix other than E0 and that is not E1 1D, - which is, for our purposes, invalid. */ - if ((scancode == 0x00f) && !(rawKB.Flags & RI_KEY_BREAK) && (recv_lalt || recv_ralt) && (!kbd_req_capture || mouse_capture)) { - /* We received a TAB while ALT was pressed, while the mouse - is not captured, suppress the TAB and send an ALT key up. */ - if (recv_lalt) { - keyboard_input(0, 0x038); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x038); - keyboard_input(0, 0x038); - recv_lalt = 0; - } - if (recv_ralt) { - keyboard_input(0, 0x138); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x138); - keyboard_input(0, 0x138); - recv_ralt = 0; - } - } else if (((scancode == 0x038) || (scancode == 0x138)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_tab && (!kbd_req_capture || mouse_capture)) { - /* We received an ALT while TAB was pressed, while the mouse - is not captured, suppress the ALT and send a TAB key up. */ - keyboard_input(0, 0x00f); - recv_tab = 0; - } else { - switch (scancode) { - case 0x00f: - recv_tab = !(rawKB.Flags & RI_KEY_BREAK); - break; - case 0x038: - recv_lalt = !(rawKB.Flags & RI_KEY_BREAK); - break; - case 0x138: - recv_ralt = !(rawKB.Flags & RI_KEY_BREAK); - break; - } + keyboard. + We use scan code 0xFFFF to mean a mapping that + has a prefix other than E0 and that is not E1 1D, + which is, for our purposes, invalid. */ - /* Translate right CTRL to left ALT if the user has so + /* Translate right CTRL to left ALT if the user has so chosen. */ - if ((scancode == 0x11d) && rctrl_is_lalt) - scancode = 0x038; + if ((scancode == 0x11d) && rctrl_is_lalt) + scancode = 0x038; - /* Normal scan code pass through, pass it through as is if + /* Normal scan code pass through, pass it through as is if it's not an invalid scan code. */ - if (scancode != 0xFFFF) - keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode); - - window->checkFullscreenHotkey(); - } - } else { - if (rawKB.MakeCode == 0x1D) { - scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would - otherwise be E0 00 but that is invalid - anyway). - Also, take a potential mapping into - account. */ - } else - scancode = 0xFFFF; if (scancode != 0xFFFF) keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode); + + window->checkFullscreenHotkey(); } } diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index 8f5bffbd9..b1f358676 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -178,10 +178,8 @@ scsi_card_init(void) bus left. */ if (max > 0) { for (int i = 0; i < max; i++) { - if (!scsi_cards[scsi_card_current[i]].device) - continue; - - device_add_inst(scsi_cards[scsi_card_current[i]].device, i + 1); + if ((scsi_card_current[i] > 0) && scsi_cards[scsi_card_current[i]].device) + device_add_inst(scsi_cards[scsi_card_current[i]].device, i + 1); } } } diff --git a/src/sio/sio_w83787f.c b/src/sio/sio_w83787f.c index 1870741c7..33cfc6311 100644 --- a/src/sio/sio_w83787f.c +++ b/src/sio/sio_w83787f.c @@ -374,6 +374,8 @@ w83787f_read(uint16_t port, void *priv) static void w83787f_reset(w83787f_t *dev) { + uint16_t hefere = dev->reg_init & 0x0100; + lpt1_remove(); lpt1_init(LPT1_ADDR); lpt1_irq(LPT1_IRQ); @@ -410,7 +412,7 @@ w83787f_reset(w83787f_t *dev) dev->regs[0x07] = 0xF5; dev->regs[0x09] = dev->reg_init & 0xff; dev->regs[0x0a] = 0x1F; - dev->regs[0x0c] = 0x2C; + dev->regs[0x0c] = 0x0C | (hefere >> 3); dev->regs[0x0d] = 0xA3; gameport_remap(dev->gameport, 0); @@ -420,7 +422,7 @@ w83787f_reset(w83787f_t *dev) w83787f_lpt_handler(dev); - dev->key = 0x89; + dev->key = 0x88 | (hefere >> 8); w83787f_remap(dev); @@ -456,17 +458,31 @@ w83787f_init(const device_t *info) dev->ide_start = !!(info->local & 0x40); - dev->reg_init = info->local & 0x0f; + dev->reg_init = info->local & 0x010f; w83787f_reset(dev); return dev; } +const device_t w83787f_88h_device = { + .name = "Winbond W83787F/IF Super I/O", + .internal_name = "w83787f", + .flags = 0, + .local = 0x0009, + .init = w83787f_init, + .close = w83787f_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t w83787f_device = { .name = "Winbond W83787F/IF Super I/O", .internal_name = "w83787f", .flags = 0, - .local = 0x09, + .local = 0x0109, .init = w83787f_init, .close = w83787f_close, .reset = NULL, @@ -480,7 +496,7 @@ const device_t w83787f_ide_device = { .name = "Winbond W83787F/IF Super I/O (With IDE)", .internal_name = "w83787f_ide", .flags = 0, - .local = 0x19, + .local = 0x0119, .init = w83787f_init, .close = w83787f_close, .reset = NULL, @@ -494,7 +510,7 @@ const device_t w83787f_ide_en_device = { .name = "Winbond W83787F/IF Super I/O (With IDE Enabled)", .internal_name = "w83787f_ide_en", .flags = 0, - .local = 0x59, + .local = 0x0159, .init = w83787f_init, .close = w83787f_close, .reset = NULL, @@ -508,7 +524,7 @@ const device_t w83787f_ide_sec_device = { .name = "Winbond W83787F/IF Super I/O (With Secondary IDE)", .internal_name = "w83787f_ide_sec", .flags = 0, - .local = 0x39, + .local = 0x0139, .init = w83787f_init, .close = w83787f_close, .reset = NULL, diff --git a/src/sound/midi.c b/src/sound/midi.c index 10377fccb..c5dbd666f 100644 --- a/src/sound/midi.c +++ b/src/sound/midi.c @@ -175,7 +175,7 @@ midi_out_device_get_from_internal_name(char *s) void midi_out_device_init(void) { - if (devices[midi_output_device_current].device) + if ((midi_output_device_current > 0) && devices[midi_output_device_current].device) device_add(devices[midi_output_device_current].device); midi_output_device_last = midi_output_device_current; } @@ -293,7 +293,7 @@ midi_in_device_get_from_internal_name(char *s) void midi_in_device_init(void) { - if (midi_in_devices[midi_input_device_current].device) + if ((midi_input_device_current > 0) && midi_in_devices[midi_input_device_current].device) device_add(midi_in_devices[midi_input_device_current].device); midi_input_device_last = midi_input_device_current; } diff --git a/src/sound/snd_adlibgold.c b/src/sound/snd_adlibgold.c index 48a74cf5a..71cbbcaa6 100644 --- a/src/sound/snd_adlibgold.c +++ b/src/sound/snd_adlibgold.c @@ -182,18 +182,18 @@ adgold_update_irq_status(adgold_t *adgold) adgold->adgold_irq_status = adgold->adgold_status ^ 0xf; } -void +int adgold_getsamp_dma(adgold_t *adgold, int channel) { int temp; dma_set_drq(adgold->dma, 1); if ((adgold->adgold_mma_regs[channel][0xc] & 0x60) && (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) >= 127)) - return; + return 2; temp = dma_channel_read(adgold->dma); if (temp == DMA_NODATA) { - return; + return 1; } adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_end[channel]] = temp; adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255; @@ -207,6 +207,8 @@ adgold_getsamp_dma(adgold_t *adgold, int channel) adgold_update_irq_status(adgold); dma_set_drq(adgold->dma, 0); } + + return 0; } void @@ -377,8 +379,16 @@ adgold_write(uint16_t addr, uint8_t val, void *priv) adgold->adgold_mma.voice_count[1] = adgold->adgold_mma.voice_latch[1]; while (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) { - adgold_getsamp_dma(adgold, 0); - adgold_getsamp_dma(adgold, 1); + if (adgold_getsamp_dma(adgold, 0)) { + adgold->adgold_mma_fifo_end[0] = 0; + adgold->adgold_mma_fifo_start[0] = 0; + break; + } + if (adgold_getsamp_dma(adgold, 1)) { + adgold->adgold_mma_fifo_end[1] = 0; + adgold->adgold_mma_fifo_start[1] = 0; + break; + } } if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0]) { adgold->adgold_mma_status &= ~0x01; @@ -392,7 +402,11 @@ adgold_write(uint16_t addr, uint8_t val, void *priv) } } else { while (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) { - adgold_getsamp_dma(adgold, 0); + if (adgold_getsamp_dma(adgold, 0)) { + adgold->adgold_mma_fifo_end[0] = 0; + adgold->adgold_mma_fifo_start[0] = 0; + break; + } } if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0]) { adgold->adgold_mma_status &= ~0x01; @@ -502,7 +516,11 @@ adgold_write(uint16_t addr, uint8_t val, void *priv) if (adgold->adgold_mma_regs[1][0xc] & 1) { while (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) < 128) { - adgold_getsamp_dma(adgold, 1); + if (adgold_getsamp_dma(adgold, 1)) { + adgold->adgold_mma_fifo_end[1] = 0; + adgold->adgold_mma_fifo_start[1] = 0; + break; + } } } } @@ -675,10 +693,14 @@ adgold_mma_poll(adgold_t *adgold, int channel) } if (adgold->adgold_mma_regs[channel][0xc] & 1) { - adgold_getsamp_dma(adgold, channel); + if (adgold_getsamp_dma(adgold, channel)) { + adgold->adgold_mma_fifo_end[channel] = 0; + adgold->adgold_mma_fifo_start[channel] = 0; + return; + } } if (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) < adgold->adgold_mma_intpos[channel] && !(adgold->adgold_mma_status & 0x01)) { - adgold->adgold_mma_status |= 1 << channel; + adgold->adgold_mma_status |= (1 << channel); adgold_update_irq_status(adgold); } } @@ -693,7 +715,7 @@ adgold_timer_poll(void *priv) adgold_t *adgold = (adgold_t *) priv; /*A small timer period will result in hangs.*/ - timer_on_auto(&adgold->adgold_mma_timer_count, 4.88964); + timer_advance_u64(&adgold->adgold_mma_timer_count, (uint64_t) ((double) TIMER_USEC * 1.88964)); if (adgold->adgold_midi_ctrl & 0x3f) { if ((adgold->adgold_midi_ctrl & 0x3f) != 0x3f) { diff --git a/src/sound/snd_opl_ymfm.cpp b/src/sound/snd_opl_ymfm.cpp index 7dd5dc3a1..0f996f6bc 100644 --- a/src/sound/snd_opl_ymfm.cpp +++ b/src/sound/snd_opl_ymfm.cpp @@ -450,7 +450,7 @@ const device_t ymf289b_ymfm_device = { const device_t ymf278b_ymfm_device = { .name = "Yamaha YMF278B OPL4 (YMFM)", - .internal_name = "ymf289b_ymfm", + .internal_name = "ymf278b_ymfm", .flags = 0, .local = FM_YMF278B, .init = ymfm_drv_init, diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index fde2e98ba..bb889921b 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -158,6 +158,7 @@ static uint8_t sb_16_pnp_rom[] = { // clang-format on }; +// #define ENABLE_SB_LOG 1 #ifdef ENABLE_SB_LOG int sb_do_log = ENABLE_SB_LOG; @@ -520,6 +521,48 @@ sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv) *buffer = c * output_gain; } +void +sb16_awe32_filter_pc_speaker(int channel, double *buffer, void *priv) +{ + const sb_t *sb = (sb_t *) priv; + const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; + double c; + double spk = mixer->speaker; + double master = channel ? mixer->master_r : mixer->master_l; + int32_t bass = channel ? mixer->bass_r : mixer->bass_l; + int32_t treble = channel ? mixer->treble_r : mixer->treble_l; + double bass_treble; + double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L); + + if (mixer->output_filter) + c = (low_fir_sb16(2, channel, *buffer) * spk) / 3.0; + else + c = ((*buffer) * spk) / 3.0; + c *= master; + + /* This is not exactly how one does bass/treble controls, but the end result is like it. + A better implementation would reduce the CPU usage. */ + if (bass != 8) { + bass_treble = sb_bass_treble_4bits[bass]; + + if (bass > 8) + c += (low_iir(2, channel, c) * bass_treble); + else if (bass < 8) + c = (c * bass_treble + low_cut_iir(1, channel, c) * (1.0 - bass_treble)); + } + + if (treble != 8) { + bass_treble = sb_bass_treble_4bits[treble]; + + if (treble > 8) + c += (high_iir(2, channel, c) * bass_treble); + else if (treble < 8) + c = (c * bass_treble + high_cut_iir(1, channel, c) * (1.0 - bass_treble)); + } + + *buffer = c * output_gain; +} + void sb_ct1335_mixer_write(uint16_t addr, uint8_t val, void *priv) { @@ -743,6 +786,8 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv) SoundBlaster 16 sets bit 7 if previous mixer index invalid. Status bytes initially 080h on startup for all but level bytes (SB16). */ + sb_log("CT1745: [W] %02X = %02X\n", mixer->index, val); + if (mixer->index == 0) { /* Reset: Changed defaults from -14dB to 0dB */ @@ -764,8 +809,13 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->regs[0x44] = mixer->regs[0x45] = 0x80; mixer->regs[0x46] = mixer->regs[0x47] = 0x80; + /* 0x43 = Mic AGC (Automatic Gain Control?) according to Linux's sb.h. + NSC LM4560 datasheet: Bit 0: 1 = Enable, 0 = Disable; + Another source says this: Bit 0: 0 = AGC on (default), 1 = Fixed gain of 20 dB. */ mixer->regs[0x43] = 0x00; + mixer->regs[0x49] = mixer->regs[0x4a] = 0x80; + mixer->regs[0x83] = 0xff; sb->dsp.sb_irqm8 = 0; sb->dsp.sb_irqm16 = 0; @@ -820,31 +870,37 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv) Note: Registers 80h and 81h are Read-only for PnP boards. */ case 0x80: - if (val & 0x01) - sb_dsp_setirq(&sb->dsp, 2); - if (val & 0x02) - sb_dsp_setirq(&sb->dsp, 5); - if (val & 0x04) - sb_dsp_setirq(&sb->dsp, 7); - if (val & 0x08) - sb_dsp_setirq(&sb->dsp, 10); + if (!sb->pnp) { + if (val & 0x01) + sb_dsp_setirq(&sb->dsp, 2); + if (val & 0x02) + sb_dsp_setirq(&sb->dsp, 5); + if (val & 0x04) + sb_dsp_setirq(&sb->dsp, 7); + if (val & 0x08) + sb_dsp_setirq(&sb->dsp, 10); + } break; case 0x81: /* The documentation is confusing. sounds as if multple dma8 channels could be set. */ - if (val & 0x01) - sb_dsp_setdma8(&sb->dsp, 0); - if (val & 0x02) - sb_dsp_setdma8(&sb->dsp, 1); - if (val & 0x08) - sb_dsp_setdma8(&sb->dsp, 3); - if (val & 0x20) - sb_dsp_setdma16(&sb->dsp, 5); - if (val & 0x40) - sb_dsp_setdma16(&sb->dsp, 6); - if (val & 0x80) - sb_dsp_setdma16(&sb->dsp, 7); + if (!sb->pnp) { + if (val & 0x01) + sb_dsp_setdma8(&sb->dsp, 0); + else if (val & 0x02) + sb_dsp_setdma8(&sb->dsp, 1); + else if (val & 0x08) + sb_dsp_setdma8(&sb->dsp, 3); + + sb_dsp_setdma16(&sb->dsp, 4); + if (val & 0x20) + sb_dsp_setdma16(&sb->dsp, 5); + else if (val & 0x40) + sb_dsp_setdma16(&sb->dsp, 6); + else if (val & 0x80) + sb_dsp_setdma16(&sb->dsp, 7); + } break; case 0x83: @@ -863,19 +919,30 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv) 0, 0 = 200-207h; 0, 1 = Disabled */ - if (sb->mpu != NULL) { - if ((val & 0x06) == 0x00) - mpu401_change_addr(sb->mpu, 0x330); - else if ((val & 0x06) == 0x04) - mpu401_change_addr(sb->mpu, 0x300); - else if ((val & 0x06) == 0x02) - mpu401_change_addr(sb->mpu, 0); + if (!sb->pnp) { + if (sb->mpu != NULL) { + if ((val & 0x06) == 0x00) + mpu401_change_addr(sb->mpu, 0x330); + else if ((val & 0x06) == 0x04) + mpu401_change_addr(sb->mpu, 0x300); + else if ((val & 0x06) == 0x02) + mpu401_change_addr(sb->mpu, 0); + } + sb->gameport_addr = 0; + gameport_remap(sb->gameport, 0); + if (!(val & 0x01)) { + sb->gameport_addr = 0x200; + gameport_remap(sb->gameport, 0x200); + } } - sb->gameport_addr = 0; - gameport_remap(sb->gameport, 0); - if (!(val & 0x01)) { - sb->gameport_addr = 0x200; - gameport_remap(sb->gameport, 0x200); + break; + + case 0xff: + if (sb->dsp.sb_type >= SBAWE32) { + if (val != ISAPNP_DMA_DISABLED) + sb_dsp_setdma16_8(&sb->dsp, val & 0x07); + sb_dsp_setdma16_enabled(&sb->dsp, !(val & 0x20)); + sb_dsp_setdma16_translate(&sb->dsp, val != ISAPNP_DMA_DISABLED); } break; @@ -931,7 +998,7 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) if ((mixer->index >= 0x30) && (mixer->index <= 0x47)) ret = mixer->regs[mixer->index]; - else + else { switch (mixer->index) { case 0x00: ret = mixer->regs[mixer->index]; @@ -1033,22 +1100,24 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) case 7: ret |= 0x80; break; - - default: - break; } break; case 0x82: /* The Interrupt status register, addressed as register 82h on the Mixer register map, - is used by the ISR to determine whether the interrupt is meant for it or for some other ISR, - in which case it should chain to the previous routine. */ + is used by the ISR to determine whether the interrupt is meant for it or for some + other ISR, in which case it should chain to the previous routine. */ /* 0 = none, 1 = digital 8bit or SBMIDI, 2 = digital 16bit, 4 = MPU-401 */ /* 0x02000 DSP v4.04, 0x4000 DSP v4.05, 0x8000 DSP v4.12. I haven't seen this making any difference, but I'm keeping it for now. */ /* If QEMU is any indication, then the values are actually 0x20, 0x40, and 0x80. */ - temp = ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0) | ((sb->dsp.sb_irq401) ? 4 : 0) | 0x40; - ret = temp; + /* http://the.earth.li/~tfm/oldpage/sb_mixer.html - 0x10, 0x20, 0x80. */ + temp = ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0) | + ((sb->dsp.sb_irq401) ? 4 : 0); + if (sb->dsp.sb_type >= SBAWE32) + ret = temp | 0x80; + else + ret = temp | 0x40; break; case 0x83: @@ -1074,18 +1143,24 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) ret |= 0x01; break; - case 0x90: - /* 3D Enhancement switch. */ + case 0x49: /* Undocumented register used by some Creative drivers. */ + case 0x4a: /* Undocumented register used by some Creative drivers. */ + case 0x8c: /* Undocumented register used by some Creative drivers. */ + case 0x8e: /* Undocumented register used by some Creative drivers. */ + case 0x90: /* 3D Enhancement switch. */ + case 0xfd: /* Undocumented register used by some Creative drivers. */ + case 0xfe: /* Undocumented register used by some Creative drivers. */ ret = mixer->regs[mixer->index]; break; - /* TODO: creative drivers read and write on 0xFE and 0xFF. not sure what they are supposed to be. */ - case 0xfd: - ret = 16; - break; - - case 0xfe: - ret = 6; + case 0xff: /* Undocumented register used by some Creative drivers. + This and the upper bits of 0x82 seem to affect the + playback volume: + - Register FF = FF: Volume playback normal. + - Register FF = Not FF: Volume playback low unless + bit 6 of 82h is set. */ + if (sb->dsp.sb_type >= SBAWE32) + ret = mixer->regs[mixer->index]; break; default: @@ -1093,6 +1168,9 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) break; } + sb_log("CT1745: [R] %02X = %02X\n", mixer->index, ret); + } + sb_log("CT1745: read REG%02X: %02X\n", mixer->index, ret); return ret; @@ -1103,9 +1181,6 @@ sb_ct1745_mixer_reset(sb_t *sb) { sb_ct1745_mixer_write(4, 0, sb); sb_ct1745_mixer_write(5, 0, sb); - - sb->mixer_sb16.regs[0xfd] = 16; - sb->mixer_sb16.regs[0xfe] = 6; } uint8_t @@ -1616,8 +1691,14 @@ sb_vibra16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void * sb_dsp_setdma8(&sb->dsp, val); val = config->dma[1].dma; - if (val != ISAPNP_DMA_DISABLED) - sb_dsp_setdma16(&sb->dsp, val); + sb_dsp_setdma16_enabled(&sb->dsp, val != ISAPNP_DMA_DISABLED); + sb_dsp_setdma16_translate(&sb->dsp, val < ISAPNP_DMA_DISABLED); + if (val != ISAPNP_DMA_DISABLED) { + if (sb->dsp.sb_16_dma_supported) + sb_dsp_setdma16(&sb->dsp, val); + else + sb_dsp_setdma16_8(&sb->dsp, val); + } } break; @@ -2078,11 +2159,12 @@ sb_16_init(UNUSED(const device_t *info)) if (sb->opl_enabled) fm_driver_get(info->local, &sb->opl); - sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, (info->local == FM_YMF289B) ? SBAWE32PNP : SB16, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); sb_dsp_setdma16(&sb->dsp, device_get_config_int("dma16")); + sb_dsp_setdma16_supported(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); if (sb->opl_enabled) { @@ -2106,6 +2188,8 @@ sb_16_init(UNUSED(const device_t *info)) sb_ct1745_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); + if (device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); if (mpu_addr) { sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); @@ -2134,12 +2218,15 @@ sb_16_reply_mca_init(UNUSED(const device_t *info)) fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_setdma16_supported(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); sb->mixer_enabled = 1; sb->mixer_sb16.output_filter = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); + if (device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); memset(sb->mpu, 0, sizeof(mpu_t)); @@ -2167,16 +2254,21 @@ sb_16_pnp_init(UNUSED(const device_t *info)) sb_t *sb = malloc(sizeof(sb_t)); memset(sb, 0x00, sizeof(sb_t)); + sb->pnp = 1; + sb->opl_enabled = 1; fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_setdma16_supported(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); sb->mixer_enabled = 1; sb->mixer_sb16.output_filter = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); + if (device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); memset(sb->mpu, 0, sizeof(mpu_t)); @@ -2224,16 +2316,22 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info)) sb_t *sb = malloc(sizeof(sb_t)); memset(sb, 0x00, sizeof(sb_t)); + sb->pnp = 1; + sb->opl_enabled = 1; fm_driver_get(FM_YMF262, &sb->opl); - sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, (info->local == 0) ? SBAWE64 : SBAWE32PNP, SB_SUBTYPE_DEFAULT, sb); + /* The ViBRA 16XV does 16-bit DMA through 8-bit DMA. */ + sb_dsp_setdma16_supported(&sb->dsp, info->local != 0); sb_ct1745_mixer_reset(sb); sb->mixer_enabled = 1; sb->mixer_sb16.output_filter = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); + if (device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); memset(sb->mpu, 0, sizeof(mpu_t)); @@ -2302,6 +2400,7 @@ sb_16_compat_init(const device_t *info) fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_setdma16_supported(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); sb->mixer_enabled = 1; @@ -2374,6 +2473,7 @@ sb_awe32_init(UNUSED(const device_t *info)) sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); sb_dsp_setdma16(&sb->dsp, device_get_config_int("dma16")); + sb_dsp_setdma16_supported(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); if (sb->opl_enabled) { @@ -2397,6 +2497,8 @@ sb_awe32_init(UNUSED(const device_t *info)) sb_ct1745_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); + if (device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); if (mpu_addr) { sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); @@ -2425,16 +2527,22 @@ sb_awe32_pnp_init(const device_t *info) memset(sb, 0x00, sizeof(sb_t)); + sb->pnp = 1; + sb->opl_enabled = 1; fm_driver_get(FM_YMF262, &sb->opl); - sb_dsp_init(&sb->dsp, ((info->local == 2) || (info->local == 3) || (info->local == 4)) ? SBAWE64 : SBAWE32, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, ((info->local == 2) || (info->local == 3) || (info->local == 4)) ? + SBAWE64 : SBAWE32PNP, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_setdma16_supported(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); sb->mixer_enabled = 1; sb->mixer_sb16.output_filter = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); + if (device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); memset(sb->mpu, 0, sizeof(mpu_t)); @@ -3191,6 +3299,13 @@ static const device_config_t sb_16_config[] = { .default_string = "", .default_int = 1 }, + { + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, { .name = "receive_input", .description = "Receive input (SB MIDI)", @@ -3209,6 +3324,13 @@ static const device_config_t sb_16_config[] = { }; static const device_config_t sb_16_pnp_config[] = { + { + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, { .name = "receive_input", .description = "Receive input (SB MIDI)", @@ -3259,6 +3381,13 @@ static const device_config_t sb_32_pnp_config[] = { { .description = "" } } }, + { + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, { .name = "receive_input", .description = "Receive input (SB MIDI)", @@ -3472,6 +3601,13 @@ static const device_config_t sb_awe32_config[] = { .default_string = "", .default_int = 1 }, + { + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, { .name = "receive_input", .description = "Receive input (SB MIDI)", @@ -3522,6 +3658,13 @@ static const device_config_t sb_awe32_pnp_config[] = { { .description = "" } } }, + { + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, { .name = "receive_input", .description = "Receive input (SB MIDI)", @@ -3592,6 +3735,13 @@ static const device_config_t sb_awe64_value_config[] = { { .description = "" } } }, + { + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, { .name = "receive_input", .description = "Receive input (SB MIDI)", @@ -3658,6 +3808,13 @@ static const device_config_t sb_awe64_config[] = { { .description = "" } } }, + { + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, { .name = "receive_input", .description = "Receive input (SB MIDI)", @@ -3716,6 +3873,13 @@ static const device_config_t sb_awe64_gold_config[] = { { .description = "" } } }, + { + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, { .name = "receive_input", .description = "Receive input (SB MIDI)", diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 2178367c1..486d6eda6 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -65,7 +65,7 @@ static int sb_commands[256] = { }; char sb16_copyright[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992."; -uint16_t sb_dsp_versions[] = { 0, 0, 0x105, 0x200, 0x201, 0x300, 0x302, 0x405, 0x40d, 0x410 }; +uint16_t sb_dsp_versions[] = { 0, 0, 0x105, 0x200, 0x201, 0x300, 0x302, 0x405, 0x40c, 0x40d, 0x410 }; /*These tables were 'borrowed' from DOSBox*/ int8_t scaleMap4[64] = { @@ -115,7 +115,7 @@ uint8_t adjustMap2[24] = { 252, 0, 252, 0 }; -double low_fir_sb16_coef[2][SB16_NCoef]; +double low_fir_sb16_coef[3][SB16_NCoef]; #ifdef ENABLE_SB_DSP_LOG int sb_dsp_do_log = ENABLE_SB_DSP_LOG; @@ -423,20 +423,80 @@ sb_8_write_dma(void *priv, uint8_t val) return dma_channel_write(dsp->sb_8_dmanum, val) == DMA_NODATA; } +/* + Supported High DMA Translation Channel + ---------------------------------------------------- + 0 0 0 First 8-bit + 0 0 1 First 8-bit + 0 1 0 Second 8-bit + 0 1 1 Second 8-bit + 1 0 0 First 8-bit + 1 0 1 First 8-bit + 1 1 0 16-bit + 1 1 1 Second 8-bit + */ int sb_16_read_dma(void *priv) { const sb_dsp_t *dsp = (sb_dsp_t *) priv; + int temp, ret = 0; + int dma_flags, dma_ch = dsp->sb_16_dmanum; - return dma_channel_read(dsp->sb_16_dmanum); + if (dsp->sb_16_dma_enabled && dsp->sb_16_dma_supported && !dsp->sb_16_dma_translate) + ret = dma_channel_read(dma_ch); + else { + if (dsp->sb_16_dma_enabled) { + /* High DMA channel enabled, either translation is enabled or + 16-bit transfers are not supported. */ + if (dsp->sb_16_dma_translate || !dsp->sb_16_dma_supported) + dma_ch = dsp->sb_16_8_dmanum; + } else + /* High DMA channel disabled, always use the first 8-bit channel. */ + dma_ch = dsp->sb_8_dmanum; + temp = dma_channel_read(dma_ch); + ret = temp; + if ((temp != DMA_NODATA) && !(temp & DMA_OVER)) { + temp = dma_channel_read(dma_ch); + if (temp == DMA_NODATA) + ret = DMA_NODATA; + else { + dma_flags = temp & DMA_OVER; + temp &= ~DMA_OVER; + ret |= (temp << 8) | dma_flags; + } + } + } + + return ret; } int sb_16_write_dma(void *priv, uint16_t val) { const sb_dsp_t *dsp = (sb_dsp_t *) priv; + int temp, ret = 0; + int dma_ch = dsp->sb_16_dmanum; + + if (dsp->sb_16_dma_enabled && dsp->sb_16_dma_supported && !dsp->sb_16_dma_translate) + ret = dma_channel_write(dma_ch, val) == DMA_NODATA; + else { + if (dsp->sb_16_dma_enabled) { + /* High DMA channel enabled, either translation is enabled or + 16-bit transfers are not supported. */ + if (dsp->sb_16_dma_translate || !dsp->sb_16_dma_supported) + dma_ch = dsp->sb_16_8_dmanum; + } else + /* High DMA channel disabled, always use the first 8-bit channel. */ + dma_ch = dsp->sb_8_dmanum; + temp = dma_channel_write(dma_ch, val & 0xff); + ret = temp; + if ((temp != DMA_NODATA) && (temp != DMA_OVER)) { + temp = dma_channel_write(dma_ch, val >> 8); + ret = temp; + } + } - return dma_channel_write(dsp->sb_16_dmanum, val) == DMA_NODATA; + return ret; } void @@ -448,15 +508,45 @@ sb_dsp_setirq(sb_dsp_t *dsp, int irq) void sb_dsp_setdma8(sb_dsp_t *dsp, int dma) { + sb_dsp_log("8-bit DMA now: %i\n", dma); dsp->sb_8_dmanum = dma; } void sb_dsp_setdma16(sb_dsp_t *dsp, int dma) { + sb_dsp_log("16-bit DMA now: %i\n", dma); dsp->sb_16_dmanum = dma; } +void +sb_dsp_setdma16_8(sb_dsp_t *dsp, int dma) +{ + sb_dsp_log("16-bit to 8-bit translation DMA now: %i\n", dma); + dsp->sb_16_8_dmanum = dma; +} + +void +sb_dsp_setdma16_enabled(sb_dsp_t *dsp, int enabled) +{ + sb_dsp_log("16-bit DMA now: %sabled\n", enabled ? "en" : "dis"); + dsp->sb_16_dma_enabled = enabled; +} + +void +sb_dsp_setdma16_supported(sb_dsp_t *dsp, int supported) +{ + sb_dsp_log("16-bit DMA now: %ssupported\n", supported ? "" : "not "); + dsp->sb_16_dma_supported = supported; +} + +void +sb_dsp_setdma16_translate(sb_dsp_t *dsp, int translate) +{ + sb_dsp_log("16-bit to 8-bit translation now: %sabled\n", translate ? "en" : "dis"); + dsp->sb_16_dma_translate = translate; +} + void sb_exec_command(sb_dsp_t *dsp) { @@ -479,6 +569,100 @@ sb_exec_command(sb_dsp_t *dsp) if (dsp->sb_type >= SB16) sb_add_data(dsp, 0); break; + case 0x04: /* ASP set mode register */ + if (dsp->sb_type >= SB16) { + dsp->sb_asp_mode = dsp->sb_data[0]; + if (dsp->sb_asp_mode & 4) + dsp->sb_asp_ram_index = 0; + sb_dsp_log("SB16 ASP set mode %02X\n", dsp->sb_asp_mode); + } /* else DSP Status (Obsolete) */ + break; + case 0x05: /* ASP set codec parameter */ + if (dsp->sb_type >= SB16) + sb_dsp_log("SB16 ASP unknown codec params %02X, %02X\n", dsp->sb_data[0], dsp->sb_data[1]); + break; + case 0x07: + break; + case 0x08: /* ASP get version / AZTECH type/EEPROM access */ + if (IS_AZTECH(dsp)) { + if ((dsp->sb_data[0] == 0x05 || dsp->sb_data[0] == 0x55) && dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11) + sb_add_data(dsp, 0x11); /* AZTECH get type, WASHINGTON/latest - according to devkit. E.g.: The one in the Itautec Infoway Multimidia */ + else if ((dsp->sb_data[0] == 0x05 || dsp->sb_data[0] == 0x55) && dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) + sb_add_data(dsp, 0x0C); /* AZTECH get type, CLINTON - according to devkit. E.g.: The one in the Packard Bell Legend 100CD */ + else if (dsp->sb_data[0] == 0x08) { + /* EEPROM address to write followed by byte */ + if (dsp->sb_data[1] < 0 || dsp->sb_data[1] >= AZTECH_EEPROM_SIZE) + fatal("AZT EEPROM: out of bounds write to %02X\n", dsp->sb_data[1]); + sb_dsp_log("EEPROM write = %02x\n", dsp->sb_data[2]); + dsp->azt_eeprom[dsp->sb_data[1]] = dsp->sb_data[2]; + break; + } else if (dsp->sb_data[0] == 0x07) { + /* EEPROM address to read */ + if (dsp->sb_data[1] < 0 || dsp->sb_data[1] >= AZTECH_EEPROM_SIZE) + fatal("AZT EEPROM: out of bounds read to %02X\n", dsp->sb_data[1]); + sb_dsp_log("EEPROM read = %02x\n", dsp->azt_eeprom[dsp->sb_data[1]]); + sb_add_data(dsp, dsp->azt_eeprom[dsp->sb_data[1]]); + break; + } else + sb_dsp_log("AZT2316A: UNKNOWN 0x08 COMMAND: %02X\n", dsp->sb_data[0]); /* 0x08 (when shutting down, driver tries to read 1 byte of response), 0x55, 0x0D, 0x08D seen */ + break; + } + if (dsp->sb_type == SBAWE64) /* AWE64 has no ASP or a socket for it */ + sb_add_data(dsp, 0xFF); + else if (dsp->sb_type >= SB16) + sb_add_data(dsp, 0x18); + break; + case 0x09: /* AZTECH mode set */ + if (IS_AZTECH(dsp)) { + if (dsp->sb_data[0] == 0x00) { + sb_dsp_log("AZT2316A: WSS MODE!\n"); + azt2316a_enable_wss(1, dsp->parent); + } else if (dsp->sb_data[0] == 0x01) { + sb_dsp_log("AZT2316A: SB8PROV2 MODE!\n"); + azt2316a_enable_wss(0, dsp->parent); + } else + sb_dsp_log("AZT2316A: UNKNOWN MODE! = %02x\n", dsp->sb_data[0]); // sequences 0x02->0xFF, 0x04->0xFF seen + } + break; + case 0x0E: /* ASP set register */ + if (dsp->sb_type >= SB16) { + dsp->sb_asp_regs[dsp->sb_data[0]] = dsp->sb_data[1]; + + if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory write */ + if (dsp->sb_asp_mode & 8) + dsp->sb_asp_ram_index = 0; + + dsp->sb_asp_ram[dsp->sb_asp_ram_index] = dsp->sb_data[1]; + + if (dsp->sb_asp_mode & 2) { + dsp->sb_asp_ram_index++; + if (dsp->sb_asp_ram_index >= 2048) + dsp->sb_asp_ram_index = 0; + } + } + sb_dsp_log("SB16 ASP write reg %02X, val %02X\n", dsp->sb_data[0], dsp->sb_data[1]); + } + break; + case 0x0F: /* ASP get register */ + if (dsp->sb_type >= SB16) { + if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory read */ + if (dsp->sb_asp_mode & 8) + dsp->sb_asp_ram_index = 0; + + dsp->sb_asp_regs[0x83] = dsp->sb_asp_ram[dsp->sb_asp_ram_index]; + + if (dsp->sb_asp_mode & 1) { + dsp->sb_asp_ram_index++; + if (dsp->sb_asp_ram_index >= 2048) + dsp->sb_asp_ram_index = 0; + } + } else if (dsp->sb_data[0] == 0x83) { + dsp->sb_asp_regs[0x83] = 0x18; + } + sb_add_data(dsp, dsp->sb_asp_regs[dsp->sb_data[0]]); + sb_dsp_log("SB16 ASP read reg %02X, val %02X\n", dsp->sb_data[0], dsp->sb_asp_regs[dsp->sb_data[0]]); + } + break; case 0x10: /* 8-bit direct mode */ sb_dsp_update(dsp); dsp->sbdat = dsp->sbdatl = dsp->sbdatr = (dsp->sb_data[0] ^ 0x80) << 8; @@ -670,7 +854,8 @@ sb_exec_command(sb_dsp_t *dsp) case 0xB6: case 0xB7: /* 16-bit DMA output */ if (dsp->sb_type >= SB16) { - sb_start_dma(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); + sb_start_dma(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0], + dsp->sb_data[1] + (dsp->sb_data[2] << 8)); dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); } break; @@ -683,7 +868,8 @@ sb_exec_command(sb_dsp_t *dsp) case 0xBE: case 0xBF: /* 16-bit DMA input */ if (dsp->sb_type >= SB16) { - sb_start_dma_i(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); + sb_start_dma_i(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0], + dsp->sb_data[1] + (dsp->sb_data[2] << 8)); dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); } break; @@ -696,7 +882,8 @@ sb_exec_command(sb_dsp_t *dsp) case 0xC6: case 0xC7: /* 8-bit DMA output */ if (dsp->sb_type >= SB16) { - sb_start_dma(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); + sb_start_dma(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0], + dsp->sb_data[1] + (dsp->sb_data[2] << 8)); dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); } break; @@ -709,7 +896,8 @@ sb_exec_command(sb_dsp_t *dsp) case 0xCE: case 0xCF: /* 8-bit DMA input */ if (dsp->sb_type >= SB16) { - sb_start_dma_i(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); + sb_start_dma_i(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0], + dsp->sb_data[1] + (dsp->sb_data[2] << 8)); dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); } break; @@ -788,6 +976,8 @@ sb_exec_command(sb_dsp_t *dsp) case 0xE4: /* Write test register */ dsp->sb_test = dsp->sb_data[0]; break; + case 0xE7: /* ???? */ + break; case 0xE8: /* Read test register */ sb_add_data(dsp, dsp->sb_test); break; @@ -799,79 +989,6 @@ sb_exec_command(sb_dsp_t *dsp) sb_dsp_log("Trigger IRQ\n"); sb_irq(dsp, 0); break; - case 0xE7: /* ???? */ - break; - case 0x07: - case 0xFF: /* No, that's not how you program auto-init DMA */ - break; - case 0x08: /* ASP get version / AZTECH type/EEPROM access */ - if (IS_AZTECH(dsp)) { - if ((dsp->sb_data[0] == 0x05 || dsp->sb_data[0] == 0x55) && dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11) - sb_add_data(dsp, 0x11); /* AZTECH get type, WASHINGTON/latest - according to devkit. E.g.: The one in the Itautec Infoway Multimidia */ - else if ((dsp->sb_data[0] == 0x05 || dsp->sb_data[0] == 0x55) && dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) - sb_add_data(dsp, 0x0C); /* AZTECH get type, CLINTON - according to devkit. E.g.: The one in the Packard Bell Legend 100CD */ - else if (dsp->sb_data[0] == 0x08) { - /* EEPROM address to write followed by byte */ - if (dsp->sb_data[1] < 0 || dsp->sb_data[1] >= AZTECH_EEPROM_SIZE) - fatal("AZT EEPROM: out of bounds write to %02X\n", dsp->sb_data[1]); - sb_dsp_log("EEPROM write = %02x\n", dsp->sb_data[2]); - dsp->azt_eeprom[dsp->sb_data[1]] = dsp->sb_data[2]; - break; - } else if (dsp->sb_data[0] == 0x07) { - /* EEPROM address to read */ - if (dsp->sb_data[1] < 0 || dsp->sb_data[1] >= AZTECH_EEPROM_SIZE) - fatal("AZT EEPROM: out of bounds read to %02X\n", dsp->sb_data[1]); - sb_dsp_log("EEPROM read = %02x\n", dsp->azt_eeprom[dsp->sb_data[1]]); - sb_add_data(dsp, dsp->azt_eeprom[dsp->sb_data[1]]); - break; - } else - sb_dsp_log("AZT2316A: UNKNOWN 0x08 COMMAND: %02X\n", dsp->sb_data[0]); /* 0x08 (when shutting down, driver tries to read 1 byte of response), 0x55, 0x0D, 0x08D seen */ - break; - } - if (dsp->sb_type == SBAWE64) /* AWE64 has no ASP or a socket for it */ - sb_add_data(dsp, 0xFF); - else if (dsp->sb_type >= SB16) - sb_add_data(dsp, 0x18); - break; - case 0x0E: /* ASP set register */ - if (dsp->sb_type >= SB16) { - dsp->sb_asp_regs[dsp->sb_data[0]] = dsp->sb_data[1]; - - if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory write */ - if (dsp->sb_asp_mode & 8) - dsp->sb_asp_ram_index = 0; - - dsp->sb_asp_ram[dsp->sb_asp_ram_index] = dsp->sb_data[1]; - - if (dsp->sb_asp_mode & 2) { - dsp->sb_asp_ram_index++; - if (dsp->sb_asp_ram_index >= 2048) - dsp->sb_asp_ram_index = 0; - } - } - sb_dsp_log("SB16 ASP write reg %02X, val %02X\n", dsp->sb_data[0], dsp->sb_data[1]); - } - break; - case 0x0F: /* ASP get register */ - if (dsp->sb_type >= SB16) { - if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory read */ - if (dsp->sb_asp_mode & 8) - dsp->sb_asp_ram_index = 0; - - dsp->sb_asp_regs[0x83] = dsp->sb_asp_ram[dsp->sb_asp_ram_index]; - - if (dsp->sb_asp_mode & 1) { - dsp->sb_asp_ram_index++; - if (dsp->sb_asp_ram_index >= 2048) - dsp->sb_asp_ram_index = 0; - } - } else if (dsp->sb_data[0] == 0x83) { - dsp->sb_asp_regs[0x83] = 0x18; - } - sb_add_data(dsp, dsp->sb_asp_regs[dsp->sb_data[0]]); - sb_dsp_log("SB16 ASP read reg %02X, val %02X\n", dsp->sb_data[0], dsp->sb_asp_regs[dsp->sb_data[0]]); - } - break; case 0xF8: if (dsp->sb_type < SB16) sb_add_data(dsp, 0); @@ -884,30 +1001,7 @@ sb_exec_command(sb_dsp_t *dsp) if (dsp->sb_type >= SB16) dsp->sb_8051_ram[dsp->sb_data[0]] = dsp->sb_data[1]; break; - case 0x04: /* ASP set mode register */ - if (dsp->sb_type >= SB16) { - dsp->sb_asp_mode = dsp->sb_data[0]; - if (dsp->sb_asp_mode & 4) - dsp->sb_asp_ram_index = 0; - sb_dsp_log("SB16 ASP set mode %02X\n", dsp->sb_asp_mode); - } /* else DSP Status (Obsolete) */ - break; - case 0x05: /* ASP set codec parameter */ - if (dsp->sb_type >= SB16) - sb_dsp_log("SB16 ASP unknown codec params %02X, %02X\n", dsp->sb_data[0], dsp->sb_data[1]); - break; - - case 0x09: /* AZTECH mode set */ - if (IS_AZTECH(dsp)) { - if (dsp->sb_data[0] == 0x00) { - sb_dsp_log("AZT2316A: WSS MODE!\n"); - azt2316a_enable_wss(1, dsp->parent); - } else if (dsp->sb_data[0] == 0x01) { - sb_dsp_log("AZT2316A: SB8PROV2 MODE!\n"); - azt2316a_enable_wss(0, dsp->parent); - } else - sb_dsp_log("AZT2316A: UNKNOWN MODE! = %02x\n", dsp->sb_data[0]); // sequences 0x02->0xFF, 0x04->0xFF seen - } + case 0xFF: /* No, that's not how you program auto-init DMA */ break; /* TODO: Some more data about the DSP registeres @@ -925,6 +1019,7 @@ sb_exec_command(sb_dsp_t *dsp) */ default: + sb_dsp_log("Unknown DSP command: %02X\n", dsp->sb_command); break; } @@ -939,6 +1034,10 @@ sb_write(uint16_t a, uint8_t v, void *priv) { sb_dsp_t *dsp = (sb_dsp_t *) priv; + /* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */ + if (dsp->sb_type < SB16) + a &= 0xfffe; + switch (a & 0xF) { case 6: /* Reset */ if (!dsp->uart_midi) { @@ -1003,6 +1102,10 @@ sb_read(uint16_t a, void *priv) sb_dsp_t *dsp = (sb_dsp_t *) priv; uint8_t ret = 0x00; + /* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */ + if (dsp->sb_type < SB16) + a &= 0xfffe; + switch (a & 0xf) { case 0xA: /* Read data */ if (dsp->mpu && dsp->uart_midi) { @@ -1153,6 +1256,7 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) a set frequency command is sent. */ recalc_sb16_filter(0, 3200 * 2); recalc_sb16_filter(1, FREQ_44100); + recalc_sb16_filter(2, 18939); /* Initialize SB16 8051 RAM and ASP internal RAM */ memset(dsp->sb_8051_ram, 0x00, sizeof(dsp->sb_8051_ram)); diff --git a/src/sound/snd_speaker.c b/src/sound/snd_speaker.c index 693c3afc3..0537cd09a 100644 --- a/src/sound/snd_speaker.c +++ b/src/sound/snd_speaker.c @@ -88,15 +88,20 @@ speaker_update(void) void speaker_get_buffer(int32_t *buffer, int len, UNUSED(void *priv)) { - int32_t val; + double val_l, val_r; speaker_update(); if (!speaker_mute) { for (int c = 0; c < len * 2; c += 2) { - val = speaker_buffer[c >> 1]; - buffer[c] += val; - buffer[c + 1] += val; + val_l = val_r = (double) speaker_buffer[c >> 1]; + /* Apply PC speaker volume and filters */ + if (filter_pc_speaker != NULL) { + filter_pc_speaker(0, &val_l, filter_pc_speaker_p); + filter_pc_speaker(1, &val_r, filter_pc_speaker_p); + } + buffer[c] += (int32_t) val_l; + buffer[c + 1] += (int32_t) val_r; } } diff --git a/src/sound/sound.c b/src/sound/sound.c index 4e0b4aa57..ed7f821e0 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -77,7 +77,10 @@ static volatile int cdaudioon = 0; static int cd_thread_enable = 0; static void (*filter_cd_audio)(int channel, double *buffer, void *priv) = NULL; -static void *filter_cd_audio_p = NULL; +static void *filter_cd_audio_p = NULL; + +void (*filter_pc_speaker)(int channel, double *buffer, void *priv) = NULL; +void *filter_pc_speaker_p = NULL; static const device_t sound_none_device = { .name = "None", @@ -222,13 +225,13 @@ sound_card_get_from_internal_name(const char *s) void sound_card_init(void) { - if ((sound_card_current[0] != SOUND_INTERNAL) && (sound_cards[sound_card_current[0]].device)) + if ((sound_card_current[0] > SOUND_INTERNAL) && (sound_cards[sound_card_current[0]].device)) device_add(sound_cards[sound_card_current[0]].device); - if (sound_cards[sound_card_current[1]].device) + if ((sound_card_current[1] > SOUND_INTERNAL) && (sound_cards[sound_card_current[1]].device)) device_add(sound_cards[sound_card_current[1]].device); - if (sound_cards[sound_card_current[2]].device) + if ((sound_card_current[2] > SOUND_INTERNAL) && (sound_cards[sound_card_current[2]].device)) device_add(sound_cards[sound_card_current[2]].device); - if (sound_cards[sound_card_current[3]].device) + if ((sound_card_current[3] > SOUND_INTERNAL) && (sound_cards[sound_card_current[3]].device)) device_add(sound_cards[sound_card_current[3]].device); } @@ -444,6 +447,15 @@ sound_set_cd_audio_filter(void (*filter)(int channel, double *buffer, void *priv } } +void +sound_set_pc_speaker_filter(void (*filter)(int channel, double *buffer, void *priv), void *priv) +{ + if ((filter_pc_speaker == NULL) || (filter == NULL)) { + filter_pc_speaker = filter; + filter_pc_speaker_p = priv; + } +} + void sound_poll(UNUSED(void *priv)) { @@ -514,6 +526,9 @@ sound_reset(void) filter_cd_audio = NULL; filter_cd_audio_p = NULL; + filter_pc_speaker = NULL; + filter_pc_speaker_p = NULL; + sound_set_cd_volume(65535, 65535); /* Reset the MPU-401 already loaded flag and the chain of input/output handlers. */ diff --git a/src/unix/unix.c b/src/unix/unix.c index 860bc814f..7b3fd56cf 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -21,6 +21,10 @@ #include #include +#ifdef __APPLE__ +# include "macOSXGlue.h" +#endif + #include <86box/86box.h> #include <86box/mem.h> #include <86box/rom.h> @@ -41,10 +45,6 @@ #include <86box/ui.h> #include <86box/gdbstub.h> -#ifdef __APPLE__ -# include "macOSXGlue.h" -#endif - static int first_use = 1; static uint64_t StartingTime; static uint64_t Frequency; @@ -191,6 +191,7 @@ dynld_module(const char *name, dllimp_t *table) { dllimp_t *imp; void *modhandle = dlopen(name, RTLD_LAZY | RTLD_GLOBAL); + if (modhandle) { for (imp = table; imp->name != NULL; imp++) { if ((*(void **) imp->func = dlsym(modhandle, imp->name)) == NULL) { @@ -199,6 +200,7 @@ dynld_module(const char *name, dllimp_t *table) } } } + return modhandle; } @@ -405,7 +407,7 @@ plat_mmap(size_t size, uint8_t executable) #if defined __APPLE__ && defined MAP_JIT void *ret = mmap(0, size, PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0), MAP_ANON | MAP_PRIVATE | (executable ? MAP_JIT : 0), -1, 0); #else - void *ret = mmap(0, size, PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0), MAP_ANON | MAP_PRIVATE, -1, 0); + void *ret = mmap(0, size, PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0), MAP_ANON | MAP_PRIVATE, -1, 0); #endif return (ret < 0) ? NULL : ret; } @@ -427,6 +429,7 @@ plat_get_ticks_common(void) { uint64_t EndingTime; uint64_t ElapsedMicroseconds; + if (first_use) { Frequency = SDL_GetPerformanceFrequency(); StartingTime = SDL_GetPerformanceCounter(); @@ -434,6 +437,7 @@ plat_get_ticks_common(void) } EndingTime = SDL_GetPerformanceCounter(); ElapsedMicroseconds = ((EndingTime - StartingTime) * 1000000) / Frequency; + return ElapsedMicroseconds; } @@ -458,11 +462,13 @@ plat_remove(char *path) void ui_sb_update_icon_state(int tag, int state) { + /* No-op. */ } void ui_sb_update_icon(int tag, int active) { + /* No-op. */ } void @@ -474,25 +480,26 @@ plat_delay_ms(uint32_t count) void ui_sb_update_tip(int arg) { + /* No-op. */ } void ui_sb_update_panes(void) { + /* No-op. */ } void ui_sb_update_text(void) { + /* No-op. */ } void path_get_dirname(char *dest, const char *path) { int c = (int) strlen(path); - char *ptr; - - ptr = (char *) path; + char *ptr = (char *) path; while (c > 0) { if (path[c] == '/' || path[c] == '\\') { @@ -511,6 +518,7 @@ volatile int cpu_thread_run = 1; void ui_sb_set_text_w(wchar_t *wstr) { + /* No-op. */ } int @@ -634,12 +642,16 @@ ui_msgbox_header(int flags, void *header, void *message) { SDL_MessageBoxData msgdata; SDL_MessageBoxButtonData msgbtn; + +#if 0 if (!header) header = (void *) (flags & MBX_ANSI) ? "86Box" : L"86Box"; +#endif if (header <= (void *) 7168) - header = (void *) plat_get_string((int) header); + header = (void *) plat_get_string((uintptr_t) header); if (message <= (void *) 7168) - message = (void *) plat_get_string((int) message); + message = (void *) plat_get_string((uintptr_t) message); + msgbtn.buttonid = 1; msgbtn.text = "OK"; msgbtn.flags = 0; @@ -679,6 +691,7 @@ void plat_get_exe_name(char *s, int size) { char *basepath = SDL_GetBasePath(); + snprintf(s, size, "%s%s", basepath, basepath[strlen(basepath) - 1] == '/' ? "86box" : "/86box"); } @@ -699,6 +712,7 @@ plat_power_off(void) void ui_sb_bugui(char *str) { + /* No-op. */ } extern void sdl_blit(int x, int y, int w, int h); @@ -709,13 +723,17 @@ typedef struct mouseinputdata { int deltaz; int mousebuttons; } mouseinputdata; -SDL_mutex *mousemutex; -int real_sdl_w; -int real_sdl_h; + +SDL_mutex *mousemutex; +int real_sdl_w; +int real_sdl_h; + void ui_sb_set_ready(int ready) { + /* No-op. */ } + char *xargv[512]; // From musl. @@ -724,6 +742,7 @@ local_strsep(char **str, const char *sep) { char *s = *str; char *end; + if (!s) return NULL; end = s + strcspn(s, sep); @@ -732,6 +751,7 @@ local_strsep(char **str, const char *sep) else end = 0; *str = end; + return s; } @@ -761,6 +781,7 @@ plat_init_rom_paths(void) #ifndef __APPLE__ if (getenv("XDG_DATA_HOME")) { char xdg_rom_path[1024] = { 0 }; + strncpy(xdg_rom_path, getenv("XDG_DATA_HOME"), 1024); path_slash(xdg_rom_path); strncat(xdg_rom_path, "86Box/", 1024); @@ -774,6 +795,7 @@ plat_init_rom_paths(void) rom_add_path(xdg_rom_path); } else { char home_rom_path[1024] = { 0 }; + snprintf(home_rom_path, 1024, "%s/.local/share/86Box/", getenv("HOME") ? getenv("HOME") : getpwuid(getuid())->pw_dir); if (!plat_dir_check(home_rom_path)) @@ -788,6 +810,7 @@ plat_init_rom_paths(void) char *xdg_rom_paths = strdup(getenv("XDG_DATA_DIRS")); char *xdg_rom_paths_orig = xdg_rom_paths; char *cur_xdg_rom_path = NULL; + if (xdg_rom_paths) { while (xdg_rom_paths[strlen(xdg_rom_paths) - 1] == ':') { xdg_rom_paths[strlen(xdg_rom_paths) - 1] = '\0'; @@ -828,7 +851,9 @@ bool process_media_commands_3(uint8_t *id, char *fn, uint8_t *wp, int cmdargc) { bool err = false; + *id = atoi(xargv[1]); + if (xargv[2][0] == '\'' || xargv[2][0] == '"') { for (int curarg = 2; curarg < cmdargc; curarg++) { if (strlen(fn) + strlen(xargv[curarg]) >= PATH_MAX) { @@ -868,6 +893,7 @@ void (*f_rl_callback_handler_remove)(void) = NULL; #else # define LIBEDIT_LIBRARY "libedit.so" #endif + uint32_t timer_onesec(uint32_t interval, void *param) { @@ -882,6 +908,7 @@ monitor_thread(void *param) if (isatty(fileno(stdin)) && isatty(fileno(stdout))) { char *line = NULL; size_t n; + printf("86Box monitor console.\n"); while (!exit_event) { if (feof(stdin)) @@ -890,11 +917,12 @@ monitor_thread(void *param) line = f_readline("(86Box) "); else { printf("(86Box) "); - getline(&line, &n, stdin); + !getline(&line, &n, stdin); } if (line) { int cmdargc = 0; char *linecpy; + line[strcspn(line, "\r\n")] = '\0'; linecpy = strdup(line); if (!linecpy) { @@ -989,6 +1017,7 @@ monitor_thread(void *param) memset(fn, 0, sizeof(fn)); if (xargv[2][0] == '\'' || xargv[2][0] == '"') { int curarg = 2; + for (curarg = 2; curarg < cmdargc; curarg++) { if (strlen(fn) + strlen(xargv[curarg]) >= PATH_MAX) { err = true; @@ -1031,7 +1060,9 @@ monitor_thread(void *param) uint8_t wp; bool err = false; char fn[PATH_MAX]; + memset(fn, 0, sizeof(fn)); + if (!xargv[2] || !xargv[1]) { free(line); free(linecpy); @@ -1051,7 +1082,9 @@ monitor_thread(void *param) uint8_t wp; bool err = false; char fn[PATH_MAX]; + memset(fn, 0, sizeof(fn)); + if (!xargv[2] || !xargv[1]) { free(line); free(linecpy); @@ -1071,7 +1104,9 @@ monitor_thread(void *param) uint8_t wp; bool err = false; char fn[PATH_MAX]; + memset(fn, 0, sizeof(fn)); + if (!xargv[2] || !xargv[1]) { free(line); free(linecpy); @@ -1091,7 +1126,9 @@ monitor_thread(void *param) uint8_t wp; bool err = false; char fn[PATH_MAX]; + memset(fn, 0, sizeof(fn)); + if (!xargv[2] || !xargv[1]) { free(line); free(linecpy); @@ -1170,6 +1207,7 @@ main(int argc, char **argv) SDL_AddTimer(1000, timer_onesec, NULL); while (!is_quit) { static int mouse_inside = 0; + while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: @@ -1244,6 +1282,7 @@ main(int argc, char **argv) case SDL_RENDER_TARGETS_RESET: { extern void sdl_reinit_texture(void); + sdl_reinit_texture(); break; } @@ -1251,6 +1290,7 @@ main(int argc, char **argv) case SDL_KEYUP: { uint16_t xtkey = 0; + switch (event.key.keysym.scancode) { default: xtkey = sdl_to_xt[event.key.keysym.scancode]; @@ -1326,6 +1366,7 @@ plat_language_code(char *langcode) void plat_get_cpu_string(char *outbuf, uint8_t len) { char cpu_string[] = "Unknown"; + strncpy(outbuf, cpu_string, len); } @@ -1340,15 +1381,21 @@ plat_language_code_r(uint32_t lcid, char *outbuf, int len) void joystick_init(void) { + /* No-op. */ } + void joystick_close(void) { + /* No-op. */ } + void joystick_process(void) { + /* No-op. */ } + void startblit(void) { @@ -1365,9 +1412,11 @@ endblit(void) void ui_sb_mt32lcd(char *str) { + /* No-op. */ } void ui_hard_reset_completed(void) { + /* No-op. */ } diff --git a/src/unix/unix_sdl.c b/src/unix/unix_sdl.c index e20abbcd6..19af4b71e 100644 --- a/src/unix/unix_sdl.c +++ b/src/unix/unix_sdl.c @@ -51,7 +51,7 @@ int title_set = 0; int resize_pending = 0; int resize_w = 0; int resize_h = 0; -static uint8_t interpixels[17842176]; +static void *pixeldata; extern void RenderImGui(void); static void @@ -150,11 +150,15 @@ sdl_blit_shim(int x, int y, int w, int h, int monitor_index) params.y = y; params.w = w; params.h = h; + if (!(!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL)) || (monitor_index >= 1)) - video_copy(interpixels, &(buffer32->line[y][x]), h * 2048 * sizeof(uint32_t)); - if (screenshots) - video_screenshot(interpixels, 0, 0, 2048); + for (int row = 0; row < h; ++row) + video_copy(&(((uint8_t *) pixeldata)[row * 2048 * sizeof(uint32_t)]), &(buffer32->line[y + row][x]), w * sizeof(uint32_t)); + + if (monitors[monitor_index].mon_screenshots) + video_screenshot((uint32_t *) pixeldata, 0, 0, 2048); blitreq = 1; + video_blit_complete_monitor(monitor_index); } @@ -167,6 +171,7 @@ sdl_real_blit(SDL_Rect *r_src) int ret; int winx; int winy; + SDL_GL_GetDrawableSize(sdl_win, &winx, &winy); SDL_RenderClear(sdl_render); @@ -213,7 +218,7 @@ sdl_blit(int x, int y, int w, int h) r_src.y = y; r_src.w = w; r_src.h = h; - SDL_UpdateTexture(sdl_tex, &r_src, interpixels, 2048 * 4); + SDL_UpdateTexture(sdl_tex, &r_src, pixeldata, 2048 * 4); blitreq = 0; sdl_real_blit(&r_src); @@ -270,8 +275,6 @@ sdl_close(void) sdl_flags = -1; } -static int old_capture = 0; - void sdl_enable(int enable) { @@ -392,7 +395,6 @@ plat_vidapi(char *api) static int sdl_init_common(int flags) { - wchar_t temp[128]; SDL_version ver; /* Get and log the version of the DLL we are using. */ @@ -526,10 +528,13 @@ ui_window_title(wchar_t *str) void ui_init_monitor(int monitor_index) { + /* No-op. */ } + void ui_deinit_monitor(int monitor_index) { + /* No-op. */ } void diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 75e79dec9..da1b5d556 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -229,6 +229,7 @@ typedef struct mach64_t { int dst_size; int src_size; int host_size; + int temp_cnt; uint32_t dp_bkgd_clr; uint32_t dp_frgd_clr; @@ -1326,10 +1327,12 @@ mach64_start_fill(mach64_t *mach64) mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST); - for (uint8_t y = 0; y < 8; y++) { - for (uint8_t x = 0; x < 8; x++) { - uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; - mach64->accel.pattern[y][7 - x] = (temp >> (x + ((y & 3) * 8))) & 1; + if (mach64->pat_cntl & 1) { + for (uint8_t y = 0; y < 8; y++) { + for (uint8_t x = 0; x < 8; x++) { + uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; + mach64->accel.pattern[y][7 - x] = (temp >> (x + ((y & 3) << 3))) & 1; + } } } @@ -1342,7 +1345,9 @@ mach64_start_fill(mach64_t *mach64) mach64->accel.pattern_clr4x2[1][1] = ((mach64->pat_reg1 >> 8) & 0xff); mach64->accel.pattern_clr4x2[1][2] = ((mach64->pat_reg1 >> 16) & 0xff); mach64->accel.pattern_clr4x2[1][3] = ((mach64->pat_reg1 >> 24) & 0xff); - } else if (mach64->pat_cntl & 4) { + } + + if (mach64->pat_cntl & 4) { mach64->accel.pattern_clr8x1[0] = (mach64->pat_reg0 & 0xff); mach64->accel.pattern_clr8x1[1] = ((mach64->pat_reg0 >> 8) & 0xff); mach64->accel.pattern_clr8x1[2] = ((mach64->pat_reg0 >> 16) & 0xff); @@ -1425,10 +1430,12 @@ mach64_start_line(mach64_t *mach64) mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST); - for (uint8_t y = 0; y < 8; y++) { - for (uint8_t x = 0; x < 8; x++) { - uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; - mach64->accel.pattern[y][7 - x] = (temp >> (x + ((y & 3) * 8))) & 1; + if (mach64->pat_cntl & 1) { + for (uint8_t y = 0; y < 8; y++) { + for (uint8_t x = 0; x < 8; x++) { + uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; + mach64->accel.pattern[y][7 - x] = (temp >> (x + ((y & 3) << 3))) & 1; + } } } @@ -1555,6 +1562,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) { svga_t *svga = &mach64->svga; int cmp_clr = 0; + int mix = 0; if (!mach64->accel.busy) { mach64_log("mach64_blit : return as not busy\n"); @@ -1565,11 +1573,10 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) case OP_RECT: while (count) { uint8_t write_mask = 0; - uint32_t src_dat = 0; + uint32_t src_dat = 0; uint32_t dest_dat; uint32_t host_dat = 0; uint32_t old_dest_dat; - int mix = 0; int dst_x; int dst_y; int src_x; @@ -1617,7 +1624,11 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) } break; case MONO_SRC_PAT: - mix = mach64->accel.pattern[dst_y & 7][dst_x & 7]; + if (mach64->dst_cntl & DST_24_ROT_EN) { + if (!mach64->accel.xx_count) + mix = mach64->accel.pattern[dst_y & 7][dst_x & 7]; + } else + mix = mach64->accel.pattern[dst_y & 7][dst_x & 7]; break; case MONO_SRC_1: mix = 1; @@ -1643,18 +1654,18 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, src_dat, mach64->accel.src_size); break; case SRC_FG: - if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) { + if (mach64->dst_cntl & DST_24_ROT_EN) { if (mach64->accel.xinc == -1) { - if ((mach64->accel.xx_count % 3) == 2) + if (mach64->accel.xx_count == 2) src_dat = mach64->accel.dp_frgd_clr & 0xff; - else if ((mach64->accel.xx_count % 3) == 1) + else if (mach64->accel.xx_count == 1) src_dat = (mach64->accel.dp_frgd_clr >> 8) & 0xff; else src_dat = (mach64->accel.dp_frgd_clr >> 16) & 0xff; } else { - if ((mach64->accel.xx_count % 3) == 2) + if (mach64->accel.xx_count == 2) src_dat = (mach64->accel.dp_frgd_clr >> 16) & 0xff; - else if ((mach64->accel.xx_count % 3) == 1) + else if (mach64->accel.xx_count == 1) src_dat = (mach64->accel.dp_frgd_clr >> 8) & 0xff; else src_dat = mach64->accel.dp_frgd_clr & 0xff; @@ -1663,18 +1674,18 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) src_dat = mach64->accel.dp_frgd_clr; break; case SRC_BG: - if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) { + if (mach64->dst_cntl & DST_24_ROT_EN) { if (mach64->accel.xinc == -1) { - if ((mach64->accel.xx_count % 3) == 2) + if (mach64->accel.xx_count == 2) src_dat = mach64->accel.dp_bkgd_clr & 0xff; - else if ((mach64->accel.xx_count % 3) == 1) + else if (mach64->accel.xx_count == 1) src_dat = (mach64->accel.dp_bkgd_clr >> 8) & 0xff; else src_dat = (mach64->accel.dp_bkgd_clr >> 16) & 0xff; } else { - if ((mach64->accel.xx_count % 3) == 2) + if (mach64->accel.xx_count == 2) src_dat = (mach64->accel.dp_bkgd_clr >> 16) & 0xff; - else if ((mach64->accel.xx_count % 3) == 1) + else if (mach64->accel.xx_count == 1) src_dat = (mach64->accel.dp_bkgd_clr >> 8) & 0xff; else src_dat = mach64->accel.dp_bkgd_clr & 0xff; @@ -1724,27 +1735,25 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) if (!cmp_clr) { old_dest_dat = dest_dat; MIX - - if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) { + if (mach64->dst_cntl & DST_24_ROT_EN) { if (mach64->accel.xinc == -1) { - if ((mach64->accel.xx_count % 3) == 2) + if (mach64->accel.xx_count == 2) write_mask = mach64->accel.write_mask & 0xff; - else if ((mach64->accel.xx_count % 3) == 1) + else if (mach64->accel.xx_count == 1) write_mask = (mach64->accel.write_mask >> 8) & 0xff; else write_mask = (mach64->accel.write_mask >> 16) & 0xff; } else { - if ((mach64->accel.xx_count % 3) == 2) + if (mach64->accel.xx_count == 2) write_mask = (mach64->accel.write_mask >> 16) & 0xff; - else if ((mach64->accel.xx_count % 3) == 1) + else if (mach64->accel.xx_count == 1) write_mask = (mach64->accel.write_mask >> 8) & 0xff; else write_mask = mach64->accel.write_mask & 0xff; } dest_dat = (dest_dat & write_mask) | (old_dest_dat & ~write_mask); - } else { + } else dest_dat = (dest_dat & mach64->accel.write_mask) | (old_dest_dat & ~mach64->accel.write_mask); - } } WRITE(mach64->accel.dst_offset + ((dst_y) * mach64->accel.dst_pitch) + (dst_x), mach64->accel.dst_size); @@ -1767,11 +1776,11 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) } } - mach64->accel.xx_count++; mach64->accel.x_count--; + mach64->accel.xx_count = (mach64->accel.xx_count + 1) % 3; if (mach64->accel.x_count <= 0) { - mach64->accel.xx_count = 0; mach64->accel.x_count = mach64->accel.dst_width; + mach64->accel.xx_count = 0; mach64->accel.dst_x = 0; mach64->accel.dst_y += mach64->accel.yinc; mach64->accel.src_x_start = (mach64->src_y_x >> 16) & 0xfff; @@ -1794,9 +1803,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) } mach64->accel.poly_draw = 0; - mach64->accel.dst_height--; - if (mach64->accel.dst_height <= 0) { /*Blit finished*/ mach64_log("mach64 blit finished\n"); diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 86926f26e..8e7174666 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2427,16 +2427,6 @@ mach_out(uint16_t addr, uint8_t val, void *priv) svga_out(addr, val, svga); return; - case 0x3CF: - if (svga->gdcaddr == 6) { - uint8_t old_val = svga->gdcreg[6]; - svga->gdcreg[6] = val; - if ((svga->gdcreg[6] & 0xc) != (old_val & 0xc)) - mach32_updatemapping(mach); - return; - } - break; - case 0x3D4: svga->crtcreg = val & 0x3f; return; diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 41aadf6ba..83c4f5a63 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -3693,8 +3693,7 @@ cl_pci_read(UNUSED(int func), int addr, void *priv) if ((addr >= 0x30) && (addr <= 0x33) && (!gd54xx->has_bios)) ret = 0x00; - else - switch (addr) { + else switch (addr) { case 0x00: ret = 0x13; /*Cirrus Logic*/ break; @@ -3743,7 +3742,7 @@ cl_pci_read(UNUSED(int func), int addr, void *priv) case 0x13: ret = gd54xx->lfb_base >> 24; if (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) - ret = 0xfe; + ret &= 0xfe; break; case 0x14: @@ -3781,7 +3780,7 @@ cl_pci_read(UNUSED(int func), int addr, void *priv) default: break; - } + } return ret; } diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 865087bf8..db86d273f 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -246,10 +246,10 @@ typedef struct s3_t { uint8_t pix_trans[4]; int ssv_state; - int cx, cy; - int px, py; - int sx, sy; - int dx, dy; + int16_t cx, cy; + int16_t px, py; + int16_t sx, sy; + int16_t dx, dy; uint32_t src, dest, pattern; int poly_cx, poly_cx2; @@ -262,7 +262,6 @@ typedef struct s3_t { uint32_t dat_buf; int dat_count; int b2e8_pix, temp_cnt; - uint8_t cur_x_bit12, cur_y_bit12; int ssv_len; uint8_t ssv_dir; uint8_t ssv_draw; @@ -712,15 +711,12 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) switch (port) { case 0x8148: case 0x82e8: - s3->accel.cur_y_bitres = (s3->accel.cur_y_bitres & 0xff00) | val; s3->accel.cur_y = (s3->accel.cur_y & 0xf00) | val; s3->accel.poly_cy = s3->accel.cur_y; break; case 0x8149: case 0x82e9: - s3->accel.cur_y_bitres = (s3->accel.cur_y_bitres & 0xff) | (val << 8); s3->accel.cur_y = (s3->accel.cur_y & 0xff) | ((val & 0x0f) << 8); - s3->accel.cur_y_bit12 = val & 0x10; s3->accel.poly_cy = s3->accel.cur_y; break; case 0x814a: @@ -736,16 +732,13 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x8548: case 0x86e8: - s3->accel.cur_x_bitres = (s3->accel.cur_x_bitres & 0xff00) | val; s3->accel.cur_x = (s3->accel.cur_x & 0xf00) | val; s3->accel.poly_cx = s3->accel.cur_x << 20; s3->accel.poly_x = s3->accel.poly_cx >> 20; break; case 0x8549: case 0x86e9: - s3->accel.cur_x_bitres = (s3->accel.cur_x_bitres & 0xff) | (val << 8); s3->accel.cur_x = (s3->accel.cur_x & 0xff) | ((val & 0x0f) << 8); - s3->accel.cur_x_bit12 = val & 0x10; s3->accel.poly_cx = s3->accel.poly_x = s3->accel.cur_x << 20; s3->accel.poly_x = s3->accel.poly_cx >> 20; break; @@ -884,14 +877,14 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.short_stroke = (s3->accel.short_stroke & 0xff) | (val << 8); s3->accel.ssv_state = 1; - s3->accel.cx = s3->accel.cur_x & 0x7ff; - s3->accel.cy = s3->accel.cur_y & 0x7ff; + s3->accel.cx = s3->accel.cur_x & 0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cur_x & 0x800) { - s3->accel.cx |= ~0x7ff; + if (s3->accel.cur_x & 0x1000) { + s3->accel.cx |= ~0xfff; } - if (s3->accel.cur_y & 0x800) { - s3->accel.cy |= ~0x7ff; + if (s3->accel.cur_y & 0x1000) { + s3->accel.cy |= ~0xfff; } if (s3->accel.cmd & 0x1000) { @@ -1426,14 +1419,14 @@ s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) s3->accel.short_stroke = val; s3->accel.ssv_state = 1; - s3->accel.cx = s3->accel.cur_x & 0x7ff; - s3->accel.cy = s3->accel.cur_y & 0x7ff; + s3->accel.cx = s3->accel.cur_x & 0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cur_x & 0x800) { - s3->accel.cx |= ~0x7ff; + if (s3->accel.cur_x & 0x1000) { + s3->accel.cx |= ~0xfff; } - if (s3->accel.cur_y & 0x800) { - s3->accel.cy |= ~0x7ff; + if (s3->accel.cur_y & 0x1000) { + s3->accel.cy |= ~0xfff; } if (s3->accel.cmd & 0x1000) { @@ -6380,14 +6373,14 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 1: /*Draw line*/ if (!cpu_input) { - s3->accel.cx = s3->accel.cur_x & 0x7ff; - s3->accel.cy = s3->accel.cur_y & 0x7ff; + s3->accel.cx = s3->accel.cur_x & 0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cur_x & 0x800) - s3->accel.cx |= ~0x7ff; + if (s3->accel.cur_x & 0x1000) + s3->accel.cx |= ~0xfff; - if (s3->accel.cur_y & 0x800) - s3->accel.cy |= ~0x7ff; + if (s3->accel.cur_y & 0x1000) + s3->accel.cy |= ~0xfff; s3->accel.sy = s3->accel.maj_axis_pcnt; @@ -6615,14 +6608,14 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ { s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; s3->accel.sy = s3->accel.multifunc[0] & 0xfff; - s3->accel.cx = s3->accel.cur_x & 0x7ff; - s3->accel.cy = s3->accel.cur_y & 0x7ff; + s3->accel.cx = s3->accel.cur_x & 0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cur_x & 0x800) { - s3->accel.cx |= ~0x7ff; + if (s3->accel.cur_x & 0x1000) { + s3->accel.cx |= ~0xfff; } - if (s3->accel.cur_y & 0x800) { - s3->accel.cy |= ~0x7ff; + if (s3->accel.cur_y & 0x1000) { + s3->accel.cy |= ~0xfff; } s3->accel.dest = dstbase + s3->accel.cy * s3->width; @@ -6844,14 +6837,14 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (s3->accel.desty_axstp & 0x800) s3->accel.dy |= ~0x7ff; - s3->accel.cx = s3->accel.cur_x & 0x7ff; - s3->accel.cy = s3->accel.cur_y & 0x7ff; + s3->accel.cx = s3->accel.cur_x & 0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cur_x & 0x800) { - s3->accel.cx |= ~0x7ff; + if (s3->accel.cur_x & 0x1000) { + s3->accel.cx |= ~0xfff; } - if (s3->accel.cur_y & 0x800) { - s3->accel.cy |= ~0x7ff; + if (s3->accel.cur_y & 0x1000) { + s3->accel.cy |= ~0xfff; } s3->accel.src = srcbase + s3->accel.cy * s3->width; @@ -7007,10 +7000,10 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.dy |= ~0xfff; s3->accel.cx = s3->accel.cur_x & 0xfff; - if (s3->accel.cur_x_bit12) + if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff; s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cur_y_bit12) + if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; /*Align source with destination*/ @@ -7132,10 +7125,10 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.dy |= ~0xfff; s3->accel.cx = s3->accel.cur_x; - if (s3->accel.cur_x_bit12) + if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff; s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_y_bit12) + if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; } @@ -7323,10 +7316,10 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.dy |= ~0xfff; s3->accel.cx = s3->accel.cur_x & 0xfff; - if (s3->accel.cur_x_bit12) + if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff; s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cur_y_bit12) + if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; s3->accel.px = s3->accel.pat_x & 0xfff; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 360fcbb5f..8ec645016 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1259,6 +1259,8 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv) xga->test = val; if (addr == 0xa0001) xga->a5_test = 1; + else if (addr == 0xafffe) + xga->a5_test = 2; xga->on = 0; vga_on = 1; @@ -1479,7 +1481,7 @@ svga_read_common(uint32_t addr, uint8_t linear, void *priv) ret = xga->test; xga->on = 1; vga_on = 0; - } else if ((addr == 0xa0000) && xga->a5_test) { /*This is required by XGAKIT to pass the memory test*/ + } else if ((addr == 0xa0000) && (xga->a5_test == 1)) { /*This is required by XGAKIT to pass the memory test*/ svga_log("A5 test bank = %x.\n", addr); addr += xga->read_bank; ret = xga->vram[addr & xga->vram_mask]; diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 29769d599..b4198eefd 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -344,10 +344,8 @@ video_reset(int card) monitor_index_global = 0; loadfont("roms/video/mda/mda.rom", 0); - if ((card != VID_NONE) - && !machine_has_flags(machine, MACHINE_VIDEO_ONLY) - && (gfxcard[1] != 0) - && device_is_valid(video_card_getdevice(gfxcard[1]), machine)) { + if ((card != VID_NONE) && !machine_has_flags(machine, MACHINE_VIDEO_ONLY) && + (gfxcard[1] > VID_INTERNAL) && device_is_valid(video_card_getdevice(gfxcard[1]), machine)) { video_monitor_init(1); monitor_index_global = 1; device_add(video_cards[gfxcard[1]].device); @@ -355,7 +353,7 @@ video_reset(int card) } /* Do not initialize internal cards here. */ - if ((card != VID_NONE) && (card != VID_INTERNAL) && !machine_has_flags(machine, MACHINE_VIDEO_ONLY)) { + if ((card > VID_INTERNAL) && !machine_has_flags(machine, MACHINE_VIDEO_ONLY)) { vid_table_log("VIDEO: initializing '%s'\n", video_cards[card].device->name); video_prepare(); diff --git a/src/video/video.c b/src/video/video.c index 4e4ed332e..34e602e39 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -80,6 +80,8 @@ volatile int screenshots = 0; uint8_t edatlookup[4][4]; uint8_t fontdat[2048][8]; /* IBM CGA font */ uint8_t fontdatm[2048][16]; /* IBM MDA font */ +uint8_t fontdat2[2048][8]; /* IBM CGA 2nd instance font */ +uint8_t fontdatm2[2048][16]; /* IBM MDA 2nd instance font */ uint8_t fontdatw[512][32]; /* Wyse700 font */ uint8_t fontdat8x12[256][16]; /* MDSI Genius font */ uint8_t fontdat12x18[256][36]; /* IM1024 font */ @@ -1088,6 +1090,19 @@ loadfont_common(FILE *f, int format) for (d = 0; d < 8; d++) fontdat[c][d] = fgetc(f) & 0xff; break; + + + case 11: /* PC200 */ + for (d = 0; d < 4; d++) { + /* There are 4 fonts in the ROM */ + for (c = 0; c < 256; c++) /* 8x14 MDA in 8x16 cell */ + (void) !fread(&fontdatm2[256 * d + c][0], 1, 16, f); + for (c = 0; c < 256; c++) { /* 8x8 CGA in 8x16 cell */ + (void) !fread(&fontdat2[256 * d + c][0], 1, 8, f); + fseek(f, 8, SEEK_CUR); + } + } + break; } (void) fclose(f);